<commit_before>#![feature(old_io)]
#![feature(std_misc)]
#![feature(step_by)]

use std::old_io::{timer, Timer};
use std::time::duration::Duration;
use std::sync::mpsc;

fn main() {
    let interval = Duration::milliseconds(1000);
    // Create a timer object
    let mut timer = Timer::new().unwrap();

    // Create a one-shot notification
    // (superfluous type annotation)
    let oneshot: mpsc::Receiver<()> = timer.oneshot(interval);

    println!("Wait {} ms...", interval.num_milliseconds());

    // Block the thread until notification arrives
    let _ = oneshot.recv();

    println!("Done");

    println!("Sleep for {} ms...", interval.num_milliseconds());

    // This is equivalent to `timer.oneshot(interval).recv()`
    timer::sleep(interval);

    println!("Done");

    // The same timer can be used to generate periodic notifications
    // (superfluous type annotation)
    let metronome: mpsc::Receiver<()> = timer.periodic(interval);

    println!("Countdown");
    for i in (5i32..0).step_by(-1) {
        // This loop will run once every second
        let _ = metronome.recv();

        println!("{}", i);
    }
    let _ = metronome.recv();
    println!("Ignition!");
}
<commit_msg>Trim timer to what remains in std<commit_after>use std::thread;

fn main() {
    let interval = 1000;

    println!("Block for {} ms...", interval);
    thread::park_timeout_ms(interval);

    println!("Done");

    println!("Sleep for {} ms...", interval);
    thread::sleep_ms(interval);

    println!("Done");
}
<|endoftext|>


<commit_before>// &'static is a "lifetime specifier", something you'll learn more about later
pub fn hello() -> &'static str {
    "Goodbye, Mars!"
}
<commit_msg>Solve hello world<commit_after>// &'static is a "lifetime specifier", something you'll learn more about later
pub fn hello() -> &'static str {
    "Hello, World!"
}
<|endoftext|>


<commit_before>use std::error::Error as StdError;
use std::fmt::{Display, Formatter, Result as FmtResult};
use super::Permissions;

/// An error returned from the [`model`] module.
///
/// This is always wrapped within the library's [`Error::Model`] variant.
///
/// # Examples
///
/// Matching an [`Error`] with this variant would look something like the
/// following for the [`GuildId::ban`] method, which in this example is used to
/// re-ban all members with an odd discriminator:
///
/// ```rust,no_run
/// # #[cfg(feature="client")]
/// # fn try_main() -> Result<(), Box<Error>> {
/// use serenity::{Client, Error};
/// use serenity::model::ModelError;
/// use std::env;
///
/// let token = env::var("DISCORD_BOT_TOKEN")?;
/// let mut client = Client::new(&token);
///
/// client.on_member_unban(|context, guild_id, user| {
///     // If the user has an even discriminator, don't re-ban them.
///     if user.discriminator % 2 == 0 {
///         return;
///     }
///
///     match guild_id.ban(user, 8) {
///         Ok(()) => {
///             // Ban successful.
///         },
///         Err(Error::Model(ModelError::DeleteMessageDaysAmount(amount))) => {
///             println!("Failed deleting {} days' worth of messages", amount);
///         },
///         Err(why) => {
///             println!("Unexpected error: {:?}", why);
///         },
///     }
/// });
/// #     Ok(())
/// # }
/// #
/// # #[cfg(feature="client")]
/// # fn main() {
/// #     try_main().unwrap();
/// # }
/// #
/// # #[cfg(not(feature="client"))]
/// # fn main() { }
/// ```
///
/// [`Error`]: ../enum.Error.html
/// [`Error::Model`]: ../enum.Error.html#variant.Model
/// [`GuildId::ban`]: struct.GuildId.html#method.ban
/// [`model`]: ./index.html
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum Error {
    /// When attempting to delete below or above the minimum and maximum allowed
    /// number of messages.
    BulkDeleteAmount,
    /// When attempting to delete a number of days' worth of messages that is
    /// not allowed.
    DeleteMessageDaysAmount(u8),
    /// Indicates that the textual content of an embed exceeds the maximum
    /// length.
    EmbedTooLarge(u64),
    /// An indication that a [guild][`Guild`] could not be found by
    /// [Id][`GuildId`] in the [`Cache`].
    ///
    /// [`Guild`]: ../model/struct.Guild.html
    /// [`GuildId`]: ../model/struct.GuildId.html
    /// [`Cache`]: ../cache/struct.Cache.html
    GuildNotFound,
    /// Indicates that you do not have the required permissions to perform an
    /// operation.
    ///
    /// The provided [`Permission`]s is the set of required permissions
    /// required.
    ///
    /// [`Permission`]: ../model/permissions/struct.Permissions.html
    InvalidPermissions(Permissions),
    /// An indicator that the [current user] can not perform an action.
    ///
    /// [current user]: ../model/struct.CurrentUser.html
    InvalidUser,
    /// An indicator that an item is missing from the [`Cache`], and the action
    /// can not be continued.
    ///
    /// [`Cache`]: ../cache/struct.Cache.html
    ItemMissing,
    /// Indicates that a [`Message`]s content was too long and will not
    /// successfully send, as the length is over 2000 codepoints, or 4000 bytes.
    ///
    /// The number of bytes larger than the limit is provided.
    ///
    /// [`Message`]: ../model/struct.Message.html
    MessageTooLong(u64),
}

impl Display for Error {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        f.write_str(self.description())
    }
}

impl StdError for Error {
    fn description(&self) -> &str {
        match *self {
            Error::BulkDeleteAmount => "Too few/many messages to bulk delete",
            Error::DeleteMessageDaysAmount(_) => "Invalid delete message days",
            Error::EmbedTooLarge(_) => "Embed too large",
            Error::GuildNotFound => "Guild not found in the cache",
            Error::InvalidPermissions(_) => "Invalid permissions",
            Error::InvalidUser => "The current user can not perform the action",
            Error::ItemMissing => "The required item is missing from the cache",
            Error::MessageTooLong(_) => "Message too large",
        }
    }
}
<commit_msg>Fix ModelError doctest<commit_after>use std::error::Error as StdError;
use std::fmt::{Display, Formatter, Result as FmtResult};
use super::Permissions;

/// An error returned from the [`model`] module.
///
/// This is always wrapped within the library's [`Error::Model`] variant.
///
/// # Examples
///
/// Matching an [`Error`] with this variant would look something like the
/// following for the [`GuildId::ban`] method, which in this example is used to
/// re-ban all members with an odd discriminator:
///
/// ```rust,no_run
/// # #[cfg(feature="client")]
/// # use std::error::Error;
/// #
/// # #[cfg(feature="client")]
/// # fn try_main() -> Result<(), Box<Error>> {
/// use serenity::{Client, Error};
/// use serenity::model::ModelError;
/// use std::env;
///
/// let token = env::var("DISCORD_BOT_TOKEN")?;
/// let mut client = Client::new(&token);
///
/// client.on_member_unban(|context, guild_id, user| {
///     // If the user has an even discriminator, don't re-ban them.
///     if user.discriminator % 2 == 0 {
///         return;
///     }
///
///     match guild_id.ban(user, 8) {
///         Ok(()) => {
///             // Ban successful.
///         },
///         Err(Error::Model(ModelError::DeleteMessageDaysAmount(amount))) => {
///             println!("Failed deleting {} days' worth of messages", amount);
///         },
///         Err(why) => {
///             println!("Unexpected error: {:?}", why);
///         },
///     }
/// });
/// #     Ok(())
/// # }
/// #
/// # #[cfg(feature="client")]
/// # fn main() {
/// #     try_main().unwrap();
/// # }
/// #
/// # #[cfg(not(feature="client"))]
/// # fn main() { }
/// ```
///
/// [`Error`]: ../enum.Error.html
/// [`Error::Model`]: ../enum.Error.html#variant.Model
/// [`GuildId::ban`]: struct.GuildId.html#method.ban
/// [`model`]: ./index.html
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub enum Error {
    /// When attempting to delete below or above the minimum and maximum allowed
    /// number of messages.
    BulkDeleteAmount,
    /// When attempting to delete a number of days' worth of messages that is
    /// not allowed.
    DeleteMessageDaysAmount(u8),
    /// Indicates that the textual content of an embed exceeds the maximum
    /// length.
    EmbedTooLarge(u64),
    /// An indication that a [guild][`Guild`] could not be found by
    /// [Id][`GuildId`] in the [`Cache`].
    ///
    /// [`Guild`]: ../model/struct.Guild.html
    /// [`GuildId`]: ../model/struct.GuildId.html
    /// [`Cache`]: ../cache/struct.Cache.html
    GuildNotFound,
    /// Indicates that you do not have the required permissions to perform an
    /// operation.
    ///
    /// The provided [`Permission`]s is the set of required permissions
    /// required.
    ///
    /// [`Permission`]: ../model/permissions/struct.Permissions.html
    InvalidPermissions(Permissions),
    /// An indicator that the [current user] can not perform an action.
    ///
    /// [current user]: ../model/struct.CurrentUser.html
    InvalidUser,
    /// An indicator that an item is missing from the [`Cache`], and the action
    /// can not be continued.
    ///
    /// [`Cache`]: ../cache/struct.Cache.html
    ItemMissing,
    /// Indicates that a [`Message`]s content was too long and will not
    /// successfully send, as the length is over 2000 codepoints, or 4000 bytes.
    ///
    /// The number of bytes larger than the limit is provided.
    ///
    /// [`Message`]: ../model/struct.Message.html
    MessageTooLong(u64),
}

impl Display for Error {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        f.write_str(self.description())
    }
}

impl StdError for Error {
    fn description(&self) -> &str {
        match *self {
            Error::BulkDeleteAmount => "Too few/many messages to bulk delete",
            Error::DeleteMessageDaysAmount(_) => "Invalid delete message days",
            Error::EmbedTooLarge(_) => "Embed too large",
            Error::GuildNotFound => "Guild not found in the cache",
            Error::InvalidPermissions(_) => "Invalid permissions",
            Error::InvalidUser => "The current user can not perform the action",
            Error::ItemMissing => "The required item is missing from the cache",
            Error::MessageTooLong(_) => "Message too large",
        }
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use app_units::Au;
use device::TextureFilter;
use euclid::{TypedPoint2D, UnknownUnit};
use fnv::FnvHasher;
use profiler::BackendProfileCounters;
use std::collections::{HashMap, HashSet};
use std::f32;
use std::hash::BuildHasherDefault;
use std::{i32, usize};
use std::path::PathBuf;
use std::sync::Arc;
use tiling;
use renderer::BlendMode;
use webrender_traits::{ClipId, ColorF, DeviceUintRect, Epoch, ExternalImageData, ExternalImageId};
use webrender_traits::{ImageData, ImageFormat, NativeFontHandle, PipelineId};

// An ID for a texture that is owned by the
// texture cache module. This can include atlases
// or standalone textures allocated via the
// texture cache (e.g. if an image is too large
// to be added to an atlas). The texture cache
// manages the allocation and freeing of these
// IDs, and the rendering thread maintains a
// map from cache texture ID to native texture.

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct CacheTextureId(pub usize);

// Represents the source for a texture.
// These are passed from throughout the
// pipeline until they reach the rendering
// thread, where they are resolved to a
// native texture ID.

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum SourceTexture {
    Invalid,
    TextureCache(CacheTextureId),
    External(ExternalImageData),
    #[cfg_attr(not(feature = "webgl"), allow(dead_code))]
    /// This is actually a gl::GLuint, with the shared texture id between the
    /// main context and the WebGL context.
    WebGL(u32),
}

const COLOR_FLOAT_TO_FIXED: f32 = 255.0;
pub const ANGLE_FLOAT_TO_FIXED: f32 = 65535.0;

pub const ORTHO_NEAR_PLANE: f32 = -1000000.0;
pub const ORTHO_FAR_PLANE: f32 = 1000000.0;

#[derive(Debug, PartialEq, Eq)]
pub enum TextureSampler {
    Color0,
    Color1,
    Color2,
    CacheA8,
    CacheRGBA8,
    Data32,
    ResourceCache,
    Layers,
    RenderTasks,
    Dither,
}

impl TextureSampler {
    pub fn color(n: usize) -> TextureSampler {
        match n {
            0 => TextureSampler::Color0,
            1 => TextureSampler::Color1,
            2 => TextureSampler::Color2,
            _ => {
                panic!("There are only 3 color samplers.");
            }
        }
    }
}

/// Optional textures that can be used as a source in the shaders.
/// Textures that are not used by the batch are equal to TextureId::invalid().
#[derive(Copy, Clone, Debug)]
pub struct BatchTextures {
    pub colors: [SourceTexture; 3],
}

impl BatchTextures {
    pub fn no_texture() -> Self {
        BatchTextures {
            colors: [SourceTexture::Invalid; 3],
        }
    }
}

// In some places we need to temporarily bind a texture to any slot.
pub const DEFAULT_TEXTURE: TextureSampler = TextureSampler::Color0;

#[derive(Clone, Copy, Debug)]
pub enum VertexAttribute {
    // vertex-frequency basic attributes
    Position,
    Color,
    ColorTexCoord,
    // instance-frequency primitive attributes
    Data0,
    Data1,
}

#[derive(Clone, Copy, Debug)]
pub enum BlurAttribute {
    // vertex frequency
    Position,
    // instance frequency
    RenderTaskIndex,
    SourceTaskIndex,
    Direction,
}

#[derive(Clone, Copy, Debug)]
pub enum ClipAttribute {
    // vertex frequency
    Position,
    // instance frequency
    RenderTaskIndex,
    LayerIndex,
    DataIndex,
    SegmentIndex,
    ResourceAddress,
}

// A packed RGBA8 color ordered for vertex data or similar.

#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct PackedColor {
    pub r: u8,
    pub g: u8,
    pub b: u8,
    pub a: u8,
}

impl PackedColor {
    pub fn from_color(color: &ColorF) -> PackedColor {
        PackedColor {
            r: (0.5 + color.r * COLOR_FLOAT_TO_FIXED).floor() as u8,
            g: (0.5 + color.g * COLOR_FLOAT_TO_FIXED).floor() as u8,
            b: (0.5 + color.b * COLOR_FLOAT_TO_FIXED).floor() as u8,
            a: (0.5 + color.a * COLOR_FLOAT_TO_FIXED).floor() as u8,
        }
    }
}

#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct PackedVertex {
    pub pos: [f32; 2],
}

#[derive(Debug)]
#[repr(C)]
pub struct DebugFontVertex {
    pub x: f32,
    pub y: f32,
    pub color: PackedColor,
    pub u: f32,
    pub v: f32,
}

impl DebugFontVertex {
    pub fn new(x: f32, y: f32, u: f32, v: f32, color: PackedColor) -> DebugFontVertex {
        DebugFontVertex {
            x: x,
            y: y,
            color: color,
            u: u,
            v: v,
        }
    }
}

#[repr(C)]
pub struct DebugColorVertex {
    pub x: f32,
    pub y: f32,
    pub color: PackedColor,
}

impl DebugColorVertex {
    pub fn new(x: f32, y: f32, color: PackedColor) -> DebugColorVertex {
        DebugColorVertex {
            x: x,
            y: y,
            color: color,
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum RenderTargetMode {
    None,
    SimpleRenderTarget,
    LayerRenderTarget(i32),      // Number of texture layers
}

pub enum TextureUpdateOp {
    Create {
      width: u32,
      height: u32,
      format: ImageFormat,
      filter: TextureFilter,
      mode: RenderTargetMode,
      data: Option<ImageData>,
    },
    Update {
        page_pos_x: u32,    // the texture page position which we want to upload
        page_pos_y: u32,
        width: u32,
        height: u32,
        data: Arc<Vec<u8>>,
        stride: Option<u32>,
        offset: u32,
    },
    UpdateForExternalBuffer {
        rect: DeviceUintRect,
        id: ExternalImageId,
        channel_index: u8,
        stride: Option<u32>,
        offset: u32,
    },
    Grow {
        width: u32,
        height: u32,
        format: ImageFormat,
        filter: TextureFilter,
        mode: RenderTargetMode,
    },
    Free,
}

pub struct TextureUpdate {
    pub id: CacheTextureId,
    pub op: TextureUpdateOp,
}

pub struct TextureUpdateList {
    pub updates: Vec<TextureUpdate>,
}

impl TextureUpdateList {
    pub fn new() -> TextureUpdateList {
        TextureUpdateList {
            updates: Vec::new(),
        }
    }

    #[inline]
    pub fn push(&mut self, update: TextureUpdate) {
        self.updates.push(update);
    }
}

/// Mostly wraps a tiling::Frame, adding a bit of extra information.
pub struct RendererFrame {
    /// The last rendered epoch for each pipeline present in the frame.
    /// This information is used to know if a certain transformation on the layout has
    /// been rendered, which is necessary for reftests.
    pub pipeline_epoch_map: HashMap<PipelineId, Epoch, BuildHasherDefault<FnvHasher>>,
    /// The layers that are currently affected by the over-scrolling animation.
    pub layers_bouncing_back: HashSet<ClipId, BuildHasherDefault<FnvHasher>>,

    pub frame: Option<tiling::Frame>,
}

impl RendererFrame {
    pub fn new(pipeline_epoch_map: HashMap<PipelineId, Epoch, BuildHasherDefault<FnvHasher>>,
               layers_bouncing_back: HashSet<ClipId, BuildHasherDefault<FnvHasher>>,
               frame: Option<tiling::Frame>)
               -> RendererFrame {
        RendererFrame {
            pipeline_epoch_map: pipeline_epoch_map,
            layers_bouncing_back: layers_bouncing_back,
            frame: frame,
        }
    }
}

pub enum ResultMsg {
    RefreshShader(PathBuf),
    NewFrame(RendererFrame, TextureUpdateList, BackendProfileCounters),
}

#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AxisDirection {
    Horizontal,
    Vertical,
}

#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
pub struct StackingContextIndex(pub usize);

#[derive(Clone, Copy, Debug)]
pub struct RectUv<T, U = UnknownUnit> {
    pub top_left: TypedPoint2D<T, U>,
    pub top_right: TypedPoint2D<T, U>,
    pub bottom_left: TypedPoint2D<T, U>,
    pub bottom_right: TypedPoint2D<T, U>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum LowLevelFilterOp {
    Blur(Au, AxisDirection),
    Brightness(Au),
    Contrast(Au),
    Grayscale(Au),
    /// Fixed-point in `ANGLE_FLOAT_TO_FIXED` units.
    HueRotate(i32),
    Invert(Au),
    Opacity(Au),
    Saturate(Au),
    Sepia(Au),
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum HardwareCompositeOp {
    PremultipliedAlpha,
}

impl HardwareCompositeOp {
    pub fn to_blend_mode(&self) -> BlendMode {
        match *self {
            HardwareCompositeOp::PremultipliedAlpha => BlendMode::PremultipliedAlpha,
        }
    }
}
<commit_msg>Remove unused import<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use app_units::Au;
use device::TextureFilter;
use euclid::{TypedPoint2D, UnknownUnit};
use fnv::FnvHasher;
use profiler::BackendProfileCounters;
use std::collections::{HashMap, HashSet};
use std::f32;
use std::hash::BuildHasherDefault;
use std::{i32, usize};
use std::path::PathBuf;
use std::sync::Arc;
use tiling;
use renderer::BlendMode;
use webrender_traits::{ClipId, ColorF, DeviceUintRect, Epoch, ExternalImageData, ExternalImageId};
use webrender_traits::{ImageData, ImageFormat, PipelineId};

// An ID for a texture that is owned by the
// texture cache module. This can include atlases
// or standalone textures allocated via the
// texture cache (e.g. if an image is too large
// to be added to an atlas). The texture cache
// manages the allocation and freeing of these
// IDs, and the rendering thread maintains a
// map from cache texture ID to native texture.

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct CacheTextureId(pub usize);

// Represents the source for a texture.
// These are passed from throughout the
// pipeline until they reach the rendering
// thread, where they are resolved to a
// native texture ID.

#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub enum SourceTexture {
    Invalid,
    TextureCache(CacheTextureId),
    External(ExternalImageData),
    #[cfg_attr(not(feature = "webgl"), allow(dead_code))]
    /// This is actually a gl::GLuint, with the shared texture id between the
    /// main context and the WebGL context.
    WebGL(u32),
}

const COLOR_FLOAT_TO_FIXED: f32 = 255.0;
pub const ANGLE_FLOAT_TO_FIXED: f32 = 65535.0;

pub const ORTHO_NEAR_PLANE: f32 = -1000000.0;
pub const ORTHO_FAR_PLANE: f32 = 1000000.0;

#[derive(Debug, PartialEq, Eq)]
pub enum TextureSampler {
    Color0,
    Color1,
    Color2,
    CacheA8,
    CacheRGBA8,
    Data32,
    ResourceCache,
    Layers,
    RenderTasks,
    Dither,
}

impl TextureSampler {
    pub fn color(n: usize) -> TextureSampler {
        match n {
            0 => TextureSampler::Color0,
            1 => TextureSampler::Color1,
            2 => TextureSampler::Color2,
            _ => {
                panic!("There are only 3 color samplers.");
            }
        }
    }
}

/// Optional textures that can be used as a source in the shaders.
/// Textures that are not used by the batch are equal to TextureId::invalid().
#[derive(Copy, Clone, Debug)]
pub struct BatchTextures {
    pub colors: [SourceTexture; 3],
}

impl BatchTextures {
    pub fn no_texture() -> Self {
        BatchTextures {
            colors: [SourceTexture::Invalid; 3],
        }
    }
}

// In some places we need to temporarily bind a texture to any slot.
pub const DEFAULT_TEXTURE: TextureSampler = TextureSampler::Color0;

#[derive(Clone, Copy, Debug)]
pub enum VertexAttribute {
    // vertex-frequency basic attributes
    Position,
    Color,
    ColorTexCoord,
    // instance-frequency primitive attributes
    Data0,
    Data1,
}

#[derive(Clone, Copy, Debug)]
pub enum BlurAttribute {
    // vertex frequency
    Position,
    // instance frequency
    RenderTaskIndex,
    SourceTaskIndex,
    Direction,
}

#[derive(Clone, Copy, Debug)]
pub enum ClipAttribute {
    // vertex frequency
    Position,
    // instance frequency
    RenderTaskIndex,
    LayerIndex,
    DataIndex,
    SegmentIndex,
    ResourceAddress,
}

// A packed RGBA8 color ordered for vertex data or similar.

#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct PackedColor {
    pub r: u8,
    pub g: u8,
    pub b: u8,
    pub a: u8,
}

impl PackedColor {
    pub fn from_color(color: &ColorF) -> PackedColor {
        PackedColor {
            r: (0.5 + color.r * COLOR_FLOAT_TO_FIXED).floor() as u8,
            g: (0.5 + color.g * COLOR_FLOAT_TO_FIXED).floor() as u8,
            b: (0.5 + color.b * COLOR_FLOAT_TO_FIXED).floor() as u8,
            a: (0.5 + color.a * COLOR_FLOAT_TO_FIXED).floor() as u8,
        }
    }
}

#[derive(Debug, Clone, Copy)]
#[repr(C)]
pub struct PackedVertex {
    pub pos: [f32; 2],
}

#[derive(Debug)]
#[repr(C)]
pub struct DebugFontVertex {
    pub x: f32,
    pub y: f32,
    pub color: PackedColor,
    pub u: f32,
    pub v: f32,
}

impl DebugFontVertex {
    pub fn new(x: f32, y: f32, u: f32, v: f32, color: PackedColor) -> DebugFontVertex {
        DebugFontVertex {
            x: x,
            y: y,
            color: color,
            u: u,
            v: v,
        }
    }
}

#[repr(C)]
pub struct DebugColorVertex {
    pub x: f32,
    pub y: f32,
    pub color: PackedColor,
}

impl DebugColorVertex {
    pub fn new(x: f32, y: f32, color: PackedColor) -> DebugColorVertex {
        DebugColorVertex {
            x: x,
            y: y,
            color: color,
        }
    }
}

#[derive(Copy, Clone, Debug, PartialEq)]
pub enum RenderTargetMode {
    None,
    SimpleRenderTarget,
    LayerRenderTarget(i32),      // Number of texture layers
}

pub enum TextureUpdateOp {
    Create {
      width: u32,
      height: u32,
      format: ImageFormat,
      filter: TextureFilter,
      mode: RenderTargetMode,
      data: Option<ImageData>,
    },
    Update {
        page_pos_x: u32,    // the texture page position which we want to upload
        page_pos_y: u32,
        width: u32,
        height: u32,
        data: Arc<Vec<u8>>,
        stride: Option<u32>,
        offset: u32,
    },
    UpdateForExternalBuffer {
        rect: DeviceUintRect,
        id: ExternalImageId,
        channel_index: u8,
        stride: Option<u32>,
        offset: u32,
    },
    Grow {
        width: u32,
        height: u32,
        format: ImageFormat,
        filter: TextureFilter,
        mode: RenderTargetMode,
    },
    Free,
}

pub struct TextureUpdate {
    pub id: CacheTextureId,
    pub op: TextureUpdateOp,
}

pub struct TextureUpdateList {
    pub updates: Vec<TextureUpdate>,
}

impl TextureUpdateList {
    pub fn new() -> TextureUpdateList {
        TextureUpdateList {
            updates: Vec::new(),
        }
    }

    #[inline]
    pub fn push(&mut self, update: TextureUpdate) {
        self.updates.push(update);
    }
}

/// Mostly wraps a tiling::Frame, adding a bit of extra information.
pub struct RendererFrame {
    /// The last rendered epoch for each pipeline present in the frame.
    /// This information is used to know if a certain transformation on the layout has
    /// been rendered, which is necessary for reftests.
    pub pipeline_epoch_map: HashMap<PipelineId, Epoch, BuildHasherDefault<FnvHasher>>,
    /// The layers that are currently affected by the over-scrolling animation.
    pub layers_bouncing_back: HashSet<ClipId, BuildHasherDefault<FnvHasher>>,

    pub frame: Option<tiling::Frame>,
}

impl RendererFrame {
    pub fn new(pipeline_epoch_map: HashMap<PipelineId, Epoch, BuildHasherDefault<FnvHasher>>,
               layers_bouncing_back: HashSet<ClipId, BuildHasherDefault<FnvHasher>>,
               frame: Option<tiling::Frame>)
               -> RendererFrame {
        RendererFrame {
            pipeline_epoch_map: pipeline_epoch_map,
            layers_bouncing_back: layers_bouncing_back,
            frame: frame,
        }
    }
}

pub enum ResultMsg {
    RefreshShader(PathBuf),
    NewFrame(RendererFrame, TextureUpdateList, BackendProfileCounters),
}

#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum AxisDirection {
    Horizontal,
    Vertical,
}

#[derive(Debug, Clone, Copy, Eq, Hash, PartialEq)]
pub struct StackingContextIndex(pub usize);

#[derive(Clone, Copy, Debug)]
pub struct RectUv<T, U = UnknownUnit> {
    pub top_left: TypedPoint2D<T, U>,
    pub top_right: TypedPoint2D<T, U>,
    pub bottom_left: TypedPoint2D<T, U>,
    pub bottom_right: TypedPoint2D<T, U>,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum LowLevelFilterOp {
    Blur(Au, AxisDirection),
    Brightness(Au),
    Contrast(Au),
    Grayscale(Au),
    /// Fixed-point in `ANGLE_FLOAT_TO_FIXED` units.
    HueRotate(i32),
    Invert(Au),
    Opacity(Au),
    Saturate(Au),
    Sepia(Au),
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum HardwareCompositeOp {
    PremultipliedAlpha,
}

impl HardwareCompositeOp {
    pub fn to_blend_mode(&self) -> BlendMode {
        match *self {
            HardwareCompositeOp::PremultipliedAlpha => BlendMode::PremultipliedAlpha,
        }
    }
}
<|endoftext|>


<commit_before>/// Quasi-quotation macro that accepts input like the [`quote!`] macro but uses
/// type inference to figure out a return type for those tokens.
///
/// [`quote!`]: https://docs.rs/quote/1.0/quote/index.html
///
/// The return type can be any syntax tree node that implements the [`Parse`]
/// trait.
///
/// [`Parse`]: crate::parse::Parse
///
/// ```
/// use quote::quote;
/// use syn::{parse_quote, Stmt};
///
/// fn main() {
///     let name = quote!(v);
///     let ty = quote!(u8);
///
///     let stmt: Stmt = parse_quote! {
///         let #name: #ty = Default::default();
///     };
///
///     println!("{:#?}", stmt);
/// }
/// ```
///
/// *This macro is available only if Syn is built with the `"parsing"` feature,
/// although interpolation of syntax tree nodes into the quoted tokens is only
/// supported if Syn is built with the `"printing"` feature as well.*
///
/// # Example
///
/// The following helper function adds a bound `T: HeapSize` to every type
/// parameter `T` in the input generics.
///
/// ```
/// use syn::{parse_quote, Generics, GenericParam};
///
/// // Add a bound `T: HeapSize` to every type parameter T.
/// fn add_trait_bounds(mut generics: Generics) -> Generics {
///     for param in &mut generics.params {
///         if let GenericParam::Type(type_param) = param {
///             type_param.bounds.push(parse_quote!(HeapSize));
///         }
///     }
///     generics
/// }
/// ```
///
/// # Special cases
///
/// This macro can parse the following additional types as a special case even
/// though they do not implement the `Parse` trait.
///
/// - [`Attribute`] — parses one attribute, allowing either outer like `#[...]`
///   or inner like `#![...]`
/// - [`Punctuated<T, P>`] — parses zero or more `T` separated by punctuation
///   `P` with optional trailing punctuation
/// - [`Vec<Stmt>`] — parses the same as `Block::parse_within`
///
/// [`Punctuated<T, P>`]: crate::punctuated::Punctuated
/// [`Vec<Stmt>`]: Block::parse_within
///
/// # Panics
///
/// Panics if the tokens fail to parse as the expected syntax tree type. The
/// caller is responsible for ensuring that the input tokens are syntactically
/// valid.
//
// TODO: allow Punctuated to be inferred as intra doc link, currently blocked on
// https://github.com/rust-lang/rust/issues/62834
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "parsing", feature = "printing"))))]
#[macro_export]
macro_rules! parse_quote {
    ($($tt:tt)*) => {
        $crate::parse_quote::parse($crate::__private::quote::quote!($($tt)*))
    };
}

////////////////////////////////////////////////////////////////////////////////
// Can parse any type that implements Parse.

use crate::parse::{Parse, ParseStream, Parser, Result};
use proc_macro2::TokenStream;

// Not public API.
#[doc(hidden)]
pub fn parse<T: ParseQuote>(token_stream: TokenStream) -> T {
    let parser = T::parse;
    match parser.parse2(token_stream) {
        Ok(t) => t,
        Err(err) => panic!("{}", err),
    }
}

// Not public API.
#[doc(hidden)]
pub trait ParseQuote: Sized {
    fn parse(input: ParseStream) -> Result<Self>;
}

impl<T: Parse> ParseQuote for T {
    fn parse(input: ParseStream) -> Result<Self> {
        <T as Parse>::parse(input)
    }
}

////////////////////////////////////////////////////////////////////////////////
// Any other types that we want `parse_quote!` to be able to parse.

use crate::punctuated::Punctuated;
#[cfg(any(feature = "full", feature = "derive"))]
use crate::{attr, Attribute};
#[cfg(feature = "full")]
use crate::{Block, Stmt};

#[cfg(any(feature = "full", feature = "derive"))]
impl ParseQuote for Attribute {
    fn parse(input: ParseStream) -> Result<Self> {
        if input.peek(Token![#]) && input.peek2(Token![!]) {
            attr::parsing::single_parse_inner(input)
        } else {
            attr::parsing::single_parse_outer(input)
        }
    }
}

impl<T: Parse, P: Parse> ParseQuote for Punctuated<T, P> {
    fn parse(input: ParseStream) -> Result<Self> {
        Self::parse_terminated(input)
    }
}

#[cfg(feature = "full")]
impl ParseQuote for Vec<Stmt> {
    fn parse(input: ParseStream) -> Result<Self> {
        Block::parse_within(input)
    }
}
<commit_msg>Add parse_quote_spanned macro = parse_quote + quote_spanned<commit_after>/// Quasi-quotation macro that accepts input like the [`quote!`] macro but uses
/// type inference to figure out a return type for those tokens.
///
/// [`quote!`]: https://docs.rs/quote/1.0/quote/index.html
///
/// The return type can be any syntax tree node that implements the [`Parse`]
/// trait.
///
/// [`Parse`]: crate::parse::Parse
///
/// ```
/// use quote::quote;
/// use syn::{parse_quote, Stmt};
///
/// fn main() {
///     let name = quote!(v);
///     let ty = quote!(u8);
///
///     let stmt: Stmt = parse_quote! {
///         let #name: #ty = Default::default();
///     };
///
///     println!("{:#?}", stmt);
/// }
/// ```
///
/// *This macro is available only if Syn is built with the `"parsing"` feature,
/// although interpolation of syntax tree nodes into the quoted tokens is only
/// supported if Syn is built with the `"printing"` feature as well.*
///
/// # Example
///
/// The following helper function adds a bound `T: HeapSize` to every type
/// parameter `T` in the input generics.
///
/// ```
/// use syn::{parse_quote, Generics, GenericParam};
///
/// // Add a bound `T: HeapSize` to every type parameter T.
/// fn add_trait_bounds(mut generics: Generics) -> Generics {
///     for param in &mut generics.params {
///         if let GenericParam::Type(type_param) = param {
///             type_param.bounds.push(parse_quote!(HeapSize));
///         }
///     }
///     generics
/// }
/// ```
///
/// # Special cases
///
/// This macro can parse the following additional types as a special case even
/// though they do not implement the `Parse` trait.
///
/// - [`Attribute`] — parses one attribute, allowing either outer like `#[...]`
///   or inner like `#![...]`
/// - [`Punctuated<T, P>`] — parses zero or more `T` separated by punctuation
///   `P` with optional trailing punctuation
/// - [`Vec<Stmt>`] — parses the same as `Block::parse_within`
///
/// [`Punctuated<T, P>`]: crate::punctuated::Punctuated
/// [`Vec<Stmt>`]: Block::parse_within
///
/// # Panics
///
/// Panics if the tokens fail to parse as the expected syntax tree type. The
/// caller is responsible for ensuring that the input tokens are syntactically
/// valid.
//
// TODO: allow Punctuated to be inferred as intra doc link, currently blocked on
// https://github.com/rust-lang/rust/issues/62834
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "parsing", feature = "printing"))))]
#[macro_export]
macro_rules! parse_quote {
    ($($tt:tt)*) => {
        $crate::parse_quote::parse($crate::__private::quote::quote!($($tt)*))
    };
}

/// This macro is [`parse_quote!`] + [`quote_spanned!`][quote::quote_spanned].
///
/// Please refer to each of their documentation.
///
/// # Example
///
/// ```
/// use quote::{quote, quote_spanned};
/// use syn::spanned::Spanned;
/// use syn::{parse_quote_spanned, ReturnType, Signature};
///
/// // Changes `fn()` to `fn() -> Pin<Box<dyn Future<Output = ()>>>`,
/// // and `fn() -> T` to `fn() -> Pin<Box<dyn Future<Output = T>>>`,
/// // without introducing any call_site() spans.
/// fn make_ret_pinned_future(sig: &mut Signature) {
///     let ret = match &sig.output {
///         ReturnType::Default => quote_spanned!(sig.paren_token.span=> ()),
///         ReturnType::Type(_, ret) => quote!(#ret),
///     };
///     sig.output = parse_quote_spanned! {ret.span()=>
///         -> ::std::pin::Pin<::std::boxed::Box<dyn ::std::future::Future<Output = #ret>>>
///     };
/// }
/// ```
#[cfg_attr(doc_cfg, doc(cfg(all(feature = "parsing", feature = "printing"))))]
#[macro_export]
macro_rules! parse_quote_spanned {
    ($span:expr=> $($tt:tt)*) => {
        $crate::parse_quote::parse($crate::__private::quote::quote_spanned!($span=> $($tt)*))
    };
}

////////////////////////////////////////////////////////////////////////////////
// Can parse any type that implements Parse.

use crate::parse::{Parse, ParseStream, Parser, Result};
use proc_macro2::TokenStream;

// Not public API.
#[doc(hidden)]
pub fn parse<T: ParseQuote>(token_stream: TokenStream) -> T {
    let parser = T::parse;
    match parser.parse2(token_stream) {
        Ok(t) => t,
        Err(err) => panic!("{}", err),
    }
}

// Not public API.
#[doc(hidden)]
pub trait ParseQuote: Sized {
    fn parse(input: ParseStream) -> Result<Self>;
}

impl<T: Parse> ParseQuote for T {
    fn parse(input: ParseStream) -> Result<Self> {
        <T as Parse>::parse(input)
    }
}

////////////////////////////////////////////////////////////////////////////////
// Any other types that we want `parse_quote!` to be able to parse.

use crate::punctuated::Punctuated;
#[cfg(any(feature = "full", feature = "derive"))]
use crate::{attr, Attribute};
#[cfg(feature = "full")]
use crate::{Block, Stmt};

#[cfg(any(feature = "full", feature = "derive"))]
impl ParseQuote for Attribute {
    fn parse(input: ParseStream) -> Result<Self> {
        if input.peek(Token![#]) && input.peek2(Token![!]) {
            attr::parsing::single_parse_inner(input)
        } else {
            attr::parsing::single_parse_outer(input)
        }
    }
}

impl<T: Parse, P: Parse> ParseQuote for Punctuated<T, P> {
    fn parse(input: ParseStream) -> Result<Self> {
        Self::parse_terminated(input)
    }
}

#[cfg(feature = "full")]
impl ParseQuote for Vec<Stmt> {
    fn parse(input: ParseStream) -> Result<Self> {
        Block::parse_within(input)
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::path::PathBuf;

pub struct EnvironmentUtils {}

impl EnvironmentUtils {
    pub fn sovrin_home_path() -> PathBuf {
        // TODO: FIXME: Provide better handling for the unknown home path case!!!
        let mut path = env::home_dir().unwrap_or(PathBuf::from("/home/sovrin"));
        path.push(".sovrin");
        path
    }

    pub fn wallet_home_path() -> PathBuf {
        let mut path = EnvironmentUtils::sovrin_home_path();
        path.push("wallet");
        path
    }

    pub fn wallet_path(wallet_name: &str) -> PathBuf {
        let mut path = EnvironmentUtils::wallet_home_path();
        path.push(wallet_name);
        path
    }

    pub fn pool_home_path() -> PathBuf {
        let mut path = EnvironmentUtils::sovrin_home_path();
        path.push("pool");
        path
    }

    pub fn pool_path(pool_name: &str) -> PathBuf {
        let mut path = EnvironmentUtils::pool_home_path();
        path.push(pool_name);
        path
    }

    pub fn tmp_path() -> PathBuf {
        let mut path = env::temp_dir();
        path.push("sovrin");
        path
    }

    pub fn tmp_file_path(file_name: &str) -> PathBuf {
        let mut path = EnvironmentUtils::tmp_path();
        path.push(file_name);
        path
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn sovrin_home_path_works() {
        let path = EnvironmentUtils::sovrin_home_path();

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains(".sovrin"));
    }

    #[test]
    fn wallet_home_path_works() {
        let path = EnvironmentUtils::wallet_home_path();

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains(".sovrin/wallet"));
    }

    #[test]
    fn wallet_path_works() {
        let path = EnvironmentUtils::wallet_path("wallet1");

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains(".sovrin/wallet/wallet1"));
    }

    #[test]
    fn pool_home_path_works() {
        let path = EnvironmentUtils::pool_home_path();

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains(".sovrin/pool"));
    }

    #[test]
    fn pool_path_works() {
        let path = EnvironmentUtils::pool_path("pool1");

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains(".sovrin/pool/pool1"));
    }

    #[test]
    fn tmp_path_works() {
        let path = EnvironmentUtils::tmp_path();

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains("sovrin"));
    }

    #[test]
    fn tmp_file_path_works() {
        let path = EnvironmentUtils::tmp_file_path("test.txt");

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains("sovrin"));
        assert!(path.to_string_lossy().contains("test.txt"));
    }
}<commit_msg>fix home dir path for IOS platform<commit_after>use std::env;
use std::path::PathBuf;

pub struct EnvironmentUtils {}

impl EnvironmentUtils {
    pub fn sovrin_home_path() -> PathBuf {
        // TODO: FIXME: Provide better handling for the unknown home path case!!!
        let mut path = env::home_dir().unwrap_or(PathBuf::from("/home/sovrin"));
        if cfg!(target_os = "ios") {
            path.push("Documents/.sovrin");
        }
        else {
            path.push(".sovrin");
        }
        path
    }

    pub fn wallet_home_path() -> PathBuf {
        let mut path = EnvironmentUtils::sovrin_home_path();
        path.push("wallet");
        path
    }

    pub fn wallet_path(wallet_name: &str) -> PathBuf {
        let mut path = EnvironmentUtils::wallet_home_path();
        path.push(wallet_name);
        path
    }

    pub fn pool_home_path() -> PathBuf {
        let mut path = EnvironmentUtils::sovrin_home_path();
        path.push("pool");
        path
    }

    pub fn pool_path(pool_name: &str) -> PathBuf {
        let mut path = EnvironmentUtils::pool_home_path();
        path.push(pool_name);
        path
    }

    pub fn tmp_path() -> PathBuf {
        let mut path = env::temp_dir();
        path.push("sovrin");
        path
    }

    pub fn tmp_file_path(file_name: &str) -> PathBuf {
        let mut path = EnvironmentUtils::tmp_path();
        path.push(file_name);
        path
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn sovrin_home_path_works() {
        let path = EnvironmentUtils::sovrin_home_path();

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains(".sovrin"));
    }

    #[test]
    fn wallet_home_path_works() {
        let path = EnvironmentUtils::wallet_home_path();

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains(".sovrin/wallet"));
    }

    #[test]
    fn wallet_path_works() {
        let path = EnvironmentUtils::wallet_path("wallet1");

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains(".sovrin/wallet/wallet1"));
    }

    #[test]
    fn pool_home_path_works() {
        let path = EnvironmentUtils::pool_home_path();

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains(".sovrin/pool"));
    }

    #[test]
    fn pool_path_works() {
        let path = EnvironmentUtils::pool_path("pool1");

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains(".sovrin/pool/pool1"));
    }

    #[test]
    fn tmp_path_works() {
        let path = EnvironmentUtils::tmp_path();

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains("sovrin"));
    }

    #[test]
    fn tmp_file_path_works() {
        let path = EnvironmentUtils::tmp_file_path("test.txt");

        assert!(path.is_absolute());
        assert!(path.has_root());
        assert!(path.to_string_lossy().contains("sovrin"));
        assert!(path.to_string_lossy().contains("test.txt"));
    }
}<|endoftext|>


<commit_before>use crate::{enumerations::ParsingError, range::ParseError};
use base64;
use chrono;
use http;
use http::header::ToStrError;
use hyper::{self, body, Body, StatusCode};
use serde_json;
use serde_xml_rs;
use std;
use std::io::Error as IOError;
use std::num;
use std::num::ParseIntError;
use std::str;
use std::str::ParseBoolError;
use std::string;
use url::ParseError as URLParseError;
use uuid;
use xml::BuilderError as XMLError;

quick_error! {
    #[derive(Debug)]
     pub enum AzurePathParseError {
        PathSeparatorNotFoundError {
            display("Path separator not found")
        }
        MultiplePathSeparatorsFoundError {
            display("Multiple path separators found")
        }
        MissingContainerError {
            display("Missing container name")
        }
        MissingBlobError {
            display("Missing blob name")
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub struct UnexpectedValue {
    expected: Vec<String>,
    received: String,
}

impl UnexpectedValue {
    pub fn new(expected: String, received: String) -> UnexpectedValue {
        Self {
            expected: vec![expected],
            received,
        }
    }

    pub fn new_multiple(allowed: Vec<String>, received: String) -> Self {
        UnexpectedValue {
            expected: allowed,
            received,
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub struct UnexpectedHTTPResult {
    expected: Vec<StatusCode>,
    received: StatusCode,
    body: String,
}

impl UnexpectedHTTPResult {
    pub fn new(expected: StatusCode, received: StatusCode, body: &str) -> UnexpectedHTTPResult {
        UnexpectedHTTPResult {
            expected: vec![expected],
            received,
            body: body.to_owned(),
        }
    }

    pub fn new_multiple(
        allowed: Vec<StatusCode>,
        received: StatusCode,
        body: &str,
    ) -> UnexpectedHTTPResult {
        UnexpectedHTTPResult {
            expected: allowed,
            received,
            body: body.to_owned(),
        }
    }

    pub fn status_code(&self) -> StatusCode {
        self.received
    }
}

impl std::fmt::Display for UnexpectedHTTPResult {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "Unexpected HTTP result (expected: {:?}, received: {:?})",
            self.expected, self.received
        )
    }
}

impl std::error::Error for UnexpectedHTTPResult {
    fn description(&self) -> &str {
        "Unexpected HTTP result"
    }

    fn cause(&self) -> Option<&dyn std::error::Error> {
        None
    }
}

quick_error! {
    #[derive(Debug)]
    pub enum Not512ByteAlignedError {
        StartRange(u: u64) {
            display("start range not 512-byte aligned: {}", u)
        }
        EndRange(u: u64) {
            display("end range not 512-byte aligned: {}", u)
        }
    }
}

quick_error! {
    #[derive(Debug)]
    pub enum Parse512AlignedError {
        SplitNotFound {
            display("split not found")
        }
        ParseIntError(p :ParseIntError) {
            from()
            display("parse int error: {}", p)
            cause(p)
        }
        Not512ByteAlignedError(nb: Not512ByteAlignedError)  {
            from()
            display("not 512 byte aligned error: {}", nb)
            cause(nb)
        }
    }
}

quick_error! {
    #[derive(Debug)]
    pub enum AzureError {
        PageNot512ByteAlignedError(start: u64, end: u64) {
            display("{}-{} is not 512 byte aligned", start, end)
        }
         Not512ByteAlignedError(size: u64) {
            display("{} is not 512 byte aligned", size)
        }
        Base64DecodeError(err: base64::DecodeError) {
            from()
            display("base64 decode error: {}", err)
            cause(err)
        }
        DigestNot16BytesLong(len : u64) {
            display("digest length {} bytes instead of 16", len)
        }
        ParseBoolError(err: ParseBoolError) {
            from()
            display("parse bool error: {}", err)
            cause(err)
        }
        ToStrError(err: ToStrError) {
            from()
            display("to str error: {}", err)
            cause(err)
        }
        JSONError(err: serde_json::Error) {
            from()
            display("json error: {}", err)
            cause(err)
        }
        HyperError(err: hyper::error::Error){
            from()
            display("Hyper error: {}", err)
            cause(err)
        }
        IOError(err: IOError){
            from()
            display("IO error: {}", err)
            cause(err)
        }
        XMLError(err: XMLError){
            from()
            display("XML error: {}", err)
            cause(err)
        }
        UnexpectedXMLError(err: String) {
            display("UnexpectedXMLError: {}", err)
        }
        AzurePathParseError(err: AzurePathParseError){
            from()
            display("Azure Path parse error: {}", err)
            cause(err)
        }
        UnexpectedHTTPResult(err: UnexpectedHTTPResult){
            from()
            display("UnexpectedHTTPResult error: {}", err)
        }
        UnexpectedValue(err: UnexpectedValue){
            from()
            display("UnexpectedValue error: {:?}", err)
        }
        HeaderNotFound(msg: String) {
            display("Header not found: {}", msg)
        }
        ResponseParsingError(err: TraversingError){
            from()
            display("Traversing error: {}", err)
            cause(err)
        }
        ParseIntError(err: num::ParseIntError){
            from()
            display("Parse int error: {}", err)
            cause(err)
        }
        ParseFloatError(err: std::num::ParseFloatError) {
            from()
            display("Parse float error: {}", err)
            cause(err)
        }
        ParseError(err: ParseError){
            from()
            display("Parse error")
        }
        GenericError
        GenericErrorWithText(err: String) {
            display("Generic error: {}", err)
        }
        ParsingError(err: ParsingError){
            from()
            display("Parsing error")
        }
        InputParametersError(msg: String) {
            display("Input parameters error: {}", msg)
        }
        URLParseError(err: URLParseError){
            from()
            display("URL parse error: {}", err)
            cause(err)
        }
        HttpPrepareError(err: http::Error) {
            from()
            display("Error preparing HTTP request: {}", err) // todo: revisit usages / message here
            cause(err)
        }
        ParseUuidError(err: uuid::Error){
            from()
            display("uuid error: {}", err)
            cause(err)
        }
       ChronoParserError(err: chrono::ParseError) {
            from()
            display("Chrono parser error: {}", err)
            cause(err)
        }
        UTF8Error(err: str::Utf8Error) {
            from()
            display("UTF8 conversion error: {}", err)
            cause(err)
        }
        FromUtf8Error(err: string::FromUtf8Error) {
            from()
            display("FromUTF8 error: {}", err)
            cause(err)
        }
        SerdeXMLDeserializationError(err:serde_xml_rs::Error) {
            from()
            display("XML deserialization error: {}", err)
            cause(err)
        }
        MissingHeaderError(header: String) {
            display("A required header is missing: {}", header)
        }
        MissingValueError(value: String, expected_type: String) {
            display("An expected JSON node is missing: {} of expected type {}", value, expected_type)
        }
        FailureError(error: failure::Error) {
            display("failure::Error error {}", error)
        }
    }
}

quick_error! {
    #[derive(Debug)]
    pub enum TraversingError {
        PathNotFound(msg: String) {
            display("Path not found: {}", msg)
        }
        MultipleNode(msg: String) {
            display("Multiple node: {}", msg)
        }
        EnumerationNotMatched(msg: String) {
            display("Enumeration not matched: {}", msg)
        }
        BooleanNotMatched(s: String) {
            display("Input string cannot be converted in boolean: {}", s)
        }
        UnexpectedNodeTypeError(expected: String) {
            display("Unexpected node type received: expected {}", expected)
        }
        DateTimeParseError(err: chrono::format::ParseError){
            from()
            display("DateTime parse error: {}", err)
            cause(err)
        }
        TextNotFound
        ParseIntError(err: num::ParseIntError){
            from()
            display("Parse int error: {}", err)
            cause(err)
        }
        GenericParseError(msg: String) {
            display("Generic parse error: {}", msg)
        }
        ParsingError(err: ParsingError){
            from()
            display("Parsing error: {:?}", err)
        }
   }
}

impl From<()> for AzureError {
    fn from(_: ()) -> AzureError {
        AzureError::GenericError
    }
}

impl From<failure::Error> for AzureError {
    fn from(error: failure::Error) -> AzureError {
        AzureError::FailureError(error)
    }
}

#[inline]
pub async fn extract_status_headers_and_body(
    resp: hyper::client::ResponseFuture,
) -> Result<(hyper::StatusCode, hyper::HeaderMap, body::Bytes), AzureError> {
    let res = resp.await?;
    let (head, body) = res.into_parts();
    let status = head.status;
    let headers = head.headers;
    let body = body::to_bytes(body).await?;

    Ok((status, headers, body))
}

#[inline]
pub async fn check_status_extract_headers_and_body(
    resp: hyper::client::ResponseFuture,
    expected_status_code: hyper::StatusCode,
) -> Result<(hyper::HeaderMap, body::Bytes), AzureError> {
    let (status, headers, body) = extract_status_headers_and_body(resp).await?;
    if status == expected_status_code {
        Ok((headers, body))
    } else {
        Err(AzureError::UnexpectedHTTPResult(UnexpectedHTTPResult::new(
            expected_status_code,
            status,
            str::from_utf8(&body)?,
        )))
    }
}

#[inline]
pub async fn check_status_extract_headers_and_body_as_string(
    resp: hyper::client::ResponseFuture,
    expected_status_code: hyper::StatusCode,
) -> Result<(hyper::HeaderMap, String), AzureError> {
    let (headers, body) = check_status_extract_headers_and_body(resp, expected_status_code).await?;
    let body = str::from_utf8(&body)?.to_owned();
    Ok((headers, body))
}

#[inline]
pub async fn extract_status_and_body(
    resp: hyper::client::ResponseFuture,
) -> Result<(StatusCode, String), AzureError> {
    let res = resp.await?;
    let status = res.status();
    let body = body::to_bytes(res.into_body()).await?;
    Ok((status, str::from_utf8(&body)?.to_owned()))
}

#[inline]
pub async fn extract_location_status_and_body(
    resp: hyper::client::ResponseFuture,
) -> Result<(http::StatusCode, String, String), AzureError> {
    let res = resp.await?;
    let status = res.status();
    let location: String = match res.headers().get("Location") {
        Some(header_value) => header_value.to_str()?.to_owned(),
        _ => "".to_owned(),
    };
    let body = body::to_bytes(res.into_body()).await?;
    Ok((status, location, str::from_utf8(&body)?.to_owned()))
}

#[inline]
pub async fn check_status_extract_body(
    resp: hyper::client::ResponseFuture,
    expected_status_code: hyper::StatusCode,
) -> Result<String, AzureError> {
    let (status, body) = extract_status_and_body(resp).await?;
    if status == expected_status_code {
        Ok(body)
    } else {
        Err(AzureError::UnexpectedHTTPResult(UnexpectedHTTPResult::new(
            expected_status_code,
            status,
            &body,
        )))
    }
}

pub async fn check_status_extract_body_2(
    resp: hyper::Response<Body>,
    expected_status: StatusCode,
) -> Result<String, AzureError> {
    let received_status = resp.status();

    let body = body::to_bytes(resp.into_body()).await?;
    let s = String::from_utf8(body.to_vec())?;
    debug!("body: {}", s);
    if received_status != expected_status {
        Err(AzureError::UnexpectedHTTPResult(UnexpectedHTTPResult::new(
            expected_status,
            received_status,
            &s,
        )))
    } else {
        Ok(s)
    }
}
<commit_msg>Added Sync+Send tests for AzureError<commit_after>use crate::{enumerations::ParsingError, range::ParseError};
use base64;
use chrono;
use http;
use http::header::ToStrError;
use hyper::{self, body, Body, StatusCode};
use serde_json;
use serde_xml_rs;
use std;
use std::io::Error as IOError;
use std::num;
use std::num::ParseIntError;
use std::str;
use std::str::ParseBoolError;
use std::string;
use url::ParseError as URLParseError;
use uuid;
use xml::BuilderError as XMLError;

quick_error! {
    #[derive(Debug)]
     pub enum AzurePathParseError {
        PathSeparatorNotFoundError {
            display("Path separator not found")
        }
        MultiplePathSeparatorsFoundError {
            display("Multiple path separators found")
        }
        MissingContainerError {
            display("Missing container name")
        }
        MissingBlobError {
            display("Missing blob name")
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub struct UnexpectedValue {
    expected: Vec<String>,
    received: String,
}

impl UnexpectedValue {
    pub fn new(expected: String, received: String) -> UnexpectedValue {
        Self {
            expected: vec![expected],
            received,
        }
    }

    pub fn new_multiple(allowed: Vec<String>, received: String) -> Self {
        UnexpectedValue {
            expected: allowed,
            received,
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub struct UnexpectedHTTPResult {
    expected: Vec<StatusCode>,
    received: StatusCode,
    body: String,
}

impl UnexpectedHTTPResult {
    pub fn new(expected: StatusCode, received: StatusCode, body: &str) -> UnexpectedHTTPResult {
        UnexpectedHTTPResult {
            expected: vec![expected],
            received,
            body: body.to_owned(),
        }
    }

    pub fn new_multiple(
        allowed: Vec<StatusCode>,
        received: StatusCode,
        body: &str,
    ) -> UnexpectedHTTPResult {
        UnexpectedHTTPResult {
            expected: allowed,
            received,
            body: body.to_owned(),
        }
    }

    pub fn status_code(&self) -> StatusCode {
        self.received
    }
}

impl std::fmt::Display for UnexpectedHTTPResult {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "Unexpected HTTP result (expected: {:?}, received: {:?})",
            self.expected, self.received
        )
    }
}

impl std::error::Error for UnexpectedHTTPResult {
    fn description(&self) -> &str {
        "Unexpected HTTP result"
    }

    fn cause(&self) -> Option<&dyn std::error::Error> {
        None
    }
}

quick_error! {
    #[derive(Debug)]
    pub enum Not512ByteAlignedError {
        StartRange(u: u64) {
            display("start range not 512-byte aligned: {}", u)
        }
        EndRange(u: u64) {
            display("end range not 512-byte aligned: {}", u)
        }
    }
}

quick_error! {
    #[derive(Debug)]
    pub enum Parse512AlignedError {
        SplitNotFound {
            display("split not found")
        }
        ParseIntError(p :ParseIntError) {
            from()
            display("parse int error: {}", p)
            cause(p)
        }
        Not512ByteAlignedError(nb: Not512ByteAlignedError)  {
            from()
            display("not 512 byte aligned error: {}", nb)
            cause(nb)
        }
    }
}

quick_error! {
    #[derive(Debug)]
    pub enum AzureError {
        PageNot512ByteAlignedError(start: u64, end: u64) {
            display("{}-{} is not 512 byte aligned", start, end)
        }
         Not512ByteAlignedError(size: u64) {
            display("{} is not 512 byte aligned", size)
        }
        Base64DecodeError(err: base64::DecodeError) {
            from()
            display("base64 decode error: {}", err)
            cause(err)
        }
        DigestNot16BytesLong(len : u64) {
            display("digest length {} bytes instead of 16", len)
        }
        ParseBoolError(err: ParseBoolError) {
            from()
            display("parse bool error: {}", err)
            cause(err)
        }
        ToStrError(err: ToStrError) {
            from()
            display("to str error: {}", err)
            cause(err)
        }
        JSONError(err: serde_json::Error) {
            from()
            display("json error: {}", err)
            cause(err)
        }
        HyperError(err: hyper::error::Error){
            from()
            display("Hyper error: {}", err)
            cause(err)
        }
        IOError(err: IOError){
            from()
            display("IO error: {}", err)
            cause(err)
        }
        XMLError(err: XMLError){
            from()
            display("XML error: {}", err)
            cause(err)
        }
        UnexpectedXMLError(err: String) {
            display("UnexpectedXMLError: {}", err)
        }
        AzurePathParseError(err: AzurePathParseError){
            from()
            display("Azure Path parse error: {}", err)
            cause(err)
        }
        UnexpectedHTTPResult(err: UnexpectedHTTPResult){
            from()
            display("UnexpectedHTTPResult error: {}", err)
        }
        UnexpectedValue(err: UnexpectedValue){
            from()
            display("UnexpectedValue error: {:?}", err)
        }
        HeaderNotFound(msg: String) {
            display("Header not found: {}", msg)
        }
        ResponseParsingError(err: TraversingError){
            from()
            display("Traversing error: {}", err)
            cause(err)
        }
        ParseIntError(err: num::ParseIntError){
            from()
            display("Parse int error: {}", err)
            cause(err)
        }
        ParseFloatError(err: std::num::ParseFloatError) {
            from()
            display("Parse float error: {}", err)
            cause(err)
        }
        ParseError(err: ParseError){
            from()
            display("Parse error")
        }
        GenericError
        GenericErrorWithText(err: String) {
            display("Generic error: {}", err)
        }
        ParsingError(err: ParsingError){
            from()
            display("Parsing error")
        }
        InputParametersError(msg: String) {
            display("Input parameters error: {}", msg)
        }
        URLParseError(err: URLParseError){
            from()
            display("URL parse error: {}", err)
            cause(err)
        }
        HttpPrepareError(err: http::Error) {
            from()
            display("Error preparing HTTP request: {}", err) // todo: revisit usages / message here
            cause(err)
        }
        ParseUuidError(err: uuid::Error){
            from()
            display("uuid error: {}", err)
            cause(err)
        }
       ChronoParserError(err: chrono::ParseError) {
            from()
            display("Chrono parser error: {}", err)
            cause(err)
        }
        UTF8Error(err: str::Utf8Error) {
            from()
            display("UTF8 conversion error: {}", err)
            cause(err)
        }
        FromUtf8Error(err: string::FromUtf8Error) {
            from()
            display("FromUTF8 error: {}", err)
            cause(err)
        }
        SerdeXMLDeserializationError(err:serde_xml_rs::Error) {
            from()
            display("XML deserialization error: {}", err)
            cause(err)
        }
        MissingHeaderError(header: String) {
            display("A required header is missing: {}", header)
        }
        MissingValueError(value: String, expected_type: String) {
            display("An expected JSON node is missing: {} of expected type {}", value, expected_type)
        }
        FailureError(error: failure::Error) {
            display("failure::Error error {}", error)
        }
    }
}

quick_error! {
    #[derive(Debug)]
    pub enum TraversingError {
        PathNotFound(msg: String) {
            display("Path not found: {}", msg)
        }
        MultipleNode(msg: String) {
            display("Multiple node: {}", msg)
        }
        EnumerationNotMatched(msg: String) {
            display("Enumeration not matched: {}", msg)
        }
        BooleanNotMatched(s: String) {
            display("Input string cannot be converted in boolean: {}", s)
        }
        UnexpectedNodeTypeError(expected: String) {
            display("Unexpected node type received: expected {}", expected)
        }
        DateTimeParseError(err: chrono::format::ParseError){
            from()
            display("DateTime parse error: {}", err)
            cause(err)
        }
        TextNotFound
        ParseIntError(err: num::ParseIntError){
            from()
            display("Parse int error: {}", err)
            cause(err)
        }
        GenericParseError(msg: String) {
            display("Generic parse error: {}", msg)
        }
        ParsingError(err: ParsingError){
            from()
            display("Parsing error: {:?}", err)
        }
   }
}

impl From<()> for AzureError {
    fn from(_: ()) -> AzureError {
        AzureError::GenericError
    }
}

impl From<failure::Error> for AzureError {
    fn from(error: failure::Error) -> AzureError {
        AzureError::FailureError(error)
    }
}

#[inline]
pub async fn extract_status_headers_and_body(
    resp: hyper::client::ResponseFuture,
) -> Result<(hyper::StatusCode, hyper::HeaderMap, body::Bytes), AzureError> {
    let res = resp.await?;
    let (head, body) = res.into_parts();
    let status = head.status;
    let headers = head.headers;
    let body = body::to_bytes(body).await?;

    Ok((status, headers, body))
}

#[inline]
pub async fn check_status_extract_headers_and_body(
    resp: hyper::client::ResponseFuture,
    expected_status_code: hyper::StatusCode,
) -> Result<(hyper::HeaderMap, body::Bytes), AzureError> {
    let (status, headers, body) = extract_status_headers_and_body(resp).await?;
    if status == expected_status_code {
        Ok((headers, body))
    } else {
        Err(AzureError::UnexpectedHTTPResult(UnexpectedHTTPResult::new(
            expected_status_code,
            status,
            str::from_utf8(&body)?,
        )))
    }
}

#[inline]
pub async fn check_status_extract_headers_and_body_as_string(
    resp: hyper::client::ResponseFuture,
    expected_status_code: hyper::StatusCode,
) -> Result<(hyper::HeaderMap, String), AzureError> {
    let (headers, body) = check_status_extract_headers_and_body(resp, expected_status_code).await?;
    let body = str::from_utf8(&body)?.to_owned();
    Ok((headers, body))
}

#[inline]
pub async fn extract_status_and_body(
    resp: hyper::client::ResponseFuture,
) -> Result<(StatusCode, String), AzureError> {
    let res = resp.await?;
    let status = res.status();
    let body = body::to_bytes(res.into_body()).await?;
    Ok((status, str::from_utf8(&body)?.to_owned()))
}

#[inline]
pub async fn extract_location_status_and_body(
    resp: hyper::client::ResponseFuture,
) -> Result<(http::StatusCode, String, String), AzureError> {
    let res = resp.await?;
    let status = res.status();
    let location: String = match res.headers().get("Location") {
        Some(header_value) => header_value.to_str()?.to_owned(),
        _ => "".to_owned(),
    };
    let body = body::to_bytes(res.into_body()).await?;
    Ok((status, location, str::from_utf8(&body)?.to_owned()))
}

#[inline]
pub async fn check_status_extract_body(
    resp: hyper::client::ResponseFuture,
    expected_status_code: hyper::StatusCode,
) -> Result<String, AzureError> {
    let (status, body) = extract_status_and_body(resp).await?;
    if status == expected_status_code {
        Ok(body)
    } else {
        Err(AzureError::UnexpectedHTTPResult(UnexpectedHTTPResult::new(
            expected_status_code,
            status,
            &body,
        )))
    }
}

pub async fn check_status_extract_body_2(
    resp: hyper::Response<Body>,
    expected_status: StatusCode,
) -> Result<String, AzureError> {
    let received_status = resp.status();

    let body = body::to_bytes(resp.into_body()).await?;
    let s = String::from_utf8(body.to_vec())?;
    debug!("body: {}", s);
    if received_status != expected_status {
        Err(AzureError::UnexpectedHTTPResult(UnexpectedHTTPResult::new(
            expected_status,
            received_status,
            &s,
        )))
    } else {
        Ok(s)
    }
}

#[cfg(test)]
mod test {
    use super::*;

    fn send_fn<T>(_t: T)
    where
        T: Send,
    {
    }

    fn sync_fn<T>(_t: T)
    where
        T: Sync,
    {
    }

    #[test]
    fn test_azure_error_send() {
        let e = AzureError::HeaderNotFound("Content-Length".to_owned());
        send_fn(e);
    }

    #[test]
    fn test_azure_error_sync() {
        let e = AzureError::HeaderNotFound("Content-Length".to_owned());
        sync_fn(e);
    }

    // This does not compile
    //#[test]
    //fn test_not_send() {
    //    let a = std::rc::Rc::new(100);
    //    send_fn(a);
    //}

    // This does not compile
    //#[test]
    //fn test_not_sync() {
    //    let a = std::cell::Cell::new(500);
    //    sync_fn(a);
    //}
}
<|endoftext|>


<commit_before>use entities::{ EntitiesState, EntityID, ComponentID, NativeComponentType };
use std::collections::{ HashSet, HashMap };
use std::cell::RefCell;
use std::rc::Rc;
use nalgebra::na::{ Norm, Translation, Vec2 };
use ncollide::geom::geom::Geom;
use nphysics::world::World;
use nphysics::object::{ RigidBody };

pub struct PhysicsSystem {
	world: World,
	bodies: HashMap<EntityID, Rc<RefCell<RigidBody>>>
}

impl PhysicsSystem {
	pub fn new(_: &EntitiesState)
		-> PhysicsSystem
	{
		let mut world = World::new();
		world.set_gravity(Vec2::new(0.0f32, -9.8));

		let shape = ::ncollide::geom::Plane::new(Vec2::new(0.0f32, 1.0));
		let body = Rc::new(RefCell::new(RigidBody::new_static(shape, 0.3, 0.6)));
		world.add_body(body);

		PhysicsSystem {
			world: world,
			bodies: HashMap::new()
		}
	}

	pub fn process(&mut self, state: &mut EntitiesState, elapsed: &u64)
	{
		// getting the list of all entities that have physics activated
		let listOfEntities: HashSet<EntityID> = state.get_components_iter()
            .filter(|c| state.is_component_visible(*c).unwrap())
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "physics", _ => false })
			.filter(|c| match state.get(*c, "activated") { Ok(&::entities::Boolean(ref b)) => *b, _ => false })
			.map(|c| state.get_owner(c).unwrap())
			.collect();

		// removing from the world the elements that have disappeared
		{
			let toRemove: Vec<EntityID> = self.bodies.keys().filter(|e| !listOfEntities.contains(e.clone())).map(|e| e.clone()).collect();
			for e in toRemove.move_iter() {
				//self.bodies.find(&e).		// TODO: remove body from the world
				self.bodies.remove(&e);
			}
		}

		// adding elements that are not yet in the world
		{
			let toCreate: Vec<EntityID> = listOfEntities.iter().filter(|e| !self.bodies.contains_key(e.clone())).map(|e| e.clone()).collect();
			for e in toCreate.move_iter() {
				let shape = ::ncollide::geom::Cuboid::new(Vec2::new(0.5f32, 0.5f32));
				let body = Rc::new(RefCell::new(RigidBody::new_dynamic(shape, 1.0, 0.5, 0.0)));

				// initializing body with current position and movement
				body.borrow_mut().set_translation(PhysicsSystem::get_position(state, &e));
				body.borrow_mut().set_lin_vel(PhysicsSystem::get_movement(state, &e));

				self.bodies.insert(e.clone(), body.clone());
				self.world.add_body(body.clone());
			}
		}

		// setting all positions and movements
		for (entity, body) in self.bodies.iter() {
			let position = PhysicsSystem::get_position(state, entity);
			let movement = PhysicsSystem::get_movement(state, entity);
			let requestedMovement = PhysicsSystem::get_requested_movement(state, entity);
			let acceleration = Norm::normalize_cpy(&(requestedMovement - movement)) * 5.0f32;

			let mut borrowedBody = body.borrow_mut();
			borrowedBody.set_translation(position);
			borrowedBody.set_lin_vel(movement);
			borrowedBody.set_lin_acc(acceleration);
		}

		// step
		self.world.step((*elapsed as f32) / 1000.0);

		//
		for (entity, body) in self.bodies.iter() {
			PhysicsSystem::set_position(state, entity, &body.borrow().translation());
			PhysicsSystem::set_movement(state, entity, &body.borrow().lin_vel());
		}
	}

	/// returns the position of an entity
	fn get_position(state: &EntitiesState, id: &EntityID)
		-> Vec2<f32>
	{
		state
			.get_components_iter()

			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)

			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "position", _ => false })

			// build a vector from each of the component
			.filter_map(|cmp| match (state.get(cmp, "x"), state.get(cmp, "y"), state.get(cmp, "z")) {
				(Ok(&::entities::Number(ref x)), Ok(&::entities::Number(ref y)), _)
					=> Some(Vec2::new(*x as f32, *y as f32)),
				_ => None
			})

			// add all the elements together
			.fold(Vec2::new(0.0, 0.0), |vec, a| Vec2::new(vec.x + a.x, vec.y + a.y))
	}

	/// returns the total movement of an entity
	fn get_movement(state: &EntitiesState, id: &EntityID)
		-> Vec2<f32>
	{
		state
			.get_components_iter()

			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)

			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "movement", _ => false })

			// build a vector from each of the component
			.filter_map(|cmp| match (state.get(cmp, "x"), state.get(cmp, "y"), state.get(cmp, "z")) {
				(Ok(&::entities::Number(ref x)), Ok(&::entities::Number(ref y)), _)
					=> Some(Vec2::new(*x as f32, *y as f32)),
				_ => None
			})

			// add all the elements together
			.fold(Vec2::new(0.0, 0.0), |vec, a| Vec2::new(vec.x + a.x, vec.y + a.y))
	}

	/// returns the total requested movement of an entity
	fn get_requested_movement(state: &EntitiesState, id: &EntityID)
		-> Vec2<f32>
	{
		state
			.get_components_iter()

			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)

			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "requestedMovement", _ => false })

			// build a vector from each of the component
			.filter_map(|cmp| match (state.get(cmp, "x"), state.get(cmp, "y"), state.get(cmp, "z")) {
				(Ok(&::entities::Number(ref x)), Ok(&::entities::Number(ref y)), _)
					=> Some(Vec2::new(*x as f32, *y as f32)),
				_ => None
			})

			// add all the elements together
			.fold(Vec2::new(0.0, 0.0), |vec, a| Vec2::new(vec.x + a.x, vec.y + a.y))
	}

	/// changes the position of an entity
	fn set_position(state: &mut EntitiesState, id: &EntityID, pos: &Vec2<f32>)
	{
		let list: Vec<ComponentID> = state
			.get_components_iter()
			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)
			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "position", _ => false })
			.map(|c| c.clone()).collect();

		for cmp in list.iter()
		{
			state.set(cmp, "x", ::entities::Number(pos.x as f64));
			state.set(cmp, "y", ::entities::Number(pos.y as f64));
		}
	}

	/// changes the movement of an entity
	fn set_movement(state: &mut EntitiesState, id: &EntityID, pos: &Vec2<f32>)
	{
		let list: Vec<ComponentID> = state
			.get_components_iter()
			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)
			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "movement", _ => false })
			.map(|c| c.clone()).collect();

		for cmp in list.iter()
		{
			state.set(cmp, "x", ::entities::Number(pos.x as f64));
			state.set(cmp, "y", ::entities::Number(pos.y as f64));
		}
	}
}
<commit_msg>Minor cleanup in physics<commit_after>use entities::{ EntitiesState, EntityID, ComponentID, NativeComponentType };
use std::collections::{ HashSet, HashMap };
use std::cell::RefCell;
use std::rc::Rc;
use nalgebra::na;
use nalgebra::na::{ Norm, Translation, Vec2 };
use ncollide::geom::geom::Geom;
use nphysics::world::World;
use nphysics::object::{ RigidBody };

pub struct PhysicsSystem {
	world: World,
	bodies: HashMap<EntityID, Rc<RefCell<RigidBody>>>
}

impl PhysicsSystem {
	pub fn new(_: &EntitiesState)
		-> PhysicsSystem
	{
		let mut world = World::new();
		world.set_gravity(Vec2::new(0.0f32, -9.8));

		let shape = ::ncollide::geom::Plane::new(Vec2::new(0.0f32, 1.0));
		let body = Rc::new(RefCell::new(RigidBody::new_static(shape, 0.3, 0.6)));
		world.add_body(body);

		PhysicsSystem {
			world: world,
			bodies: HashMap::new()
		}
	}

	pub fn process(&mut self, state: &mut EntitiesState, elapsed: &u64)
	{
		// getting the list of all entities that have physics activated
		let listOfEntities: HashSet<EntityID> = state.get_components_iter()
            .filter(|c| state.is_component_visible(*c).unwrap())
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "physics", _ => false })
			.filter(|c| match state.get(*c, "activated") { Ok(&::entities::Boolean(ref b)) => *b, _ => false })
			.map(|c| state.get_owner(c).unwrap())
			.collect();

		// removing from the world the elements that have disappeared
		{
			let toRemove: Vec<EntityID> = self.bodies.keys().filter(|e| !listOfEntities.contains(e.clone())).map(|e| e.clone()).collect();
			for e in toRemove.move_iter() {
				//self.bodies.find(&e).		// TODO: remove body from the world
				self.bodies.remove(&e);
			}
		}

		// adding elements that are not yet in the world
		{
			let toCreate: Vec<EntityID> = listOfEntities.iter().filter(|e| !self.bodies.contains_key(e.clone())).map(|e| e.clone()).collect();
			for e in toCreate.move_iter() {
				let shape = ::ncollide::geom::Cuboid::new(Vec2::new(0.5f32, 0.5f32));
				let body = Rc::new(RefCell::new(RigidBody::new_dynamic(shape, 1.0, 0.5, 0.0)));

				// initializing body with current position and movement
				body.borrow_mut().set_translation(PhysicsSystem::get_position(state, &e));
				body.borrow_mut().set_lin_vel(PhysicsSystem::get_movement(state, &e));

				self.bodies.insert(e.clone(), body.clone());
				self.world.add_body(body.clone());
			}
		}

		// setting all positions and movements
		for (entity, body) in self.bodies.iter() {
			let position = PhysicsSystem::get_position(state, entity);
			let movement = PhysicsSystem::get_movement(state, entity);
			let requestedMovement = PhysicsSystem::get_requested_movement(state, entity);

			let mut borrowedBody = body.borrow_mut();
			borrowedBody.set_translation(position);
			borrowedBody.set_lin_vel(movement);

			if requestedMovement != movement {
				let acceleration = na::normalize(&(requestedMovement - movement)) * 5.0f32;
				borrowedBody.set_lin_acc(acceleration);
			}
		}

		// step
		self.world.step((*elapsed as f32) / 1000.0);

		//
		for (entity, body) in self.bodies.iter() {
			PhysicsSystem::set_position(state, entity, &body.borrow().translation());
			PhysicsSystem::set_movement(state, entity, &body.borrow().lin_vel());
		}
	}

	/// returns the position of an entity
	fn get_position(state: &EntitiesState, id: &EntityID)
		-> Vec2<f32>
	{
		state
			.get_components_iter()

			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)

			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "position", _ => false })

			// build a vector from each of the component
			.filter_map(|cmp| match (state.get(cmp, "x"), state.get(cmp, "y"), state.get(cmp, "z")) {
				(Ok(&::entities::Number(ref x)), Ok(&::entities::Number(ref y)), _)
					=> Some(Vec2::new(*x as f32, *y as f32)),
				_ => None
			})

			// add all the elements together
			.fold(Vec2::new(0.0, 0.0), |vec, a| vec + a)
	}

	/// returns the total movement of an entity
	fn get_movement(state: &EntitiesState, id: &EntityID)
		-> Vec2<f32>
	{
		state
			.get_components_iter()

			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)

			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "movement", _ => false })

			// build a vector from each of the component
			.filter_map(|cmp| match (state.get(cmp, "x"), state.get(cmp, "y"), state.get(cmp, "z")) {
				(Ok(&::entities::Number(ref x)), Ok(&::entities::Number(ref y)), _)
					=> Some(Vec2::new(*x as f32, *y as f32)),
				_ => None
			})

			// add all the elements together
			.fold(Vec2::new(0.0, 0.0), |vec, a| vec + a)
	}

	/// returns the total requested movement of an entity
	fn get_requested_movement(state: &EntitiesState, id: &EntityID)
		-> Vec2<f32>
	{
		state
			.get_components_iter()

			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)

			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "requestedMovement", _ => false })

			// build a vector from each of the component
			.filter_map(|cmp| match (state.get(cmp, "x"), state.get(cmp, "y"), state.get(cmp, "z")) {
				(Ok(&::entities::Number(ref x)), Ok(&::entities::Number(ref y)), _)
					=> Some(Vec2::new(*x as f32, *y as f32)),
				_ => None
			})

			// add all the elements together
			.fold(Vec2::new(0.0, 0.0), |vec, a| vec + a)
	}

	/// changes the position of an entity
	/// TODO: this is wrong
	fn set_position(state: &mut EntitiesState, id: &EntityID, pos: &Vec2<f32>)
	{
		let list: Vec<ComponentID> = state
			.get_components_iter()
			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)
			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "position", _ => false })
			.map(|c| c.clone()).collect();

		for cmp in list.iter()
		{
			state.set(cmp, "x", ::entities::Number(pos.x as f64));
			state.set(cmp, "y", ::entities::Number(pos.y as f64));
		}
	}

	/// changes the movement of an entity
	/// TODO: this is wrong
	fn set_movement(state: &mut EntitiesState, id: &EntityID, pos: &Vec2<f32>)
	{
		let list: Vec<ComponentID> = state
			.get_components_iter()
			// take only the components owned by the entity
			.filter(|c| state.get_owner(*c).unwrap() == *id)
			// take only the "position" components
			.filter(|c| match state.get_type(*c) { Ok(NativeComponentType(t)) => t.as_slice() == "movement", _ => false })
			.map(|c| c.clone()).collect();

		for cmp in list.iter()
		{
			state.set(cmp, "x", ::entities::Number(pos.x as f64));
			state.set(cmp, "y", ::entities::Number(pos.y as f64));
		}
	}
}
<|endoftext|>


<commit_before>use crate::miller_rabin::Result::*;
use crate::{miller_rabin, Factors};
use numeric::*;
use rand::distributions::{Distribution, Uniform};
use rand::rngs::SmallRng;
use rand::{thread_rng, SeedableRng};
use std::cmp::{max, min};

fn find_divisor<A: Arithmetic>(n: u64) -> u64 {
    #![allow(clippy::many_single_char_names)]
    let mut rand = {
        let range = Uniform::new(1, n);
        let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
        move || range.sample(&mut rng)
    };

    let quadratic = |a, b| move |x| A::add(A::mul(a, A::mul(x, x, n), n), b, n);

    loop {
        let f = quadratic(rand(), rand());
        let mut x = rand();
        let mut y = x;

        loop {
            x = f(x);
            y = f(f(y));
            let d = gcd(n, max(x, y) - min(x, y));
            if d == n {
                // Failure, retry with a different quadratic
                break;
            } else if d > 1 {
                return d;
            }
        }
    }
}

pub(crate) fn factor(mut num: u64) -> Factors {
    let mut factors = Factors::new();
    if num == 1 {
        return factors;
    }

    match if num < 1 << 63 {
        miller_rabin::test::<Small>(num)
    } else {
        miller_rabin::test::<Big>(num)
    } {
        Prime => {
            factors.push(num);
            return factors;
        }

        Composite(d) => {
            num /= d;
            factors *= factor(d);
        }

        Pseudoprime => {}
    };

    let divisor = if num < 1 << 63 {
        find_divisor::<Small>(num)
    } else {
        find_divisor::<Big>(num)
    };
    factors *= factor(divisor);
    factors *= factor(num / divisor);
    factors
}
<commit_msg>factor::rho: Small refactor<commit_after>use crate::miller_rabin::Result::*;
use crate::{miller_rabin, Factors};
use numeric::*;
use rand::distributions::{Distribution, Uniform};
use rand::rngs::SmallRng;
use rand::{thread_rng, SeedableRng};
use std::cmp::{max, min};

fn find_divisor<A: Arithmetic>(n: u64) -> u64 {
    #![allow(clippy::many_single_char_names)]
    let mut rand = {
        let range = Uniform::new(1, n);
        let mut rng = SmallRng::from_rng(&mut thread_rng()).unwrap();
        move || range.sample(&mut rng)
    };

    let quadratic = |a, b| move |x| A::add(A::mul(a, A::mul(x, x, n), n), b, n);

    loop {
        let f = quadratic(rand(), rand());
        let mut x = rand();
        let mut y = x;

        loop {
            x = f(x);
            y = f(f(y));
            let d = gcd(n, max(x, y) - min(x, y));
            if d == n {
                // Failure, retry with a different quadratic
                break;
            } else if d > 1 {
                return d;
            }
        }
    }
}

fn _factor<A: Arithmetic>(mut num: u64) -> Factors {
    // Shadow the name, so the recursion automatically goes from “Big” arithmetic to small.
    let _factor = |n| {
        if n < 1 << 63 {
            _factor::<Small>(n)
        } else {
            _factor::<A>(n)
        }
    };

    let mut factors = Factors::new();
    if num == 1 {
        return factors;
    }

    match miller_rabin::test::<A>(num) {
        Prime => {
            factors.push(num);
            return factors;
        }

        Composite(d) => {
            num /= d;
            factors *= _factor(d)
        }

        Pseudoprime => {}
    };

    let divisor = find_divisor::<A>(num);
    factors *= _factor(divisor);
    factors *= _factor(num / divisor);
    factors
}

pub(crate) fn factor(n: u64) -> Factors {
    if n < 1 << 63 {
        _factor::<Small>(n)
    } else {
        _factor::<Big>(n)
    }
}
<|endoftext|>


<commit_before>struct NFA
{
	states: ~[State],
}

impl NFA
{
	pub fn new()	->	NFA
	{
		NFA { states: ~[] }
	}

	pub fn add_state(&mut self, state: State)
	{
		self.states.push(state);
	}

	pub fn add_transition(&mut self, id0: int, c: char, id1: int)
	{
		self.states[id0].add_transition(c, id1);
	}

	pub fn print(&self)
	{
		println("\nprinting states:");
		for i in range(0, self.states.len())
		{
			print(fmt!("%u: ", i));
			self.states[i].print();
		}
		println("");
	}

	pub fn pop(&mut self)	->	State
	{
		self.states.pop()
	}

	pub fn len(&self)	->	int
	{
		self.states.len() as int
	}
	pub fn check(&self, string: ~str, c: ~[int])		->	bool
	{
		let mut curr = c.clone();
		//println(fmt!("check: string=%? c=%?", string, c));
		if string.len() > 0
		{
			let c = string.char_at(0);
			let mut next = ~[];
			// look to see if any current states have c or an
			// epsilon transition as a value
			let mut l = curr.len();
			let mut i = 0;
			while i < l
			{
				for j in range(0, self.states[curr[i]].transitions.len())
				{
					let (t, id) = (self.states[curr[i]].transitions[j]).clone();
					if t == c
					{
						next.push(id);
					}
					else if t == '%'
					{
						curr.push(id);
						l += 1;
					}
				}
				i += 1;
			}
			if next.len() == 0 { return false; }
			return self.check(string.slice_from(1).to_owned(), next);
		}
		else // the NFA has eaten all of the characters
		{
			// see if we're in a matching state
			for i in range(0, curr.len())
			{
				if self.states[curr[i]].accept
				{
					return true;
				}
			}
			// check to see if there are any epsilon transitions we
			// can make
			let mut next = ~[];
			for i in range(0, curr.len())
			{
				for j in range(0, self.states[curr[i]].transitions.len())
				{
					let (t , id) = (self.states[curr[i]].transitions[j]).clone();
					if t == '%'
					{
						next.push(id);
					}
				}
			}
			//println(fmt!("curr=%? next=%?", curr, next));
			if next.len() > 0
			{
				return self.check(string, next);
			}
			return false;
		}
	}
}

#[deriving(Clone, Eq)]
struct State
{
	accept: bool,
	transitions: ~[(char, int)]
}

impl State
{
	pub fn new(b: bool)	->	State
	{
		State { accept: b, transitions: ~[] }
	}

	pub fn print(&self)
	{
		print(fmt!("matching=%? transitions={", self.accept));
		for i in range(0, self.transitions.len())
		{
			print(fmt!("%?,", self.transitions[i]));
		}
		println("}");
	}

	pub fn is_accept(&mut self, b: bool)
	{
		self.accept = b;
	}

	pub fn add_transition(&mut self, c: char, id: int )
	{
		self.transitions.push((c, id));
	}
}

fn generate(lang: &[char], len: uint)	->	~[~str]
{
	let mut set = ~[];
	if len == 0 { return ~[~""]; }
	if len == 1
	{
		for i in range(0, lang.len())
		{
			set.push(lang[i].to_str());
		}
		return set;
	}
	for i in range(0, lang.len())
	{
		let s = generate(lang, len-1);
		for j in range(0, s.len())
		{
			set.push(lang[i].to_str() + s[j].clone());
		}
	}
	return set;
}

fn main()
{
	let test = std::os::args()[1];
	let lang = ['a', 'b'];
	let len = 4u;
	let mut strings = ~[];
	for i in range(0, len+1)
	{
		let s = generate(lang, i);
		for j in range(0,s.len())
		{
			strings.push(s[j].clone());
		}
	}
	let mut nfa = NFA::new();
	//let mut parenthesis: ~[int] = ~[];
	//let head_state = State::new(false);
	//nfa.add_state(head_state);
	let mut j = -1;
	let mut escaped = false;
	for i in range(1,(test.len()+1) as int)
	{
		let c = test.char_at((i-1) as uint);
		if c == '\\'
		{
			escaped = true;
		}
		/*
		else if c == '(' && !escaped
		{
			// note the place and make an 'in' state
			parenthesis.push(i);
			let state_in = State::new('%', false);
			nfa.add_state(state_in);
			j += 1;

			// link this and the previous
			nfa.link_states(j-1, j);
		}
		else if c == ')' && !escaped
		{
			let state_out = State::new('%', false);
			nfa.add_state(state_out);
			j += 1;

			// link to state_in
			nfa.link_states(j, parenthesis.pop()-1);

			// link to prev
			nfa.link_states(j-1, j);
		}
		*/
		else if c == '*' && !escaped
		{
			// link curr to itself
			for i in range(0, nfa.states[j].transitions.len())
			{
				let (a,_) = (nfa.states[j].transitions[i]).clone();
				if a != '%'
				{
					nfa.add_transition(j, a, j);
				}
			}
			// add epsilon transition to skip this state
			nfa.add_transition(j, '%', j+1);

		}
		else if c == '+' && !escaped
		{
			let state_next = State::new(false);
			// link next to curr

			nfa.add_state(state_next);
			j += 1;

			// link next to curr
			nfa.add_transition(j, '%', j-1);
			// add transition to next state
			nfa.add_transition(j, '%', j+1);
		}
		else if c == '?' && !escaped
		{
			// add epsilon transition
			nfa.add_transition(j, '%', j+1);
		}
		else if c == '.' && !escaped
		{
			let state = State::new(false);
			nfa.add_state(state);
			j += 1;

			// unconditional jump
			for i in range(0, lang.len())
			{
				nfa.add_transition(j, lang[i], j+1);
			}
		}
		else
		{
			let state = State::new(false);
			nfa.add_state(state);
			j += 1;

			// link with next
			nfa.add_transition(j, c, j+1);
			escaped = false;
		}

		nfa.print();
	}
	// make the last state true
	let state = State::new(true);
	nfa.add_state(state);

	nfa.print();

	let curr = ~[0];
	println(fmt!("Regex is: %s", test));
	for i in range(0, strings.len())
	{
		println(fmt!("%? %?", strings[i], nfa.check(strings[i].clone(), curr.clone())));
	}

}
<commit_msg>added support for ()<commit_after>struct NFA
{
	states: ~[State],
}

impl NFA
{
	pub fn new()	->	NFA
	{
		NFA { states: ~[] }
	}

	pub fn add_state(&mut self, state: State)
	{
		self.states.push(state);
	}

	pub fn add_transition(&mut self, id0: int, c: char, id1: int)
	{
		self.states[id0].add_transition(c, id1);
	}

	pub fn print(&self)
	{
		println("\nprinting states:");
		for i in range(0, self.states.len())
		{
			print(fmt!("%u: ", i));
			self.states[i].print();
		}
		println("");
	}

	pub fn pop(&mut self)	->	State
	{
		self.states.pop()
	}

	pub fn len(&self)	->	int
	{
		self.states.len() as int
	}
	pub fn check(&self, string: ~str, c: ~[int])		->	bool
	{
		let mut curr = c.clone();
		//println(fmt!("check: string=%? c=%?", string, c));
		if string.len() > 0
		{
			let c = string.char_at(0);
			let mut next = ~[];
			// look to see if any current states have c or an
			// epsilon transition as a value
			let mut l = curr.len();
			let mut i = 0;
			while i < l
			{
				for j in range(0, self.states[curr[i]].transitions.len())
				{
					let (t, id) = (self.states[curr[i]].transitions[j]).clone();
					if t == c
					{
						next.push(id);
					}
					else if t == '%'
					{
						curr.push(id);
						l += 1;
					}
				}
				i += 1;
			}
			if next.len() == 0 { return false; }
			return self.check(string.slice_from(1).to_owned(), next);
		}
		else // the NFA has eaten all of the characters
		{
			// see if we're in a matching state
			for i in range(0, curr.len())
			{
				if self.states[curr[i]].accept
				{
					return true;
				}
			}
			// check to see if there are any epsilon transitions we
			// can make
			let mut next = ~[];
			for i in range(0, curr.len())
			{
				for j in range(0, self.states[curr[i]].transitions.len())
				{
					let (t , id) = (self.states[curr[i]].transitions[j]).clone();
					if t == '%'
					{
						next.push(id);
					}
				}
			}
			//println(fmt!("curr=%? next=%?", curr, next));
			if next.len() > 0
			{
				return self.check(string, next);
			}
			return false;
		}
	}
}

#[deriving(Clone, Eq)]
struct State
{
	accept: bool,
	transitions: ~[(char, int)]
}

impl State
{
	pub fn new(b: bool)	->	State
	{
		State { accept: b, transitions: ~[] }
	}

	pub fn print(&self)
	{
		print(fmt!("matching=%? transitions={", self.accept));
		for i in range(0, self.transitions.len())
		{
			print(fmt!("%?,", self.transitions[i]));
		}
		println("}");
	}

	pub fn is_accept(&mut self, b: bool)
	{
		self.accept = b;
	}

	pub fn add_transition(&mut self, c: char, id: int )
	{
		self.transitions.push((c, id));
	}
}

fn generate(lang: &[char], len: uint)	->	~[~str]
{
	let mut set = ~[];
	if len == 0 { return ~[~""]; }
	if len == 1
	{
		for i in range(0, lang.len())
		{
			set.push(lang[i].to_str());
		}
		return set;
	}
	for i in range(0, lang.len())
	{
		let s = generate(lang, len-1);
		for j in range(0, s.len())
		{
			set.push(lang[i].to_str() + s[j].clone());
		}
	}
	return set;
}

fn main()
{
	let test = std::os::args()[1];
	let lang = ['a', 'b'];
	let len = 4u;
	let mut strings = ~[];
	for i in range(0, len+1)
	{
		let s = generate(lang, i);
		for j in range(0,s.len())
		{
			strings.push(s[j].clone());
		}
	}
	let mut nfa = NFA::new();
	let mut parenthesis: ~[int] = ~[];
	let mut j = -1;
	let mut escaped = false;
	let mut special = false;
	for i in range(1,(test.len()+1) as int)
	{
		let c = test.char_at((i-1) as uint);
		if c == '\\'
		{
			escaped = true;
		}
		else if c == '(' && !escaped
		{
			parenthesis.push(j+1);
		}
		else if c == ')' && !escaped
		{
			special = true;
		}
		else if c == '*' && !escaped
		{
			let mut place = j;
			if special
			{
				place = parenthesis.pop();
				special = false;
			}

			// link curr to place
			for i in range(0, nfa.states[j].transitions.len())
			{
				let (a,_) = (nfa.states[j].transitions[i]).clone();
				if a != '%'
				{
					nfa.add_transition(j, a, place);
				}
			}

			// add epsilon transition to skip this state
			nfa.add_transition(place, '%', j+1);

		}
		else if c == '+' && !escaped
		{
			let mut place = j;
			if special
			{
				place = parenthesis.pop();
				special = false;
			}

			for i in range(0, nfa.states[j].transitions.len())
			{
				let (a,_) = (nfa.states[j].transitions[i]).clone();
				if a != '%'
				{
					nfa.add_transition(j, a, place);
				}
			}
		}
		else if c == '?' && !escaped
		{
			let mut place = j;
			if special
			{
				place = parenthesis.pop();
				special = false;
			}

			// add epsilon transition
			nfa.add_transition(place, '%', j+1);
		}
		else if c == '.' && !escaped
		{
			let state = State::new(false);
			nfa.add_state(state);
			j += 1;

			// unconditional jump
			for i in range(0, lang.len())
			{
				nfa.add_transition(j, lang[i], j+1);
			}
		}
		else
		{
			let state = State::new(false);
			nfa.add_state(state);
			j += 1;

			// link with next
			nfa.add_transition(j, c, j+1);
			escaped = false;
		}

		nfa.print();
	}
	// make the last state true
	let state = State::new(true);
	nfa.add_state(state);

	nfa.print();

	let curr = ~[0];
	println(fmt!("Regex is: %s", test));
	for i in range(0, strings.len())
	{
		println(fmt!("%? %?", strings[i], nfa.check(strings[i].clone(), curr.clone())));
	}

}
<|endoftext|>