<commit_before>extern crate orbclient;
extern crate sinulation;

use super::start;

#[cfg(target_os = "redox")] // if os is redox use these trig functions instead of the ones from standard lib
use sinulation::Trig;

pub struct Shader {
    pub id: u16,
    pub shader: Box<Fn(&Triangle, &mut start::Window, &Shader)>,
    pub image_data: orbclient::BmpFile,
}

impl Shader {
    pub fn new(id: u16, shader: Box<Fn(&Triangle, &mut start::Window, &Shader)>) -> Shader {
        Shader {
            id: id,
            shader: shader,
            image_data: orbclient::BmpFile::default(),
        }
    }

    pub fn null() -> Shader {
        Shader {
            id: 0,
            shader: Box::new(|triangle: &Triangle, window: &mut start::Window, wrapper: &Shader| {}),
            image_data: orbclient::BmpFile::default(),
        }
    }

    /*pub fn apply(self, triangle: &Triangle) {
        (self.shader)(triangle);
    }*/
}

/// Color struct. Stores colors in 8-bit RGB.
#[derive(Debug, Clone, Copy)]
pub struct Color {
    pub r: u8,
    pub g: u8,
    pub b: u8,
}

impl Color {
    pub fn new(r: u8, g: u8, b: u8) -> Color {
        Color {
            r: r,
            g: g,
            b: b,
        }
    }

    /// Converts tetrahedrane colors to ones accepted by orbclient library.
    pub fn orb_color(&self) -> orbclient::color::Color {
        orbclient::color::Color::rgb(self.r, self.g, self.b)
    }
}

/// 2D point. Coordinates are screen pixels.
#[derive(Clone, Copy, Debug)]
pub struct FlatPoint {
    pub x: i32,
    pub y: i32,
}

/// 3D point. Coordinates are floating point, similar to OpenGL coordinates.
///
/// 0.0 is center, -1.0 is left, 1.0 is right etc.
///
#[derive(Clone, Copy, Debug)]
pub struct DepthPoint {
    pub x: f32,
    pub y: f32,
    pub z: f32,

    pub x_y: f32,
    pub x_z: f32,
    pub y_z: f32,

    last_x_y: f32,
    last_x_z: f32,
    last_y_z: f32,
}

impl DepthPoint {
    /// Creates a new 3D point.
    pub fn new(x: f32, y: f32, z: f32) -> DepthPoint {
        DepthPoint {
            x: x,
            y: y,
            z: z,

            x_y: 0.0,
            x_z: 0.0,
            y_z: 0.0,

            last_x_y: 0.0,
            last_x_z: 0.0,
            last_y_z: 0.0,
        }
    }

    /// Converts into 2D point, with perspective.
    pub fn flat_point(&mut self, engine_scr_x: u32, engine_scr_y: u32, offset_x: f32, offset_y: f32, offset_z: f32) -> FlatPoint {
        if self.z > -0.01 && self.z < 0.0 {
            self.z = 0.001
        }

        else if self.z < 0.1 { // Prevents division by nearly 0, that cause integer overflow/underflow
            self.z = 0.11;
        }

        FlatPoint {
            x: ((engine_scr_x as f32 * (self.x + offset_x) as f32/(self.z + offset_z)) + engine_scr_x as f32 / 2.0) as i32,
            y: ((engine_scr_x as f32 * (self.y + offset_y) as f32/(self.z + offset_z)) + engine_scr_y as f32 / 2.0) as i32,
        }
    }

    /// Applies camera rotations from variables `x_y`, `x_z` and `y_z`
    pub fn apply_camera_rotations(&mut self, engine: &start::Window) {
        #[cfg(not(target_os = "redox"))]
        use std::f32::consts::PI;

        #[cfg(target_os = "redox")]
        const PI: f32 = 3.141592653589793;

        let x_y = self.x_y;
        let x_z = self.x_z;
        let y_z = self.y_z;

        let last_x_y = self.last_x_y;
        let last_x_z = self.last_x_z;
        let last_y_z = self.last_y_z;

        self.camera_rotate_x_y(&engine, x_y - last_x_y);
        self.camera_rotate_x_z(&engine, x_z - last_x_z);
        self.camera_rotate_y_z(&engine, y_z - last_y_z);

        self.last_x_y = x_y;
        self.last_x_z = x_z;
        self.last_y_z = y_z;

        //normalize rotations
        if self.x_z > (PI * 2.0) {
            self.x_z -= (PI * 2.0);
        }

        if self.x_y > (PI * 2.0) {
            self.x_y -= (PI * 2.0);
        }

        if self.y_z > (PI * 2.0) {
            self.y_z -= (PI * 2.0);
        }
    }

    pub fn camera_rotate_x_y(&mut self, engine: &start::Window, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= engine.camera_x;
        self.y -= engine.camera_y;

        let new_x = self.x * c - self.y * s;
        let new_y = self.x * s + self.y * c;

        self.x = new_x + engine.camera_x;
        self.y = new_y + engine.camera_y;
    }

    pub fn camera_rotate_x_z(&mut self, engine: &start::Window, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= engine.camera_x;
        self.z -= engine.camera_z;

        let new_x = self.x * c - self.z * s;
        let new_z = self.x * s + self.z * c;

        self.x = new_x + engine.camera_x;
        self.z = new_z + engine.camera_z;
    }

    pub fn camera_rotate_y_z(&mut self, engine: &start::Window, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.y -= engine.camera_y;
        self.z -= engine.camera_z;

        let new_y = self.y * c - self.z * s;
        let new_z = self.y * s + self.z * c;

        self.y = new_y + engine.camera_y;
        self.z = new_z + engine.camera_z;
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_x_y(&mut self, x: f32, y: f32, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= x;
        self.y -= y;

        let new_x = self.x * c - self.y * s;
        let new_y = self.x * s + self.y * c;

        self.x = new_x + x;
        self.y = new_y + y;
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_x_z(&mut self, x: f32, z: f32, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= x;
        self.z -= z;

        let new_x = self.x * c - self.z * s;
        let new_z = self.x * s + self.z * c;

        self.x = new_x + x;
        self.z = new_z + z;
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_y_z(&mut self, y: f32, z: f32, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.y -= y;
        self.z -= z;

        let new_y = self.y * c - self.z * s;
        let new_z = self.y * s + self.z * c;

        self.y = new_y + y;
        self.z = new_z + z;
    }
}

/// Triangle. `p1`, `p2`, `p3` are it's vertexes.
#[derive(Clone, Copy)]
pub struct Triangle {
    pub p1: DepthPoint,
    pub p2: DepthPoint,
    pub p3: DepthPoint,

    pub x: f32,
    pub y: f32,
    pub z: f32,

    pub x_y: f32,
    pub x_z: f32,
    pub y_z: f32,

    pub color: Color,

    pub shader_ids: [u16; 8],
}

impl Triangle {
    /// Creates a new triangle
    pub fn new(p1: DepthPoint, p2: DepthPoint, p3: DepthPoint, x: f32, y: f32, z: f32, color: Color) -> Triangle {
        Triangle {
            p1: p1,
            p2: p2,
            p3: p3,

            x: x,
            y: y,
            z: z,

            x_y: 0.0,
            x_z: 0.0,
            y_z: 0.0,

            color: color,

            shader_ids: [0; 8],
        }
    }

    /// Applies camera rotations from variables `x_y`, `x_z` and `y_z`
    pub fn apply_camera_rotations(&mut self, engine: &start::Window) {
        self.p1.x_y += self.x_y;
        self.p1.x_z += self.x_z;
        self.p1.y_z += self.y_z;

        self.p2.x_y += self.x_y;
        self.p2.x_z += self.x_z;
        self.p2.y_z += self.y_z;

        self.p3.x_y += self.x_y;
        self.p3.x_z += self.x_z;
        self.p3.y_z += self.y_z;

        self.p1.apply_camera_rotations(&engine);
        self.p2.apply_camera_rotations(&engine);
        self.p3.apply_camera_rotations(&engine);

        self.p1.x_y -= self.x_y;
        self.p1.x_z -= self.x_z;
        self.p1.y_z -= self.y_z;

        self.p2.x_y -= self.x_y;
        self.p2.x_z -= self.x_z;
        self.p2.y_z -= self.y_z;

        self.p3.x_y -= self.x_y;
        self.p3.x_z -= self.x_z;
        self.p3.y_z -= self.y_z;
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_x_y(&mut self, x: f32, y: f32, angle: f32) {
        self.p1.coord_rotate_x_y(x, y, angle);
        self.p2.coord_rotate_x_y(x, y, angle);
        self.p3.coord_rotate_x_y(x, y, angle);
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_x_z(&mut self, x: f32, z: f32, angle: f32) {
        self.p1.coord_rotate_x_z(x, z, angle);
        self.p2.coord_rotate_x_z(x, z, angle);
        self.p3.coord_rotate_x_z(x, z, angle);
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_y_z(&mut self, y: f32, z: f32, angle: f32) {
        self.p1.coord_rotate_y_z(y, z, angle);
        self.p2.coord_rotate_y_z(y, z, angle);
        self.p3.coord_rotate_y_z(y, z, angle);
    }
}

/// A group of triangles.
//#[derive(Clone)]
pub struct TriangleGroup {
    pub triangles: Vec<Triangle>,
    pub shader_ids: [u16; 8],
}

impl TriangleGroup {
    /// Create a new group of triangles.
    pub fn new(triangles: Vec<Triangle>) -> TriangleGroup {
        TriangleGroup {
            triangles: triangles,
            shader_ids: [0; 8],
        }
    }
}
<commit_msg>Added a flag field to shaders<commit_after>extern crate orbclient;
extern crate sinulation;

use super::start;

#[cfg(target_os = "redox")] // if os is redox use these trig functions instead of the ones from standard lib
use sinulation::Trig;

pub struct Shader {
    pub id: u16,
    pub shader: Box<Fn(&Triangle, &mut start::Window, &Shader)>,
    pub image_data: orbclient::BmpFile,
    pub flags: [f32; 8],
}

impl Shader {
    pub fn new(id: u16, shader: Box<Fn(&Triangle, &mut start::Window, &Shader)>) -> Shader {
        Shader {
            id: id,
            shader: shader,
            image_data: orbclient::BmpFile::default(),
            flags: [0.0; 8],
        }
    }

    pub fn null() -> Shader {
        Shader {
            id: 0,
            shader: Box::new(|triangle: &Triangle, window: &mut start::Window, wrapper: &Shader| {}),
            image_data: orbclient::BmpFile::default(),
            flags: [0.0; 8],
        }
    }

    /*pub fn apply(self, triangle: &Triangle) {
        (self.shader)(triangle);
    }*/
}

/// Color struct. Stores colors in 8-bit RGB.
#[derive(Debug, Clone, Copy)]
pub struct Color {
    pub r: u8,
    pub g: u8,
    pub b: u8,
}

impl Color {
    pub fn new(r: u8, g: u8, b: u8) -> Color {
        Color {
            r: r,
            g: g,
            b: b,
        }
    }

    /// Converts tetrahedrane colors to ones accepted by orbclient library.
    pub fn orb_color(&self) -> orbclient::color::Color {
        orbclient::color::Color::rgb(self.r, self.g, self.b)
    }
}

/// 2D point. Coordinates are screen pixels.
#[derive(Clone, Copy, Debug)]
pub struct FlatPoint {
    pub x: i32,
    pub y: i32,
}

/// 3D point. Coordinates are floating point, similar to OpenGL coordinates.
///
/// 0.0 is center, -1.0 is left, 1.0 is right etc.
///
#[derive(Clone, Copy, Debug)]
pub struct DepthPoint {
    pub x: f32,
    pub y: f32,
    pub z: f32,

    pub x_y: f32,
    pub x_z: f32,
    pub y_z: f32,

    last_x_y: f32,
    last_x_z: f32,
    last_y_z: f32,
}

impl DepthPoint {
    /// Creates a new 3D point.
    pub fn new(x: f32, y: f32, z: f32) -> DepthPoint {
        DepthPoint {
            x: x,
            y: y,
            z: z,

            x_y: 0.0,
            x_z: 0.0,
            y_z: 0.0,

            last_x_y: 0.0,
            last_x_z: 0.0,
            last_y_z: 0.0,
        }
    }

    /// Converts into 2D point, with perspective.
    pub fn flat_point(&mut self, engine_scr_x: u32, engine_scr_y: u32, offset_x: f32, offset_y: f32, offset_z: f32) -> FlatPoint {
        if self.z > -0.01 && self.z < 0.0 {
            self.z = 0.001
        }

        else if self.z < 0.1 { // Prevents division by nearly 0, that cause integer overflow/underflow
            self.z = 0.11;
        }

        FlatPoint {
            x: ((engine_scr_x as f32 * (self.x + offset_x) as f32/(self.z + offset_z)) + engine_scr_x as f32 / 2.0) as i32,
            y: ((engine_scr_x as f32 * (self.y + offset_y) as f32/(self.z + offset_z)) + engine_scr_y as f32 / 2.0) as i32,
        }
    }

    /// Applies camera rotations from variables `x_y`, `x_z` and `y_z`
    pub fn apply_camera_rotations(&mut self, engine: &start::Window) {
        #[cfg(not(target_os = "redox"))]
        use std::f32::consts::PI;

        #[cfg(target_os = "redox")]
        const PI: f32 = 3.141592653589793;

        let x_y = self.x_y;
        let x_z = self.x_z;
        let y_z = self.y_z;

        let last_x_y = self.last_x_y;
        let last_x_z = self.last_x_z;
        let last_y_z = self.last_y_z;

        self.camera_rotate_x_y(&engine, x_y - last_x_y);
        self.camera_rotate_x_z(&engine, x_z - last_x_z);
        self.camera_rotate_y_z(&engine, y_z - last_y_z);

        self.last_x_y = x_y;
        self.last_x_z = x_z;
        self.last_y_z = y_z;

        //normalize rotations
        if self.x_z > (PI * 2.0) {
            self.x_z -= (PI * 2.0);
        }

        if self.x_y > (PI * 2.0) {
            self.x_y -= (PI * 2.0);
        }

        if self.y_z > (PI * 2.0) {
            self.y_z -= (PI * 2.0);
        }
    }

    pub fn camera_rotate_x_y(&mut self, engine: &start::Window, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= engine.camera_x;
        self.y -= engine.camera_y;

        let new_x = self.x * c - self.y * s;
        let new_y = self.x * s + self.y * c;

        self.x = new_x + engine.camera_x;
        self.y = new_y + engine.camera_y;
    }

    pub fn camera_rotate_x_z(&mut self, engine: &start::Window, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= engine.camera_x;
        self.z -= engine.camera_z;

        let new_x = self.x * c - self.z * s;
        let new_z = self.x * s + self.z * c;

        self.x = new_x + engine.camera_x;
        self.z = new_z + engine.camera_z;
    }

    pub fn camera_rotate_y_z(&mut self, engine: &start::Window, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.y -= engine.camera_y;
        self.z -= engine.camera_z;

        let new_y = self.y * c - self.z * s;
        let new_z = self.y * s + self.z * c;

        self.y = new_y + engine.camera_y;
        self.z = new_z + engine.camera_z;
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_x_y(&mut self, x: f32, y: f32, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= x;
        self.y -= y;

        let new_x = self.x * c - self.y * s;
        let new_y = self.x * s + self.y * c;

        self.x = new_x + x;
        self.y = new_y + y;
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_x_z(&mut self, x: f32, z: f32, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.x -= x;
        self.z -= z;

        let new_x = self.x * c - self.z * s;
        let new_z = self.x * s + self.z * c;

        self.x = new_x + x;
        self.z = new_z + z;
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_y_z(&mut self, y: f32, z: f32, angle: f32) {
        #[cfg(not(target_os = "redox"))]
        use std::f32;

        let s = f32::sin(angle);
        let c = f32::cos(angle);

        self.y -= y;
        self.z -= z;

        let new_y = self.y * c - self.z * s;
        let new_z = self.y * s + self.z * c;

        self.y = new_y + y;
        self.z = new_z + z;
    }
}

/// Triangle. `p1`, `p2`, `p3` are it's vertexes.
#[derive(Clone, Copy)]
pub struct Triangle {
    pub p1: DepthPoint,
    pub p2: DepthPoint,
    pub p3: DepthPoint,

    pub x: f32,
    pub y: f32,
    pub z: f32,

    pub x_y: f32,
    pub x_z: f32,
    pub y_z: f32,

    pub color: Color,

    pub shader_ids: [u16; 8],
}

impl Triangle {
    /// Creates a new triangle
    pub fn new(p1: DepthPoint, p2: DepthPoint, p3: DepthPoint, x: f32, y: f32, z: f32, color: Color) -> Triangle {
        Triangle {
            p1: p1,
            p2: p2,
            p3: p3,

            x: x,
            y: y,
            z: z,

            x_y: 0.0,
            x_z: 0.0,
            y_z: 0.0,

            color: color,

            shader_ids: [0; 8],
        }
    }

    /// Applies camera rotations from variables `x_y`, `x_z` and `y_z`
    pub fn apply_camera_rotations(&mut self, engine: &start::Window) {
        self.p1.x_y += self.x_y;
        self.p1.x_z += self.x_z;
        self.p1.y_z += self.y_z;

        self.p2.x_y += self.x_y;
        self.p2.x_z += self.x_z;
        self.p2.y_z += self.y_z;

        self.p3.x_y += self.x_y;
        self.p3.x_z += self.x_z;
        self.p3.y_z += self.y_z;

        self.p1.apply_camera_rotations(&engine);
        self.p2.apply_camera_rotations(&engine);
        self.p3.apply_camera_rotations(&engine);

        self.p1.x_y -= self.x_y;
        self.p1.x_z -= self.x_z;
        self.p1.y_z -= self.y_z;

        self.p2.x_y -= self.x_y;
        self.p2.x_z -= self.x_z;
        self.p2.y_z -= self.y_z;

        self.p3.x_y -= self.x_y;
        self.p3.x_z -= self.x_z;
        self.p3.y_z -= self.y_z;
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_x_y(&mut self, x: f32, y: f32, angle: f32) {
        self.p1.coord_rotate_x_y(x, y, angle);
        self.p2.coord_rotate_x_y(x, y, angle);
        self.p3.coord_rotate_x_y(x, y, angle);
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_x_z(&mut self, x: f32, z: f32, angle: f32) {
        self.p1.coord_rotate_x_z(x, z, angle);
        self.p2.coord_rotate_x_z(x, z, angle);
        self.p3.coord_rotate_x_z(x, z, angle);
    }

    /// Rotates the point around provided coordinates by the angle.
    pub fn coord_rotate_y_z(&mut self, y: f32, z: f32, angle: f32) {
        self.p1.coord_rotate_y_z(y, z, angle);
        self.p2.coord_rotate_y_z(y, z, angle);
        self.p3.coord_rotate_y_z(y, z, angle);
    }
}

/// A group of triangles.
//#[derive(Clone)]
pub struct TriangleGroup {
    pub triangles: Vec<Triangle>,
    pub shader_ids: [u16; 8],
}

impl TriangleGroup {
    /// Create a new group of triangles.
    pub fn new(triangles: Vec<Triangle>) -> TriangleGroup {
        TriangleGroup {
            triangles: triangles,
            shader_ids: [0; 8],
        }
    }
}
<|endoftext|>


<commit_before><commit_msg>Removed Clone from FlagArg<commit_after><|endoftext|>


<commit_before>use std::io::Write;
use serde::ser::{self, Impossible, Serialize};
use error::Error;

/// An XML Serializer.
pub struct Serializer<W>
    where W: Write
{
    writer: W,
}

impl<W> Serializer<W>
    where W: Write
{
    pub fn new(writer: W) -> Self {
        Self { writer: writer }
    }
}

#[allow(unused_variables)]
impl<'w, W> ser::Serializer for &'w mut Serializer<W>
    where W: Write
{
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Impossible<Self::Ok, Self::Error>;
    type SerializeTuple = Impossible<Self::Ok, Self::Error>;
    type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
    type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
    type SerializeMap = Map<'w, W>;
    type SerializeStruct = Struct<'w, W>;
    type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;

    fn serialize_bool(mut self, v: bool) -> Result<Self::Ok, Self::Error> {
        if v {
            write!(self.writer, "true")?;
        } else {
            write!(self.writer, "false")?;
        }

        Ok(())
    }

    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_i8".to_string()))
    }

    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_i16".to_string()))
    }

    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_i32".to_string()))
    }

    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_i64".to_string()))
    }

    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_u8".to_string()))
    }

    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_u16".to_string()))
    }

    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
        write!(self.writer, "{}", v)
            .map(|_| ())
            .map_err(|e| e.into())
    }

    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_u64".to_string()))
    }

    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_f32".to_string()))
    }

    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_f64".to_string()))
    }

    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_char".to_string()))
    }

    fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
        write!(self.writer, "{}", value)
            .map(|_| ())
            .map_err(|e| e.into())
    }

    fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_bytes".to_string()))
    }

    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_none".to_string()))
    }

    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_some".to_string()))
    }

    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_unit".to_string()))
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_unit_struct".to_string()))
    }

    fn serialize_unit_variant(self,
                              name: &'static str,
                              variant_index: usize,
                              variant: &'static str)
                              -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_unit_variant".to_string()))
    }

    fn serialize_newtype_struct<T: ?Sized + Serialize>(self,
                                                       name: &'static str,
                                                       value: &T)
                                                       -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_newtype_struct".to_string()))
    }

    fn serialize_newtype_variant<T: ?Sized + Serialize>(self,
                                                        name: &'static str,
                                                        variant_index: usize,
                                                        variant: &'static str,
                                                        value: &T)
                                                        -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_newtype_variant".to_string()))
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_seq".to_string()))
    }

    fn serialize_seq_fixed_size(self, size: usize) -> Result<Self::SerializeSeq, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_seq_fixed_size".to_string()))
    }

    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple".to_string()))
    }

    fn serialize_tuple_struct(self,
                              name: &'static str,
                              len: usize)
                              -> Result<Self::SerializeTupleStruct, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple_struct".to_string()))
    }

    fn serialize_tuple_variant(self,
                               name: &'static str,
                               variant_index: usize,
                               variant: &'static str,
                               len: usize)
                               -> Result<Self::SerializeTupleVariant, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple_variant".to_string()))
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
        Ok(Map { parent: self })
    }

    fn serialize_struct(self,
                        name: &'static str,
                        len: usize)
                        -> Result<Self::SerializeStruct, Self::Error> {
        write!(self.writer, "<{}>", name)?;
        Ok(Struct {
               parent: self,
               name: name,
           })
    }

    fn serialize_struct_variant(self,
                                name: &'static str,
                                variant_index: usize,
                                variant: &'static str,
                                len: usize)
                                -> Result<Self::SerializeStructVariant, Self::Error> {
        Err(Error::UnsupportedOperation("Result".to_string()))
    }
}

/// An implementation of SerializeStruct for serializing to XML.
pub struct Struct<'w, W>
    where W: 'w + Write
{
    parent: &'w mut Serializer<W>,
    name: &'w str,
}

impl<'w, W> ser::SerializeStruct for Struct<'w, W>
    where W: 'w + Write
{
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized + Serialize>(&mut self,
                                              key: &'static str,
                                              value: &T)
                                              -> Result<(), Self::Error> {
        write!(self.parent.writer, "<{}>", key)?;
        value.serialize(&mut *self.parent)?;
        write!(self.parent.writer, "</{}>", key)?;
        Ok(())
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        write!(self.parent.writer, "</{}>", self.name).map_err(|e| e.into())
    }
}

/// An implementation of SerializeMap for serializing to XML.
pub struct Map<'w, W>
    where W: 'w + Write
{
    parent: &'w mut Serializer<W>,
}

impl<'w, W> ser::SerializeMap for Map<'w, W>
    where W: 'w + Write
{
    type Ok = ();
    type Error = Error;

    fn serialize_key<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<(), Self::Error> {
        panic!("impossible to serialize just the key, please use serialize_entry()")
    }

    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
        value.serialize(&mut *self.parent)
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        Ok(())
    }

    fn serialize_entry<K: ?Sized + Serialize, V: ?Sized + Serialize>(&mut self,
                                                                     key: &K,
                                                                     value: &V)
                                                                     -> Result<(), Self::Error> {
        // TODO: Is it possible to ensure our key is never a composite type?
        // Anything which isn't a "primitive" would lead to malformed XML here...
        write!(self.parent.writer, "<")?;
        key.serialize(&mut *self.parent)?;
        write!(self.parent.writer, ">")?;

        value.serialize(&mut *self.parent)?;

        write!(self.parent.writer, "</")?;
        key.serialize(&mut *self.parent)?;
        write!(self.parent.writer, ">")?;
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde::Serializer as SerSerializer;
    use serde::ser::{SerializeMap, SerializeStruct};

    #[test]
    fn test_serialize_bool() {
        let inputs = vec![(true, "true"), (false, "false")];

        for (src, should_be) in inputs {
            let mut buffer = Vec::new();

            {
                let mut ser = Serializer::new(&mut buffer);
                ser.serialize_bool(src).unwrap();
            }

            let got = String::from_utf8(buffer).unwrap();
            assert_eq!(got, should_be);
        }
    }

    #[test]
    fn test_start_serialize_struct() {
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let _ = ser.serialize_struct("foo", 0).unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, "<foo>");
    }

    #[test]
    fn test_serialize_struct_field() {
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let mut struct_ser = Struct {
                parent: &mut ser,
                name: "baz",
            };
            struct_ser.serialize_field("foo", "bar").unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, "<foo>bar</foo>");
    }

    #[test]
    fn test_serialize_struct() {
        #[derive(Serialize)]
        struct Person {
            name: String,
            age: u32,
        }

        let bob = Person {
            name: "Bob".to_string(),
            age: 42,
        };
        let should_be = "<Person><name>Bob</name><age>42</age></Person>";
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            bob.serialize(&mut ser).unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, should_be);
    }

    #[test]
    fn test_serialize_map_entries() {
        let should_be = "<name>Bob</name><age>5</age>";
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let mut map = Map { parent: &mut ser };
            map.serialize_entry("name", "Bob").unwrap();
            map.serialize_entry("age", "5").unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, should_be);
    }
}
<commit_msg>Added implementations for most primitives<commit_after>use std::io::Write;
use std::fmt::Display;
use serde::ser::{self, Impossible, Serialize};
use error::Error;

/// An XML Serializer.
pub struct Serializer<W>
    where W: Write
{
    writer: W,
}

impl<W> Serializer<W>
    where W: Write
{
    pub fn new(writer: W) -> Self {
        Self { writer: writer }
    }

    fn write_primitive<P: Display>(&mut self, primitive: P) -> Result<(), Error> {
        write!(self.writer, "{}", primitive)
            .map(|_| ())
            .map_err(|e| e.into())
    }
}

#[allow(unused_variables)]
impl<'w, W> ser::Serializer for &'w mut Serializer<W>
    where W: Write
{
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Impossible<Self::Ok, Self::Error>;
    type SerializeTuple = Impossible<Self::Ok, Self::Error>;
    type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
    type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
    type SerializeMap = Map<'w, W>;
    type SerializeStruct = Struct<'w, W>;
    type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;

    fn serialize_bool(mut self, v: bool) -> Result<Self::Ok, Self::Error> {
        if v {
            write!(self.writer, "true")?;
        } else {
            write!(self.writer, "false")?;
        }

        Ok(())
    }

    fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(v)
    }

    fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
        self.write_primitive(value)
    }

    fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
        // TODO: I imagine you'd want to use base64 here.
        // Not sure how to roundtrip effectively though...
        Err(Error::UnsupportedOperation("serialize_bytes".to_string()))
    }

    fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
        Ok(())
    }

    fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, Self::Error> {
        value.serialize(self)
    }

    fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
        self.serialize_none()
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
        write!(self.writer, "<{0}></{0}>", name)
            .map(|_| ())
            .map_err(|e| e.into())
    }

    fn serialize_unit_variant(self,
                              name: &'static str,
                              variant_index: usize,
                              variant: &'static str)
                              -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_unit_variant".to_string()))
    }

    fn serialize_newtype_struct<T: ?Sized + Serialize>(self,
                                                       name: &'static str,
                                                       value: &T)
                                                       -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_newtype_struct".to_string()))
    }

    fn serialize_newtype_variant<T: ?Sized + Serialize>(self,
                                                        name: &'static str,
                                                        variant_index: usize,
                                                        variant: &'static str,
                                                        value: &T)
                                                        -> Result<Self::Ok, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_newtype_variant".to_string()))
    }

    fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
        // TODO: Figure out how to constrain the things written to only be composites
        Err(Error::UnsupportedOperation("serialize_seq".to_string()))
    }

    fn serialize_seq_fixed_size(self, size: usize) -> Result<Self::SerializeSeq, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_seq_fixed_size".to_string()))
    }

    fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple".to_string()))
    }

    fn serialize_tuple_struct(self,
                              name: &'static str,
                              len: usize)
                              -> Result<Self::SerializeTupleStruct, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple_struct".to_string()))
    }

    fn serialize_tuple_variant(self,
                               name: &'static str,
                               variant_index: usize,
                               variant: &'static str,
                               len: usize)
                               -> Result<Self::SerializeTupleVariant, Self::Error> {
        Err(Error::UnsupportedOperation("serialize_tuple_variant".to_string()))
    }

    fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
        Ok(Map { parent: self })
    }

    fn serialize_struct(self,
                        name: &'static str,
                        len: usize)
                        -> Result<Self::SerializeStruct, Self::Error> {
        write!(self.writer, "<{}>", name)?;
        Ok(Struct {
               parent: self,
               name: name,
           })
    }

    fn serialize_struct_variant(self,
                                name: &'static str,
                                variant_index: usize,
                                variant: &'static str,
                                len: usize)
                                -> Result<Self::SerializeStructVariant, Self::Error> {
        Err(Error::UnsupportedOperation("Result".to_string()))
    }
}

/// An implementation of SerializeStruct for serializing to XML.
pub struct Struct<'w, W>
    where W: 'w + Write
{
    parent: &'w mut Serializer<W>,
    name: &'w str,
}

impl<'w, W> ser::SerializeStruct for Struct<'w, W>
    where W: 'w + Write
{
    type Ok = ();
    type Error = Error;

    fn serialize_field<T: ?Sized + Serialize>(&mut self,
                                              key: &'static str,
                                              value: &T)
                                              -> Result<(), Self::Error> {
        write!(self.parent.writer, "<{}>", key)?;
        value.serialize(&mut *self.parent)?;
        write!(self.parent.writer, "</{}>", key)?;
        Ok(())
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        write!(self.parent.writer, "</{}>", self.name).map_err(|e| e.into())
    }
}

/// An implementation of SerializeMap for serializing to XML.
pub struct Map<'w, W>
    where W: 'w + Write
{
    parent: &'w mut Serializer<W>,
}

impl<'w, W> ser::SerializeMap for Map<'w, W>
    where W: 'w + Write
{
    type Ok = ();
    type Error = Error;

    fn serialize_key<T: ?Sized + Serialize>(&mut self, _: &T) -> Result<(), Self::Error> {
        panic!("impossible to serialize just the key, please use serialize_entry()")
    }

    fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error> {
        value.serialize(&mut *self.parent)
    }

    fn end(self) -> Result<Self::Ok, Self::Error> {
        Ok(())
    }

    fn serialize_entry<K: ?Sized + Serialize, V: ?Sized + Serialize>(&mut self,
                                                                     key: &K,
                                                                     value: &V)
                                                                     -> Result<(), Self::Error> {
        // TODO: Is it possible to ensure our key is never a composite type?
        // Anything which isn't a "primitive" would lead to malformed XML here...
        write!(self.parent.writer, "<")?;
        key.serialize(&mut *self.parent)?;
        write!(self.parent.writer, ">")?;

        value.serialize(&mut *self.parent)?;

        write!(self.parent.writer, "</")?;
        key.serialize(&mut *self.parent)?;
        write!(self.parent.writer, ">")?;
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use serde::Serializer as SerSerializer;
    use serde::ser::{SerializeMap, SerializeStruct};

    #[test]
    fn test_serialize_bool() {
        let inputs = vec![(true, "true"), (false, "false")];

        for (src, should_be) in inputs {
            let mut buffer = Vec::new();

            {
                let mut ser = Serializer::new(&mut buffer);
                ser.serialize_bool(src).unwrap();
            }

            let got = String::from_utf8(buffer).unwrap();
            assert_eq!(got, should_be);
        }
    }

    #[test]
    fn test_start_serialize_struct() {
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let _ = ser.serialize_struct("foo", 0).unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, "<foo>");
    }

    #[test]
    fn test_serialize_struct_field() {
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let mut struct_ser = Struct {
                parent: &mut ser,
                name: "baz",
            };
            struct_ser.serialize_field("foo", "bar").unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, "<foo>bar</foo>");
    }

    #[test]
    fn test_serialize_struct() {
        #[derive(Serialize)]
        struct Person {
            name: String,
            age: u32,
        }

        let bob = Person {
            name: "Bob".to_string(),
            age: 42,
        };
        let should_be = "<Person><name>Bob</name><age>42</age></Person>";
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            bob.serialize(&mut ser).unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, should_be);
    }

    #[test]
    fn test_serialize_map_entries() {
        let should_be = "<name>Bob</name><age>5</age>";
        let mut buffer = Vec::new();

        {
            let mut ser = Serializer::new(&mut buffer);
            let mut map = Map { parent: &mut ser };
            map.serialize_entry("name", "Bob").unwrap();
            map.serialize_entry("age", "5").unwrap();
        }

        let got = String::from_utf8(buffer).unwrap();
        assert_eq!(got, should_be);
    }
}
<|endoftext|>


<commit_before><commit_msg>Recursive Aliases Closes #610<commit_after><|endoftext|>


<commit_before>#![crate_name = "uu_test"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) mahkoh (ju.orth [at] gmail [dot] com)
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate libc;
#[cfg(target_os = "redox")]
extern crate syscall;

use std::collections::HashMap;
use std::ffi::OsString;
use std::env::args_os;
use std::str::from_utf8;

static NAME: &'static str = "test";

// TODO: decide how to handle non-UTF8 input for all the utils
// Definitely don't use [u8], try keeping it as OsStr or OsString instead
pub fn uumain(_: Vec<String>) -> i32 {
    let args = args_os().collect::<Vec<OsString>>();
    // This is completely disregarding valid windows paths that aren't valid unicode
    let args = args.iter()
        .map(|a| a.to_str().unwrap().as_bytes())
        .collect::<Vec<&[u8]>>();
    if args.is_empty() {
        return 2;
    }
    let args = if !args[0].ends_with(NAME.as_bytes()) {
        &args[1..]
    } else {
        &args[..]
    };
    let args = match args[0] {
        b"[" => match args[args.len() - 1] {
            b"]" => &args[1..args.len() - 1],
            _ => return 2,
        },
        _ => &args[1..args.len()],
    };
    let mut error = false;
    let retval = 1 - parse_expr(args, &mut error) as i32;
    if error {
        2
    } else {
        retval
    }
}

fn one(args: &[&[u8]]) -> bool {
    args[0].len() > 0
}

fn two(args: &[&[u8]], error: &mut bool) -> bool {
    match args[0] {
        b"!" => !one(&args[1..]),
        b"-b" => path(args[1], PathCondition::BlockSpecial),
        b"-c" => path(args[1], PathCondition::CharacterSpecial),
        b"-d" => path(args[1], PathCondition::Directory),
        b"-e" => path(args[1], PathCondition::Exists),
        b"-f" => path(args[1], PathCondition::Regular),
        b"-g" => path(args[1], PathCondition::GroupIDFlag),
        b"-h" => path(args[1], PathCondition::SymLink),
        b"-L" => path(args[1], PathCondition::SymLink),
        b"-n" => one(&args[1..]),
        b"-p" => path(args[1], PathCondition::FIFO),
        b"-r" => path(args[1], PathCondition::Readable),
        b"-S" => path(args[1], PathCondition::Socket),
        b"-s" => path(args[1], PathCondition::NonEmpty),
        b"-t" => isatty(args[1]),
        b"-u" => path(args[1], PathCondition::UserIDFlag),
        b"-w" => path(args[1], PathCondition::Writable),
        b"-x" => path(args[1], PathCondition::Executable),
        b"-z" => !one(&args[1..]),
        _ => {
            *error = true;
            false
        }
    }
}

fn three(args: &[&[u8]], error: &mut bool) -> bool {
    match args[1] {
        b"=" => args[0] == args[2],
        b"==" => args[0] == args[2],
        b"!=" => args[0] != args[2],
        b"-eq" => integers(args[0], args[2], IntegerCondition::Equal),
        b"-ne" => integers(args[0], args[2], IntegerCondition::Unequal),
        b"-gt" => integers(args[0], args[2], IntegerCondition::Greater),
        b"-ge" => integers(args[0], args[2], IntegerCondition::GreaterEqual),
        b"-lt" => integers(args[0], args[2], IntegerCondition::Less),
        b"-le" => integers(args[0], args[2], IntegerCondition::LessEqual),
        _ => match args[0] {
            b"!" => !two(&args[1..], error),
            _ => {
                *error = true;
                false
            }
        },
    }
}

fn four(args: &[&[u8]], error: &mut bool) -> bool {
    match args[0] {
        b"!" => !three(&args[1..], error),
        _ => {
            *error = true;
            false
        }
    }
}

enum IntegerCondition {
    Equal,
    Unequal,
    Greater,
    GreaterEqual,
    Less,
    LessEqual,
}

fn integers(a: &[u8], b: &[u8], cond: IntegerCondition) -> bool {
    let (a, b): (&str, &str) = match (from_utf8(a), from_utf8(b)) {
        (Ok(a), Ok(b)) => (a, b),
        _ => return false,
    };
    let (a, b): (i64, i64) = match (a.parse(), b.parse()) {
        (Ok(a), Ok(b)) => (a, b),
        _ => return false,
    };
    match cond {
        IntegerCondition::Equal => a == b,
        IntegerCondition::Unequal => a != b,
        IntegerCondition::Greater => a > b,
        IntegerCondition::GreaterEqual => a >= b,
        IntegerCondition::Less => a < b,
        IntegerCondition::LessEqual => a <= b,
    }
}

fn isatty(fd: &[u8]) -> bool {
    from_utf8(fd)
        .ok()
        .and_then(|s| s.parse().ok())
        .map_or(false, |i| {
            #[cfg(not(target_os = "redox"))]
            unsafe { libc::isatty(i) == 1 }
            #[cfg(target_os = "redox")]
            syscall::dup(i, b"termios").map(syscall::close).is_ok()
        })
}

fn dispatch(args: &mut &[&[u8]], error: &mut bool) -> bool {
    let (val, idx) = match args.len() {
        0 => {
            *error = true;
            (false, 0)
        }
        1 => (one(*args), 1),
        2 => dispatch_two(args, error),
        3 => dispatch_three(args, error),
        _ => dispatch_four(args, error),
    };
    *args = &(*args)[idx..];
    val
}

fn dispatch_two(args: &mut &[&[u8]], error: &mut bool) -> (bool, usize) {
    let val = two(*args, error);
    if *error {
        *error = false;
        (one(*args), 1)
    } else {
        (val, 2)
    }
}

fn dispatch_three(args: &mut &[&[u8]], error: &mut bool) -> (bool, usize) {
    let val = three(*args, error);
    if *error {
        *error = false;
        dispatch_two(args, error)
    } else {
        (val, 3)
    }
}

fn dispatch_four(args: &mut &[&[u8]], error: &mut bool) -> (bool, usize) {
    let val = four(*args, error);
    if *error {
        *error = false;
        dispatch_three(args, error)
    } else {
        (val, 4)
    }
}

#[derive(Clone, Copy)]
enum Precedence {
    Unknown = 0,
    Paren, // FIXME: this is useless (parentheses have not been implemented)
    Or,
    And,
    BUnOp,
    BinOp,
    UnOp,
}

fn parse_expr(mut args: &[&[u8]], error: &mut bool) -> bool {
    if args.len() == 0 {
        false
    } else {
        let hashmap = setup_hashmap();
        let lhs = dispatch(&mut args, error);

        if args.len() > 0 {
            parse_expr_helper(&hashmap, &mut args, lhs, Precedence::Unknown, error)
        } else {
            lhs
        }
    }
}

fn parse_expr_helper<'a>(
    hashmap: &HashMap<&'a [u8], Precedence>,
    args: &mut &[&'a [u8]],
    mut lhs: bool,
    min_prec: Precedence,
    error: &mut bool,
) -> bool {
    let mut prec = *hashmap.get(&args[0]).unwrap_or_else(|| {
        *error = true;
        &min_prec
    });
    while !*error && args.len() > 0 && prec as usize >= min_prec as usize {
        let op = args[0];
        *args = &(*args)[1..];
        let mut rhs = dispatch(args, error);
        while args.len() > 0 {
            let subprec = *hashmap.get(&args[0]).unwrap_or_else(|| {
                *error = true;
                &min_prec
            });
            if subprec as usize <= prec as usize || *error {
                break;
            }
            rhs = parse_expr_helper(hashmap, args, rhs, subprec, error);
        }
        lhs = match prec {
            Precedence::UnOp | Precedence::BUnOp => {
                *error = true;
                false
            }
            Precedence::And => lhs && rhs,
            Precedence::Or => lhs || rhs,
            Precedence::BinOp => three(
                &[
                    if lhs { b" " } else { b"" },
                    op,
                    if rhs { b" " } else { b"" },
                ],
                error,
            ),
            Precedence::Paren => unimplemented!(), // TODO: implement parentheses
            _ => unreachable!(),
        };
        if args.len() > 0 {
            prec = *hashmap.get(&args[0]).unwrap_or_else(|| {
                *error = true;
                &min_prec
            });
        }
    }
    lhs
}

#[inline]
fn setup_hashmap<'a>() -> HashMap<&'a [u8], Precedence> {
    let mut hashmap = HashMap::<&'a [u8], Precedence>::new();

    hashmap.insert(b"-b", Precedence::UnOp);
    hashmap.insert(b"-c", Precedence::UnOp);
    hashmap.insert(b"-d", Precedence::UnOp);
    hashmap.insert(b"-e", Precedence::UnOp);
    hashmap.insert(b"-f", Precedence::UnOp);
    hashmap.insert(b"-g", Precedence::UnOp);
    hashmap.insert(b"-h", Precedence::UnOp);
    hashmap.insert(b"-L", Precedence::UnOp);
    hashmap.insert(b"-n", Precedence::UnOp);
    hashmap.insert(b"-p", Precedence::UnOp);
    hashmap.insert(b"-r", Precedence::UnOp);
    hashmap.insert(b"-S", Precedence::UnOp);
    hashmap.insert(b"-s", Precedence::UnOp);
    hashmap.insert(b"-t", Precedence::UnOp);
    hashmap.insert(b"-u", Precedence::UnOp);
    hashmap.insert(b"-w", Precedence::UnOp);
    hashmap.insert(b"-x", Precedence::UnOp);
    hashmap.insert(b"-z", Precedence::UnOp);

    hashmap.insert(b"=", Precedence::BinOp);
    hashmap.insert(b"!=", Precedence::BinOp);
    hashmap.insert(b"-eq", Precedence::BinOp);
    hashmap.insert(b"-ne", Precedence::BinOp);
    hashmap.insert(b"-gt", Precedence::BinOp);
    hashmap.insert(b"-ge", Precedence::BinOp);
    hashmap.insert(b"-lt", Precedence::BinOp);
    hashmap.insert(b"-le", Precedence::BinOp);

    hashmap.insert(b"!", Precedence::BUnOp);

    hashmap.insert(b"-a", Precedence::And);
    hashmap.insert(b"-o", Precedence::Or);

    hashmap.insert(b"(", Precedence::Paren);
    hashmap.insert(b")", Precedence::Paren);

    hashmap
}

#[derive(Eq, PartialEq)]
enum PathCondition {
    BlockSpecial,
    CharacterSpecial,
    Directory,
    Exists,
    Regular,
    GroupIDFlag,
    SymLink,
    FIFO,
    Readable,
    Socket,
    NonEmpty,
    UserIDFlag,
    Writable,
    Executable,
}

#[cfg(not(windows))]
fn path(path: &[u8], cond: PathCondition) -> bool {
    use std::os::unix::fs::{MetadataExt, FileTypeExt};
    use std::os::unix::ffi::OsStrExt;
    use std::fs::{self, Metadata};
    use std::ffi::OsStr;

    let path = OsStr::from_bytes(path);

    static S_ISUID: u32 = 0o4000;
    static S_ISGID: u32 = 0o2000;

    enum Permission {
        Read = 0o4,
        Write = 0o2,
        Execute = 0o1,
    }

    let perm = |metadata: Metadata, p: Permission| {
        #[cfg(not(target_os = "redox"))]
        let (uid, gid) = unsafe { (libc::getuid(), libc::getgid()) };
        #[cfg(target_os = "redox")]
        let (uid, gid) = (syscall::getuid().unwrap() as u32,
                          syscall::getgid().unwrap() as u32);

        if uid == metadata.uid() {
            metadata.mode() & ((p as u32) << 6) != 0
        } else if gid == metadata.gid() {
            metadata.mode() & ((p as u32) << 3) != 0
        } else {
            metadata.mode() & ((p as u32)) != 0
        }
    };

    let metadata = if cond == PathCondition::SymLink {
        fs::symlink_metadata(path)
    } else {
        fs::metadata(path)
    };

    let metadata = match metadata {
        Ok(metadata) => metadata,
        Err(_) => { return false; }
    };

    let file_type = metadata.file_type();

    match cond {
        PathCondition::BlockSpecial => file_type.is_block_device(),
        PathCondition::CharacterSpecial => file_type.is_char_device(),
        PathCondition::Directory => file_type.is_dir(),
        PathCondition::Exists => true,
        PathCondition::Regular => file_type.is_file(),
        PathCondition::GroupIDFlag => metadata.mode() & S_ISGID != 0,
        PathCondition::SymLink => metadata.file_type().is_symlink(),
        PathCondition::FIFO => file_type.is_fifo(),
        PathCondition::Readable => perm(metadata, Permission::Read),
        PathCondition::Socket => file_type.is_socket(),
        PathCondition::NonEmpty => metadata.size() > 0,
        PathCondition::UserIDFlag => metadata.mode() & S_ISUID != 0,
        PathCondition::Writable => perm(metadata, Permission::Write),
        PathCondition::Executable => perm(metadata, Permission::Execute),
    }
}

#[cfg(windows)]
fn path(path: &[u8], cond: PathCondition) -> bool {
    use std::fs::metadata;
    let path = from_utf8(path).unwrap();
    let stat = match metadata(path) {
        Ok(s) => s,
        _ => return false,
    };
    match cond {
        PathCondition::BlockSpecial => false,
        PathCondition::CharacterSpecial => false,
        PathCondition::Directory => stat.is_dir(),
        PathCondition::Exists => true,
        PathCondition::Regular => stat.is_file(),
        PathCondition::GroupIDFlag => false,
        PathCondition::SymLink => false,
        PathCondition::FIFO => false,
        PathCondition::Readable => false, // TODO
        PathCondition::Socket => false,
        PathCondition::NonEmpty => stat.len() > 0,
        PathCondition::UserIDFlag => false,
        PathCondition::Writable => false,   // TODO
        PathCondition::Executable => false, // TODO
    }
}
<commit_msg>Change static to const<commit_after>#![crate_name = "uu_test"]

/*
 * This file is part of the uutils coreutils package.
 *
 * (c) mahkoh (ju.orth [at] gmail [dot] com)
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

extern crate libc;
#[cfg(target_os = "redox")]
extern crate syscall;

use std::collections::HashMap;
use std::ffi::OsString;
use std::env::args_os;
use std::str::from_utf8;

static NAME: &'static str = "test";

// TODO: decide how to handle non-UTF8 input for all the utils
// Definitely don't use [u8], try keeping it as OsStr or OsString instead
pub fn uumain(_: Vec<String>) -> i32 {
    let args = args_os().collect::<Vec<OsString>>();
    // This is completely disregarding valid windows paths that aren't valid unicode
    let args = args.iter()
        .map(|a| a.to_str().unwrap().as_bytes())
        .collect::<Vec<&[u8]>>();
    if args.is_empty() {
        return 2;
    }
    let args = if !args[0].ends_with(NAME.as_bytes()) {
        &args[1..]
    } else {
        &args[..]
    };
    let args = match args[0] {
        b"[" => match args[args.len() - 1] {
            b"]" => &args[1..args.len() - 1],
            _ => return 2,
        },
        _ => &args[1..args.len()],
    };
    let mut error = false;
    let retval = 1 - parse_expr(args, &mut error) as i32;
    if error {
        2
    } else {
        retval
    }
}

fn one(args: &[&[u8]]) -> bool {
    args[0].len() > 0
}

fn two(args: &[&[u8]], error: &mut bool) -> bool {
    match args[0] {
        b"!" => !one(&args[1..]),
        b"-b" => path(args[1], PathCondition::BlockSpecial),
        b"-c" => path(args[1], PathCondition::CharacterSpecial),
        b"-d" => path(args[1], PathCondition::Directory),
        b"-e" => path(args[1], PathCondition::Exists),
        b"-f" => path(args[1], PathCondition::Regular),
        b"-g" => path(args[1], PathCondition::GroupIDFlag),
        b"-h" => path(args[1], PathCondition::SymLink),
        b"-L" => path(args[1], PathCondition::SymLink),
        b"-n" => one(&args[1..]),
        b"-p" => path(args[1], PathCondition::FIFO),
        b"-r" => path(args[1], PathCondition::Readable),
        b"-S" => path(args[1], PathCondition::Socket),
        b"-s" => path(args[1], PathCondition::NonEmpty),
        b"-t" => isatty(args[1]),
        b"-u" => path(args[1], PathCondition::UserIDFlag),
        b"-w" => path(args[1], PathCondition::Writable),
        b"-x" => path(args[1], PathCondition::Executable),
        b"-z" => !one(&args[1..]),
        _ => {
            *error = true;
            false
        }
    }
}

fn three(args: &[&[u8]], error: &mut bool) -> bool {
    match args[1] {
        b"=" => args[0] == args[2],
        b"==" => args[0] == args[2],
        b"!=" => args[0] != args[2],
        b"-eq" => integers(args[0], args[2], IntegerCondition::Equal),
        b"-ne" => integers(args[0], args[2], IntegerCondition::Unequal),
        b"-gt" => integers(args[0], args[2], IntegerCondition::Greater),
        b"-ge" => integers(args[0], args[2], IntegerCondition::GreaterEqual),
        b"-lt" => integers(args[0], args[2], IntegerCondition::Less),
        b"-le" => integers(args[0], args[2], IntegerCondition::LessEqual),
        _ => match args[0] {
            b"!" => !two(&args[1..], error),
            _ => {
                *error = true;
                false
            }
        },
    }
}

fn four(args: &[&[u8]], error: &mut bool) -> bool {
    match args[0] {
        b"!" => !three(&args[1..], error),
        _ => {
            *error = true;
            false
        }
    }
}

enum IntegerCondition {
    Equal,
    Unequal,
    Greater,
    GreaterEqual,
    Less,
    LessEqual,
}

fn integers(a: &[u8], b: &[u8], cond: IntegerCondition) -> bool {
    let (a, b): (&str, &str) = match (from_utf8(a), from_utf8(b)) {
        (Ok(a), Ok(b)) => (a, b),
        _ => return false,
    };
    let (a, b): (i64, i64) = match (a.parse(), b.parse()) {
        (Ok(a), Ok(b)) => (a, b),
        _ => return false,
    };
    match cond {
        IntegerCondition::Equal => a == b,
        IntegerCondition::Unequal => a != b,
        IntegerCondition::Greater => a > b,
        IntegerCondition::GreaterEqual => a >= b,
        IntegerCondition::Less => a < b,
        IntegerCondition::LessEqual => a <= b,
    }
}

fn isatty(fd: &[u8]) -> bool {
    from_utf8(fd)
        .ok()
        .and_then(|s| s.parse().ok())
        .map_or(false, |i| {
            #[cfg(not(target_os = "redox"))]
            unsafe { libc::isatty(i) == 1 }
            #[cfg(target_os = "redox")]
            syscall::dup(i, b"termios").map(syscall::close).is_ok()
        })
}

fn dispatch(args: &mut &[&[u8]], error: &mut bool) -> bool {
    let (val, idx) = match args.len() {
        0 => {
            *error = true;
            (false, 0)
        }
        1 => (one(*args), 1),
        2 => dispatch_two(args, error),
        3 => dispatch_three(args, error),
        _ => dispatch_four(args, error),
    };
    *args = &(*args)[idx..];
    val
}

fn dispatch_two(args: &mut &[&[u8]], error: &mut bool) -> (bool, usize) {
    let val = two(*args, error);
    if *error {
        *error = false;
        (one(*args), 1)
    } else {
        (val, 2)
    }
}

fn dispatch_three(args: &mut &[&[u8]], error: &mut bool) -> (bool, usize) {
    let val = three(*args, error);
    if *error {
        *error = false;
        dispatch_two(args, error)
    } else {
        (val, 3)
    }
}

fn dispatch_four(args: &mut &[&[u8]], error: &mut bool) -> (bool, usize) {
    let val = four(*args, error);
    if *error {
        *error = false;
        dispatch_three(args, error)
    } else {
        (val, 4)
    }
}

#[derive(Clone, Copy)]
enum Precedence {
    Unknown = 0,
    Paren, // FIXME: this is useless (parentheses have not been implemented)
    Or,
    And,
    BUnOp,
    BinOp,
    UnOp,
}

fn parse_expr(mut args: &[&[u8]], error: &mut bool) -> bool {
    if args.len() == 0 {
        false
    } else {
        let hashmap = setup_hashmap();
        let lhs = dispatch(&mut args, error);

        if args.len() > 0 {
            parse_expr_helper(&hashmap, &mut args, lhs, Precedence::Unknown, error)
        } else {
            lhs
        }
    }
}

fn parse_expr_helper<'a>(
    hashmap: &HashMap<&'a [u8], Precedence>,
    args: &mut &[&'a [u8]],
    mut lhs: bool,
    min_prec: Precedence,
    error: &mut bool,
) -> bool {
    let mut prec = *hashmap.get(&args[0]).unwrap_or_else(|| {
        *error = true;
        &min_prec
    });
    while !*error && args.len() > 0 && prec as usize >= min_prec as usize {
        let op = args[0];
        *args = &(*args)[1..];
        let mut rhs = dispatch(args, error);
        while args.len() > 0 {
            let subprec = *hashmap.get(&args[0]).unwrap_or_else(|| {
                *error = true;
                &min_prec
            });
            if subprec as usize <= prec as usize || *error {
                break;
            }
            rhs = parse_expr_helper(hashmap, args, rhs, subprec, error);
        }
        lhs = match prec {
            Precedence::UnOp | Precedence::BUnOp => {
                *error = true;
                false
            }
            Precedence::And => lhs && rhs,
            Precedence::Or => lhs || rhs,
            Precedence::BinOp => three(
                &[
                    if lhs { b" " } else { b"" },
                    op,
                    if rhs { b" " } else { b"" },
                ],
                error,
            ),
            Precedence::Paren => unimplemented!(), // TODO: implement parentheses
            _ => unreachable!(),
        };
        if args.len() > 0 {
            prec = *hashmap.get(&args[0]).unwrap_or_else(|| {
                *error = true;
                &min_prec
            });
        }
    }
    lhs
}

#[inline]
fn setup_hashmap<'a>() -> HashMap<&'a [u8], Precedence> {
    let mut hashmap = HashMap::<&'a [u8], Precedence>::new();

    hashmap.insert(b"-b", Precedence::UnOp);
    hashmap.insert(b"-c", Precedence::UnOp);
    hashmap.insert(b"-d", Precedence::UnOp);
    hashmap.insert(b"-e", Precedence::UnOp);
    hashmap.insert(b"-f", Precedence::UnOp);
    hashmap.insert(b"-g", Precedence::UnOp);
    hashmap.insert(b"-h", Precedence::UnOp);
    hashmap.insert(b"-L", Precedence::UnOp);
    hashmap.insert(b"-n", Precedence::UnOp);
    hashmap.insert(b"-p", Precedence::UnOp);
    hashmap.insert(b"-r", Precedence::UnOp);
    hashmap.insert(b"-S", Precedence::UnOp);
    hashmap.insert(b"-s", Precedence::UnOp);
    hashmap.insert(b"-t", Precedence::UnOp);
    hashmap.insert(b"-u", Precedence::UnOp);
    hashmap.insert(b"-w", Precedence::UnOp);
    hashmap.insert(b"-x", Precedence::UnOp);
    hashmap.insert(b"-z", Precedence::UnOp);

    hashmap.insert(b"=", Precedence::BinOp);
    hashmap.insert(b"!=", Precedence::BinOp);
    hashmap.insert(b"-eq", Precedence::BinOp);
    hashmap.insert(b"-ne", Precedence::BinOp);
    hashmap.insert(b"-gt", Precedence::BinOp);
    hashmap.insert(b"-ge", Precedence::BinOp);
    hashmap.insert(b"-lt", Precedence::BinOp);
    hashmap.insert(b"-le", Precedence::BinOp);

    hashmap.insert(b"!", Precedence::BUnOp);

    hashmap.insert(b"-a", Precedence::And);
    hashmap.insert(b"-o", Precedence::Or);

    hashmap.insert(b"(", Precedence::Paren);
    hashmap.insert(b")", Precedence::Paren);

    hashmap
}

#[derive(Eq, PartialEq)]
enum PathCondition {
    BlockSpecial,
    CharacterSpecial,
    Directory,
    Exists,
    Regular,
    GroupIDFlag,
    SymLink,
    FIFO,
    Readable,
    Socket,
    NonEmpty,
    UserIDFlag,
    Writable,
    Executable,
}

#[cfg(not(windows))]
fn path(path: &[u8], cond: PathCondition) -> bool {
    use std::os::unix::fs::{MetadataExt, FileTypeExt};
    use std::os::unix::ffi::OsStrExt;
    use std::fs::{self, Metadata};
    use std::ffi::OsStr;

    let path = OsStr::from_bytes(path);

    const S_ISUID: u32 = 0o4000;
    const S_ISGID: u32 = 0o2000;

    enum Permission {
        Read = 0o4,
        Write = 0o2,
        Execute = 0o1,
    }

    let perm = |metadata: Metadata, p: Permission| {
        #[cfg(not(target_os = "redox"))]
        let (uid, gid) = unsafe { (libc::getuid(), libc::getgid()) };
        #[cfg(target_os = "redox")]
        let (uid, gid) = (syscall::getuid().unwrap() as u32,
                          syscall::getgid().unwrap() as u32);

        if uid == metadata.uid() {
            metadata.mode() & ((p as u32) << 6) != 0
        } else if gid == metadata.gid() {
            metadata.mode() & ((p as u32) << 3) != 0
        } else {
            metadata.mode() & ((p as u32)) != 0
        }
    };

    let metadata = if cond == PathCondition::SymLink {
        fs::symlink_metadata(path)
    } else {
        fs::metadata(path)
    };

    let metadata = match metadata {
        Ok(metadata) => metadata,
        Err(_) => { return false; }
    };

    let file_type = metadata.file_type();

    match cond {
        PathCondition::BlockSpecial => file_type.is_block_device(),
        PathCondition::CharacterSpecial => file_type.is_char_device(),
        PathCondition::Directory => file_type.is_dir(),
        PathCondition::Exists => true,
        PathCondition::Regular => file_type.is_file(),
        PathCondition::GroupIDFlag => metadata.mode() & S_ISGID != 0,
        PathCondition::SymLink => metadata.file_type().is_symlink(),
        PathCondition::FIFO => file_type.is_fifo(),
        PathCondition::Readable => perm(metadata, Permission::Read),
        PathCondition::Socket => file_type.is_socket(),
        PathCondition::NonEmpty => metadata.size() > 0,
        PathCondition::UserIDFlag => metadata.mode() & S_ISUID != 0,
        PathCondition::Writable => perm(metadata, Permission::Write),
        PathCondition::Executable => perm(metadata, Permission::Execute),
    }
}

#[cfg(windows)]
fn path(path: &[u8], cond: PathCondition) -> bool {
    use std::fs::metadata;
    let path = from_utf8(path).unwrap();
    let stat = match metadata(path) {
        Ok(s) => s,
        _ => return false,
    };
    match cond {
        PathCondition::BlockSpecial => false,
        PathCondition::CharacterSpecial => false,
        PathCondition::Directory => stat.is_dir(),
        PathCondition::Exists => true,
        PathCondition::Regular => stat.is_file(),
        PathCondition::GroupIDFlag => false,
        PathCondition::SymLink => false,
        PathCondition::FIFO => false,
        PathCondition::Readable => false, // TODO
        PathCondition::Socket => false,
        PathCondition::NonEmpty => stat.len() > 0,
        PathCondition::UserIDFlag => false,
        PathCondition::Writable => false,   // TODO
        PathCondition::Executable => false, // TODO
    }
}
<|endoftext|>


<commit_before><commit_msg>start new<commit_after>/*fn replace_words<'a>(words: &'a Vec<&'a str>, sentence: &'a str) -> Vec<String> {
    let temp = sentence.split(' ').collect();
    let mut result: Vec<String>;
    for w in temp {}
}*/

fn match_head_of_str(a: &str, b: &str) -> bool {
    let len1 = a.chars().count();
    let len2 = b.chars().count();

    if len1 >= len2 {
        return a.starts_with(b);
    } else {
        return b.starts_with(a);
    }
}

fn main() {
    let words = vec!["cat", "bat", "rat"];
    let sentence = "the cattle was rattled by the battery";
    //println!("{:?}", replace_words(&words, &sentence));
    println!("{:?}", match_head_of_str("aa", "aaab"));
}
<|endoftext|>


<commit_before>use std::ops::DerefMut;

use runtime::Runtime;
use error::RuntimeError;
use error::RuntimeErrorKind;

use libimagstore::store::FileLockEntry;
use libimagstore::store::Entry;

pub type EditResult<T> = Result<T, RuntimeError>;

pub trait Edit {
    fn edit_content(&mut self, rt: &Runtime) -> EditResult<()>;
}

impl Edit for Entry {

    fn edit_content(&mut self, rt: &Runtime) -> EditResult<()> {
        edit_in_tmpfile(rt, self.get_content_mut())
            .map(|_| ())
    }

}

impl<'a> Edit for FileLockEntry<'a> {

    fn edit_content(&mut self, rt: &Runtime) -> EditResult<()> {
        self.deref_mut().edit_content(rt)
    }

}

pub fn edit_in_tmpfile(rt: &Runtime, s: &mut String) -> EditResult<()> {
    use tempfile::NamedTempFile;
    use std::io::Seek;
    use std::io::Read;
    use std::io::SeekFrom;
    use std::io::Write;

    let file      = try!(NamedTempFile::new());
    let file_path = file.path();
    let mut file  = try!(file.reopen());

    file.write_all(&s.clone().into_bytes()[..]);

    try!(file.sync_data());

    if let Some(mut editor) = rt.editor() {
        let exit_status = editor.arg(file_path).status();

        match exit_status.map(|s| s.success()) {
            Ok(true) => {
                file.sync_data()
                    .and_then(|_| file.seek(SeekFrom::Start(0)))
                    .and_then(|_| file.read_to_string(s))
                    .map(|_| ())
                    .map_err(|e| RuntimeError::new(RuntimeErrorKind::IOError, Some(Box::new(e))))
            },
            Ok(_)    => Err(RuntimeError::new(RuntimeErrorKind::ProcessExitFailure, None)),
            Err(e)   => Err(RuntimeError::new(RuntimeErrorKind::IOError, Some(Box::new(e)))),
        }
    } else {
        Err(RuntimeError::new(RuntimeErrorKind::Instantiate, None))
    }
}
<commit_msg>We can match for true/false instead of true/_<commit_after>use std::ops::DerefMut;

use runtime::Runtime;
use error::RuntimeError;
use error::RuntimeErrorKind;

use libimagstore::store::FileLockEntry;
use libimagstore::store::Entry;

pub type EditResult<T> = Result<T, RuntimeError>;

pub trait Edit {
    fn edit_content(&mut self, rt: &Runtime) -> EditResult<()>;
}

impl Edit for Entry {

    fn edit_content(&mut self, rt: &Runtime) -> EditResult<()> {
        edit_in_tmpfile(rt, self.get_content_mut())
            .map(|_| ())
    }

}

impl<'a> Edit for FileLockEntry<'a> {

    fn edit_content(&mut self, rt: &Runtime) -> EditResult<()> {
        self.deref_mut().edit_content(rt)
    }

}

pub fn edit_in_tmpfile(rt: &Runtime, s: &mut String) -> EditResult<()> {
    use tempfile::NamedTempFile;
    use std::io::Seek;
    use std::io::Read;
    use std::io::SeekFrom;
    use std::io::Write;

    let file      = try!(NamedTempFile::new());
    let file_path = file.path();
    let mut file  = try!(file.reopen());

    file.write_all(&s.clone().into_bytes()[..]);

    try!(file.sync_data());

    if let Some(mut editor) = rt.editor() {
        let exit_status = editor.arg(file_path).status();

        match exit_status.map(|s| s.success()) {
            Ok(true)  => {
                file.sync_data()
                    .and_then(|_| file.seek(SeekFrom::Start(0)))
                    .and_then(|_| file.read_to_string(s))
                    .map(|_| ())
                    .map_err(|e| RuntimeError::new(RuntimeErrorKind::IOError, Some(Box::new(e))))
            },
            Ok(false) => Err(RuntimeError::new(RuntimeErrorKind::ProcessExitFailure, None)),
            Err(e)    => Err(RuntimeError::new(RuntimeErrorKind::IOError, Some(Box::new(e)))),
        }
    } else {
        Err(RuntimeError::new(RuntimeErrorKind::Instantiate, None))
    }
}
<|endoftext|>


<commit_before><commit_msg>Rust - 19: Add solution for part 2<commit_after>// adventofcode - day 19
// part 2

use std::io::prelude::*;
use std::fs::File;

struct Replacement {
    from: String,
    to: String,
}

impl Replacement {
    fn print(&self) {
        println!("Replacement: {} -> {}", self.from, self.to);
    }
}

fn main(){
    println!("Advent of Code - day 19 | part 2");

    // import data
    let data = import_data();

    let (replacements, molecule) = parse_data(data);

    println!("Replacements possible:");
    for replacement in &replacements {
        replacement.print();
    }

    println!("\nMolecule: {}\n", molecule);

    let steps = dissolve_molecule(&molecule, &replacements, "e");

    println!("It took {} steps to create the molecule.", steps);
}

fn dissolve_molecule(base: &str, repls: &Vec<Replacement>, goal: &str) -> i32 {

    let mut mol = base.to_string();
    let mut ctr = 0;
    while mol != goal {
        for ref repl in repls {
            if mol.contains(&repl.to) {
                mol = replace_first(&mol, &repl.to, &repl.from);
                ctr += 1;
            }
        }
    }

    ctr
}

fn replace_first(string: &str, from: &str, to: &str) -> String {
    let matches: Vec<_> = string.match_indices(&from).collect();

    return if matches.len() > 0 {
        let (idx, _) = matches[0];

        // split the string into 3 strings:
        // a: substring BEFORE our element
        // _: the substring to replace
        // b: substring AFTER our element
        let (a, tmp) = string.split_at( idx );
        let (_, b) = tmp.split_at( from.len() );

        let mut result = a.to_string();
        result.push_str(&to);
        result.push_str(b);

        result
    } else {
        string.to_string()
    }
}

fn parse_data(data: String) -> (Vec<Replacement>, String) {

    let mut lines = data.lines();

    let mut replacements = Vec::new();
    loop {
        let line = lines.next().unwrap();
        // an empty line marks the end of the replacements, next line will be
        // our molecule
        if line == "" {
            break;
        }

        let replacement = string_to_replacement(line);
        replacements.push( replacement );
    }

    let molecule = lines.next().unwrap();

    ( replacements, molecule.parse::<String>().unwrap() )
}

fn string_to_replacement(string: &str) -> Replacement {
    let properties = string.split(" => ")
                            .map(|s| s.parse::<String>().unwrap())
                            .collect::<Vec<String>>();

    Replacement { from: properties[0].clone(), to: properties[1].clone() }
}

// This function simply imports the data set from a file called input.txt
fn import_data() -> String {
    let mut file = match File::open("../../inputs/19.txt") {
        Ok(f) => f,
        Err(e) => panic!("file error: {}", e),
    };

    let mut data = String::new();
    match file.read_to_string(&mut data){
        Ok(_) => {},
        Err(e) => panic!("file error: {}", e),
    };

    data.pop();
    data
}
<|endoftext|>


<commit_before><commit_msg>Minor<commit_after><|endoftext|>


<commit_before><commit_msg>Add animation code<commit_after>use num::rational::Ratio;

use buffer::RgbaImage;

/// Hold the frames of the animated image
pub struct Frames {
    frames: Vec<Frame>,
    current_frame: uint,
}

impl Frames {
    /// Contructs a new frame iterator
    pub fn new(frames: Vec<Frame>) -> Frames {
        Frames {
            frames: frames,
            current_frame: 0
        }
    }
}

/// A single animation frame
#[deriving(Clone)]
pub struct Frame {
    /// Delay between the frames in s
    delay: Ratio<u16>,
    buffer: RgbaImage,
}

impl Frame {
    /// Contructs a new frame
    pub fn new(buffer: RgbaImage) -> Frame {
        Frame {
            delay: Ratio::from_integer(0),
            buffer: buffer
        }
    }
}

impl<'a> Iterator<Frame> for Frames {
    fn next(&mut self) -> Option<Frame> {
        let frame = self.current_frame;
        self.current_frame += 1;
        self.frames.get(frame).map(|v| v.clone())
    }
}<|endoftext|>


<commit_before><commit_msg>day 3 solved.<commit_after>use std::collections::HashSet;
use std::io::prelude::*;
use std::fs::File;
use std::path::Path;

fn main() {
    let mut f = File::open(Path::new("/Users/PetarV/rust-proj/advent-of-rust/target/input.txt"))
    	.ok()
    	.expect("Failed to open the input file!");

    let mut input = String::new();

	f.read_to_string(&mut input)
		.ok()
		.expect("Failed to read from the input file!");

    let mut pos_x = 0;
    let mut pos_y = 0;
    let mut visited = HashSet::new();

    visited.insert((0, 0));

    for ch in input.chars() {
        match ch {
            'v' => pos_x = pos_x + 1,
            '>' => pos_y = pos_y + 1,
            '^' => pos_x = pos_x - 1,
            '<' => pos_y = pos_y - 1,
            _   => ()
        };
        visited.insert((pos_x, pos_y));
    }

    let ret = visited.len();

    println!("The Santa has visited {} houses.", ret);

    let mut pos_x = [0, 0];
    let mut pos_y = [0, 0];
    let mut visited = HashSet::new();

    visited.insert((0, 0));

    for (i, ch) in input.chars().enumerate() {
        let ind = i % 2;
        match ch {
            'v' => pos_x[ind] = pos_x[ind] + 1,
            '>' => pos_y[ind] = pos_y[ind] + 1,
            '^' => pos_x[ind] = pos_x[ind] - 1,
            '<' => pos_y[ind] = pos_y[ind] - 1,
            _   => ()
        };
        visited.insert((pos_x[ind], pos_y[ind]));
    }

    let ret = visited.len();

    println!("The Santa and Robo-Santa have visited {} houses.", ret);
}<|endoftext|>


<commit_before><commit_msg>core view<commit_after>use std::path::PathBuf;
use std::fs::File;
use std::io::{BufReader, BufRead, Error as IoError};

#[derive(Debug)]
pub struct View {
    path: Option<PathBuf>,
    lines: Vec<Line>
}

#[derive(Debug)]
pub struct Line {
    text: String
}

impl Line {
    fn new(text: String) -> Line {
        Line {
            text: text
        }
    }
}

impl View {
    pub fn new() -> View {
        View {
            path: None,
            lines: Vec::new()
        }
    }

    pub fn open(path: PathBuf) -> Result<View, IoError> {
        let mut lines = Vec::new();
        for text in BufReader::new(try!(File::open(&path))).lines() {
            lines.push(Line::new(try!(text)));
        }
        Ok(View {
            path: Some(path),
            lines: lines
        })
    }
}
<|endoftext|>


<commit_before><commit_msg>Convert to new closure syntax: &fn() -> ||<commit_after><|endoftext|>


<commit_before><commit_msg>- Added test for cases when there creatures without assigned action. - Fix popping logic<commit_after><|endoftext|>


<commit_before><commit_msg>heap and stack<commit_after><|endoftext|>


<commit_before><commit_msg>Placeholder for pattern tests<commit_after><|endoftext|>