<commit_before>#![crate_name = "piston"]
#![deny(missing_docs)]
#![warn(dead_code)]
#![feature(default_type_params)]
#![feature(globs)]
#![feature(if_let)]

//! A user friendly game engine written in Rust.

extern crate sync;
extern crate gfx;
extern crate gfx_graphics;
extern crate opengl_graphics;
extern crate sdl2;
extern crate sdl2_window;
extern crate window;

// Crates used to reexport.
extern crate "vecmath" as vecmath_lib;
extern crate "shader_version" as shader_version_lib;
extern crate "image" as image_lib;
extern crate "graphics" as graphics_lib;
extern crate "input" as input_lib;
extern crate "event" as event_lib;
extern crate "cam" as cam_lib;
extern crate "noise" as noise_lib;
extern crate "genmesh" as genmesh_lib;
extern crate "sprite" as sprite_lib;
extern crate "current" as current_lib;
extern crate "fps_counter" as fps_counter_lib;
extern crate "wavefront-obj" as wavefront_obj_lib;
extern crate "drag_controller" as drag_controller_lib;
extern crate "read_color" as read_color_lib;
extern crate "select_color" as select_color_lib;
extern crate "texture_packer" as texture_packer_lib;

// Reexports.
pub use shader_version_lib as shader_version;
pub use image_lib as image;
pub use graphics_lib as graphics;
pub use vecmath_lib as vecmath;
pub use input_lib as input;
pub use event_lib as event;
pub use cam_lib as cam;
pub use noise_lib as noise;
pub use genmesh_lib as genmesh;
pub use sprite_lib as sprite;
pub use current_lib as current;
pub use fps_counter_lib as fps_counter;
pub use wavefront_obj_lib as wavefront_obj;
pub use drag_controller_lib as drag_controller;
pub use texture_packer_lib as texture_packer;

pub use sdl2_window::Sdl2Window as WindowBackEnd;
pub use event::{
    Render,
    Update,
    Input,
    Event,
    Events,
    NoWindow,
    RenderArgs,
    UpdateArgs,
    Window,
    WindowSettings,
};
pub use current::{
    Get,
    Set,
    Modifier,
    Current,
    CurrentGuard,
};

use gfx_graphics::G2D;
use opengl_graphics::Gl;
use fps_counter::FPSCounter;
use gfx::{ DeviceHelper };

pub mod color {
    //! Rexported libraries for working with colors
    pub use read_color_lib as read_color;
    pub use select_color_lib as select_color;
}

/// Initializes window and sets up current objects.
pub fn start(
    opengl: shader_version::opengl::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    let mut window = WindowBackEnd::new(
        opengl,
        window_settings,
    );

    let mut device = gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    });
    let mut gl = Gl::new(opengl);
    let mut g2d = G2D::new(&mut device);
    let mut renderer = device.create_renderer();
    let event::window::Size([w, h]) = window.get();
    let mut frame = gfx::Frame::new(w as u16, h as u16);
    let mut fps_counter = FPSCounter::new();

    let window_guard = CurrentGuard::new(&mut window);
    let device_guard = CurrentGuard::new(&mut device);
    let gl_guard = CurrentGuard::new(&mut gl);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let frame_guard = CurrentGuard::new(&mut frame);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(device_guard);
    drop(gl_guard);
    drop(g2d_guard);
    drop(renderer_guard);
    drop(frame_guard);
    drop(fps_counter_guard);
}

/// The current window
pub unsafe fn current_window() -> Current<WindowBackEnd> { Current }
/// The current Gfx device
pub unsafe fn current_gfx_device() -> Current<gfx::GlDevice> { Current }
/// The current opengl_graphics back-end
pub unsafe fn current_gl() -> Current<Gl> { Current }
/// The current gfx_graphics back-end
pub unsafe fn current_g2d() -> Current<G2D> { Current }
/// The current Gfx renderer
pub unsafe fn current_renderer() -> Current<gfx::Renderer<gfx::GlCommandBuffer>> { Current }
/// The current Gfx frame
pub unsafe fn current_frame() -> Current<gfx::Frame> { Current }
/// The current FPS counter
pub unsafe fn current_fps_counter() -> Current<FPSCounter> { Current }

/// Returns an event iterator for the event loop
pub fn events() -> event::Events<Current<WindowBackEnd>> {
    unsafe {
        Events::new(current_window())
    }
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> uint {
    unsafe {
        current_fps_counter().tick()
    }
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    unsafe {
        current_window().set_mut(window::Title(text));
    }
}

/// Renders 2D graphics using Gfx.
pub fn render_2d_gfx(
    bg_color: Option<[f32, ..4]>,
    f: |&graphics::Context,
        &mut gfx_graphics::GraphicsBackEnd<gfx::GlCommandBuffer>|
) {
    use gfx::Device;

    unsafe {
        current_g2d().draw(
            &mut *current_renderer(),
            &*current_frame(),
            |c, g| {
                use graphics::*;
                if let Some(bg_color) = bg_color {
                    c.color(bg_color).draw(g);
                }
                f(&c, g);
            });
        current_gfx_device().submit(current_renderer().as_buffer());
        current_renderer().reset();
    }
}

/// Renders 2D graphics using OpenGL.
pub fn render_2d_opengl(
    bg_color: Option<[f32, ..4]>,
    f: |&graphics::Context,
        &mut opengl_graphics::Gl|
) {
    unsafe {
        use graphics::*;
        let gl = &mut *current_gl();
        let window::Size([w, h]) = current_window().get();
        gl.viewport(0, 0, w as i32, h as i32);
        gl.clear_program();
        let c = Context::abs(w as f64, h as f64);
        if let Some(bg_color) = bg_color {
            c.color(bg_color).draw(gl);
        }
        f(&c, gl);
    }
}

<commit_msg>Updating for enum namespace chage in event<commit_after>#![crate_name = "piston"]
#![deny(missing_docs)]
#![warn(dead_code)]
#![feature(default_type_params)]
#![feature(globs)]
#![feature(if_let)]

//! A user friendly game engine written in Rust.

extern crate sync;
extern crate gfx;
extern crate gfx_graphics;
extern crate opengl_graphics;
extern crate sdl2;
extern crate sdl2_window;
extern crate window;

// Crates used to reexport.
extern crate "vecmath" as vecmath_lib;
extern crate "shader_version" as shader_version_lib;
extern crate "image" as image_lib;
extern crate "graphics" as graphics_lib;
extern crate "input" as input_lib;
extern crate "event" as event_lib;
extern crate "cam" as cam_lib;
extern crate "noise" as noise_lib;
extern crate "genmesh" as genmesh_lib;
extern crate "sprite" as sprite_lib;
extern crate "current" as current_lib;
extern crate "fps_counter" as fps_counter_lib;
extern crate "wavefront-obj" as wavefront_obj_lib;
extern crate "drag_controller" as drag_controller_lib;
extern crate "read_color" as read_color_lib;
extern crate "select_color" as select_color_lib;
extern crate "texture_packer" as texture_packer_lib;

// Reexports.
pub use shader_version_lib as shader_version;
pub use image_lib as image;
pub use graphics_lib as graphics;
pub use vecmath_lib as vecmath;
pub use input_lib as input;
pub use event_lib as event;
pub use cam_lib as cam;
pub use noise_lib as noise;
pub use genmesh_lib as genmesh;
pub use sprite_lib as sprite;
pub use current_lib as current;
pub use fps_counter_lib as fps_counter;
pub use wavefront_obj_lib as wavefront_obj;
pub use drag_controller_lib as drag_controller;
pub use texture_packer_lib as texture_packer;

pub use sdl2_window::Sdl2Window as WindowBackEnd;
pub use event::{
    Event,
    Events,
    NoWindow,
    RenderArgs,
    UpdateArgs,
    Window,
    WindowSettings,
};
pub use current::{
    Get,
    Set,
    Modifier,
    Current,
    CurrentGuard,
};

use gfx_graphics::G2D;
use opengl_graphics::Gl;
use fps_counter::FPSCounter;
use gfx::{ DeviceHelper };

pub mod color {
    //! Rexported libraries for working with colors
    pub use read_color_lib as read_color;
    pub use select_color_lib as select_color;
}

/// Initializes window and sets up current objects.
pub fn start(
    opengl: shader_version::opengl::OpenGL,
    window_settings: WindowSettings,
    f: ||
) {
    let mut window = WindowBackEnd::new(
        opengl,
        window_settings,
    );

    let mut device = gfx::GlDevice::new(|s| unsafe {
        std::mem::transmute(sdl2::video::gl_get_proc_address(s))
    });
    let mut gl = Gl::new(opengl);
    let mut g2d = G2D::new(&mut device);
    let mut renderer = device.create_renderer();
    let event::window::Size([w, h]) = window.get();
    let mut frame = gfx::Frame::new(w as u16, h as u16);
    let mut fps_counter = FPSCounter::new();

    let window_guard = CurrentGuard::new(&mut window);
    let device_guard = CurrentGuard::new(&mut device);
    let gl_guard = CurrentGuard::new(&mut gl);
    let g2d_guard = CurrentGuard::new(&mut g2d);
    let renderer_guard = CurrentGuard::new(&mut renderer);
    let frame_guard = CurrentGuard::new(&mut frame);
    let fps_counter_guard = CurrentGuard::new(&mut fps_counter);

    f();

    drop(window_guard);
    drop(device_guard);
    drop(gl_guard);
    drop(g2d_guard);
    drop(renderer_guard);
    drop(frame_guard);
    drop(fps_counter_guard);
}

/// The current window
pub unsafe fn current_window() -> Current<WindowBackEnd> { Current }
/// The current Gfx device
pub unsafe fn current_gfx_device() -> Current<gfx::GlDevice> { Current }
/// The current opengl_graphics back-end
pub unsafe fn current_gl() -> Current<Gl> { Current }
/// The current gfx_graphics back-end
pub unsafe fn current_g2d() -> Current<G2D> { Current }
/// The current Gfx renderer
pub unsafe fn current_renderer() -> Current<gfx::Renderer<gfx::GlCommandBuffer>> { Current }
/// The current Gfx frame
pub unsafe fn current_frame() -> Current<gfx::Frame> { Current }
/// The current FPS counter
pub unsafe fn current_fps_counter() -> Current<FPSCounter> { Current }

/// Returns an event iterator for the event loop
pub fn events() -> event::Events<Current<WindowBackEnd>> {
    unsafe {
        Events::new(current_window())
    }
}

/// Updates the FPS counter and gets the frames per second.
pub fn fps_tick() -> uint {
    unsafe {
        current_fps_counter().tick()
    }
}

/// Sets title of the current window.
pub fn set_title(text: String) {
    unsafe {
        current_window().set_mut(window::Title(text));
    }
}

/// Renders 2D graphics using Gfx.
pub fn render_2d_gfx(
    bg_color: Option<[f32, ..4]>,
    f: |&graphics::Context,
        &mut gfx_graphics::GraphicsBackEnd<gfx::GlCommandBuffer>|
) {
    use gfx::Device;

    unsafe {
        current_g2d().draw(
            &mut *current_renderer(),
            &*current_frame(),
            |c, g| {
                use graphics::*;
                if let Some(bg_color) = bg_color {
                    c.color(bg_color).draw(g);
                }
                f(&c, g);
            });
        current_gfx_device().submit(current_renderer().as_buffer());
        current_renderer().reset();
    }
}

/// Renders 2D graphics using OpenGL.
pub fn render_2d_opengl(
    bg_color: Option<[f32, ..4]>,
    f: |&graphics::Context,
        &mut opengl_graphics::Gl|
) {
    unsafe {
        use graphics::*;
        let gl = &mut *current_gl();
        let window::Size([w, h]) = current_window().get();
        gl.viewport(0, 0, w as i32, h as i32);
        gl.clear_program();
        let c = Context::abs(w as f64, h as f64);
        if let Some(bg_color) = bg_color {
            c.color(bg_color).draw(gl);
        }
        f(&c, gl);
    }
}

<|endoftext|>


<commit_before>#![allow(unused_imports,dead_code)]

#[macro_use]
extern crate lazy_static;

mod color;
mod style;

use color::*;

use std::convert::From;
use std::ops::Deref;
use std::string::String;
use std::fmt;

/// Colored mean both color or styled
#[derive(Debug,PartialEq, Eq)]
pub struct ColoredString {
    input: String,
    fgcolor: Option<Color>,
    bgcolor: Option<Color>,
    style: style::Style,
}

pub trait Colorize {
    // Font Colors
    fn black(self) -> ColoredString;
    fn red(self) -> ColoredString;
    fn green(self) -> ColoredString;
    fn yellow(self) -> ColoredString;
    fn blue(self) -> ColoredString;
    fn magenta(self) -> ColoredString;
    fn purple(self) -> ColoredString;
    fn cyan(self) -> ColoredString;
    fn white(self) -> ColoredString;
    // Background Colors
    fn on_black(self) -> ColoredString;
    fn on_red(self) -> ColoredString;
    fn on_green(self) -> ColoredString;
    fn on_yellow(self) -> ColoredString;
    fn on_blue(self) -> ColoredString;
    fn on_magenta(self) -> ColoredString;
    fn on_purple(self) -> ColoredString;
    fn on_cyan(self) -> ColoredString;
    fn on_white(self) -> ColoredString;
    // Styles
    fn clear(self) -> ColoredString;
    fn normal(self) -> ColoredString;
    fn bold(self) -> ColoredString;
    fn dimmed(self) -> ColoredString;
    fn italic(self) -> ColoredString;
    fn underline(self) -> ColoredString;
    fn blink(self) -> ColoredString;
    fn reverse(self) -> ColoredString;
    fn hidden(self) -> ColoredString;
}

impl ColoredString {
    pub fn is_plain(&self) -> bool {
        (self.bgcolor.is_none() && self.fgcolor.is_none() && self.style == style::CLEAR)
    }

    #[cfg(not(feature = "no-color"))]
    fn has_colors(&self) -> bool {
        use std::env::var_os;
        use std::ffi::OsString;
        fn is_good(var: Option<OsString>) -> bool {
            var.is_none() || var != Some("0".into())
        }
        lazy_static! {
            static ref COLOR_STATE : bool = (
                (var_os("CLICOLOR_FORCE").or(Some("0".into()))
                 != Some("0".into()))
                 || is_good(var_os("CLICOLOR"))
            );
        }
        *COLOR_STATE
    }

    #[cfg(feature = "no-color")]
    fn has_colors(&self) -> bool {
        false
    }

    fn compute_style(&self) -> String {

        if !self.has_colors() || self.is_plain() {
            return String::new();
        }

        let mut res = String::from("\x1B[");
        let mut has_wrote = false;

        if self.style != style::CLEAR {
            res.push_str(&self.style.to_str());
            has_wrote = true;
        }

        if let Some(ref bgcolor) = self.bgcolor {
            if has_wrote {
                res.push(';');
            }

            res.push_str(bgcolor.to_bg_str());
            has_wrote = true;
        }

        if let Some(ref fgcolor) = self.fgcolor {
            if has_wrote {
                res.push(';');
            }

            res.push_str(fgcolor.to_fg_str());
        }

        res.push('m');
        res
    }

    fn escape_inner_reset_sequence(&self) -> String {

        if !self.has_colors() || self.is_plain() {
            return self.input.clone();
        }

        // TODO: BoyScoutRule
        let reset = "\x1B[0m";
        let style = self.compute_style();
        let matches : Vec<usize> = self.input.match_indices(reset)
                                             .map(|(idx, _)| idx)
                                             .collect();

        let mut input = self.input.clone();
        input.reserve(matches.len() * style.len());

        for idx in matches {
            let mut idx = idx + reset.len();

            for cchar in style.chars() {
                input.insert(idx, cchar);
                idx += 1;
            }
        }

        input
    }
}

impl Default for ColoredString {
    fn default() -> Self {
        ColoredString {
            input: String::default(),
            fgcolor: None,
            bgcolor: None,
            style: style::CLEAR,
        }
    }
}

impl Deref for ColoredString {
    type Target = str;
    fn deref(&self) -> &str {
        &self.input
    }
}

impl<'a> From<&'a str> for ColoredString {
    fn from(s: &'a str) -> Self {
        ColoredString { input: String::from(s), ..ColoredString::default() }
    }
}

macro_rules! def_color {
    ($side:ident: $name: ident => $color: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                $side: Some($color), .. self
            }
        }
    };
}

macro_rules! def_style {
    ($name: ident, $value: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                style: style::Style::from_both(self.style, $value),
                .. self
            }
        }
    };
}

impl Colorize for ColoredString {
    def_color!(fgcolor: black => Color::Black);
    fn red(self) -> ColoredString {
        ColoredString { fgcolor: Some(Color::Red), ..self }
    }
    def_color!(fgcolor: green => Color::Green);
    def_color!(fgcolor: yellow => Color::Yellow);
    def_color!(fgcolor: blue => Color::Blue);
    def_color!(fgcolor: magenta => Color::Magenta);
    def_color!(fgcolor: purple => Color::Magenta);
    def_color!(fgcolor: cyan => Color::Cyan);
    def_color!(fgcolor: white => Color::White);

    def_color!(bgcolor: on_black => Color::Black);
    fn on_red(self) -> ColoredString {
        ColoredString { bgcolor: Some(Color::Red), ..self }
    }
    def_color!(bgcolor: on_green => Color::Green);
    def_color!(bgcolor: on_yellow => Color::Yellow);
    def_color!(bgcolor: on_blue => Color::Blue);
    def_color!(bgcolor: on_magenta => Color::Magenta);
    def_color!(bgcolor: on_purple => Color::Magenta);
    def_color!(bgcolor: on_cyan => Color::Cyan);
    def_color!(bgcolor: on_white => Color::White);

    fn clear(self) -> ColoredString {
        ColoredString { input: self.input, ..ColoredString::default() }
    }
    fn normal(self) -> ColoredString {
        self.clear()
    }
    def_style!(bold, style::Styles::Bold);
    def_style!(dimmed, style::Styles::Dimmed);
    def_style!(italic, style::Styles::Italic);
    def_style!(underline, style::Styles::Underline);
    def_style!(blink, style::Styles::Blink);
    def_style!(reverse, style::Styles::Reversed);
    def_style!(hidden, style::Styles::Hidden);
}

macro_rules! def_str_color {
    ($side:ident: $name: ident => $color: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                input: String::from(self),
                $side: Some($color),
                .. ColoredString::default()
            }
        }
    }
}

macro_rules! def_str_style {
    ($name:ident, $style:path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                input: String::from(self),
                style: style::Style::new($style),
                .. ColoredString::default()
            }
        }
    }
}

impl<'a> Colorize for &'a str {
    def_str_color!(fgcolor: black => Color::Black);
    fn red(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            fgcolor: Some(Color::Red),
            ..ColoredString::default()
        }
    }
    def_str_color!(fgcolor: green => Color::Green);
    def_str_color!(fgcolor: yellow => Color::Yellow);
    def_str_color!(fgcolor: blue => Color::Blue);
    def_str_color!(fgcolor: magenta => Color::Magenta);
    def_str_color!(fgcolor: purple => Color::Magenta);
    def_str_color!(fgcolor: cyan => Color::Cyan);
    def_str_color!(fgcolor: white => Color::White);

    def_str_color!(bgcolor: on_black => Color::Black);
    fn on_red(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            bgcolor: Some(Color::Red),
            ..ColoredString::default()
        }
    }
    def_str_color!(bgcolor: on_green => Color::Green);
    def_str_color!(bgcolor: on_yellow => Color::Yellow);
    def_str_color!(bgcolor: on_blue => Color::Blue);
    def_str_color!(bgcolor: on_magenta => Color::Magenta);
    def_str_color!(bgcolor: on_purple => Color::Magenta);
    def_str_color!(bgcolor: on_cyan => Color::Cyan);
    def_str_color!(bgcolor: on_white => Color::White);

    fn clear(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            style: style::CLEAR,
            ..ColoredString::default()
        }
    }
    fn normal(self) -> ColoredString {
        self.clear()
    }
    def_str_style!(bold, style::Styles::Bold);
    def_str_style!(dimmed, style::Styles::Dimmed);
    def_str_style!(italic, style::Styles::Italic);
    def_str_style!(underline, style::Styles::Underline);
    def_str_style!(blink, style::Styles::Blink);
    def_str_style!(reverse, style::Styles::Reversed);
    def_str_style!(hidden, style::Styles::Hidden);
}

impl fmt::Display for ColoredString {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

        if !self.has_colors() || self.is_plain() {
            return (<String as fmt::Display>::fmt(&self.input, f));
        }

        // XXX: see tests. Useful when nesting colored strings
        let escaped_input = self.escape_inner_reset_sequence();

        try!(f.write_str(&self.compute_style()));
        try!(<String as fmt::Display>::fmt(&escaped_input, f));
        try!(f.write_str("\x1B[0m"));
        Ok(())
    }
}

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

    #[test]
    fn formatting() {
        // respect the formatting. Escape sequence add some padding so >= 40
        assert!(format!("{:40}", "".blue()).len() >= 40);
        // both should be truncated to 1 char before coloring
        assert_eq!(format!("{:1.1}", "toto".blue()).len(),
                   format!("{:1.1}", "1".blue()).len())
    }

    #[test]
    fn it_works() {
        let toto = "toto";
        println!("{}", toto.red());
        println!("{}", String::from(toto).red());
        println!("{}", toto.blue());

        println!("blue style ****");
        println!("{}", toto.bold());
        println!("{}", "yeah ! Red bold !".red().bold());
        println!("{}", "yeah ! Yellow bold !".bold().yellow());
        println!("{}", toto.bold().blue());
        println!("{}", toto.blue().bold());
        println!("{}", toto.blue().bold().underline());
        println!("{}", toto.blue().italic());
        println!("******");
        println!("test clearing");
        println!("{}", "red cleared".red().clear());
        println!("{}", "bold cyan cleared".bold().cyan().clear());
        println!("******");
        println!("Bg tests");
        println!("{}", toto.green().on_blue());
        println!("{}", toto.on_magenta().yellow());
        println!("{}", toto.purple().on_yellow());
        println!("{}", toto.magenta().on_white());
        println!("{}", toto.cyan().on_green());
        println!("{}", toto.black().on_white());
        println!("******");
        println!("{}", toto.green());
        println!("{}", toto.yellow());
        println!("{}", toto.purple());
        println!("{}", toto.magenta());
        println!("{}", toto.cyan());
        println!("{}", toto.white());
        println!("{}", toto.white().red().blue().green());
        // uncomment to see term output
        // assert!(false)
    }

    #[test]
    fn compute_style_empty_string() {
        assert_eq!("", "".clear().compute_style());
    }

    #[test]
    fn compute_style_simple_fg_blue() {
        let blue = "\x1B[34m";

        assert_eq!(blue, "".blue().compute_style());
    }

    #[test]
    fn compute_style_simple_bg_blue() {
        let on_blue = "\x1B[44m";

        assert_eq!(on_blue, "".on_blue().compute_style());
    }

    #[test]
    fn compute_style_blue_on_blue() {
        let blue_on_blue = "\x1B[44;34m";

        assert_eq!(blue_on_blue, "".blue().on_blue().compute_style());
    }

    #[test]
    fn compute_style_simple_bold() {
        let bold = "\x1B[1m";

        assert_eq!(bold, "".bold().compute_style());
    }

    #[test]
    fn compute_style_blue_bold() {
        let blue_bold = "\x1B[1;34m";

        assert_eq!(blue_bold, "".blue().bold().compute_style());
    }

    #[test]
    fn compute_style_blue_bold_on_blue() {
        let blue_bold_on_blue = "\x1B[1;44;34m";

        assert_eq!(blue_bold_on_blue, "".blue().bold().on_blue().compute_style());
    }

    #[test]
    fn escape_reset_sequence_spec_should_do_nothing_on_empty_strings() {
        let style = ColoredString::default();
        let expected = String::new();

        let output = style.escape_inner_reset_sequence();

        assert_eq!(expected, output);
    }

    #[test]
    fn escape_reset_sequence_spec_should_do_nothing_on_string_with_no_reset() {
        let style = ColoredString { input: String::from("hello world !"), .. ColoredString::default() };

        let expected = String::from("hello world !");
        let output = style.escape_inner_reset_sequence();

        assert_eq!(expected, output);
    }

    #[test]
    fn escape_reset_sequence_spec_should_replace_inner_reset_sequence_with_current_style() {
        let input = format!("start {} end", String::from("hello world !").red());
        let style = input.blue();

        let output = style.escape_inner_reset_sequence();
        let blue = "\x1B[34m";
        let red = "\x1B[31m";
        let reset = "\x1B[0m";
        let expected = format!("start {}hello world !{}{} end", red, reset, blue);
        assert_eq!(expected, output);
    }
}
<commit_msg> Fix issue #11 (#14)<commit_after>#![allow(unused_imports,dead_code)]

#[macro_use]
extern crate lazy_static;

mod color;
mod style;

use color::*;

use std::convert::From;
use std::ops::Deref;
use std::string::String;
use std::fmt;

/// Colored mean both color or styled
#[derive(Debug,PartialEq, Eq)]
pub struct ColoredString {
    input: String,
    fgcolor: Option<Color>,
    bgcolor: Option<Color>,
    style: style::Style,
}

pub trait Colorize {
    // Font Colors
    fn black(self) -> ColoredString;
    fn red(self) -> ColoredString;
    fn green(self) -> ColoredString;
    fn yellow(self) -> ColoredString;
    fn blue(self) -> ColoredString;
    fn magenta(self) -> ColoredString;
    fn purple(self) -> ColoredString;
    fn cyan(self) -> ColoredString;
    fn white(self) -> ColoredString;
    // Background Colors
    fn on_black(self) -> ColoredString;
    fn on_red(self) -> ColoredString;
    fn on_green(self) -> ColoredString;
    fn on_yellow(self) -> ColoredString;
    fn on_blue(self) -> ColoredString;
    fn on_magenta(self) -> ColoredString;
    fn on_purple(self) -> ColoredString;
    fn on_cyan(self) -> ColoredString;
    fn on_white(self) -> ColoredString;
    // Styles
    fn clear(self) -> ColoredString;
    fn normal(self) -> ColoredString;
    fn bold(self) -> ColoredString;
    fn dimmed(self) -> ColoredString;
    fn italic(self) -> ColoredString;
    fn underline(self) -> ColoredString;
    fn blink(self) -> ColoredString;
    fn reverse(self) -> ColoredString;
    fn hidden(self) -> ColoredString;
}

impl ColoredString {
    pub fn is_plain(&self) -> bool {
        (self.bgcolor.is_none() && self.fgcolor.is_none() && self.style == style::CLEAR)
    }

    #[cfg(not(feature = "no-color"))]
    fn has_colors(&self) -> bool {
        use std::env::var_os;
        use std::ffi::OsString;
        fn is_good(var: Option<OsString>) -> bool {
            var.is_none() || var != Some("0".into())
        }
        lazy_static! {
            static ref COLOR_STATE : bool = (
                (var_os("CLICOLOR_FORCE").or(Some("0".into()))
                 != Some("0".into()))
                 || is_good(var_os("CLICOLOR"))
            );
        }
        *COLOR_STATE
    }

    #[cfg(feature = "no-color")]
    fn has_colors(&self) -> bool {
        false
    }

    fn compute_style(&self) -> String {

        if !self.has_colors() || self.is_plain() {
            return String::new();
        }

        let mut res = String::from("\x1B[");
        let mut has_wrote = false;

        if self.style != style::CLEAR {
            res.push_str(&self.style.to_str());
            has_wrote = true;
        }

        if let Some(ref bgcolor) = self.bgcolor {
            if has_wrote {
                res.push(';');
            }

            res.push_str(bgcolor.to_bg_str());
            has_wrote = true;
        }

        if let Some(ref fgcolor) = self.fgcolor {
            if has_wrote {
                res.push(';');
            }

            res.push_str(fgcolor.to_fg_str());
        }

        res.push('m');
        res
    }

    fn escape_inner_reset_sequences(&self) -> String {

        if !self.has_colors() || self.is_plain() {
            return self.input.clone();
        }

        // TODO: BoyScoutRule
        let reset = "\x1B[0m";
        let style = self.compute_style();
        let matches : Vec<usize> = self.input.match_indices(reset)
                                             .map(|(idx, _)| idx)
                                             .collect();

        let mut idx_in_matches = 0;
        let mut input = self.input.clone();
        input.reserve(matches.len() * style.len());

        for offset in matches {
            // shift the offset to the end of the reset sequence and take in account
            // the number of matches we have escaped (which shift the index to insert)
            let mut offset = offset + reset.len() + idx_in_matches * style.len();

            for cchar in style.chars() {
                input.insert(offset, cchar);
                offset += 1;
            }

            idx_in_matches += 1;
        }

        input
    }
}

impl Default for ColoredString {
    fn default() -> Self {
        ColoredString {
            input: String::default(),
            fgcolor: None,
            bgcolor: None,
            style: style::CLEAR,
        }
    }
}

impl Deref for ColoredString {
    type Target = str;
    fn deref(&self) -> &str {
        &self.input
    }
}

impl<'a> From<&'a str> for ColoredString {
    fn from(s: &'a str) -> Self {
        ColoredString { input: String::from(s), ..ColoredString::default() }
    }
}

macro_rules! def_color {
    ($side:ident: $name: ident => $color: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                $side: Some($color), .. self
            }
        }
    };
}

macro_rules! def_style {
    ($name: ident, $value: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                style: style::Style::from_both(self.style, $value),
                .. self
            }
        }
    };
}

impl Colorize for ColoredString {
    def_color!(fgcolor: black => Color::Black);
    fn red(self) -> ColoredString {
        ColoredString { fgcolor: Some(Color::Red), ..self }
    }
    def_color!(fgcolor: green => Color::Green);
    def_color!(fgcolor: yellow => Color::Yellow);
    def_color!(fgcolor: blue => Color::Blue);
    def_color!(fgcolor: magenta => Color::Magenta);
    def_color!(fgcolor: purple => Color::Magenta);
    def_color!(fgcolor: cyan => Color::Cyan);
    def_color!(fgcolor: white => Color::White);

    def_color!(bgcolor: on_black => Color::Black);
    fn on_red(self) -> ColoredString {
        ColoredString { bgcolor: Some(Color::Red), ..self }
    }
    def_color!(bgcolor: on_green => Color::Green);
    def_color!(bgcolor: on_yellow => Color::Yellow);
    def_color!(bgcolor: on_blue => Color::Blue);
    def_color!(bgcolor: on_magenta => Color::Magenta);
    def_color!(bgcolor: on_purple => Color::Magenta);
    def_color!(bgcolor: on_cyan => Color::Cyan);
    def_color!(bgcolor: on_white => Color::White);

    fn clear(self) -> ColoredString {
        ColoredString { input: self.input, ..ColoredString::default() }
    }
    fn normal(self) -> ColoredString {
        self.clear()
    }
    def_style!(bold, style::Styles::Bold);
    def_style!(dimmed, style::Styles::Dimmed);
    def_style!(italic, style::Styles::Italic);
    def_style!(underline, style::Styles::Underline);
    def_style!(blink, style::Styles::Blink);
    def_style!(reverse, style::Styles::Reversed);
    def_style!(hidden, style::Styles::Hidden);
}

macro_rules! def_str_color {
    ($side:ident: $name: ident => $color: path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                input: String::from(self),
                $side: Some($color),
                .. ColoredString::default()
            }
        }
    }
}

macro_rules! def_str_style {
    ($name:ident, $style:path) => {
        fn $name(self) -> ColoredString {
            ColoredString {
                input: String::from(self),
                style: style::Style::new($style),
                .. ColoredString::default()
            }
        }
    }
}

impl<'a> Colorize for &'a str {
    def_str_color!(fgcolor: black => Color::Black);
    fn red(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            fgcolor: Some(Color::Red),
            ..ColoredString::default()
        }
    }
    def_str_color!(fgcolor: green => Color::Green);
    def_str_color!(fgcolor: yellow => Color::Yellow);
    def_str_color!(fgcolor: blue => Color::Blue);
    def_str_color!(fgcolor: magenta => Color::Magenta);
    def_str_color!(fgcolor: purple => Color::Magenta);
    def_str_color!(fgcolor: cyan => Color::Cyan);
    def_str_color!(fgcolor: white => Color::White);

    def_str_color!(bgcolor: on_black => Color::Black);
    fn on_red(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            bgcolor: Some(Color::Red),
            ..ColoredString::default()
        }
    }
    def_str_color!(bgcolor: on_green => Color::Green);
    def_str_color!(bgcolor: on_yellow => Color::Yellow);
    def_str_color!(bgcolor: on_blue => Color::Blue);
    def_str_color!(bgcolor: on_magenta => Color::Magenta);
    def_str_color!(bgcolor: on_purple => Color::Magenta);
    def_str_color!(bgcolor: on_cyan => Color::Cyan);
    def_str_color!(bgcolor: on_white => Color::White);

    fn clear(self) -> ColoredString {
        ColoredString {
            input: String::from(self),
            style: style::CLEAR,
            ..ColoredString::default()
        }
    }
    fn normal(self) -> ColoredString {
        self.clear()
    }
    def_str_style!(bold, style::Styles::Bold);
    def_str_style!(dimmed, style::Styles::Dimmed);
    def_str_style!(italic, style::Styles::Italic);
    def_str_style!(underline, style::Styles::Underline);
    def_str_style!(blink, style::Styles::Blink);
    def_str_style!(reverse, style::Styles::Reversed);
    def_str_style!(hidden, style::Styles::Hidden);
}

impl fmt::Display for ColoredString {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {

        if !self.has_colors() || self.is_plain() {
            return (<String as fmt::Display>::fmt(&self.input, f));
        }

        // XXX: see tests. Useful when nesting colored strings
        let escaped_input = self.escape_inner_reset_sequences();

        try!(f.write_str(&self.compute_style()));
        try!(<String as fmt::Display>::fmt(&escaped_input, f));
        try!(f.write_str("\x1B[0m"));
        Ok(())
    }
}

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

    #[test]
    fn formatting() {
        // respect the formatting. Escape sequence add some padding so >= 40
        assert!(format!("{:40}", "".blue()).len() >= 40);
        // both should be truncated to 1 char before coloring
        assert_eq!(format!("{:1.1}", "toto".blue()).len(),
                   format!("{:1.1}", "1".blue()).len())
    }

    #[test]
    fn it_works() {
        let toto = "toto";
        println!("{}", toto.red());
        println!("{}", String::from(toto).red());
        println!("{}", toto.blue());

        println!("blue style ****");
        println!("{}", toto.bold());
        println!("{}", "yeah ! Red bold !".red().bold());
        println!("{}", "yeah ! Yellow bold !".bold().yellow());
        println!("{}", toto.bold().blue());
        println!("{}", toto.blue().bold());
        println!("{}", toto.blue().bold().underline());
        println!("{}", toto.blue().italic());
        println!("******");
        println!("test clearing");
        println!("{}", "red cleared".red().clear());
        println!("{}", "bold cyan cleared".bold().cyan().clear());
        println!("******");
        println!("Bg tests");
        println!("{}", toto.green().on_blue());
        println!("{}", toto.on_magenta().yellow());
        println!("{}", toto.purple().on_yellow());
        println!("{}", toto.magenta().on_white());
        println!("{}", toto.cyan().on_green());
        println!("{}", toto.black().on_white());
        println!("******");
        println!("{}", toto.green());
        println!("{}", toto.yellow());
        println!("{}", toto.purple());
        println!("{}", toto.magenta());
        println!("{}", toto.cyan());
        println!("{}", toto.white());
        println!("{}", toto.white().red().blue().green());
        // uncomment to see term output
        // assert!(false)
    }

    #[test]
    fn compute_style_empty_string() {
        assert_eq!("", "".clear().compute_style());
    }

    #[test]
    fn compute_style_simple_fg_blue() {
        let blue = "\x1B[34m";

        assert_eq!(blue, "".blue().compute_style());
    }

    #[test]
    fn compute_style_simple_bg_blue() {
        let on_blue = "\x1B[44m";

        assert_eq!(on_blue, "".on_blue().compute_style());
    }

    #[test]
    fn compute_style_blue_on_blue() {
        let blue_on_blue = "\x1B[44;34m";

        assert_eq!(blue_on_blue, "".blue().on_blue().compute_style());
    }

    #[test]
    fn compute_style_simple_bold() {
        let bold = "\x1B[1m";

        assert_eq!(bold, "".bold().compute_style());
    }

    #[test]
    fn compute_style_blue_bold() {
        let blue_bold = "\x1B[1;34m";

        assert_eq!(blue_bold, "".blue().bold().compute_style());
    }

    #[test]
    fn compute_style_blue_bold_on_blue() {
        let blue_bold_on_blue = "\x1B[1;44;34m";

        assert_eq!(blue_bold_on_blue, "".blue().bold().on_blue().compute_style());
    }

    #[test]
    fn escape_reset_sequence_spec_should_do_nothing_on_empty_strings() {
        let style = ColoredString::default();
        let expected = String::new();

        let output = style.escape_inner_reset_sequences();

        assert_eq!(expected, output);
    }

    #[test]
    fn escape_reset_sequence_spec_should_do_nothing_on_string_with_no_reset() {
        let style = ColoredString { input: String::from("hello world !"), .. ColoredString::default() };

        let expected = String::from("hello world !");
        let output = style.escape_inner_reset_sequences();

        assert_eq!(expected, output);
    }

    #[test]
    fn escape_reset_sequence_spec_should_replace_inner_reset_sequence_with_current_style() {
        let input = format!("start {} end", String::from("hello world !").red());
        let style = input.blue();

        let output = style.escape_inner_reset_sequences();
        let blue = "\x1B[34m";
        let red = "\x1B[31m";
        let reset = "\x1B[0m";
        let expected = format!("start {}hello world !{}{} end", red, reset, blue);
        assert_eq!(expected, output);
    }

    #[test]
    fn escape_reset_sequence_spec_should_replace_multiple_inner_reset_sequences_with_current_style() {
        let italic_str = String::from("yo").italic();
        let input = format!("start 1:{} 2:{} 3:{} end", italic_str, italic_str, italic_str);
        let style = input.blue();

        let output = style.escape_inner_reset_sequences();
        let blue = "\x1B[34m";
        let italic = "\x1B[3m";
        let reset = "\x1B[0m";
        let expected = format!(
            "start 1:{}yo{}{} 2:{}yo{}{} 3:{}yo{}{} end",
            italic,
            reset,
            blue,
            italic,
            reset,
            blue,
            italic,
            reset,
            blue
        );

        println!("first: {}\nsecond: {}", expected, output);

        assert_eq!(expected, output);
    }
}
<|endoftext|>


<commit_before>
use std::sync::atomic::AtomicPtr;
use std::sync::Arc;
use std::mem;
use std::ptr;
use std::ops::Deref;
use std::fmt::{self, Debug, Formatter};
use std::marker::PhantomData;

pub use std::sync::atomic::Ordering;

/// An Atom wraps an AtomicPtr, it allows for safe mutation of an atomic
/// into common Rust Types.
pub struct Atom<T, P> where P: IntoRawPtr<T> + FromRawPtr<T> {
    inner: AtomicPtr<T>,
    data: PhantomData

}

impl<T, P> Debug for Atom<T, P> where P: IntoRawPtr<T> + FromRawPtr<T> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(f, "atom({:?})", self.inner.load(Ordering::Relaxed))
    }
}

impl<T, P> Atom<T, P> where P: IntoRawPtr<T> + FromRawPtr<T> {
    /// Create a empty Atom
    pub fn empty() -> Atom<T, P> {
        Atom {
            inner: AtomicPtr::new(ptr::null_mut()),
            data: PhantomData
        }
    }

    /// Create a new Atomic from Pointer P
    pub fn new(value: P) -> Atom<T, P> {
        Atom {
            inner: AtomicPtr::new(unsafe { value.into_raw() }),
            data: PhantomData
        }
    }

    /// Swap a new value into the Atom, This will try multiple
    /// times until it succeeds. The old value will be returned.
    pub fn swap(&self, v: P, order: Ordering) -> Option
 {
        let new = unsafe { v.into_raw() };
        let old = self.inner.swap(new, order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(old) })
        } else {
            None
        }
    }

    /// Take the value of the Atom replacing it with null pointer
    /// Returning the contents. If the contents was a `null` pointer the
    /// result will be `None`.
    pub fn take(&self, order: Ordering) -> Option
 {
        let old = self.inner.swap(ptr::null_mut(), order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(old) })
        } else {
            None
        }
    }

    /// This will do a `CAS` setting the value only if it is NULL
    /// this will return `None` if the value was written,
    /// otherwise a `Some(v)` will be returned, where the value was
    /// the same value that you passed into this function
    pub fn set_if_none(&self, v: P, order: Ordering) -> Option
 {
        let new = unsafe { v.into_raw() };
        let old = self.inner.compare_and_swap(ptr::null_mut(), new, order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(new) })
        } else {
            None
        }
    }
}

impl<T, P> Drop for Atom<T, P> where P: IntoRawPtr<T> + FromRawPtr<T>  {
    fn drop(&mut self) {
        // this is probably paranoid
        // TODO: Acquire?
        self.take(Ordering::SeqCst);
    }
}

unsafe impl<T, P> Send for Atom<T, P> where P: IntoRawPtr<T> + FromRawPtr<T> {}

/// Convert from into a raw pointer
pub trait IntoRawPtr<T> {
    unsafe fn into_raw(self) -> *mut T;
}

/// Convert from a raw ptr into a pointer
pub trait FromRawPtr<T> {
    unsafe fn from_raw(ptr: *mut T) -> Self;
}

impl<T> IntoRawPtr<T> for Box<T> {
    unsafe fn into_raw(self) -> *mut T {
        mem::transmute(self)
    }
}

impl<T> FromRawPtr<T> for Box<T> {
    unsafe fn from_raw(ptr: *mut T) -> Box<T> {
        mem::transmute(ptr)
    }
}

impl<T> IntoRawPtr<T> for Arc<T> {
    unsafe fn into_raw(self) -> *mut T {
        mem::transmute(self)
    }
}

impl<T> FromRawPtr<T> for Arc<T> {
    unsafe fn from_raw(ptr: *mut T) -> Arc<T> {
        mem::transmute(ptr)
    }
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
unsafe fn copy_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                       ptr: &T) -> &'a T {
    mem::transmute(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
unsafe fn copy_mut_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                    ptr: &mut T) -> &'a mut T {
    mem::transmute(ptr)
}

/// This is a restricted version of the Atom. It allows for only
/// `set_if_none` to be called.
///
/// `swap` and `take` can be used only with a mutable reference. Meaning
/// that AtomSetOnce is not usable as a
#[derive(Debug)]
pub struct AtomSetOnce<T, P> where P: IntoRawPtr<T> + FromRawPtr<T> {
    inner: Atom<T, P>
}

impl<T, P> AtomSetOnce<T, P>
    where P: IntoRawPtr<T> + FromRawPtr<T> + Deref<Target=T> {

    /// Create a empty AtomSetOnce
    pub fn empty() -> AtomSetOnce<T, P> {
        AtomSetOnce { inner: Atom::empty() }
    }

    /// Create a new AtomSetOnce from Pointer P
    pub fn new(value: P) -> AtomSetOnce<T, P> {
        AtomSetOnce { inner: Atom::new(value) }
    }

    /// This will do a `CAS` setting the value only if it is NULL
    /// this will return `OK(())` if the value was written,
    /// otherwise a `Err(P)` will be returned, where the value was
    /// the same value that you passed into this function
    pub fn set_if_none(&self, v: P, order: Ordering) -> Option
 {
        self.inner.set_if_none(v, order)
    }

    /// Convert an AtomSetOnce into an Atom
    pub fn into_atom(self) -> Atom<T, P> { self.inner }

    /// Allow access to the atom if exclusive access is granted
    pub fn atom(&mut self) -> &mut Atom<T, P> { &mut self.inner }

    /// If the Atom is set, get the value
    pub fn get<'a>(&'a self, order: Ordering) -> Option<&'a T> {
        let ptr = self.inner.inner.load(order);
        if ptr.is_null() {
            None
        } else {
            unsafe {
                // This is safe since ptr cannot be changed once it is set
                // which means that this is now a Arc or a Box.
                let v: P = FromRawPtr::from_raw(ptr);
                let out = copy_lifetime(self, &*v);
                mem::forget(v);
                Some(out)
            }
        }
    }
}

impl<T> AtomSetOnce<T, Box<T>> {
    /// If the Atom is set, get the value
    pub fn get_mut<'a>(&'a mut self, order: Ordering) -> Option<&'a mut T> {
        let ptr = self.inner.inner.load(order);
        if ptr.is_null() {
            None
        } else {
            unsafe {
                // This is safe since ptr cannot be changed once it is set
                // which means that this is now a Arc or a Box.
                let mut v: Box<T> = FromRawPtr::from_raw(ptr);
                let out = copy_mut_lifetime(self, &mut *v);
                mem::forget(v);
                Some(out)
            }
        }
    }
}

<commit_msg>Add more safe methods for AtomSetOnce<commit_after>
use std::sync::atomic::AtomicPtr;
use std::sync::Arc;
use std::mem;
use std::ptr;
use std::ops::Deref;
use std::fmt::{self, Debug, Formatter};
use std::marker::PhantomData;

pub use std::sync::atomic::Ordering;

/// An Atom wraps an AtomicPtr, it allows for safe mutation of an atomic
/// into common Rust Types.
pub struct Atom<T, P> where P: IntoRawPtr<T> + FromRawPtr<T> {
    inner: AtomicPtr<T>,
    data: PhantomData

}

impl<T, P> Debug for Atom<T, P> where P: IntoRawPtr<T> + FromRawPtr<T> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), fmt::Error> {
        write!(f, "atom({:?})", self.inner.load(Ordering::Relaxed))
    }
}

impl<T, P> Atom<T, P> where P: IntoRawPtr<T> + FromRawPtr<T> {
    /// Create a empty Atom
    pub fn empty() -> Atom<T, P> {
        Atom {
            inner: AtomicPtr::new(ptr::null_mut()),
            data: PhantomData
        }
    }

    /// Create a new Atomic from Pointer P
    pub fn new(value: P) -> Atom<T, P> {
        Atom {
            inner: AtomicPtr::new(unsafe { value.into_raw() }),
            data: PhantomData
        }
    }

    /// Swap a new value into the Atom, This will try multiple
    /// times until it succeeds. The old value will be returned.
    pub fn swap(&self, v: P, order: Ordering) -> Option
 {
        let new = unsafe { v.into_raw() };
        let old = self.inner.swap(new, order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(old) })
        } else {
            None
        }
    }

    /// Take the value of the Atom replacing it with null pointer
    /// Returning the contents. If the contents was a `null` pointer the
    /// result will be `None`.
    pub fn take(&self, order: Ordering) -> Option
 {
        let old = self.inner.swap(ptr::null_mut(), order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(old) })
        } else {
            None
        }
    }

    /// This will do a `CAS` setting the value only if it is NULL
    /// this will return `None` if the value was written,
    /// otherwise a `Some(v)` will be returned, where the value was
    /// the same value that you passed into this function
    pub fn set_if_none(&self, v: P, order: Ordering) -> Option
 {
        let new = unsafe { v.into_raw() };
        let old = self.inner.compare_and_swap(ptr::null_mut(), new, order);
        if !old.is_null() {
            Some(unsafe { FromRawPtr::from_raw(new) })
        } else {
            None
        }
    }
}

impl<T, P> Drop for Atom<T, P> where P: IntoRawPtr<T> + FromRawPtr<T>  {
    fn drop(&mut self) {
        // this is probably paranoid
        // TODO: Acquire?
        self.take(Ordering::SeqCst);
    }
}

unsafe impl<T, P> Send for Atom<T, P> where P: IntoRawPtr<T> + FromRawPtr<T> {}

/// Convert from into a raw pointer
pub trait IntoRawPtr<T> {
    unsafe fn into_raw(self) -> *mut T;
}

/// Convert from a raw ptr into a pointer
pub trait FromRawPtr<T> {
    unsafe fn from_raw(ptr: *mut T) -> Self;
}

impl<T> IntoRawPtr<T> for Box<T> {
    unsafe fn into_raw(self) -> *mut T {
        mem::transmute(self)
    }
}

impl<T> FromRawPtr<T> for Box<T> {
    unsafe fn from_raw(ptr: *mut T) -> Box<T> {
        mem::transmute(ptr)
    }
}

impl<T> IntoRawPtr<T> for Arc<T> {
    unsafe fn into_raw(self) -> *mut T {
        mem::transmute(self)
    }
}

impl<T> FromRawPtr<T> for Arc<T> {
    unsafe fn from_raw(ptr: *mut T) -> Arc<T> {
        mem::transmute(ptr)
    }
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
unsafe fn copy_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                       ptr: &T) -> &'a T {
    mem::transmute(ptr)
}

/// Transforms lifetime of the second pointer to match the first.
#[inline]
unsafe fn copy_mut_lifetime<'a, S: ?Sized, T: ?Sized + 'a>(_ptr: &'a S,
                                                    ptr: &mut T) -> &'a mut T {
    mem::transmute(ptr)
}

/// This is a restricted version of the Atom. It allows for only
/// `set_if_none` to be called.
///
/// `swap` and `take` can be used only with a mutable reference. Meaning
/// that AtomSetOnce is not usable as a
#[derive(Debug)]
pub struct AtomSetOnce<T, P> where P: IntoRawPtr<T> + FromRawPtr<T> {
    inner: Atom<T, P>
}

impl<T, P> AtomSetOnce<T, P>
    where P: IntoRawPtr<T> + FromRawPtr<T> + Deref<Target=T> {

    /// Create a empty AtomSetOnce
    pub fn empty() -> AtomSetOnce<T, P> {
        AtomSetOnce { inner: Atom::empty() }
    }

    /// Create a new AtomSetOnce from Pointer P
    pub fn new(value: P) -> AtomSetOnce<T, P> {
        AtomSetOnce { inner: Atom::new(value) }
    }

    /// This will do a `CAS` setting the value only if it is NULL
    /// this will return `OK(())` if the value was written,
    /// otherwise a `Err(P)` will be returned, where the value was
    /// the same value that you passed into this function
    pub fn set_if_none(&self, v: P, order: Ordering) -> Option
 {
        self.inner.set_if_none(v, order)
    }

    /// Convert an AtomSetOnce into an Atom
    pub fn into_atom(self) -> Atom<T, P> { self.inner }

    /// Allow access to the atom if exclusive access is granted
    pub fn atom(&mut self) -> &mut Atom<T, P> { &mut self.inner }

    /// If the Atom is set, get the value
    pub fn get<'a>(&'a self, order: Ordering) -> Option<&'a T> {
        let ptr = self.inner.inner.load(order);
        if ptr.is_null() {
            None
        } else {
            unsafe {
                // This is safe since ptr cannot be changed once it is set
                // which means that this is now a Arc or a Box.
                let v: P = FromRawPtr::from_raw(ptr);
                let out = copy_lifetime(self, &*v);
                mem::forget(v);
                Some(out)
            }
        }
    }
}

impl<T> AtomSetOnce<T, Box<T>> {
    /// If the Atom is set, get the value
    pub fn get_mut<'a>(&'a mut self, order: Ordering) -> Option<&'a mut T> {
        let ptr = self.inner.inner.load(order);
        if ptr.is_null() {
            None
        } else {
            unsafe {
                // This is safe since ptr cannot be changed once it is set
                // which means that this is now a Arc or a Box.
                let mut v: Box<T> = FromRawPtr::from_raw(ptr);
                let out = copy_mut_lifetime(self, &mut *v);
                mem::forget(v);
                Some(out)
            }
        }
    }
}

impl<T> AtomSetOnce<T, Arc<T>> {
    /// Duplicate the inner pointer if it is set
    pub fn dup<'a>(&self, order: Ordering) -> Option<Arc<T>> {
        let ptr = self.inner.inner.load(order);
        if ptr.is_null() {
            None
        } else {
            unsafe {
                // This is safe since ptr cannot be changed once it is set
                // which means that this is now a Arc or a Box.
                let v: Arc<T> = FromRawPtr::from_raw(ptr);
                let out = v.clone();
                mem::forget(v);
                Some(out)
            }
        }
    }
}

<|endoftext|>


<commit_before>use std::iter::repeat;

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

    #[test]
    fn zeros_creates_zero_filled_vector_of_correct_size_and_length() {
        let a1 = zeros(vec![0]);
        assert_eq!(a1.shape, vec![0]);
        assert_eq!(a1.data, vec![]);

        let a2 = zeros(vec![1]);
        assert_eq!(a2.shape, vec![1]);
        assert_eq!(a2.data, vec![0]);

        let a3 = zeros(vec![10]);
        assert_eq!(a3.shape, vec![10]);
        assert_eq!(a3.data, vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);

        let a4 = zeros(vec![1, 2, 3]);
        assert_eq!(a4.shape, vec![1, 2, 3]);
        assert_eq!(a4.data, vec![0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn full_test() {
        let a1 = full(vec![0], 1);
        assert_eq!(a1.shape, vec![0]);
        assert_eq!(a1.data, vec![]);

        let a2 = full(vec![1], -3);
        assert_eq!(a2.shape, vec![1]);
        assert_eq!(a2.data, vec![-3]);

        let a3 = full(vec![10], 5);
        assert_eq!(a3.shape, vec![10]);
        assert_eq!(a3.data, vec![5, 5, 5, 5, 5, 5, 5, 5, 5, 5]);

        let a4 = full(vec![1, 2, 3], 0);
        assert_eq!(a4.shape, vec![1, 2, 3]);
        assert_eq!(a4.data, vec![0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn index_test_1() {
        let array = QArray {
            shape: vec![1, 1, 1],
            data: vec![1],
        };

        assert_eq!(array.index(vec![0, 0, 0].as_slice()), Some(1));
    }

    #[test]
    fn index_test_2() {
        let array = QArray {
            shape: vec![2, 2, 1],
            data: vec![1, 2, 3, 4],
        };

        assert_eq!(array.index(vec![1, 0, 0].as_slice()), Some(2));
        assert_eq!(array.index(vec![0, 1, 0].as_slice()), Some(3));
    }

    #[test]
    fn index_test_3() {
        let array = QArray {
            shape: vec![2, 4, 3],
            data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
                       22, 23, 24],
        };

        assert_eq!(array.index(vec![1, 2, 1].as_slice()), Some(14));
        assert_eq!(array.index(vec![0, 2, 2].as_slice()), Some(21));
    }

    #[test]
    fn test_1d_vec_to_qarray() {
        let v = vec![1, 2, 3];
        let array = v.to_qarray();

        assert_eq!(array.shape, vec![3]);
        assert_eq!(array.data, vec![1, 2, 3]);
    }

    #[test]
    fn test_2d_vec_to_qarray() {
        let v1 = vec![vec![1, 2], vec![3, 4]];
        let array1 = v1.to_qarray();

        assert_eq!(array1.shape, vec![2, 2]);
        assert_eq!(array1.data, vec![1, 2, 3, 4]);

        let v2 = vec![vec![1, 2, 3], vec![4, 5, 6]];
        let array2 = v2.to_qarray();

        assert_eq!(array2.shape, vec![2, 3]);
        assert_eq!(array2.data, vec![1, 2, 3, 4, 5, 6]);
    }

    #[test]
    fn test_3d_vec_to_qarray() {
        let v = vec![vec![vec![1, 2], vec![3, 4]], vec![vec![5, 6], vec![7, 8]]];
        let array = v.to_qarray();

        assert_eq!(array.shape, vec![2, 2, 2]);
        assert_eq!(array.data, vec![1, 2, 3, 4, 5, 6, 7, 8]);
    }
}

/// Return a new QArray of the given shape, filled with zeroes.
///
/// ```
/// use quota::zeros;
/// let qarray = zeros(vec![1, 2, 3]);
/// assert_eq!(qarray.shape, vec![1, 2, 3]);
/// assert_eq!(qarray.data, vec![0, 0, 0, 0, 0, 0])
/// ```
pub fn zeros(shape: Vec<usize>) -> QArray {
    full(shape, 0)
}

/// Return a new QArray of the given shape, filled with the given fill value.
///
/// ```
/// use quota::full;
/// let qarray = full(vec![1, 2, 3], 2);
/// assert_eq!(qarray.shape, vec![1, 2, 3]);
/// assert_eq!(qarray.data, vec![2, 2, 2, 2, 2, 2])
/// ```
pub fn full(shape: Vec<usize>, fill_value: isize) -> QArray {
    let data = repeat(fill_value).take(shape.iter().sum()).collect::<Vec<isize>>();
    QArray { shape, data }
}

#[derive(Debug)]
pub struct QArray {
    pub shape: Vec<usize>,
    pub data: Vec<isize>,
}

impl QArray {
    /// Return the element at the given coordinates.
    /// If the coordinates don't specify a single element (e.g. 2D coordinates
    /// are given for a 3D array), or the coordinates are invalid,
    /// this function will return None.
    ///
    /// ```
    /// use quota::*;
    ///
    /// let qarray = zeros(vec![2, 2]);
    /// assert_eq!(qarray.index(vec![0, 0].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![1, 1].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![3, 3].as_slice()), None);
    /// assert_eq!(qarray.index(vec![1].as_slice()), None);
    /// ```
    pub fn index(&self, coordinates: &[usize]) -> Option<isize> {
        // Check that the coordinates are valid
        // The number of coordinates should match the shape of the array.
        // Each coordinate should be less than the length of the array
        // in that dimension.
        if coordinates.len() != self.shape.len() { return None }
        for (coord, dim) in coordinates.iter().zip(self.shape.as_slice()) {
            if *coord >= *dim { return None }
        }

        return Some(self.data[offset(self, coordinates)])
    }
}

fn offset(array: &QArray, coordinates: &[usize]) -> usize {
    coordinates
        .into_iter()
        .enumerate()
        .map(|(idx, coord)| {
                 array
                     .shape
                     .iter()
                     .take(idx)
                     .fold(*coord, |acc, x| acc * x)
             })
        .fold(0, |acc, x| acc + x)
}

trait ToQArray {
    fn to_qarray(&self) -> QArray;
}

impl ToQArray for Vec<isize> {
    fn to_qarray(&self) -> QArray {
        QArray {
            shape: vec![self.len()],
            data: self.clone(),
        }
    }
}

impl ToQArray for Vec<Vec<isize>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let l2 = match self.first() {
            Some(fst) => fst.len(),
            None => 0,
        };
        let shape = vec![l1, l2];

        let mut data = Vec::new();

        for row in self {
            for e in row {
                data.push(*e);
            }
        }

        QArray { shape, data }
    }
}

impl ToQArray for Vec<Vec<Vec<isize>>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let (l2, l3) = match self.first() {
            Some(fst) => match fst.first() {
                Some(ffst) => (fst.len(), ffst.len()),
                None => (fst.len(), 0)
            },
            None => (0, 0)
        };
        let shape = vec![l1, l2, l3];

        let mut data = Vec::new();

        for row in self {
            for col in row {
                for e in col {
                    data.push(*e)
                }
            }
        };

        QArray { shape, data }
    }
}
<commit_msg>Implement identity<commit_after>use std::iter::repeat;

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

    #[test]
    fn zeros_creates_zero_filled_vector_of_correct_size_and_length() {
        let a1 = zeros(vec![0]);
        assert_eq!(a1.shape, vec![0]);
        assert_eq!(a1.data, vec![]);

        let a2 = zeros(vec![1]);
        assert_eq!(a2.shape, vec![1]);
        assert_eq!(a2.data, vec![0]);

        let a3 = zeros(vec![10]);
        assert_eq!(a3.shape, vec![10]);
        assert_eq!(a3.data, vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);

        let a4 = zeros(vec![1, 2, 3]);
        assert_eq!(a4.shape, vec![1, 2, 3]);
        assert_eq!(a4.data, vec![0, 0, 0, 0, 0, 0]);

        let a5 = zeros(vec![3, 3]);
        assert_eq!(a5.shape, vec![3, 3]);
        assert_eq!(a5.data, vec![0, 0, 0, 0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn full_test() {
        let a1 = full(vec![0], 1);
        assert_eq!(a1.shape, vec![0]);
        assert_eq!(a1.data, vec![]);

        let a2 = full(vec![1], -3);
        assert_eq!(a2.shape, vec![1]);
        assert_eq!(a2.data, vec![-3]);

        let a3 = full(vec![10], 5);
        assert_eq!(a3.shape, vec![10]);
        assert_eq!(a3.data, vec![5, 5, 5, 5, 5, 5, 5, 5, 5, 5]);

        let a4 = full(vec![1, 2, 3], 0);
        assert_eq!(a4.shape, vec![1, 2, 3]);
        assert_eq!(a4.data, vec![0, 0, 0, 0, 0, 0]);
    }

    #[test]
    fn index_test_1() {
        let array = QArray {
            shape: vec![1, 1, 1],
            data: vec![1],
        };

        assert_eq!(array.index(vec![0, 0, 0].as_slice()), Some(1));
    }

    #[test]
    fn index_test_2() {
        let array = QArray {
            shape: vec![2, 2, 1],
            data: vec![1, 2, 3, 4],
        };

        assert_eq!(array.index(vec![1, 0, 0].as_slice()), Some(2));
        assert_eq!(array.index(vec![0, 1, 0].as_slice()), Some(3));
    }

    #[test]
    fn index_test_3() {
        let array = QArray {
            shape: vec![2, 4, 3],
            data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
                       22, 23, 24],
        };

        assert_eq!(array.index(vec![1, 2, 1].as_slice()), Some(14));
        assert_eq!(array.index(vec![0, 2, 2].as_slice()), Some(21));
    }

    #[test]
    fn test_1d_vec_to_qarray() {
        let v = vec![1, 2, 3];
        let array = v.to_qarray();

        assert_eq!(array.shape, vec![3]);
        assert_eq!(array.data, vec![1, 2, 3]);
    }

    #[test]
    fn test_2d_vec_to_qarray() {
        let v1 = vec![vec![1, 2], vec![3, 4]];
        let array1 = v1.to_qarray();

        assert_eq!(array1.shape, vec![2, 2]);
        assert_eq!(array1.data, vec![1, 2, 3, 4]);

        let v2 = vec![vec![1, 2, 3], vec![4, 5, 6]];
        let array2 = v2.to_qarray();

        assert_eq!(array2.shape, vec![2, 3]);
        assert_eq!(array2.data, vec![1, 2, 3, 4, 5, 6]);
    }

    #[test]
    fn test_3d_vec_to_qarray() {
        let v = vec![vec![vec![1, 2], vec![3, 4]], vec![vec![5, 6], vec![7, 8]]];
        let array = v.to_qarray();

        assert_eq!(array.shape, vec![2, 2, 2]);
        assert_eq!(array.data, vec![1, 2, 3, 4, 5, 6, 7, 8]);
    }

    #[test]
    fn test_identity() {
        let a1 = identity(1);
        assert_eq!(a1.shape, vec![1, 1]);
        assert_eq!(a1.data, vec![1]);

        let a2 = identity(2);
        assert_eq!(a2.shape, vec![2, 2]);
        assert_eq!(a2.data, vec![1, 0, 0, 1]);

        let a3 = identity(0);
        assert_eq!(a3.shape, vec![0, 0]);
        assert_eq!(a3.data, vec![]);
    }
}

/// Return a new QArray of the given shape, filled with zeroes.
///
/// ```
/// use quota::zeros;
/// let qarray = zeros(vec![1, 2, 3]);
/// assert_eq!(qarray.shape, vec![1, 2, 3]);
/// assert_eq!(qarray.data, vec![0, 0, 0, 0, 0, 0])
/// ```
pub fn zeros(shape: Vec<usize>) -> QArray {
    full(shape, 0)
}

/// Return a new QArray of the given shape, filled with the given fill value.
///
/// ```
/// use quota::full;
/// let qarray = full(vec![1, 2, 3], 2);
/// assert_eq!(qarray.shape, vec![1, 2, 3]);
/// assert_eq!(qarray.data, vec![2, 2, 2, 2, 2, 2])
/// ```
pub fn full(shape: Vec<usize>, fill_value: isize) -> QArray {
    let data = repeat(fill_value).take(shape.iter().product()).collect::<Vec<isize>>();
    QArray { shape, data }
}

/// Return a new square QArray of the given size, with ones on the main diagonal
///
/// ```
/// use quota::identity;
///
/// let qarray = identity(3);
/// assert_eq!(qarray.shape, vec![3, 3]);
/// assert_eq!(qarray.data, vec![1, 0, 0, 0, 1, 0, 0, 0, 1]);
/// ```
pub fn identity(num_rows: usize) -> QArray {
    let QArray { shape, mut data } = zeros(vec![num_rows, num_rows]);
    {
        for x in 0..num_rows {
            let offset = offset(shape.as_slice(), &[x, x]);
            data[offset] = 1;
        }
    }
    QArray { shape, data }
}

#[derive(Debug)]
pub struct QArray {
    pub shape: Vec<usize>,
    pub data: Vec<isize>,
}

impl QArray {
    /// Return the element at the given coordinates.
    /// If the coordinates don't specify a single element (e.g. 2D coordinates
    /// are given for a 3D array), or the coordinates are invalid,
    /// this function will return None.
    ///
    /// ```
    /// use quota::*;
    ///
    /// let qarray = zeros(vec![2, 2]);
    /// assert_eq!(qarray.index(vec![0, 0].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![1, 1].as_slice()), Some(0));
    /// assert_eq!(qarray.index(vec![3, 3].as_slice()), None);
    /// assert_eq!(qarray.index(vec![1].as_slice()), None);
    /// ```
    pub fn index(&self, coordinates: &[usize]) -> Option<isize> {
        // Check that the coordinates are valid
        // The number of coordinates should match the shape of the array.
        // Each coordinate should be less than the length of the array
        // in that dimension.
        if coordinates.len() != self.shape.len() { return None }
        for (coord, dim) in coordinates.iter().zip(self.shape.as_slice()) {
            if *coord >= *dim { return None }
        }

        return Some(self.data[offset(self.shape.as_slice(), coordinates)])
    }
}

fn offset(shape: &[usize], coordinates: &[usize]) -> usize {
    coordinates
        .into_iter()
        .enumerate()
        .map(|(idx, coord)| {
                 shape
                     .iter()
                     .take(idx)
                     .fold(*coord, |acc, x| acc * x)
             })
        .fold(0, |acc, x| acc + x)
}

trait ToQArray {
    fn to_qarray(&self) -> QArray;
}

impl ToQArray for Vec<isize> {
    fn to_qarray(&self) -> QArray {
        QArray {
            shape: vec![self.len()],
            data: self.clone(),
        }
    }
}

impl ToQArray for Vec<Vec<isize>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let l2 = match self.first() {
            Some(fst) => fst.len(),
            None => 0,
        };
        let shape = vec![l1, l2];

        let mut data = Vec::new();

        for row in self {
            for e in row {
                data.push(*e);
            }
        }

        QArray { shape, data }
    }
}

impl ToQArray for Vec<Vec<Vec<isize>>> {
    fn to_qarray(&self) -> QArray {
        let l1 = self.len();
        let (l2, l3) = match self.first() {
            Some(fst) => match fst.first() {
                Some(ffst) => (fst.len(), ffst.len()),
                None => (fst.len(), 0)
            },
            None => (0, 0)
        };
        let shape = vec![l1, l2, l3];

        let mut data = Vec::new();

        for row in self {
            for col in row {
                for e in col {
                    data.push(*e)
                }
            }
        };

        QArray { shape, data }
    }
}
<|endoftext|>


<commit_before>use std::process::Command;
use std::fs;
use std::convert::AsRef;
use std::path::Path;

#[derive(Debug)]
pub enum OSType {
    Unknown,
    Redhat,
    OSX
}

fn file_exists<P: AsRef<Path>>(path: P) -> bool {
    let metadata = fs::metadata(path);

    match metadata {
        Ok(md) => md.is_dir() || md.is_file(),
        Err(_) => false
    }
}

fn is_os_x() -> bool {
    let output = Command::new("sw_vers").output().unwrap();
    output.status.success()
}

pub fn current_platform() -> OSType {
    if file_exists("/etc/redhat-release") || file_exists("/etc/centos-release") {
        OSType::Redhat
    } else if is_os_x() {
        OSType::OSX
    } else {
        OSType::Unknown
    }
}
<commit_msg>take lsb_release into account and fix panic bug when not running on os x<commit_after>use std::process::Command;
use std::fs;
use std::convert::AsRef;
use std::path::Path;
mod lsb_release;

#[derive(Debug)]
pub enum OSType {
    Unknown,
    Redhat,
    OSX,
    Ubuntu
}

fn file_exists<P: AsRef<Path>>(path: P) -> bool {
    let metadata = fs::metadata(path);

    match metadata {
        Ok(md) => md.is_dir() || md.is_file(),
        Err(_) => false
    }
}

fn is_os_x() -> bool {
    match Command::new("sw_vers").output() {
        Ok(output) => output.status.success(),
        Err(_) => false
    }
}

fn lsb_release() -> OSType {
    match lsb_release::from_file("/etc/lsb-release") {
        Ok(release) => {
            if release.distro == Some("Ubuntu".to_string()) {
                OSType::Ubuntu
            }
            else {
                OSType::Unknown
            }
        },
        Err(_) => OSType::Unknown
    }

}

pub fn current_platform() -> OSType {
    if is_os_x() {
        OSType::OSX
    }
    else if file_exists("/etc/lsb-release") {
        lsb_release()
    }
    else if file_exists("/etc/redhat-release") || file_exists("/etc/centos-release") {
        OSType::Redhat
    }
    else {
        OSType::Unknown
    }
}
<|endoftext|>


<commit_before>
// Calculate the n^th Fibonacci number.
fn fib(n: u32) -> u32 {
  if n < 2 {
    return n;
  } else {
    return fib(n - 1) + fib(n - 2);
  }
}

fn main() {
  let res = fib(20);
  println!("{}", res);
}
<commit_msg>Blank line.<commit_after>// Calculate the n^th Fibonacci number.
fn fib(n: u32) -> u32 {
  if n < 2 {
    return n;
  } else {
    return fib(n - 1) + fib(n - 2);
  }
}

fn main() {
  let res = fib(20);
  println!("{}", res);
}
<|endoftext|>


<commit_before>use ram::cell::{Cell, ReadError, WriteError};
use ram::chunk::Chunks;
use ram::types::Id;

use bifrost::rpc::*;

service! {
    rpc read_cell(key: Id) -> Cell | ReadError;
    rpc write_cell(cell: Cell) -> Cell | WriteError;
    rpc update_cell(cell: Cell) -> Cell | WriteError;
    rpc remove_cell(key: Id) -> () | WriteError;
}

pub struct NebRPCService {
    chunks: Arc<Chunks>
}

impl Service for NebRPCService {
    fn read_cell(&self, key: Id) -> Result<Cell, ReadError> {
        Err(ReadError::CellDoesNotExisted)
    }
    fn write_cell(&self, cell: Cell)-> Result<Cell, WriteError> {
        Err(WriteError::CellDoesNotExisted)
    }
    fn update_cell(&self, cell: Cell)-> Result<Cell, WriteError> {
        Err(WriteError::CellDoesNotExisted)
    }
    fn remove_cell(&self, key: Id) -> Result<(), WriteError> {
        Err(WriteError::CellDoesNotExisted)
    }
}

dispatch_rpc_service_functions!(NebRPCService);<commit_msg>rpc bridge to chunks<commit_after>use ram::cell::{Cell, ReadError, WriteError};
use ram::chunk::Chunks;
use ram::types::Id;

use bifrost::rpc::*;

service! {
    rpc read_cell(key: Id) -> Cell | ReadError;
    rpc write_cell(cell: Cell) -> Cell | WriteError;
    rpc update_cell(cell: Cell) -> Cell | WriteError;
    rpc remove_cell(key: Id) -> () | WriteError;
}

pub struct NebRPCService {
    chunks: Arc<Chunks>
}

impl Service for NebRPCService {
    fn read_cell(&self, key: Id) -> Result<Cell, ReadError> {
        self.chunks.read_cell(&key)
    }
    fn write_cell(&self, cell: Cell) -> Result<Cell, WriteError> {
        let mut cell = cell;
        match self.chunks.write_cell(&mut cell) {
            Ok(_) => Ok(cell),
            Err(e) => Err(e)
        }
    }
    fn update_cell(&self, cell: Cell) -> Result<Cell, WriteError> {
        let mut cell = cell;
        match self.chunks.update_cell(&mut cell) {
            Ok(_) => Ok(cell),
            Err(e) => Err(e)
        }
    }
    fn remove_cell(&self, key: Id) -> Result<(), WriteError> {
        self.chunks.remove_cell(&key)
    }
}

dispatch_rpc_service_functions!(NebRPCService);<|endoftext|>


<commit_before><commit_msg>wip: fix typos<commit_after><|endoftext|>


<commit_before>// Copyright 2014 Jonathan Eyolfson

extern crate wayland;

extern crate libc;

use std::ptr;

#[link(name = "rt")]
extern { }

const WIDTH: i32 = 300;
const HEIGHT: i32 = 200;
const STRIDE: i32 = WIDTH * 4;
const PIXELS: i32 = WIDTH * HEIGHT;
const SIZE: i32 = PIXELS * 4;

struct ShmFd {
    fd: i32,
    ptr: *mut libc::c_void
}

impl ShmFd {
    pub fn new() -> ShmFd {
        unsafe {
            let fd = libc::funcs::posix88::mman::shm_open(
                "/eyl-hello-world".to_c_str().as_ptr(),
                libc::O_CREAT | libc::O_RDWR,
                libc::S_IRUSR | libc::S_IWUSR
            );
            assert!(fd >= 0);
            assert!(libc::ftruncate(fd, SIZE as i64) != -1);
            let ptr = libc::mmap(ptr::null_mut(), SIZE as u64,
                                 libc::PROT_WRITE | libc::PROT_READ, 1, fd, 0);
            assert!(ptr != libc::MAP_FAILED);
            for i in range(0, PIXELS) {
                let p: *mut u32 = (ptr as *mut u32).offset(i as int);
                let x = i % WIDTH;
                let y = i / WIDTH;
                match x {
                    0...5 => std::ptr::write(&mut *p, 0x7FFF0000),
                    294...299 => std::ptr::write(&mut *p, 0x7F0000FF),
                    _ => match y {
                        0...5 => std::ptr::write(&mut *p, 0x7F00FF00),
                        194...199 => std::ptr::write(&mut *p, 0x7FFF00FF),
                        _ =>  std::ptr::write(&mut *p, 0x7F000000),
                    }
                }
            }
            ShmFd { fd: fd, ptr: ptr }
        }
    }
    pub fn fd(&self) -> i32 {
        self.fd
    }
}

impl Drop for ShmFd {
    fn drop(&mut self) {
        unsafe {
            libc::munmap(self.ptr, SIZE as u64);
            libc::funcs::posix88::mman::shm_unlink(
                "/eyl-hello-world".to_c_str().as_ptr()
            );
        }
    }
}

fn main() {
    let mut display = wayland::Display::connect_to_env_or_default();
    let mut registry = wayland::Registry::new(&mut display);
    let shm_fd = ShmFd::new();
    let mut pool = registry.shm().create_pool(shm_fd.fd(), SIZE);
    let mut surface = registry.compositor().create_surface();
    let mut buffer = pool.create_buffer(
        0, WIDTH, HEIGHT, STRIDE, wayland::raw::WL_SHM_FORMAT_ARGB8888
    );
    let mut shell_surface = registry.shell().get_shell_surface(&mut surface);
    shell_surface.set_toplevel();
    surface.attach(&mut buffer, 0, 0);
    surface.commit();
    loop {
        display.dispatch();
    }
}
<commit_msg>Rename ShmFd to Block and use memfd_create in example<commit_after>// Copyright 2014 Jonathan Eyolfson

#![feature(asm)]

extern crate wayland;

extern crate libc;

use std::ptr;

const WIDTH: i32 = 300;
const HEIGHT: i32 = 200;
const STRIDE: i32 = WIDTH * 4;
const PIXELS: i32 = WIDTH * HEIGHT;
const SIZE: i32 = PIXELS * 4;

struct Block {
    fd: i32,
    ptr: *mut libc::c_void
}

impl Block {
    pub fn new() -> Block {
        unsafe {
            let mut fd: i32;
            let name = b"rust-wayland-shm\x00";
            asm!("syscall"
                 : "={rax}"(fd)
                 : "{rax}"(319u), "{rdi}"(name.as_ptr()), "{rsi}"(3u)
                 : "rcx", "r11", "memory"
                 : "volatile");
            assert!(fd >= 0);
            assert!(libc::ftruncate(fd, SIZE as i64) != -1);
            let ptr = libc::mmap(ptr::null_mut(), SIZE as u64,
                                 libc::PROT_WRITE | libc::PROT_READ, 1, fd, 0);
            assert!(ptr != libc::MAP_FAILED);
            for i in range(0, PIXELS) {
                let p: *mut u32 = (ptr as *mut u32).offset(i as int);
                let x = i % WIDTH;
                let y = i / WIDTH;
                match x {
                    0...5 => std::ptr::write(&mut *p, 0x7FFF0000),
                    294...299 => std::ptr::write(&mut *p, 0x7F0000FF),
                    _ => match y {
                        0...5 => std::ptr::write(&mut *p, 0x7F00FF00),
                        194...199 => std::ptr::write(&mut *p, 0x7FFF00FF),
                        _ =>  std::ptr::write(&mut *p, 0x7F000000),
                    }
                }
            }
            Block { fd: fd, ptr: ptr }
        }
    }
    pub fn fd(&self) -> i32 {
        self.fd
    }
}

impl Drop for Block {
    fn drop(&mut self) {
        unsafe {
            libc::munmap(self.ptr, SIZE as u64);
            libc::close(self.fd);
        }
    }
}

fn main() {
    let mut display = wayland::Display::connect_to_env_or_default();
    let mut registry = wayland::Registry::new(&mut display);
    let block = Block::new();
    let mut pool = registry.shm().create_pool(block.fd(), SIZE);
    let mut surface = registry.compositor().create_surface();
    let mut buffer = pool.create_buffer(
        0, WIDTH, HEIGHT, STRIDE, wayland::raw::WL_SHM_FORMAT_ARGB8888
    );
    let mut shell_surface = registry.shell().get_shell_surface(&mut surface);
    shell_surface.set_toplevel();
    surface.attach(&mut buffer, 0, 0);
    surface.commit();
    loop {
        display.dispatch();
    }
}
<|endoftext|>


<commit_before>extern crate env_logger;
extern crate cgmath;
extern crate glutin;
extern crate gfx;
extern crate gfx_pipeline;
extern crate gfx_device_gl;
extern crate gfx_debug_draw;
extern crate claymore_load;
extern crate claymore_scene; //temp

type MousePos = (i32, i32);

struct Control {
    rotate_speed: f32,
    zoom_speed: f32,
    base: Option<(MousePos, claymore_scene::Transform<f32>)>,
    last_pos: MousePos,
    space: claymore_scene::Transform<f32>,
}

impl Control {
    pub fn new(rot_speed: f32, zoom_speed: f32,
               space: claymore_scene::Transform<f32>) -> Control {
        Control {
            rotate_speed: rot_speed,
            zoom_speed: zoom_speed,
            base: None,
            last_pos: (0, 0),
            space: space,
        }
    }

    pub fn capture(&mut self, transform: &claymore_scene::Transform<f32>) {
        self.base = Some((self.last_pos, transform.clone()));
    }

    pub fn release(&mut self) {
        self.base = None;
    }

    pub fn position(&mut self, coords: MousePos,
                    transform: &mut claymore_scene::Transform<f32>) {
        self.last_pos = coords;
        match self.base {
            Some((ref base_pos, ref base_transform)) => {
                use cgmath::Transform;
                // p' = Mp * Tc^ * (Tr * Rz * Tr^) * p
                // Tx = (Tr * Rz^ * Tr^) * Tc
                let path = (coords.0 - base_pos.0) as f32 * -self.rotate_speed;
                let rotation = cgmath::Decomposed {
                    scale: 1.0,
                    rot: cgmath::Rotation3::from_axis_angle(
                        &cgmath::vec3(0.0, 0.0, 1.0), cgmath::rad(path)),
                    disp: cgmath::zero(),
                };
                let space_inv = self.space.invert().unwrap();
                let relative = self.space.concat(&rotation.concat(&space_inv));
                *transform = relative.concat(base_transform);
            },
            None => (),
        }
    }

    pub fn wheel(&mut self, shift: i32, transform: &mut claymore_scene::Transform<f32>) {
        use cgmath::{Vector, Transform};
        if self.base.is_some() {
            return
        }
        let vector = transform.transform_vector(&cgmath::vec3(0.0, 0.0, 1.0));
        transform.disp.add_self_v(&vector.mul_s(shift as f32 * -self.zoom_speed));
    }
}

fn main() {
    use std::env;
    use cgmath::{vec3, FixedArray, Matrix, ToMatrix4, Transform};
    use gfx::traits::*;
    use gfx_pipeline::Pipeline;

    env_logger::init().unwrap();
    println!("Creating the window...");

    let window = glutin::WindowBuilder::new()
        .with_title("Scene viewer".to_string())
        .with_vsync()
        .with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2)))
        .build().unwrap();
    unsafe { window.make_current() };
    let (w, h) = window.get_inner_size().unwrap();
    let mut graphics = gfx_device_gl::create(|s| window.get_proc_address(s))
                                    .into_graphics();

    let mut debug_renderer = gfx_debug_draw::DebugRenderer::new(
        &mut graphics, [w, h], 64, None, None).ok().unwrap();

    let (mut scene, texture) = {
        let mut context = claymore_load::Context::new(&mut graphics.factory,
            env::var("CARGO_MANIFEST_DIR").unwrap_or(".".to_string())
            ).unwrap();
        let mut scene = context.create_scene();
        for path in env::args().skip(1) {
            println!("Loading scene: {}", path);
            context.extend_scene(&mut scene, &path).unwrap();
        }
        (scene, (context.texture_black.clone(), None))
    };

    println!("Initializing the graphics...");
    let mut pipeline = gfx_pipeline::forward::Pipeline::<gfx_device_gl::Device>::new(
        &mut graphics.factory, texture).unwrap();
    pipeline.background = Some([0.2, 0.3, 0.4, 1.0]);
    let mut frame = gfx::Frame::new(w as u16, h as u16);

    let mut camera = scene.cameras[0].clone();
    camera.projection.aspect = w as f32 / h as f32;
    let mut control = {
        use claymore_scene::base::World;
        let target_node = scene.entities[0].node;
        Control::new(0.005, 0.5, scene.world.get_transform(&target_node))
    };

    println!("Rendering...");
    'main: loop {
        for event in window.poll_events() {
            match event {
                glutin::Event::Resized(w, h) => {
                    frame.width = w as u16;
                    frame.height = h as u16;
                    debug_renderer.resize(w, h);
                },
                glutin::Event::KeyboardInput(_, _,
                    Some(glutin::VirtualKeyCode::Escape)) =>
                    break 'main,
                glutin::Event::Closed => break 'main,
                glutin::Event::MouseInput(glutin::ElementState::Pressed, glutin::MouseButton::Left) =>
                    control.capture(&scene.world.get_node(camera.node).local),
                glutin::Event::MouseInput(glutin::ElementState::Released, glutin::MouseButton::Left) =>
                    control.release(),
                glutin::Event::MouseMoved(coords) =>
                    control.position(coords, &mut scene.world.mut_node(camera.node).local),
                glutin::Event::MouseWheel(shift) =>
                    control.wheel(shift, &mut scene.world.mut_node(camera.node).local),
                _ => {},
            }
        }

        scene.world.update();
        let len = 1f32;

        for node in scene.world.iter_nodes() {
            let r = node.world.transform_vector(&vec3(0.0, 0.0, 0.0)).into_fixed();
            let x = node.world.transform_vector(&vec3(len, 0.0, 0.0)).into_fixed();
            let y = node.world.transform_vector(&vec3(0.0, len, 0.0)).into_fixed();
            let z = node.world.transform_vector(&vec3(0.0, 0.0, len)).into_fixed();
            debug_renderer.draw_line(r, x, [1.0, 0.0, 0.0, 1.0]);
            debug_renderer.draw_line(r, y, [0.0, 1.0, 0.0, 1.0]);
            debug_renderer.draw_line(r, z, [0.0, 0.0, 1.0, 1.0]);
        }

        let buf = pipeline.render(&scene, &camera, &frame).unwrap();
        graphics.device.submit(buf);

        // this causes an ICE: https://github.com/rust-lang/rust/issues/24152
        //debug_renderer.render(&mut graphics, &frame,
        //    camera.get_view_projection(&scene.world));
        if true {
            use cgmath::FixedArray;
            use claymore_scene::base::World;
            let cam_inv = scene.world.get_transform(&camera.node).invert().unwrap();
            let proj_mx = camera.projection.to_matrix4().mul_m(&cam_inv.to_matrix4()).into_fixed();
            debug_renderer.render(&mut graphics, &frame, proj_mx);
        }

        graphics.end_frame();
        window.swap_buffers();
        graphics.device.after_frame();
    }
    println!("Done.");
}
<commit_msg>Camera movement implemented<commit_after>extern crate env_logger;
extern crate cgmath;
extern crate glutin;
extern crate gfx;
extern crate gfx_pipeline;
extern crate gfx_device_gl;
extern crate gfx_debug_draw;
extern crate claymore_load;
extern crate claymore_scene; //temp

type MousePos = (i32, i32);

struct Control {
    rotate_speed: f32,
    move_speed: f32,
    zoom_speed: f32,
    rotate_base: Option<(MousePos, claymore_scene::Transform<f32>)>,
    move_base: Option<(MousePos, cgmath::Vector3<f32>)>,
    last_pos: MousePos,
    space: claymore_scene::Transform<f32>,
}

impl Control {
    pub fn new(rot_speed: f32, move_speed: f32, zoom_speed: f32,
               space: claymore_scene::Transform<f32>) -> Control {
        Control {
            rotate_speed: rot_speed,
            move_speed: move_speed,
            zoom_speed: zoom_speed,
            rotate_base: None,
            move_base: None,
            last_pos: (0, 0),
            space: space,
        }
    }

    pub fn rot_capture(&mut self, transform: &claymore_scene::Transform<f32>) {
        self.rotate_base = Some((self.last_pos, transform.clone()));
    }

    pub fn rot_release(&mut self) {
        self.rotate_base = None;
    }

    pub fn move_capture(&mut self, transform: &claymore_scene::Transform<f32>) {
        self.move_base = Some((self.last_pos, transform.disp));
    }

    pub fn move_release(&mut self) {
        self.move_base = None;
    }

    pub fn position(&mut self, coords: MousePos,
                    transform: &mut claymore_scene::Transform<f32>) {
        self.last_pos = coords;
        match self.rotate_base {
            Some((ref base_pos, ref base_transform)) => {
                use cgmath::Transform;
                // p' = Mp * Tc^ * (Tr * Rz * Tr^) * p
                // Tx = (Tr * Rz^ * Tr^) * Tc
                let path = (coords.0 - base_pos.0) as f32 * -self.rotate_speed;
                let rotation = cgmath::Decomposed {
                    scale: 1.0,
                    rot: cgmath::Rotation3::from_axis_angle(
                        &cgmath::vec3(0.0, 0.0, 1.0), cgmath::rad(path)),
                    disp: cgmath::zero(),
                };
                let space_inv = self.space.invert().unwrap();
                let relative = self.space.concat(&rotation.concat(&space_inv));
                *transform = relative.concat(base_transform);
            },
            None => (),
        }
        match self.move_base {
            Some((base_pos, ref base_disp)) => {
                use cgmath::{Vector, Rotation};
                let local_vector = cgmath::vec3(
                    -(coords.0 - base_pos.0) as f32,
                    (coords.1 - base_pos.1) as f32,
                    0.0).mul_s(self.move_speed);
                let cam_vector = transform.rot.rotate_vector(&local_vector);
                transform.disp = base_disp.add_v(&cam_vector);
            },
            None => (),
        }
    }

    pub fn wheel(&mut self, shift: i32, transform: &mut claymore_scene::Transform<f32>) {
        use cgmath::{Vector, Transform};
        let vector = transform.transform_vector(&cgmath::vec3(0.0, 0.0, 1.0));
        transform.disp.add_self_v(&vector.mul_s(shift as f32 * -self.zoom_speed));
    }
}

fn main() {
    use std::env;
    use cgmath::{vec3, FixedArray, Matrix, ToMatrix4, Transform};
    use gfx::traits::*;
    use gfx_pipeline::Pipeline;

    env_logger::init().unwrap();
    println!("Creating the window...");

    let window = glutin::WindowBuilder::new()
        .with_title("Scene viewer".to_string())
        .with_vsync()
        .with_gl(glutin::GlRequest::Specific(glutin::Api::OpenGl, (3, 2)))
        .build().unwrap();
    unsafe { window.make_current() };
    let (w, h) = window.get_inner_size().unwrap();
    let mut graphics = gfx_device_gl::create(|s| window.get_proc_address(s))
                                    .into_graphics();

    let mut debug_renderer = gfx_debug_draw::DebugRenderer::new(
        &mut graphics, [w, h], 64, None, None).ok().unwrap();

    let (mut scene, texture) = {
        let mut context = claymore_load::Context::new(&mut graphics.factory,
            env::var("CARGO_MANIFEST_DIR").unwrap_or(".".to_string())
            ).unwrap();
        let mut scene = context.create_scene();
        for path in env::args().skip(1) {
            println!("Loading scene: {}", path);
            context.extend_scene(&mut scene, &path).unwrap();
        }
        (scene, (context.texture_black.clone(), None))
    };

    println!("Initializing the graphics...");
    let mut pipeline = gfx_pipeline::forward::Pipeline::<gfx_device_gl::Device>::new(
        &mut graphics.factory, texture).unwrap();
    pipeline.background = Some([0.2, 0.3, 0.4, 1.0]);
    let mut frame = gfx::Frame::new(w as u16, h as u16);

    let mut camera = scene.cameras[0].clone();
    camera.projection.aspect = w as f32 / h as f32;
    let mut control = {
        use claymore_scene::base::World;
        let target_node = scene.entities[0].node;
        Control::new(0.005, 0.01, 0.5, scene.world.get_transform(&target_node))
    };

    println!("Rendering...");
    'main: loop {
        for event in window.poll_events() {
            match event {
                glutin::Event::Resized(w, h) => {
                    frame.width = w as u16;
                    frame.height = h as u16;
                    debug_renderer.resize(w, h);
                },
                glutin::Event::KeyboardInput(_, _,
                    Some(glutin::VirtualKeyCode::Escape)) =>
                    break 'main,
                glutin::Event::Closed => break 'main,
                glutin::Event::MouseInput(glutin::ElementState::Pressed, glutin::MouseButton::Left) =>
                    control.rot_capture(&scene.world.get_node(camera.node).local),
                glutin::Event::MouseInput(glutin::ElementState::Released, glutin::MouseButton::Left) =>
                    control.rot_release(),
                glutin::Event::MouseInput(glutin::ElementState::Pressed, glutin::MouseButton::Middle) =>
                    control.move_capture(&scene.world.get_node(camera.node).local),
                glutin::Event::MouseInput(glutin::ElementState::Released, glutin::MouseButton::Middle) =>
                    control.move_release(),
                glutin::Event::MouseMoved(coords) =>
                    control.position(coords, &mut scene.world.mut_node(camera.node).local),
                glutin::Event::MouseWheel(shift) =>
                    control.wheel(shift, &mut scene.world.mut_node(camera.node).local),
                _ => {},
            }
        }

        scene.world.update();
        let len = 1f32;

        for node in scene.world.iter_nodes() {
            let r = node.world.transform_vector(&vec3(0.0, 0.0, 0.0)).into_fixed();
            let x = node.world.transform_vector(&vec3(len, 0.0, 0.0)).into_fixed();
            let y = node.world.transform_vector(&vec3(0.0, len, 0.0)).into_fixed();
            let z = node.world.transform_vector(&vec3(0.0, 0.0, len)).into_fixed();
            debug_renderer.draw_line(r, x, [1.0, 0.0, 0.0, 1.0]);
            debug_renderer.draw_line(r, y, [0.0, 1.0, 0.0, 1.0]);
            debug_renderer.draw_line(r, z, [0.0, 0.0, 1.0, 1.0]);
        }

        let buf = pipeline.render(&scene, &camera, &frame).unwrap();
        graphics.device.submit(buf);

        // this causes an ICE: https://github.com/rust-lang/rust/issues/24152
        //debug_renderer.render(&mut graphics, &frame,
        //    camera.get_view_projection(&scene.world));
        if true {
            use cgmath::FixedArray;
            use claymore_scene::base::World;
            let cam_inv = scene.world.get_transform(&camera.node).invert().unwrap();
            let proj_mx = camera.projection.to_matrix4().mul_m(&cam_inv.to_matrix4()).into_fixed();
            debug_renderer.render(&mut graphics, &frame, proj_mx);
        }

        graphics.end_frame();
        window.swap_buffers();
        graphics.device.after_frame();
    }
    println!("Done.");
}
<|endoftext|>