<commit_before>#![allow(dead_code)]

extern crate csv;
extern crate hex;
extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;
extern crate image;
extern crate piston_window;

mod cpu;
mod gpu;
mod system;

use piston_window::*;
use image::ImageBuffer;
use image::{RgbaImage, Rgba};
use opengl_graphics::Texture;
use piston::event_loop::*;
use piston::input::*;
use opengl_graphics::{ GlGraphics, OpenGL };
use std::fs::File;
use std::io::prelude::*;
use std::env;
use cpu::cpu::*;
use gpu::gpu::*;
use gpu::gpu_registers::*;
use system::*;
use self::hex::FromHex;

static MAX_SPRITE: u8 = 40;

fn main()
 {
    //Initialize Emulator
    let args: Vec<String> = env::args().collect();
    let emulator_type: String = String::from("CLASSIC");
    let file_name: &String = &args[1];
    let mut system_data : SystemData = get_system_data(&emulator_type);
    system_data.mem_map = read_gb_file(file_name);
    let mut registers: Registers = Registers::new();
    let mut gpu_registers: GPU_Registers = GPU_Registers::new();

    //Initialize Screen
    let opengl = OpenGL::V3_2;
    let mut window: PistonWindow = WindowSettings::new("RustBoy", [system_data.width as u32, system_data.height as u32])
                                        .opengl(opengl)
                                        .exit_on_esc(true)
                                        .build()
                                        .unwrap();
    //window.set_max_fps(60);
    let mut app = App
    {
        gl: GlGraphics::new(opengl),
    };
    let mut events = Events::new(EventSettings::new().max_fps(60));
    //events.set_max_fps(60);
    let mut background_tile_map: TileMap = TileMap::new();
    let mut window_tile_map: TileMap = TileMap::new();

    //Operation loop
    let mut emulator_loop = true;

    while let Some(e) = events.next(&mut window)
    {
        if let Some(r) = e.update_args()
        {
            while !gpu_registers.v_blank_draw_flag
            {
                let opcode = system_data.mem_map[registers.program_counter as usize];
                let address = registers.program_counter;
                cpu_continue(&mut system_data, &mut registers);
                update_gpu(&mut system_data, &mut registers, &mut gpu_registers);
            }
        }

        if let Some(r) = e.render_args(){
            gpu_registers.v_blank_draw_flag = false;
            background_tile_map.populate_tile_map(&mut system_data, gpu_registers.lcdc_register.tile_data, gpu_registers.lcdc_register.background_display_select);
            window_tile_map.populate_tile_map(&mut system_data, gpu_registers.lcdc_register.tile_data, gpu_registers.lcdc_register.window_display_select);
            //let background_image: RgbaImage = create_background_img(&background_tile_map);
            let background_image: RgbaImage = create_background_img(&window_tile_map);
            app.render(&background_image, &r);
            // break;
        }
    }
        // if system_data.cycles == 0  //|| registers.program_counter == 0x6d
        // {
        //     emulator_loop = false;
        //     println!("Location: {:04X}\tOpcode: 0x{:02X}  {:08b}", address, opcode, opcode);
        // }
    //Cleanup?
}

pub struct App
{
    gl: GlGraphics
}

impl App
{
    fn render(&mut self, img: &RgbaImage, args: &RenderArgs)
    {
            use graphics::*;
            let BLANK: types::Color = color::hex("9CBD0F");
            let tile = Texture::from_image(&img, &TextureSettings::new());

            self.gl.draw(args.viewport(), |c, gl|
            {
                clear(color::BLACK, gl);
                let transform = c.transform.trans(0.0,0.0);
                image(&tile, transform, gl);
            });
    }
}

fn read_gb_file(file_name: &str) -> Vec<u8>
{
    let mut buffer : Vec<u8> = vec![0; 0x10000];
    let file = File::open(file_name);
    if file.is_ok()
    {
        if file.unwrap().read(&mut buffer).is_ok()
        {
            return buffer;
        }
    }
    return vec![0;0];
}

fn create_background_img(background_tile_map: &TileMap) -> RgbaImage
{

    let mut buffer = ImageBuffer::new(256, 256);
    for tile_y in 0..32
    {
        for tile_x in 0..32
        {
            for pixel_y in 0..8
            {
                for pixel_x in 0..8
                {
                    let tile = background_tile_map.map[(tile_y * 32) + tile_x];
                    let pixel_data = background_tile_map.tiles[tile as usize].data[(pixel_y * 8) + pixel_x];
                    let pixel = pixel_color_map(pixel_data);
                    buffer.put_pixel(((tile_x * 8) + pixel_x) as u32, ((tile_y * 8) + pixel_y) as u32, pixel);
                }
            }
        }
    }
    return buffer;
}

fn pixel_color_map(pixel_data: u8) -> Rgba<u8>
{
    match pixel_data
    {
        0 => return Rgba([156,189,15, 0xFF]),
        1 => return Rgba([140,173,15, 0xFF]),
        2 => return Rgba([48,98,48, 0xFF]),
        3 => return Rgba([15, 56, 15, 0xFF]),
        _ => return Rgba([0, 0, 0, 0xFF]),
    }
}

fn output_mem_selection(mem_map: &Vec<u8>, start: u16, end:u16)
{
    for index in start .. end
    {
        print!("{}-{:x}\t", index, mem_map[index as usize]);
    }
    print!("\n");
}

#[cfg(test)]
mod main_tests
{
    use read_gb_file;

    #[test]
    fn passing_bad_filename_to_read_gb_file_return_empty_vec()
    {
        let return_vector : Vec<u8> = read_gb_file("");
        assert_eq!(return_vector, vec![0;0]);
    }
}
<commit_msg>Added starting state initialization settings<commit_after>#![allow(dead_code)]

extern crate csv;
extern crate hex;
extern crate piston;
extern crate graphics;
extern crate glutin_window;
extern crate opengl_graphics;
extern crate image;
extern crate piston_window;

mod cpu;
mod gpu;
mod system;

use piston_window::*;
use image::ImageBuffer;
use image::{RgbaImage, Rgba};
use opengl_graphics::Texture;
use piston::event_loop::*;
use piston::input::*;
use opengl_graphics::{ GlGraphics, OpenGL };
use std::fs::File;
use std::io::prelude::*;
use std::env;
use cpu::cpu::*;
use gpu::gpu::*;
use gpu::gpu_registers::*;
use system::*;
use self::hex::FromHex;

static MAX_SPRITE: u8 = 40;

fn main()
 {
    //Initialize Emulator
    let args: Vec<String> = env::args().collect();
    let emulator_type: String = String::from("CLASSIC");
    let file_name: &String = &args[1];
    let mut system_data : SystemData = get_system_data(&emulator_type);
    system_data.mem_map = read_gb_file(file_name);
    let mut registers: Registers = Registers::new();
    let mut gpu_registers: GPU_Registers = GPU_Registers::new();
    init_emulator_state(&mut system_data, &mut registers);

    //Initialize Screen
    let opengl = OpenGL::V3_2;
    let mut window: PistonWindow = WindowSettings::new("RustBoy", [system_data.width as u32, system_data.height as u32])
                                        .opengl(opengl)
                                        .exit_on_esc(true)
                                        .build()
                                        .unwrap();
    //window.set_max_fps(60);
    let mut app = App
    {
        gl: GlGraphics::new(opengl),
    };
    let mut events = Events::new(EventSettings::new().max_fps(60));
    //events.set_max_fps(60);
    let mut background_tile_map: TileMap = TileMap::new();
    let mut window_tile_map: TileMap = TileMap::new();

    //Operation loop
    let mut emulator_loop = true;

    while let Some(e) = events.next(&mut window)
    {
        if let Some(r) = e.update_args()
        {
            while !gpu_registers.v_blank_draw_flag
            {
                let opcode = system_data.mem_map[registers.program_counter as usize];
                let address = registers.program_counter;
                cpu_continue(&mut system_data, &mut registers);
                update_gpu(&mut system_data, &mut registers, &mut gpu_registers);
            }
        }

        if let Some(r) = e.render_args(){
            gpu_registers.v_blank_draw_flag = false;
            background_tile_map.populate_tile_map(&mut system_data, gpu_registers.lcdc_register.tile_data, gpu_registers.lcdc_register.background_display_select);
            window_tile_map.populate_tile_map(&mut system_data, gpu_registers.lcdc_register.tile_data, gpu_registers.lcdc_register.window_display_select);
            //let background_image: RgbaImage = create_background_img(&background_tile_map);
            let background_image: RgbaImage = create_background_img(&window_tile_map);
            app.render(&background_image, &r);
            // break;
        }
    }
        // if system_data.cycles == 0  //|| registers.program_counter == 0x6d
        // {
        //     emulator_loop = false;
        //     println!("Location: {:04X}\tOpcode: 0x{:02X}  {:08b}", address, opcode, opcode);
        // }
    //Cleanup?
}

pub struct App
{
    gl: GlGraphics
}

impl App
{
    fn render(&mut self, img: &RgbaImage, args: &RenderArgs)
    {
            use graphics::*;
            let BLANK: types::Color = color::hex("9CBD0F");
            let tile = Texture::from_image(&img, &TextureSettings::new());

            self.gl.draw(args.viewport(), |c, gl|
            {
                clear(color::BLACK, gl);
                let transform = c.transform.trans(0.0,0.0);
                image(&tile, transform, gl);
            });
    }
}

fn read_gb_file(file_name: &str) -> Vec<u8>
{
    let mut buffer : Vec<u8> = vec![0; 0x10000];
    let file = File::open(file_name);
    if file.is_ok()
    {
        if file.unwrap().read(&mut buffer).is_ok()
        {
            return buffer;
        }
    }
    return vec![0;0];
}

fn create_background_img(background_tile_map: &TileMap) -> RgbaImage
{

    let mut buffer = ImageBuffer::new(256, 256);
    for tile_y in 0..32
    {
        for tile_x in 0..32
        {
            for pixel_y in 0..8
            {
                for pixel_x in 0..8
                {
                    let tile = background_tile_map.map[(tile_y * 32) + tile_x];
                    let pixel_data = background_tile_map.tiles[tile as usize].data[(pixel_y * 8) + pixel_x];
                    let pixel = pixel_color_map(pixel_data);
                    buffer.put_pixel(((tile_x * 8) + pixel_x) as u32, ((tile_y * 8) + pixel_y) as u32, pixel);
                }
            }
        }
    }
    return buffer;
}

fn pixel_color_map(pixel_data: u8) -> Rgba<u8>
{
    match pixel_data
    {
        0 => return Rgba([156,189,15, 0xFF]),
        1 => return Rgba([140,173,15, 0xFF]),
        2 => return Rgba([48,98,48, 0xFF]),
        3 => return Rgba([15, 56, 15, 0xFF]),
        _ => return Rgba([0, 0, 0, 0xFF]),
    }
}

fn output_mem_selection(mem_map: &Vec<u8>, start: u16, end:u16)
{
    for index in start .. end
    {
        print!("{}-{:x}\t", index, mem_map[index as usize]);
    }
    print!("\n");
}

fn init_emulator_state(system_data: &mut SystemData, registers: &mut Registers)
{
    let registers.program_counter = 0x100;

    let states: Vec<u8> = vec![0x00, 0x00, 0x00, 0x80, 0xBF, 0xF3, 0xBF, 0x3F,
                               0x00, 0xBF, 0x7F, 0xFF, 0x9F, 0xBF, 0xFF, 0x00,
                               0x00, 0xBF, 0x77, 0xF3, 0xF1, 0x91, 0x00, 0x00,
                               0x00, 0xFC, 0xFF, 0xFF, 0x00, 0x00, 0x00];

    let mem_locations: Vec<usize> = vec![0xFF05, 0xFF06, 0xFF07, 0xFF10, 0xFF11, 0xFF12,
                                       0xFF14, 0xFF16, 0xFF17, 0xFF19, 0xFF1A, 0xFF1B,
                                       0xFF1C, 0xFF1E, 0xFF20, 0xFF21, 0xFF22, 0xFF23,
                                       0xFF24, 0xFF25, 0xFF26, 0xFF40, 0xFF42, 0xFF43,
                                       0xFF45, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFFFF];

    for i in 0..states.len()
    {
        system_data.mem_map[mem_locations[i]] = states[i];
    }

    let register_states: Vec<u16> = vec![0x01B0, 0x0013, 0x00D8, 0x014D, 0xFFFE];
    for i in 0..register_states.len()
    {
        registers.mapped_16_bit_register_setter(i as u8, register_states[i]);
    }
}

#[cfg(test)]
mod main_tests
{
    use read_gb_file;

    #[test]
    fn passing_bad_filename_to_read_gb_file_return_empty_vec()
    {
        let return_vector : Vec<u8> = read_gb_file("");
        assert_eq!(return_vector, vec![0;0]);
    }
}
<|endoftext|>


<commit_before><commit_msg>Abort if we have an error connecting to a worker<commit_after><|endoftext|>


<commit_before>///! Basic CSS block layout.

use style::{StyledNode, Inline, Block, DisplayNone};
use css::{Keyword, Length, Px};
use std::default::Default;
use std::iter::AdditiveIterator; // for `sum`

// CSS box model. All sizes are in px.

#[deriving(Default, Show)]
pub struct Dimensions {
    // Top left corner of the content area, relative to the document origin:
    pub x: f32,
    pub y: f32,

    // Content area size:
    pub width: f32,
    pub height: f32,

    // Surrounding edges:
    pub padding: EdgeSizes,
    pub border: EdgeSizes,
    pub margin: EdgeSizes,
}

#[deriving(Default, Show)]
pub struct EdgeSizes {
    pub left: f32,
    pub right: f32,
    pub top: f32,
    pub bottom: f32,
}

/// A node in the layout tree.
pub struct LayoutBox<'a> {
    pub dimensions: Dimensions,
    pub box_type: BoxType<'a>,
    pub children: Vec<LayoutBox<'a>>,
}

pub enum BoxType<'a> {
    BlockNode(&'a StyledNode<'a>),
    InlineNode(&'a StyledNode<'a>),
    AnonymousBlock,
}

impl<'a> LayoutBox<'a> {
    fn new(box_type: BoxType) -> LayoutBox {
        LayoutBox {
            box_type: box_type,
            dimensions: Default::default(),
            children: Vec::new(),
        }
    }

    fn get_style_node(&self) -> &'a StyledNode<'a> {
        match self.box_type {
            BlockNode(node) => node,
            InlineNode(node) => node,
            AnonymousBlock => fail!("Anonymous block box has no style node")
        }
    }
}

/// Transform a style tree into a layout tree.
pub fn layout_tree<'a>(node: &'a StyledNode<'a>, containing_block: Dimensions) -> LayoutBox<'a> {
    let mut root_box = build_layout_tree(node);
    root_box.layout(containing_block);
    return root_box;
}

/// Build the tree of LayoutBoxes, but don't perform any layout calculations yet.
fn build_layout_tree<'a>(style_node: &'a StyledNode<'a>) -> LayoutBox<'a> {
    // Create the root box.
    let mut root = LayoutBox::new(match style_node.display() {
        Block => BlockNode(style_node),
        Inline => InlineNode(style_node),
        DisplayNone => fail!("Root node has display: none.")
    });

    // Create the descendant boxes.
    for child in style_node.children.iter() {
        match child.display() {
            Block => root.children.push(build_layout_tree(child)),
            Inline => root.get_inline_container().children.push(build_layout_tree(child)),
            DisplayNone => {} // Don't lay out nodes with `display: none;`
        }
    }
    return root;
}

impl<'a> LayoutBox<'a> {
    /// Lay out a box and its descendants.
    fn layout(&mut self, containing_block: Dimensions) {
        match self.box_type {
            BlockNode(_) => self.layout_block(containing_block),
            InlineNode(_) => {} // TODO
            AnonymousBlock => {} // TODO
        }
    }

    /// Lay out a block-level element and its descendants.
    fn layout_block(&mut self, containing_block: Dimensions) {
        // Child width can depend on parent width, so we need to calculate this node's width before
        // laying out its children.
        self.calculate_block_width(containing_block);

        // Determine where the block is located within its container.
        self.calculate_block_position(containing_block);

        // Recursively lay out the children of this node within its content area.
        self.layout_block_children();

        // Parent height can depend on child height, so `calculate_height` must be called after the
        // content layout is finished.
        self.calculate_block_height();
    }

    /// Calculate the width of a block-level non-replaced element in normal flow.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#blockwidth
    ///
    /// Sets the horizontal margin/padding/border dimensions, and the `width`.
    fn calculate_block_width(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();

        // `width` has initial value `auto`.
        let auto = Keyword("auto".to_string());
        let mut width = style.value("width").unwrap_or(auto.clone());

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        let mut margin_left = style.lookup("margin-left", "margin", &zero);
        let mut margin_right = style.lookup("margin-right", "margin", &zero);

        let border_left = style.lookup("border-left-width", "border-width", &zero);
        let border_right = style.lookup("border-right-width", "border-width", &zero);

        let padding_left = style.lookup("padding-left", "padding", &zero);
        let padding_right = style.lookup("padding-right", "padding", &zero);

        let total = [&margin_left, &margin_right, &border_left, &border_right,
                     &padding_left, &padding_right, &width].iter().map(|v| v.to_px()).sum();

        // If width is not auto and the total is wider than the container, treat auto margins as 0.
        if width != auto && total > containing_block.width {
            if margin_left == auto {
                margin_left = Length(0.0, Px);
            }
            if margin_right == auto {
                margin_right = Length(0.0, Px);
            }
        }

        // Adjust used values so that the above sum equals `containing_block.width`.
        // Each arm of the `match` should increase the total width by exactly `underflow`,
        // and afterward all values should be absolute lengths in px.
        let underflow = containing_block.width - total;
        match (width == auto, margin_left == auto, margin_right == auto) {
            // If the values are overconstrained, calculate margin_right.
            (false, false, false) => {
                margin_right = Length(margin_right.to_px() + underflow, Px);
            }
            // If exactly one value is auto, its used value follows from the equality.
            (false, false, true) => {
                margin_right = Length(underflow, Px);
            }
            (false, true, false) => {
                margin_left = Length(underflow, Px);
            }
            // If width is set to auto, any other auto values become 0.
            (true, _, _) => {
                if margin_left == auto {
                    margin_left = Length(0.0, Px);
                }
                if margin_right == auto {
                    margin_right = Length(0.0, Px);
                }

                if underflow >= 0.0 {
                    // Expand width to fill the underflow.
                    width = Length(underflow, Px);
                } else {
                    // Width can't be negative. Adjust the right margin instead.
                    width = Length(0.0, Px);
                    margin_right = Length(margin_right.to_px() + underflow, Px);
                }
            }
            // If margin-left and margin-right are both auto, their used values are equal.
            (false, true, true) => {
                margin_left = Length(underflow / 2.0, Px);
                margin_right = Length(underflow / 2.0, Px);
            }
        }

        let d = &mut self.dimensions;
        d.width = width.to_px();

        d.padding.left = padding_left.to_px();
        d.padding.right = padding_right.to_px();

        d.border.left = border_left.to_px();
        d.border.right = border_right.to_px();

        d.margin.left = margin_left.to_px();
        d.margin.right = margin_right.to_px();
    }

    /// Finish calculating the block's edge sizes, and position it within its containing block.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#normal-block
    ///
    /// Sets the vertical margin/padding/border dimensions, and the `x`, `y` values.
    fn calculate_block_position(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();
        let d = &mut self.dimensions;

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        // If margin-top or margin-bottom is `auto`, the used value is zero.
        d.margin.top = style.lookup("margin-top", "margin", &zero).to_px();
        d.margin.bottom = style.lookup("margin-bottom", "margin", &zero).to_px();

        d.border.top = style.lookup("border-top-width", "border-width", &zero).to_px();
        d.border.bottom = style.lookup("border-bottom-width", "border-width", &zero).to_px();

        d.padding.top = style.lookup("padding-top", "padding", &zero).to_px();
        d.padding.bottom = style.lookup("padding-bottom", "padding", &zero).to_px();

        // Position the box below all the previous boxes in the container.
        d.x = containing_block.x +
              d.margin.left + d.border.left + d.padding.left;
        d.y = containing_block.y + containing_block.height +
              d.margin.top + d.border.top + d.padding.top;
    }

    /// Lay out the block's children within its content area.
    ///
    /// Sets `self.dimensions.height` to the total content height.
    fn layout_block_children(&mut self) {
        let d = &mut self.dimensions;
        for child in self.children.mut_iter() {
            child.layout(*d);
            // Increment the height so each child is laid out below the previous one.
            d.height = d.height + child.dimensions.margin_box_height();
        }
    }

    /// Height of a block-level non-replaced element in normal flow with overflow visible.
    fn calculate_block_height(&mut self) {
        // If the height is set to an explicit length, use that exact length.
        // Otherwise, just keep the value set by `layout_block_children`.
        match self.get_style_node().value("height") {
            Some(Length(h, Px)) => { self.dimensions.height = h; }
            _ => {}
        }
    }

    /// Where a new inline child should go.
    fn get_inline_container(&mut self) -> &mut LayoutBox<'a> {
        match self.box_type {
            InlineNode(_) | AnonymousBlock => self,
            BlockNode(_) => {
                // If we've just generated an anonymous block box, keep using it.
                // Otherwise, create a new one.
                match self.children.last() {
                    Some(&LayoutBox { box_type: AnonymousBlock,..}) => {}
                    _ => self.children.push(LayoutBox::new(AnonymousBlock))
                }
                self.children.mut_last().unwrap()
            }
        }
    }
}

impl Dimensions {
    /// Total height of a box including its margins, border, and padding.
    fn margin_box_height(&self) -> f32 {
        self.height + self.padding.top + self.padding.bottom
                    + self.border.top + self.border.bottom
                    + self.margin.top + self.margin.bottom
    }
}
<commit_msg>Minor comment and formatting changes<commit_after>///! Basic CSS block layout.

use style::{StyledNode, Inline, Block, DisplayNone};
use css::{Keyword, Length, Px};
use std::default::Default;
use std::iter::AdditiveIterator; // for `sum`

// CSS box model. All sizes are in px.

#[deriving(Default, Show)]
pub struct Dimensions {
    // Top left corner of the content area, relative to the document origin:
    pub x: f32,
    pub y: f32,

    // Content area size:
    pub width: f32,
    pub height: f32,

    // Surrounding edges:
    pub padding: EdgeSizes,
    pub border: EdgeSizes,
    pub margin: EdgeSizes,
}

#[deriving(Default, Show)]
pub struct EdgeSizes {
    pub left: f32,
    pub right: f32,
    pub top: f32,
    pub bottom: f32,
}

/// A node in the layout tree.
pub struct LayoutBox<'a> {
    pub dimensions: Dimensions,
    pub box_type: BoxType<'a>,
    pub children: Vec<LayoutBox<'a>>,
}

pub enum BoxType<'a> {
    BlockNode(&'a StyledNode<'a>),
    InlineNode(&'a StyledNode<'a>),
    AnonymousBlock,
}

impl<'a> LayoutBox<'a> {
    fn new(box_type: BoxType) -> LayoutBox {
        LayoutBox {
            box_type: box_type,
            dimensions: Default::default(),
            children: Vec::new(),
        }
    }

    fn get_style_node(&self) -> &'a StyledNode<'a> {
        match self.box_type {
            BlockNode(node) => node,
            InlineNode(node) => node,
            AnonymousBlock => fail!("Anonymous block box has no style node")
        }
    }
}

/// Transform a style tree into a layout tree.
pub fn layout_tree<'a>(node: &'a StyledNode<'a>, containing_block: Dimensions) -> LayoutBox<'a> {
    let mut root_box = build_layout_tree(node);
    root_box.layout(containing_block);
    return root_box;
}

/// Build the tree of LayoutBoxes, but don't perform any layout calculations yet.
fn build_layout_tree<'a>(style_node: &'a StyledNode<'a>) -> LayoutBox<'a> {
    // Create the root box.
    let mut root = LayoutBox::new(match style_node.display() {
        Block => BlockNode(style_node),
        Inline => InlineNode(style_node),
        DisplayNone => fail!("Root node has display: none.")
    });

    // Create the descendant boxes.
    for child in style_node.children.iter() {
        match child.display() {
            Block => root.children.push(build_layout_tree(child)),
            Inline => root.get_inline_container().children.push(build_layout_tree(child)),
            DisplayNone => {} // Don't lay out nodes with `display: none;`
        }
    }
    return root;
}

impl<'a> LayoutBox<'a> {
    /// Lay out a box and its descendants.
    fn layout(&mut self, containing_block: Dimensions) {
        match self.box_type {
            BlockNode(_) => self.layout_block(containing_block),
            InlineNode(_) => {} // TODO
            AnonymousBlock => {} // TODO
        }
    }

    /// Lay out a block-level element and its descendants.
    fn layout_block(&mut self, containing_block: Dimensions) {
        // Child width can depend on parent width, so we need to calculate this box's width before
        // laying out its children.
        self.calculate_block_width(containing_block);

        // Determine where the box is located within its container.
        self.calculate_block_position(containing_block);

        // Recursively lay out the children of this box.
        self.layout_block_children();

        // Parent height can depend on child height, so `calculate_height` must be called after the
        // children are laid out.
        self.calculate_block_height();
    }

    /// Calculate the width of a block-level non-replaced element in normal flow.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#blockwidth
    ///
    /// Sets the horizontal margin/padding/border dimensions, and the `width`.
    fn calculate_block_width(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();

        // `width` has initial value `auto`.
        let auto = Keyword("auto".to_string());
        let mut width = style.value("width").unwrap_or(auto.clone());

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        let mut margin_left = style.lookup("margin-left", "margin", &zero);
        let mut margin_right = style.lookup("margin-right", "margin", &zero);

        let border_left = style.lookup("border-left-width", "border-width", &zero);
        let border_right = style.lookup("border-right-width", "border-width", &zero);

        let padding_left = style.lookup("padding-left", "padding", &zero);
        let padding_right = style.lookup("padding-right", "padding", &zero);

        let total = [&margin_left, &margin_right, &border_left, &border_right,
                     &padding_left, &padding_right, &width].iter().map(|v| v.to_px()).sum();

        // If width is not auto and the total is wider than the container, treat auto margins as 0.
        if width != auto && total > containing_block.width {
            if margin_left == auto {
                margin_left = Length(0.0, Px);
            }
            if margin_right == auto {
                margin_right = Length(0.0, Px);
            }
        }

        // Adjust used values so that the above sum equals `containing_block.width`.
        // Each arm of the `match` should increase the total width by exactly `underflow`,
        // and afterward all values should be absolute lengths in px.
        let underflow = containing_block.width - total;

        match (width == auto, margin_left == auto, margin_right == auto) {
            // If the values are overconstrained, calculate margin_right.
            (false, false, false) => {
                margin_right = Length(margin_right.to_px() + underflow, Px);
            }

            // If exactly one size is auto, its used value follows from the equality.
            (false, false, true) => { margin_right = Length(underflow, Px); }
            (false, true, false) => { margin_left  = Length(underflow, Px); }

            // If width is set to auto, any other auto values become 0.
            (true, _, _) => {
                if margin_left == auto { margin_left = Length(0.0, Px); }
                if margin_right == auto { margin_right = Length(0.0, Px); }

                if underflow >= 0.0 {
                    // Expand width to fill the underflow.
                    width = Length(underflow, Px);
                } else {
                    // Width can't be negative. Adjust the right margin instead.
                    width = Length(0.0, Px);
                    margin_right = Length(margin_right.to_px() + underflow, Px);
                }
            }

            // If margin-left and margin-right are both auto, their used values are equal.
            (false, true, true) => {
                margin_left = Length(underflow / 2.0, Px);
                margin_right = Length(underflow / 2.0, Px);
            }
        }

        let d = &mut self.dimensions;
        d.width = width.to_px();

        d.padding.left = padding_left.to_px();
        d.padding.right = padding_right.to_px();

        d.border.left = border_left.to_px();
        d.border.right = border_right.to_px();

        d.margin.left = margin_left.to_px();
        d.margin.right = margin_right.to_px();
    }

    /// Finish calculating the block's edge sizes, and position it within its containing block.
    ///
    /// http://www.w3.org/TR/CSS2/visudet.html#normal-block
    ///
    /// Sets the vertical margin/padding/border dimensions, and the `x`, `y` values.
    fn calculate_block_position(&mut self, containing_block: Dimensions) {
        let style = self.get_style_node();
        let d = &mut self.dimensions;

        // margin, border, and padding have initial value 0.
        let zero = Length(0.0, Px);

        // If margin-top or margin-bottom is `auto`, the used value is zero.
        d.margin.top = style.lookup("margin-top", "margin", &zero).to_px();
        d.margin.bottom = style.lookup("margin-bottom", "margin", &zero).to_px();

        d.border.top = style.lookup("border-top-width", "border-width", &zero).to_px();
        d.border.bottom = style.lookup("border-bottom-width", "border-width", &zero).to_px();

        d.padding.top = style.lookup("padding-top", "padding", &zero).to_px();
        d.padding.bottom = style.lookup("padding-bottom", "padding", &zero).to_px();

        // Position the box below all the previous boxes in the container.
        d.x = containing_block.x +
              d.margin.left + d.border.left + d.padding.left;
        d.y = containing_block.y + containing_block.height +
              d.margin.top + d.border.top + d.padding.top;
    }

    /// Lay out the block's children within its content area.
    ///
    /// Sets `self.dimensions.height` to the total content height.
    fn layout_block_children(&mut self) {
        let d = &mut self.dimensions;
        for child in self.children.mut_iter() {
            child.layout(*d);
            // Increment the height so each child is laid out below the previous one.
            d.height = d.height + child.dimensions.margin_box_height();
        }
    }

    /// Height of a block-level non-replaced element in normal flow with overflow visible.
    fn calculate_block_height(&mut self) {
        // If the height is set to an explicit length, use that exact length.
        // Otherwise, just keep the value set by `layout_block_children`.
        match self.get_style_node().value("height") {
            Some(Length(h, Px)) => { self.dimensions.height = h; }
            _ => {}
        }
    }

    /// Where a new inline child should go.
    fn get_inline_container(&mut self) -> &mut LayoutBox<'a> {
        match self.box_type {
            InlineNode(_) | AnonymousBlock => self,
            BlockNode(_) => {
                // If we've just generated an anonymous block box, keep using it.
                // Otherwise, create a new one.
                match self.children.last() {
                    Some(&LayoutBox { box_type: AnonymousBlock,..}) => {}
                    _ => self.children.push(LayoutBox::new(AnonymousBlock))
                }
                self.children.mut_last().unwrap()
            }
        }
    }
}

impl Dimensions {
    /// Total height of a box including its margins, border, and padding.
    fn margin_box_height(&self) -> f32 {
        self.height + self.padding.top + self.padding.bottom
                    + self.border.top + self.border.bottom
                    + self.margin.top + self.margin.bottom
    }
}
<|endoftext|>


<commit_before>use std::fmt::Debug;
use std::io::{Result, Read, Write};
use ctx::{FromCtx, SizeWith};
use error::{self};

/// An extension trait to `std::io::Read`; this only deserializes simple objects, like u8, u32, f32, usize, etc.
///
/// If you implement `FromCtx` for your type, you can then `lread::<YourType>()` on a `Read`.  Note: `FromCtx` is only meant for very simple types, and should _never_ fail.
///
/// # Example
///
/// **NB** You should probably add `repr(packed)` or `repr(C)` and be very careful how you implement `SizeWith`, otherwise you
/// will get IO errors failing to fill entire buffer (the size you specified in SizeWith)
///
///```rust
/// use std::io::Cursor;
/// use scroll::{self, ctx, Pread, Lread};
///
/// #[repr(packed)]
/// struct Foo {
///     foo: usize,
///     bar: u32,
/// }
///
/// impl ctx::FromCtx for Foo {
///     fn from_ctx(bytes: &[u8], ctx: scroll::Endian) -> Self {
///         Foo { foo: bytes.pread_unsafe::<usize>(0, ctx), bar: bytes.pread_unsafe::<u32>(8, ctx) }
///     }
/// }
///
/// impl ctx::SizeWith for Foo {
///     type Units = usize;
///     // our parsing context doesn't influence our size
///     fn size_with(_: &scroll::Endian) -> Self::Units {
///         ::std::mem::size_of::<Foo>()
///     }
/// }
///
/// let bytes_ = [0x0b,0x0b,0x00,0x00,0x00,0x00,0x00,0x00, 0xef,0xbe,0x00,0x00,];
/// let mut bytes = Cursor::new(bytes_);
/// let foo = bytes.lread::<usize>().unwrap();
/// let bar = bytes.lread::<u32>().unwrap();
/// assert_eq!(foo, 0xb0b);
/// assert_eq!(bar, 0xbeef);
/// let error = bytes.lread::<f64>();
/// assert!(error.is_err());
/// let mut bytes = Cursor::new(bytes_);
/// let foo_ = bytes.lread::<Foo>().unwrap();
/// assert_eq!(foo_.foo, foo);
/// assert_eq!(foo_.bar, bar);
///```
pub trait Lread<Ctx = super::Endian, E = error::Error> : Read
 where E: Debug,
       Ctx: Copy + Default + Debug,
{
    /// Reads `N` from `Self`, with a default parsing context.
    /// For the primitive numeric types, this will be at the host machine's endianness.
    ///
    /// # Example
    /// ```rust
    /// use scroll::Lread;
    /// use std::io::Cursor;
    /// let bytes = [0xef, 0xbe];
    /// let mut bytes = Cursor::new(&bytes[..]);
    /// let beef = bytes.lread::<u16>().unwrap();
    /// assert_eq!(0xbeef, beef);
    fn lread<N: FromCtx<Ctx> + SizeWith<Ctx, Units = usize>>(&mut self) -> Result<N> {
        let ctx = Ctx::default();
        self.lread_with(ctx)
    }

    /// Reads `N` from `Self`, with the parsing context `ctx`.
    /// NB: this will panic if the type you're reading has a size greater than 256. Plans are to have this allocate in larger cases.
    ///
    /// For the primitive numeric types, this will be at the host machine's endianness.
    ///
    /// # Example
    /// ```rust
    /// use scroll::{Lread, LE, BE};
    /// use std::io::Cursor;
    /// let bytes = [0xef, 0xbe, 0xb0, 0xb0, 0xfe, 0xed, 0xde, 0xad];
    /// let mut bytes = Cursor::new(&bytes[..]);
    /// let beef = bytes.lread_with::<u16>(LE).unwrap();
    /// assert_eq!(0xbeef, beef);
    /// let b0 = bytes.lread::<u8>().unwrap();
    /// assert_eq!(0xb0, b0);
    /// let b0 = bytes.lread::<u8>().unwrap();
    /// assert_eq!(0xb0, b0);
    /// let feeddead = bytes.lread_with::<u32>(BE).unwrap();
    /// assert_eq!(0xfeeddead, feeddead);
    fn lread_with<N: FromCtx<Ctx> + SizeWith<Ctx, Units = usize>>(&mut self, ctx: Ctx) -> Result<N> {
        let mut scratch = [0u8; 256];
        let size = N::size_with(&ctx);
        let mut buf = &mut scratch[0..size];
        self.read_exact(&mut buf)?;
        Ok(N::from_ctx(buf, ctx))
    }
}

impl<R: Read + ?Sized> Lread for R {}

trait Lwrite : Write {
}

/// Types that implement `Write` get methods defined in `Lwrite`
/// for free.
impl<W: Write + ?Sized> Lwrite for W {}
<commit_msg>lesser: add lwrite impl. add documentation<commit_after>use std::fmt::Debug;
use std::io::{Result, Read, Write};
use ctx::{FromCtx, IntoCtx, SizeWith};
use error::{self};

/// An extension trait to `std::io::Read`; this only deserializes simple objects, like u8, u32, f32, usize, etc.
///
/// If you implement `FromCtx` for your type, you can then `lread::<YourType>()` on a `Read`.  Note: `FromCtx` is only meant for very simple types, and should _never_ fail.
///
/// # Example
///
/// **NB** You should probably add `repr(packed)` or `repr(C)` and be very careful how you implement `SizeWith`, otherwise you
/// will get IO errors failing to fill entire buffer (the size you specified in SizeWith)
///
///```rust
/// use std::io::Cursor;
/// use scroll::{self, ctx, Pread, Lread};
///
/// #[repr(packed)]
/// struct Foo {
///     foo: usize,
///     bar: u32,
/// }
///
/// impl ctx::FromCtx for Foo {
///     fn from_ctx(bytes: &[u8], ctx: scroll::Endian) -> Self {
///         Foo { foo: bytes.pread_unsafe::<usize>(0, ctx), bar: bytes.pread_unsafe::<u32>(8, ctx) }
///     }
/// }
///
/// impl ctx::SizeWith for Foo {
///     type Units = usize;
///     // our parsing context doesn't influence our size
///     fn size_with(_: &scroll::Endian) -> Self::Units {
///         ::std::mem::size_of::<Foo>()
///     }
/// }
///
/// let bytes_ = [0x0b,0x0b,0x00,0x00,0x00,0x00,0x00,0x00, 0xef,0xbe,0x00,0x00,];
/// let mut bytes = Cursor::new(bytes_);
/// let foo = bytes.lread::<usize>().unwrap();
/// let bar = bytes.lread::<u32>().unwrap();
/// assert_eq!(foo, 0xb0b);
/// assert_eq!(bar, 0xbeef);
/// let error = bytes.lread::<f64>();
/// assert!(error.is_err());
/// let mut bytes = Cursor::new(bytes_);
/// let foo_ = bytes.lread::<Foo>().unwrap();
/// assert_eq!(foo_.foo, foo);
/// assert_eq!(foo_.bar, bar);
///```
pub trait Lread<Ctx = super::Endian, E = error::Error> : Read
 where
    Ctx: Copy + Default + Debug,
    E: Debug,
{
    /// Reads the type `N` from `Self`, with a default parsing context.
    /// For the primitive numeric types, this will be at the host machine's endianness.
    ///
    /// # Example
    /// ```rust
    /// use scroll::Lread;
    /// use std::io::Cursor;
    /// let bytes = [0xef, 0xbe];
    /// let mut bytes = Cursor::new(&bytes[..]);
    /// let beef = bytes.lread::<u16>().unwrap();
    /// assert_eq!(0xbeef, beef);
    /// ```
    #[inline]
    fn lread<N: FromCtx<Ctx> + SizeWith<Ctx, Units = usize>>(&mut self) -> Result<N> {
        let ctx = Ctx::default();
        self.lread_with(ctx)
    }

    /// Reads the type `N` from `Self`, with the parsing context `ctx`.
    /// **NB**: this will panic if the type you're reading has a size greater than 256. Plans are to have this allocate in larger cases.
    ///
    /// For the primitive numeric types, this will be at the host machine's endianness.
    ///
    /// # Example
    /// ```rust
    /// use scroll::{Lread, LE, BE};
    /// use std::io::Cursor;
    /// let bytes = [0xef, 0xbe, 0xb0, 0xb0, 0xfe, 0xed, 0xde, 0xad];
    /// let mut bytes = Cursor::new(&bytes[..]);
    /// let beef = bytes.lread_with::<u16>(LE).unwrap();
    /// assert_eq!(0xbeef, beef);
    /// let b0 = bytes.lread::<u8>().unwrap();
    /// assert_eq!(0xb0, b0);
    /// let b0 = bytes.lread::<u8>().unwrap();
    /// assert_eq!(0xb0, b0);
    /// let feeddead = bytes.lread_with::<u32>(BE).unwrap();
    /// assert_eq!(0xfeeddead, feeddead);
    /// ```
    #[inline]
    fn lread_with<N: FromCtx<Ctx> + SizeWith<Ctx, Units = usize>>(&mut self, ctx: Ctx) -> Result<N> {
        let mut scratch = [0u8; 256];
        let size = N::size_with(&ctx);
        let mut buf = &mut scratch[0..size];
        self.read_exact(&mut buf)?;
        Ok(N::from_ctx(buf, ctx))
    }
}

/// Types that implement `Read` get methods defined in `Lread`
/// for free.
impl<R: Read + ?Sized> Lread for R {}

pub trait Lwrite<Ctx = super::Endian, E = error::Error>: Write
    where
          Ctx: Copy + Default + Debug,
          E: Debug,
{
    /// Writes the type `N` into `Self`, with the parsing context `ctx`.
    /// **NB**: this will panic if the type you're writing has a size greater than 256. Plans are to have this allocate in larger cases.
    ///
    /// For the primitive numeric types, this will be at the host machine's endianness.
    ///
    /// # Example
    /// ```rust
    /// use scroll::Lwrite;
    /// use std::io::Cursor;
    ///
    /// let mut bytes = [0x0u8; 4];
    /// let mut bytes = Cursor::new(&mut bytes[..]);
    /// bytes.lwrite(0xdeadbeef as u32).unwrap();
    /// assert_eq!(bytes.into_inner(), [0xef, 0xbe, 0xad, 0xde,]);
    /// ```
    #[inline]
    fn lwrite<N: SizeWith<Ctx, Units = usize> + IntoCtx<Ctx>>(&mut self, n: N) -> Result<()> {
        let ctx = Ctx::default();
        self.lwrite_with(n, ctx)
    }

    /// Writes the type `N` into `Self`, with the parsing context `ctx`.
    /// **NB**: this will panic if the type you're writing has a size greater than 256. Plans are to have this allocate in larger cases.
    ///
    /// For the primitive numeric types, this will be at the host machine's endianness.
    ///
    /// # Example
    /// ```rust
    /// use scroll::{Lwrite, LE, BE};
    /// use std::io::{Write, Cursor};
    ///
    /// let mut bytes = [0x0u8; 10];
    /// let mut cursor = Cursor::new(&mut bytes[..]);
    /// cursor.write_all(b"hell").unwrap();
    /// cursor.lwrite_with(0xdeadbeef as u32, BE).unwrap();
    /// assert_eq!(cursor.into_inner(), [0x68, 0x65, 0x6c, 0x6c, 0xde, 0xad, 0xbe, 0xef, 0x0, 0x0]);
    /// ```
    #[inline]
    fn lwrite_with<N: SizeWith<Ctx, Units = usize> + IntoCtx<Ctx>>(&mut self, n: N, ctx: Ctx) -> Result<()> {
        let mut buf = [0u8; 256];
        let size = N::size_with(&ctx);
        let mut buf = &mut buf[0..size];
        n.into_ctx(buf, ctx);
        self.write_all(buf)?;
        Ok(())
    }
}

/// Types that implement `Write` get methods defined in `Lwrite`
/// for free.
impl<W: Write + ?Sized> Lwrite for W {}
<|endoftext|>


<commit_before>extern crate walkdir;

use self::walkdir::{DirEntry as WalkDirEntry, WalkDir, WalkDirIterator};

use std::collections::BTreeSet;
use std::ffi::OsString;
use std::fs;
use std::io::Error as IoError;
use std::path::{Path, PathBuf};
use std::result::Result;

macro_rules! path_buf {
    ($($x: expr),+) => {
        PathBuf::new()
            $(.join($x))+
    };
}

pub fn ls<P: AsRef<Path>>(path: P) -> Result<Vec<String>, IoError> {
    let dirs = try!(fs::read_dir(path));
    let dirs = dirs
        .filter_map(Result::ok)
        .map(|d| d.file_name())
        .map(OsString::into_string)
        .filter_map(Result::ok)
        .collect::<Vec<String>>();
    Ok(dirs)
}

pub fn is_empty_dir<P: AsRef<Path>>(path: P) -> bool {
    match fs::read_dir(path) {
        Ok(rd) => rd.count() == 0,
        Err(_) => false,
    }
}

fn is_hidden_name(file_name: &str) -> bool {
    file_name.starts_with(".") && file_name.len() > 1 && file_name != ".."
}
#[test]
fn is_hidden_name_should_return_true() {
    let file_names = [
        ".a",
        ".ab",
        ".abc",
        "..a",
        "...",
    ];
    for file_name in &file_names {
        assert!(is_hidden_name(file_name));
    }
}
#[test]
fn is_hidden_name_should_return_false() {
    let file_names = [
        "",

        ".",
        "..",
        "a",
        "ab",
        "abc",
    ];
    for file_name in &file_names {
        assert!(!is_hidden_name(file_name));
    }
}

fn is_hidden(entry: &WalkDirEntry) -> bool {
    entry
        .file_name()
        .to_str()
        .map_or(false, is_hidden_name)
}

pub fn walk_dir<P: AsRef<Path>>(root: P) -> BTreeSet<String> {
    let walker = WalkDir::new(root)
        .into_iter()
        .filter_entry(|e| !is_hidden(e))
        .filter_map(Result::ok)
        .filter(|e| !e.file_type().is_dir())
        .collect::<Vec<WalkDirEntry>>();

    walker
        .into_iter()
        .filter_map(|e| e.path().to_str().map(|s| s.to_string()))
        .collect::<BTreeSet<String>>()
}

pub fn dirs_ordered_by_descending_depth<P: AsRef<Path>>(root: P) -> Vec<PathBuf> {
    let mut walker = WalkDir::new(root)
        .into_iter()
        .filter_entry(|e| !is_hidden(e))
        .filter_entry(|e| e.file_type().is_dir())
        .filter_map(Result::ok)
        .collect::<Vec<WalkDirEntry>>();

    walker.sort_by(|l, r| {
        let l_depth = &l.depth();
        let r_depth = &r.depth();
        r_depth.cmp(l_depth)
    });

    walker
        .into_iter()
        .map(|e| e.path().to_path_buf())
        .collect::<Vec<PathBuf>>()
}

#[cfg(test)]
mod tests {
    use std::path::{Path, PathBuf};

    #[test]
    fn path_buf_macro_should_create_path_buf() {
        let paths = [
            (Path::new("path").to_path_buf()          , path_buf!["path"              ]),
            (Path::new("path").join("to")             , path_buf!["path", "to"        ]),
            (Path::new("path").join("to").join("file"), path_buf!["path", "to", "file"]),
        ];
        for &(ref correct, ref calculated) in &paths {
            assert_eq!(correct, calculated);
        }
    }
}
<commit_msg>[Test] Create test scenarios for lib::fs<commit_after>extern crate walkdir;

use self::walkdir::{DirEntry as WalkDirEntry, WalkDir, WalkDirIterator};

use std::collections::BTreeSet;
use std::ffi::OsString;
use std::fs;
use std::io::Error as IoError;
use std::path::{Path, PathBuf};
use std::result::Result;

macro_rules! path_buf {
    ($($x: expr),+) => {
        PathBuf::new()
            $(.join($x))+
    };
}

pub fn ls<P: AsRef<Path>>(path: P) -> Result<Vec<String>, IoError> {
    let dirs = try!(fs::read_dir(path));
    let dirs = dirs
        .filter_map(Result::ok)
        .map(|d| d.file_name())
        .map(OsString::into_string)
        .filter_map(Result::ok)
        .collect::<Vec<String>>();
    Ok(dirs)
}

pub fn is_empty_dir<P: AsRef<Path>>(path: P) -> bool {
    match fs::read_dir(path) {
        Ok(rd) => rd.count() == 0,
        Err(_) => false,
    }
}

fn is_hidden_name(file_name: &str) -> bool {
    file_name.starts_with(".") && file_name.len() > 1 && file_name != ".."
}
#[test]
fn is_hidden_name_should_return_true() {
    let file_names = [
        ".a",
        ".ab",
        ".abc",
        "..a",
        "...",
    ];
    for file_name in &file_names {
        assert!(is_hidden_name(file_name));
    }
}
#[test]
fn is_hidden_name_should_return_false() {
    let file_names = [
        "",

        ".",
        "..",
        "a",
        "ab",
        "abc",
    ];
    for file_name in &file_names {
        assert!(!is_hidden_name(file_name));
    }
}

fn is_hidden(entry: &WalkDirEntry) -> bool {
    entry
        .file_name()
        .to_str()
        .map_or(false, is_hidden_name)
}

pub fn walk_dir<P: AsRef<Path>>(root: P) -> BTreeSet<String> {
    let walker = WalkDir::new(root)
        .into_iter()
        .filter_entry(|e| !is_hidden(e))
        .filter_map(Result::ok)
        .filter(|e| !e.file_type().is_dir())
        .collect::<Vec<WalkDirEntry>>();

    walker
        .into_iter()
        .filter_map(|e| e.path().to_str().map(|s| s.to_string()))
        .collect::<BTreeSet<String>>()
}

pub fn dirs_ordered_by_descending_depth<P: AsRef<Path>>(root: P) -> Vec<PathBuf> {
    let mut walker = WalkDir::new(root)
        .into_iter()
        .filter_entry(|e| !is_hidden(e))
        .filter_entry(|e| e.file_type().is_dir())
        .filter_map(Result::ok)
        .collect::<Vec<WalkDirEntry>>();

    walker.sort_by(|l, r| {
        let l_depth = &l.depth();
        let r_depth = &r.depth();
        r_depth.cmp(l_depth)
    });

    walker
        .into_iter()
        .map(|e| e.path().to_path_buf())
        .collect::<Vec<PathBuf>>()
}

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

    use std::fs::{self, File};
    use std::io::Write;
    use std::path::{Path, PathBuf};

    const D1: &'static str = "directory1";
    const D2: &'static str = "directory2";
    const D3: &'static str = "directory3";
    const F1: &'static str = "file1";
    const F2: &'static str = "file2";
    const F3: &'static str = "file3";

    fn remove_dirs_and_files() {
        let path_to_d1 = Path::new(D1);
        let path_to_f1 = Path::new(F1);

        fs::remove_dir_all(path_to_d1).ok();
        if path_to_f1.is_file() {
            fs::remove_file(path_to_f1).ok();
        }
    }

    fn create_dirs_and_files() {
        remove_dirs_and_files();

        let path_to_d1 = Path::new(D1);
        let path_to_d2 = path_to_d1.join(D2);
        let path_to_d3 = path_to_d2.join(D3);
        let path_to_f1 = Path::new(F1);
        let path_to_f2 = path_to_d1.join(F2);
        let path_to_f3 = path_to_d2.join(F3);

        fs::create_dir_all(path_to_d3).ok();

        let mut f = File::create(path_to_f1).unwrap();
        f.write("\n".as_ref()).ok();
        fs::copy(path_to_f1, path_to_f2).ok();
        fs::copy(path_to_f1, path_to_f3).ok();
    }

    #[test]
    fn path_buf_macro_should_create_path_buf() {
        let paths = [
            (Path::new("path").to_path_buf()          , path_buf!["path"              ]),
            (Path::new("path").join("to")             , path_buf!["path", "to"        ]),
            (Path::new("path").join("to").join("file"), path_buf!["path", "to", "file"]),
        ];
        for &(ref correct, ref calculated) in &paths {
            assert_eq!(correct, calculated);
        }
    }

    #[test]
    fn ls_should_return_ok() {
    }
    #[test]
    fn ls_should_return_err() {
    }

    #[test]
    fn is_empty_dir_should_return_true() {
    }
    #[test]
    fn is_empty_dir_should_return_false() {
    }

    #[test]
    fn walk_dir_should_return_b_tree_set() {
    }

    #[test]
    fn dirs_ordered_by_descending_depth_should_return_vec() {
    }
}
<|endoftext|>


<commit_before>use std::sync::{ONCE_INIT, Once};
use std::ffi::CStr;

use libc::c_char;
use log::LogLevel;

use raw;

/// Manually initialize logging.
///
/// It is optional to call this function, and safe to do so more than once.
pub fn init() {
    static mut INIT: Once = ONCE_INIT;

    unsafe {
        INIT.call_once(|| {
            raw::rs_trace_to(trace);
        });
    }
}

extern "C" fn trace(level: raw::rs_loglevel, msg: *const c_char) {
    let level = match level {
        raw::RS_LOG_EMERG | raw::RS_LOG_ALERT | raw::RS_LOG_CRIT | raw::RS_LOG_ERR => {
            LogLevel::Error
        }
        raw::RS_LOG_WARNING => LogLevel::Warn,
        raw::RS_LOG_NOTICE | raw::RS_LOG_INFO => LogLevel::Info,
        raw::RS_LOG_DEBUG => LogLevel::Debug,
        _ => LogLevel::Error,
    };
    let msg = unsafe { CStr::from_ptr(msg).to_string_lossy() };
    log!(target: "librsync", level, "{}", msg);
}
<commit_msg>Forward debug logs if the log level requires so<commit_after>use std::sync::{ONCE_INIT, Once};
use std::ffi::CStr;

use libc::c_char;
use log::{self, LogLevel, LogLevelFilter};

use raw;

/// Manually initialize logging.
///
/// It is optional to call this function, and safe to do so more than once.
pub fn init() {
    static mut INIT: Once = ONCE_INIT;

    unsafe {
        INIT.call_once(|| {
            // trace to our callback
            raw::rs_trace_to(trace);

            // determine log level
            // this is useful because if the setted level is not Debug we can optimize librsync log
            // calls
            let level = match log::max_log_level() {
                LogLevelFilter::Info => raw::RS_LOG_NOTICE,
                LogLevelFilter::Debug | LogLevelFilter::Trace => raw::RS_LOG_DEBUG,
                _ => raw::RS_LOG_WARNING,
            };
            raw::rs_trace_set_level(level);
        });
    }
}

extern "C" fn trace(level: raw::rs_loglevel, msg: *const c_char) {
    let level = match level {
        raw::RS_LOG_EMERG | raw::RS_LOG_ALERT | raw::RS_LOG_CRIT | raw::RS_LOG_ERR => {
            LogLevel::Error
        }
        raw::RS_LOG_WARNING => LogLevel::Warn,
        raw::RS_LOG_NOTICE | raw::RS_LOG_INFO => LogLevel::Info,
        raw::RS_LOG_DEBUG => LogLevel::Debug,
        _ => LogLevel::Error,
    };
    let msg = unsafe { CStr::from_ptr(msg).to_string_lossy() };
    log!(target: "librsync", level, "{}", msg);
}
<|endoftext|>


<commit_before>// Copyright (C) 2019 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::mem_drain::MemDrain;
use lazy_static::lazy_static;
use slog::{o, Drain, Logger};
use std::{
    boxed::Box,
    sync::{Arc, Mutex},
};

lazy_static! {
    static ref BUFFER: Arc<Mutex<MemDrain>> = Arc::new(Mutex::new(MemDrain::default()));
}

pub fn init(verbose: usize) {
    let level = match verbose {
        0 => slog::Level::Info,
        1 => slog::Level::Debug,
        _ => slog::Level::Trace,
    };

    let buffer_drain = buffer().filter_level(level).fuse();
    let terminal_drain = Mutex::new(slog_term::term_full().filter_level(level)).fuse();
    let terminal_drain = slog_async::Async::new(terminal_drain).build().fuse();

    let log = Logger::root(
        slog::Duplicate::new(buffer_drain, terminal_drain).fuse(),
        o!(),
    );
    let guard = slog_scope::set_global_logger(log);
    Box::leak(Box::new(guard));
}

pub fn buffer() -> Arc<Mutex<MemDrain>> {
    BUFFER.clone()
}
<commit_msg>logger: Add a FIXME note about the use of `Box::leak`<commit_after>// Copyright (C) 2019 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::mem_drain::MemDrain;
use lazy_static::lazy_static;
use slog::{o, Drain, Logger};
use std::{
    boxed::Box,
    sync::{Arc, Mutex},
};

lazy_static! {
    static ref BUFFER: Arc<Mutex<MemDrain>> = Arc::new(Mutex::new(MemDrain::default()));
}

pub fn init(verbose: usize) {
    let level = match verbose {
        0 => slog::Level::Info,
        1 => slog::Level::Debug,
        _ => slog::Level::Trace,
    };

    let buffer_drain = buffer().filter_level(level).fuse();
    let terminal_drain = Mutex::new(slog_term::term_full().filter_level(level)).fuse();
    let terminal_drain = slog_async::Async::new(terminal_drain).build().fuse();

    let log = Logger::root(
        slog::Duplicate::new(buffer_drain, terminal_drain).fuse(),
        o!(),
    );

    // FIXME: Drop the use of Box::leak here (issue #23).
    let guard = slog_scope::set_global_logger(log);
    Box::leak(Box::new(guard));
}

pub fn buffer() -> Arc<Mutex<MemDrain>> {
    BUFFER.clone()
}
<|endoftext|>


<commit_before>// De-duplication macro used in src/app.rs
macro_rules! get_help {
	($opt:ident) => {
		if let Some(h) = $opt.help {
	        format!("{}{}", h,
	            if let Some(ref pv) = $opt.possible_vals {
	                let mut pv_s = pv.iter().fold(String::with_capacity(50), |acc, name| acc + &format!(" {}",name)[..]);
	                pv_s.shrink_to_fit();
	                format!(" [values:{}]", &pv_s[..])
	            }else{"".to_owned()})
	    } else {
	        "    ".to_owned()
	    }
	};
}

// Thanks to bluss and flan3002 in #rust IRC
//
// Helps with rightward drift when iterating over something and matching each item.
macro_rules! for_match {
	($it:ident, $($p:pat => $($e:expr);+),*) => {
		for i in $it {
			match i {
			$(
			    $p => { $($e)+ }
			)*
			}
		}
	};
}<commit_msg>feat(macros): add convenience macro to get a typed value<commit_after>// De-duplication macro used in src/app.rs
macro_rules! get_help {
	($opt:ident) => {
		if let Some(h) = $opt.help {
	        format!("{}{}", h,
	            if let Some(ref pv) = $opt.possible_vals {
	                let mut pv_s = pv.iter().fold(String::with_capacity(50), |acc, name| acc + &format!(" {}",name)[..]);
	                pv_s.shrink_to_fit();
	                format!(" [values:{}]", &pv_s[..])
	            }else{"".to_owned()})
	    } else {
	        "    ".to_owned()
	    }
	};
}

// Thanks to bluss and flan3002 in #rust IRC
//
// Helps with rightward drift when iterating over something and matching each item.
macro_rules! for_match {
	($it:ident, $($p:pat => $($e:expr);+),*) => {
		for i in $it {
			match i {
			$(
			    $p => { $($e)+ }
			)*
			}
		}
	};
}

/// Convenience macro getting a typed value
#[macro_export]
macro_rules! value_t {
	($m:ident.value_of($v:expr), $t:ty) => {
		match $m.value_of($v) {
			Some(v) => {
				match v.parse::<$t>() {
					Ok(val) => Ok(val),
					Err(_)  => Err(format!("{} isn't a valid {}",v,stringify!($t))),
				}
			},
			None => Err(format!("Argument not found"))
		}
	};
}<|endoftext|>


<commit_before>/// Compose multiple state machines into single type
///
/// Composition requires two types: the state machine itself and Seed which
/// is used to create children state machines.
///
/// Mostly because of limitations of Rust macro system composition only works
/// on concrete context type.
///
/// # Example
/// ```ignore
/// rotor_compose!{
///     pub enum Fsm/Seed<Context> {
///         Http(HttpMachine)
///         Dns(DnsMachine)
///     }
/// }
/// ```
///
/// This creates a an `Fsm` state machine type which is enum with two options.
/// And `Seed` state machine type, which is also enum with same option names
/// but uses `<HttpMachine as rotor::Machine>::Seed` for the wrapped type.
#[macro_export]
macro_rules! rotor_compose {
    /* TODO(tailhook) make and check generic combinators
    (pub enum $name:ident { $($x:ident ($y:ty),)* }) => {
        pub enum $name { $($x ($y),)* }
        rotor_compose!(@machine $name C [] $($x($y),)*);
    };
    (enum $name:ident { $($x:ident ($y:ty),)* }) => {
        enum $name { $($x ($y),)* }
        rotor_compose!(@machine $name $($x($y),)*);
    };
    */
    (pub enum $name:ident/$cname:ident <$context_type:ident>
        { $($x:ident ($y:ty),)* })
    => {
        pub enum $name { $($x ($y),)* }
        rotor_compose!(@machine $name/$cname
            $context_type [] $($x($y),)*);
    };
    (enum $name:ident/$cname:ident <$context_type:ident>
        { $($x:ident ($y:ty),)* })
    => {
        enum $name { $($x ($y),)* }
        rotor_compose!(@machine $name/$cname
            $context_type [] $($x($y),)*);
    };
    (@machine $name:ident/$cname:ident $ctx_typ:ident
        [ $(<$ctx_name:ident $(: $ctx_bound:ident)*>)* ]
        $($iname:ident ($itype:ty),)*)
    => {
        enum $cname {
            $( $iname (<$itype as $crate::Machine>::Seed), )*
        }
        impl $( <$ctx_name:$ctx_bound> )* $crate::Machine for $name {
            type Context = $ctx_typ;
            type Seed = $cname;
            fn create(seed: $cname, scope: &mut $crate::Scope<$ctx_typ>)
                -> $crate::Response<Self, $crate::Void>
            {
                match seed {
                    $( $cname::$iname (x)
                        => $crate::Machine::create(x, scope)
                            .map($name::$iname, |x| unreachable(x)),
                    )*
                }
            }
            fn ready(self, events: $crate::EventSet,
                scope: &mut $crate::Scope<$ctx_typ>)
                -> $crate::Response<Self, Self::Seed>
            {
                match self {
                    $(
                        $name::$iname(m) => {
                            m.ready(events, scope)
                                .map($name::$iname, $cname::$iname)
                        }
                    )*
                }
            }
            fn spawned(self, scope: &mut $crate::Scope<$ctx_typ>)
                -> $crate::Response<Self, Self::Seed>
            {
                match self {
                    $(
                        $name::$iname(m) => {
                            m.spawned(scope)
                                .map($name::$iname, $cname::$iname)
                        }
                    )*
                }
            }
            fn timeout(self, scope: &mut $crate::Scope<$ctx_typ>)
                -> $crate::Response<Self, Self::Seed>
            {
                match self {
                    $(
                        $name::$iname(m) => {
                            m.timeout(scope)
                                .map($name::$iname, $cname::$iname)
                        }
                    )*
                }
            }
            fn wakeup(self, scope: &mut $crate::Scope<$ctx_typ>)
                -> $crate::Response<Self, Self::Seed>
            {
                match self {
                    $(
                        $name::$iname(m) => {
                            m.wakeup(scope)
                                .map($name::$iname, $cname::$iname)
                        }
                    )*
                }
            }
        }

    }
}
<commit_msg>Fix another namespacing issue in macro<commit_after>/// Compose multiple state machines into single type
///
/// Composition requires two types: the state machine itself and Seed which
/// is used to create children state machines.
///
/// Mostly because of limitations of Rust macro system composition only works
/// on concrete context type.
///
/// # Example
/// ```ignore
/// rotor_compose!{
///     pub enum Fsm/Seed<Context> {
///         Http(HttpMachine)
///         Dns(DnsMachine)
///     }
/// }
/// ```
///
/// This creates a an `Fsm` state machine type which is enum with two options.
/// And `Seed` state machine type, which is also enum with same option names
/// but uses `<HttpMachine as rotor::Machine>::Seed` for the wrapped type.
#[macro_export]
macro_rules! rotor_compose {
    /* TODO(tailhook) make and check generic combinators
    (pub enum $name:ident { $($x:ident ($y:ty),)* }) => {
        pub enum $name { $($x ($y),)* }
        rotor_compose!(@machine $name C [] $($x($y),)*);
    };
    (enum $name:ident { $($x:ident ($y:ty),)* }) => {
        enum $name { $($x ($y),)* }
        rotor_compose!(@machine $name $($x($y),)*);
    };
    */
    (pub enum $name:ident/$cname:ident <$context_type:ident>
        { $($x:ident ($y:ty),)* })
    => {
        pub enum $name { $($x ($y),)* }
        rotor_compose!(@machine $name/$cname
            $context_type [] $($x($y),)*);
    };
    (enum $name:ident/$cname:ident <$context_type:ident>
        { $($x:ident ($y:ty),)* })
    => {
        enum $name { $($x ($y),)* }
        rotor_compose!(@machine $name/$cname
            $context_type [] $($x($y),)*);
    };
    (@machine $name:ident/$cname:ident $ctx_typ:ident
        [ $(<$ctx_name:ident $(: $ctx_bound:ident)*>)* ]
        $($iname:ident ($itype:ty),)*)
    => {
        enum $cname {
            $( $iname (<$itype as $crate::Machine>::Seed), )*
        }
        impl $( <$ctx_name:$ctx_bound> )* $crate::Machine for $name {
            type Context = $ctx_typ;
            type Seed = $cname;
            fn create(seed: $cname, scope: &mut $crate::Scope<$ctx_typ>)
                -> $crate::Response<Self, $crate::Void>
            {
                match seed {
                    $( $cname::$iname (x)
                        => $crate::Machine::create(x, scope)
                            .map($name::$iname,
                                 |x| $crate::void::unreachable(x)),
                    )*
                }
            }
            fn ready(self, events: $crate::EventSet,
                scope: &mut $crate::Scope<$ctx_typ>)
                -> $crate::Response<Self, Self::Seed>
            {
                match self {
                    $(
                        $name::$iname(m) => {
                            m.ready(events, scope)
                                .map($name::$iname, $cname::$iname)
                        }
                    )*
                }
            }
            fn spawned(self, scope: &mut $crate::Scope<$ctx_typ>)
                -> $crate::Response<Self, Self::Seed>
            {
                match self {
                    $(
                        $name::$iname(m) => {
                            m.spawned(scope)
                                .map($name::$iname, $cname::$iname)
                        }
                    )*
                }
            }
            fn timeout(self, scope: &mut $crate::Scope<$ctx_typ>)
                -> $crate::Response<Self, Self::Seed>
            {
                match self {
                    $(
                        $name::$iname(m) => {
                            m.timeout(scope)
                                .map($name::$iname, $cname::$iname)
                        }
                    )*
                }
            }
            fn wakeup(self, scope: &mut $crate::Scope<$ctx_typ>)
                -> $crate::Response<Self, Self::Seed>
            {
                match self {
                    $(
                        $name::$iname(m) => {
                            m.wakeup(scope)
                                .map($name::$iname, $cname::$iname)
                        }
                    )*
                }
            }
        }

    }
}
<|endoftext|>


<commit_before>#[macro_export]
macro_rules! Q_OBJECT(
    (
        $t:ty :
            $(
                slot fn $name:ident ($($at:ty),*);
                signal fn $sname:ident ();
            )*
/*
            $(
                signal fn $sname:ident ( );
            )*
*/
    ) => (
/*
        impl $t {
            #[allow(dead_code, unused_mut, unused_variables, unused_assignments)]
            fn __qmlrs_signal_id(&self, name: &str) -> u32 {
                let mut id = 0;
                $(
                    if stringify!($sname) == name {
                        return id;
                    }
                    id += 1;
                )+
                panic!("__qmlrs_signal_id called with invalid signal name!");
            }

            $(
                #[allow(dead_code)]
                fn $sname (&self) {
                    qmlrs::__qobject_emit(self, self.__qmlrs_signal_id(stringify!($sname)));
                }
            )+
        }
*/
        impl qmlrs::Object for $t {
            #[allow(unused_mut, unused_variables)]
            fn qt_metaobject(&self) -> qmlrs::MetaObject {
                let x = qmlrs::MetaObject::new();
/*
                $(
                    let x = x.signal(stringify!($sname), 0);
                )+
*/
                $(
                    let mut argc = 0;
                    $(
                        let _: $at;
                        argc += 1;
                    )*
                    let x = x.slot(stringify!($name), argc);
                )+
                x
            }

            #[allow(unused_assignments, unused_mut, unused_variables)]
            fn qt_metacall(&mut self, slot: i32, args: *const *const qmlrs::OpaqueQVariant) {
                use qmlrs::ToQVariant;
                let mut i = 0;
/*
                $(
                    let _ = stringify!($sname);
                    i += 1;
                )+
*/
                $(
                    if i == slot {
                        let mut argi = 1u8; /* 0 is for return value */
                        let ret = self.$name(
                            $(
                                {
                                    let _: $at;
                                    match qmlrs::FromQVariant::from_qvariant(unsafe { *args.offset(argi as isize) }) {
                                        Some(arg) => { argi += 1; arg }
                                        None      => {
                                            println!("qmlrs: Invalid argument {} type for slot {}", argi, stringify!($name));
                                            return;
                                        }
                                    }
                                }
                            ),*
                        );
                        ret.to_qvariant(unsafe { *args.offset(0) as *mut qmlrs::OpaqueQVariant });
                        return
                    }
                    i += 1;
                )+
            }
        }
    )
);
<commit_msg>update<commit_after>#[macro_export]
macro_rules! Q_OBJECT(
    (
        $t:ty :
            $(
                slot fn $name:ident ($($at:ty),*);
            )*,
            $(
                signal fn $sname:ident ( );
            )*
    ) => (
/*
        impl $t {
            #[allow(dead_code, unused_mut, unused_variables, unused_assignments)]
            fn __qmlrs_signal_id(&self, name: &str) -> u32 {
                let mut id = 0;
                $(
                    if stringify!($sname) == name {
                        return id;
                    }
                    id += 1;
                )+
                panic!("__qmlrs_signal_id called with invalid signal name!");
            }

            $(
                #[allow(dead_code)]
                fn $sname (&self) {
                    qmlrs::__qobject_emit(self, self.__qmlrs_signal_id(stringify!($sname)));
                }
            )+
        }
*/
        impl qmlrs::Object for $t {
            #[allow(unused_mut, unused_variables)]
            fn qt_metaobject(&self) -> qmlrs::MetaObject {
                let x = qmlrs::MetaObject::new();
/*
                $(
                    let x = x.signal(stringify!($sname), 0);
                )+
*/
                $(
                    let mut argc = 0;
                    $(
                        let _: $at;
                        argc += 1;
                    )*
                    let x = x.slot(stringify!($name), argc);
                )+
                x
            }

            #[allow(unused_assignments, unused_mut, unused_variables)]
            fn qt_metacall(&mut self, slot: i32, args: *const *const qmlrs::OpaqueQVariant) {
                use qmlrs::ToQVariant;
                let mut i = 0;
/*
                $(
                    let _ = stringify!($sname);
                    i += 1;
                )+
*/
                $(
                    if i == slot {
                        let mut argi = 1u8; /* 0 is for return value */
                        let ret = self.$name(
                            $(
                                {
                                    let _: $at;
                                    match qmlrs::FromQVariant::from_qvariant(unsafe { *args.offset(argi as isize) }) {
                                        Some(arg) => { argi += 1; arg }
                                        None      => {
                                            println!("qmlrs: Invalid argument {} type for slot {}", argi, stringify!($name));
                                            return;
                                        }
                                    }
                                }
                            ),*
                        );
                        ret.to_qvariant(unsafe { *args.offset(0) as *mut qmlrs::OpaqueQVariant });
                        return
                    }
                    i += 1;
                )+
            }
        }
    )
);
<|endoftext|>


<commit_before>// Bitcoin secp256k1 bindings
// Written in 2014 by
//   Dawid Ciężarkiewicz
//   Andrew Poelstra
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//

// This is a macro that routinely comes in handy
macro_rules! impl_array_newtype {
    ($thing:ident, $ty:ty, $len:expr) => {
        impl Copy for $thing {}

        impl $thing {
            #[inline]
            /// Converts the object to a raw pointer for FFI interfacing
            pub fn as_ptr(&self) -> *const $ty {
                let &$thing(ref dat) = self;
                dat.as_ptr()
            }

            #[inline]
            /// Converts the object to a mutable raw pointer for FFI interfacing
            pub fn as_mut_ptr(&mut self) -> *mut $ty {
                let &mut $thing(ref mut dat) = self;
                dat.as_mut_ptr()
            }

            #[inline]
            /// Returns the length of the object as an array
            pub fn len(&self) -> usize { $len }
        }

        impl PartialEq for $thing {
            #[inline]
            fn eq(&self, other: &$thing) -> bool {
                &self[..] == &other[..]
            }
        }

        impl Eq for $thing {}

        impl Clone for $thing {
            #[inline]
            fn clone(&self) -> $thing {
                unsafe {
                    use std::intrinsics::copy_nonoverlapping;
                    use std::mem;
                    let mut ret: $thing = mem::uninitialized();
                    copy_nonoverlapping(self.as_ptr(),
                                        ret.as_mut_ptr(),
                                        mem::size_of::<$thing>());
                    ret
                }
            }
        }

        impl ::std::ops::Index<usize> for $thing {
            type Output = $ty;

            #[inline]
            fn index(&self, index: usize) -> &$ty {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::std::ops::Index<::std::ops::Range<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::std::ops::Range<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::std::ops::Index<::std::ops::RangeTo<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::std::ops::RangeTo<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::std::ops::Index<::std::ops::RangeFrom<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::std::ops::RangeFrom<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::std::ops::Index<::std::ops::RangeFull> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, _: ::std::ops::RangeFull) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[..]
            }
        }

        impl ::serialize::Decodable for $thing {
            fn decode<D: ::serialize::Decoder>(d: &mut D) -> Result<$thing, D::Error> {
                use serialize::Decodable;

                d.read_seq(|d, len| {
                    if len != $len {
                        Err(d.error("Invalid length"))
                    } else {
                        unsafe {
                            use std::mem;
                            let mut ret: [$ty; $len] = mem::uninitialized();
                            for i in 0..len {
                                ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d)));
                            }
                            Ok($thing(ret))
                        }
                    }
                })
            }
        }

        impl ::serialize::Encodable for $thing {
            fn encode<S: ::serialize::Encoder>(&self, s: &mut S)
                                               -> Result<(), S::Error> {
                self[..].encode(s)
            }
        }

        impl ::serde::Deserialize for $thing {
            fn deserialize<D>(d: &mut D) -> Result<$thing, D::Error>
                where D: ::serde::Deserializer
            {
                // We have to define the Visitor struct inside the function
                // to make it local ... all we really need is that it's
                // local to the macro, but this works too :)
                struct Visitor {
                    marker: ::std::marker::PhantomData<$thing>,
                }
                impl ::serde::de::Visitor for Visitor {
                    type Value = $thing;

                    #[inline]
                    fn visit_seq<V>(&mut self, mut v: V) -> Result<$thing, V::Error>
                        where V: ::serde::de::SeqVisitor
                    {
                        unsafe {
                            use std::mem;
                            let mut ret: [$ty; $len] = mem::uninitialized();
                            for i in 0..$len {
                                ret[i] = match try!(v.visit()) {
                                    Some(c) => c,
                                    None => return Err(::serde::de::Error::end_of_stream())
                                };
                            }
                            try!(v.end());
                            Ok($thing(ret))
                        }
                    }
                }

                // Begin actual function
                d.visit(Visitor { marker: ::std::marker::PhantomData })
            }
        }

        impl ::serde::Serialize for $thing {
            fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
                where S: ::serde::Serializer
            {
                (&self.0[..]).serialize(s)
            }
        }
    }
}

macro_rules! impl_pretty_debug {
    ($thing:ident) => {
        impl ::std::fmt::Debug for $thing {
            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                try!(write!(f, "{}(", stringify!($thing)));
                for i in self[..].iter().cloned() {
                    try!(write!(f, "{:02x}", i));
                }
                write!(f, ")")
            }
        }
     }
}

macro_rules! impl_raw_debug {
    ($thing:ident) => {
        impl ::std::fmt::Debug for $thing {
            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                for i in self[..].iter().cloned() {
                    try!(write!(f, "{:02x}", i));
                }
                Ok(())
            }
        }
     }
}

// for testing
macro_rules! hex_slice {
  ($s:expr) => (
    &$s.from_hex().unwrap()[..]
  )
}

<commit_msg>Remove `hex_slice` macro as it was never used<commit_after>// Bitcoin secp256k1 bindings
// Written in 2014 by
//   Dawid Ciężarkiewicz
//   Andrew Poelstra
//
// To the extent possible under law, the author(s) have dedicated all
// copyright and related and neighboring rights to this software to
// the public domain worldwide. This software is distributed without
// any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication
// along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
//

// This is a macro that routinely comes in handy
macro_rules! impl_array_newtype {
    ($thing:ident, $ty:ty, $len:expr) => {
        impl Copy for $thing {}

        impl $thing {
            #[inline]
            /// Converts the object to a raw pointer for FFI interfacing
            pub fn as_ptr(&self) -> *const $ty {
                let &$thing(ref dat) = self;
                dat.as_ptr()
            }

            #[inline]
            /// Converts the object to a mutable raw pointer for FFI interfacing
            pub fn as_mut_ptr(&mut self) -> *mut $ty {
                let &mut $thing(ref mut dat) = self;
                dat.as_mut_ptr()
            }

            #[inline]
            /// Returns the length of the object as an array
            pub fn len(&self) -> usize { $len }
        }

        impl PartialEq for $thing {
            #[inline]
            fn eq(&self, other: &$thing) -> bool {
                &self[..] == &other[..]
            }
        }

        impl Eq for $thing {}

        impl Clone for $thing {
            #[inline]
            fn clone(&self) -> $thing {
                unsafe {
                    use std::intrinsics::copy_nonoverlapping;
                    use std::mem;
                    let mut ret: $thing = mem::uninitialized();
                    copy_nonoverlapping(self.as_ptr(),
                                        ret.as_mut_ptr(),
                                        mem::size_of::<$thing>());
                    ret
                }
            }
        }

        impl ::std::ops::Index<usize> for $thing {
            type Output = $ty;

            #[inline]
            fn index(&self, index: usize) -> &$ty {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::std::ops::Index<::std::ops::Range<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::std::ops::Range<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::std::ops::Index<::std::ops::RangeTo<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::std::ops::RangeTo<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::std::ops::Index<::std::ops::RangeFrom<usize>> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, index: ::std::ops::RangeFrom<usize>) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[index]
            }
        }

        impl ::std::ops::Index<::std::ops::RangeFull> for $thing {
            type Output = [$ty];

            #[inline]
            fn index(&self, _: ::std::ops::RangeFull) -> &[$ty] {
                let &$thing(ref dat) = self;
                &dat[..]
            }
        }

        impl ::serialize::Decodable for $thing {
            fn decode<D: ::serialize::Decoder>(d: &mut D) -> Result<$thing, D::Error> {
                use serialize::Decodable;

                d.read_seq(|d, len| {
                    if len != $len {
                        Err(d.error("Invalid length"))
                    } else {
                        unsafe {
                            use std::mem;
                            let mut ret: [$ty; $len] = mem::uninitialized();
                            for i in 0..len {
                                ret[i] = try!(d.read_seq_elt(i, |d| Decodable::decode(d)));
                            }
                            Ok($thing(ret))
                        }
                    }
                })
            }
        }

        impl ::serialize::Encodable for $thing {
            fn encode<S: ::serialize::Encoder>(&self, s: &mut S)
                                               -> Result<(), S::Error> {
                self[..].encode(s)
            }
        }

        impl ::serde::Deserialize for $thing {
            fn deserialize<D>(d: &mut D) -> Result<$thing, D::Error>
                where D: ::serde::Deserializer
            {
                // We have to define the Visitor struct inside the function
                // to make it local ... all we really need is that it's
                // local to the macro, but this works too :)
                struct Visitor {
                    marker: ::std::marker::PhantomData<$thing>,
                }
                impl ::serde::de::Visitor for Visitor {
                    type Value = $thing;

                    #[inline]
                    fn visit_seq<V>(&mut self, mut v: V) -> Result<$thing, V::Error>
                        where V: ::serde::de::SeqVisitor
                    {
                        unsafe {
                            use std::mem;
                            let mut ret: [$ty; $len] = mem::uninitialized();
                            for i in 0..$len {
                                ret[i] = match try!(v.visit()) {
                                    Some(c) => c,
                                    None => return Err(::serde::de::Error::end_of_stream())
                                };
                            }
                            try!(v.end());
                            Ok($thing(ret))
                        }
                    }
                }

                // Begin actual function
                d.visit(Visitor { marker: ::std::marker::PhantomData })
            }
        }

        impl ::serde::Serialize for $thing {
            fn serialize<S>(&self, s: &mut S) -> Result<(), S::Error>
                where S: ::serde::Serializer
            {
                (&self.0[..]).serialize(s)
            }
        }
    }
}

macro_rules! impl_pretty_debug {
    ($thing:ident) => {
        impl ::std::fmt::Debug for $thing {
            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                try!(write!(f, "{}(", stringify!($thing)));
                for i in self[..].iter().cloned() {
                    try!(write!(f, "{:02x}", i));
                }
                write!(f, ")")
            }
        }
     }
}

macro_rules! impl_raw_debug {
    ($thing:ident) => {
        impl ::std::fmt::Debug for $thing {
            fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
                for i in self[..].iter().cloned() {
                    try!(write!(f, "{:02x}", i));
                }
                Ok(())
            }
        }
     }
}

<|endoftext|>


<commit_before>/// Errors related to matrix operations
#[deriving(Show)]
pub enum MatErr{
    //EmptyMatrix,
    DimensionsMismatch,
}
<commit_msg>empty matrix error<commit_after>/// Errors related to matrix operations
#[deriving(Show)]
pub enum MatErr{
    EmptyMatrix,
    DimensionsMismatch,
}
<|endoftext|>


<commit_before>use std::error::Error;

use {Ident, Value};

#[deriving(PartialEq, Show)]
/// Possible errors encountered when parsing EDN.
pub enum ParserError {
    /// The parser reached the end of the input unexpectedly.
    Eof
}

impl Error for ParserError {
    fn description(&self) -> &str { "EDN parser error" }
}

pub type ParserResult = Result<Value, ParserError>;

pub struct Parser<T: Iterator<char>> {
    inp: T,
    ch: Option<char>
}

impl<T: Iterator<char>> Parser<T> {
    pub fn new(mut inp: T) -> Parser<T> {
        let ch = inp.next();
        Parser {
            inp: inp,
            ch: ch
        }
    }

    fn is_eof(&self) -> bool {
        self.ch.is_none()
    }

    fn bump(&mut self) {
        self.ch = self.inp.next()
    }

    fn consume_ws(&mut self) {
        while self.at_whitespace() {
            self.bump();
        }
    }

    fn at_whitespace(&self) -> bool {
        // The EDN "spec" is very vague about what constitutes whitespace, but
        // tools.reader.edn uses Java's Character.isWhitespace method which has
        // identical semantics to Rust's char::is_whitespace method (*cough*
        // hopefully).
        // FIXME: verify that ^^^
        if self.is_eof() { return false }
        let ch = self.ch.unwrap();
        ch.is_whitespace() || ch == ','
    }

    fn at_symbol(&self) -> bool {
        if let Some(ch) = self.ch {
            is_ident_start_ch(ch)
        } else {
            false
        }
    }

    fn at_keyword(&self) -> bool {
        if let Some(':') = self.ch { true } else { false }
    }

    fn parse_ident(&mut self) -> Result<Ident, ParserError> {
        if self.is_eof() { return Err(ParserError::Eof) }
        let mut ident = String::with_capacity(16);
        loop {
            if self.is_eof() { break; }
            let ch = self.ch.unwrap();
            if !is_ident_ch(ch) { break; }
            ident.push(self.ch.unwrap());
            self.bump();
        }
        // FIXME: handle prefixed idents
        Ok(Ident::simple(ident))
    }

    fn parse_symbol(&mut self) -> ParserResult {
        let ident = try!(self.parse_ident());
        if ident.prefix.is_none() {
            Ok(match &*ident.name {
                "nil" => Value::Nil,
                "true" => Value::Bool(true),
                "false" => Value::Bool(false),
                _ => Value::Symbol(ident)
            })
        } else {
            Ok(Value::Symbol(ident))
        }
    }

    fn parse_keyword(&mut self) -> ParserResult {
        self.bump();
        Ok(Value::Keyword(try!(self.parse_ident())))
    }

    pub fn parse_value(&mut self) -> ParserResult {
        self.consume_ws();

        if self.is_eof() { return Err(ParserError::Eof) }
        if self.at_symbol() { return self.parse_symbol() }
        if self.at_keyword() { return self.parse_keyword() }

        unimplemented!()
    }
}

fn is_ident_start_ch(ch: char) -> bool {
    match ch {
        'a'...'z' | 'A'...'Z' => true,
        '*' | '!' | '_' | '?' | '$' | '%' | '&' | '=' | '<' | '>' => true,
        '-' | '+' | '.' => true, // can also start a number literal, watch out!
        _ => false
    }
}

fn is_ident_ch(ch: char) -> bool {
    is_ident_start_ch(ch) || ch == ':' || ch == '#' || (ch >= '0' && ch <= '9')
}

#[cfg(test)]
mod test {
    use {Ident, Value};
    use super::*;

    macro_rules! assert_val {
        ($str:expr, $val:expr) => ({
            let inp = $str.into_string();
            let mut parser = Parser::new(inp.chars());
            assert_eq!(parser.parse_value(), Ok($val))
        })
    }

    macro_rules! assert_err {
        ($str:expr, $val:expr) => ({
            let inp = $str.into_string();
            let mut parser = Parser::new(inp.chars());
            assert_eq!(parser.parse_value(), Err($val))
        })
    }

    #[test]
    fn test_parse_eof() {
        assert_err!("", ParserError::Eof);
        assert_err!("    ", ParserError::Eof);
        assert_err!(",", ParserError::Eof);
    }

    #[test]
    fn test_parse_nil() {
        assert_val!("nil", Value::Nil);
        assert_val!("nil ", Value::Nil);
    }

    #[test]
    fn test_parse_bool() {
        assert_val!("true", Value::Bool(true));
        assert_val!("false", Value::Bool(false));
        assert_val!("false,", Value::Bool(false));
    }

    #[test]
    fn test_parse_symbol() {
        assert_val!("foo", Value::Symbol(Ident::simple("foo")));
        assert_val!("foo#", Value::Symbol(Ident::simple("foo#")));
        assert_val!("foo9", Value::Symbol(Ident::simple("foo9")));
        assert_val!("-foo", Value::Symbol(Ident::simple("-foo")));
        // assert_val!("ᛰ", Value::Symbol(Ident::simple("ᛰ")));
    }

    #[test]
    fn test_parse_keyword() {
        assert_val!(":foo", Value::Keyword(Ident::simple("foo")));
    }
}
<commit_msg>Parse keywords more robustly<commit_after>use std::error::Error;

use {Ident, Value};

#[deriving(PartialEq, Show)]
/// Possible errors encountered when parsing EDN.
pub enum ParserError {
    /// The parser reached the end of the input unexpectedly.
    Eof,
    /// The parser found a token invalid for this position.
    InvalidToken(char)
}

impl Error for ParserError {
    fn description(&self) -> &str { "EDN parser error" }
}

pub type ParserResult = Result<Value, ParserError>;

pub struct Parser<T: Iterator<char>> {
    inp: T,
    ch: Option<char>
}

impl<T: Iterator<char>> Parser<T> {
    pub fn new(mut inp: T) -> Parser<T> {
        let ch = inp.next();
        Parser {
            inp: inp,
            ch: ch
        }
    }

    fn is_eof(&self) -> bool {
        self.ch.is_none()
    }

    fn bump(&mut self) {
        self.ch = self.inp.next()
    }

    fn consume_ws(&mut self) {
        while self.at_whitespace() {
            self.bump();
        }
    }

    fn at_whitespace(&self) -> bool {
        // The EDN "spec" is very vague about what constitutes whitespace, but
        // tools.reader.edn uses Java's Character.isWhitespace method which has
        // identical semantics to Rust's char::is_whitespace method (*cough*
        // hopefully).
        // FIXME: verify that ^^^
        if self.is_eof() { return false }
        let ch = self.ch.unwrap();
        ch.is_whitespace() || ch == ','
    }

    fn at_symbol(&self) -> bool {
        if let Some(ch) = self.ch {
            is_ident_start_ch(ch)
        } else {
            false
        }
    }

    fn at_keyword(&self) -> bool {
        if let Some(':') = self.ch { true } else { false }
    }

    fn parse_ident(&mut self) -> Result<Ident, ParserError> {
        if self.is_eof() { return Err(ParserError::Eof) }
        let mut ident = String::with_capacity(16);
        let ch = self.ch.unwrap();
        // It's important that parse_symbol maintains the symbol starting character
        // restrictions itself, because parse_ident is also needed for parsing
        // keywords (which don't have those restrictions).
        if !is_ident_ch(ch) { return Err(ParserError::InvalidToken(ch)) }

        loop {
            if self.is_eof() { break; }
            let ch = self.ch.unwrap();
            if !is_ident_ch(ch) { break; }
            ident.push(self.ch.unwrap());
            self.bump();
        }
        // FIXME: handle prefixed idents
        Ok(Ident::simple(ident))
    }

    fn parse_symbol(&mut self) -> ParserResult {
        let ident = try!(self.parse_ident());
        if ident.prefix.is_none() {
            Ok(match &*ident.name {
                "nil" => Value::Nil,
                "true" => Value::Bool(true),
                "false" => Value::Bool(false),
                _ => Value::Symbol(ident)
            })
        } else {
            Ok(Value::Symbol(ident))
        }
    }

    fn parse_keyword(&mut self) -> ParserResult {
        self.bump();
        Ok(Value::Keyword(try!(self.parse_ident())))
    }

    pub fn parse_value(&mut self) -> ParserResult {
        self.consume_ws();

        if self.is_eof() { return Err(ParserError::Eof) }
        if self.at_symbol() { return self.parse_symbol() }
        if self.at_keyword() { return self.parse_keyword() }

        unimplemented!()
    }
}

fn is_ident_start_ch(ch: char) -> bool {
    match ch {
        'a'...'z' | 'A'...'Z' => true,
        '*' | '!' | '_' | '?' | '$' | '%' | '&' | '=' | '<' | '>' => true,
        '-' | '+' | '.' => true, // can also start a number literal, watch out!
        _ => false
    }
}

fn is_ident_ch(ch: char) -> bool {
    is_ident_start_ch(ch) || ch == ':' || ch == '#' || (ch >= '0' && ch <= '9')
}

#[cfg(test)]
mod test {
    use {Ident, Value};
    use super::*;

    macro_rules! assert_val {
        ($str:expr, $val:expr) => ({
            let inp = $str.into_string();
            let mut parser = Parser::new(inp.chars());
            assert_eq!(parser.parse_value(), Ok($val))
        })
    }

    macro_rules! assert_err {
        ($str:expr) => ({
            let inp = $str.into_string();
            let mut parser = Parser::new(inp.chars());
            assert!(parser.parse_value().is_err())
        });
        ($str:expr, $val:expr) => ({
            let inp = $str.into_string();
            let mut parser = Parser::new(inp.chars());
            assert_eq!(parser.parse_value(), Err($val))
        })
    }

    #[test]
    fn test_parse_eof() {
        assert_err!("", ParserError::Eof);
        assert_err!("    ", ParserError::Eof);
        assert_err!(",", ParserError::Eof);
    }

    #[test]
    fn test_parse_nil() {
        assert_val!("nil", Value::Nil);
        assert_val!("nil ", Value::Nil);
    }

    #[test]
    fn test_parse_bool() {
        assert_val!("true", Value::Bool(true));
        assert_val!("false", Value::Bool(false));
        assert_val!("false,", Value::Bool(false));
    }

    #[test]
    fn test_parse_symbol() {
        assert_val!("foo", Value::Symbol(Ident::simple("foo")));
        assert_val!("foo#", Value::Symbol(Ident::simple("foo#")));
        assert_val!("foo9", Value::Symbol(Ident::simple("foo9")));
        assert_val!("-foo", Value::Symbol(Ident::simple("-foo")));
        // tools.reader.edn parses this as a symbol
        // assert_val!("ᛰ", Value::Symbol(Ident::simple("ᛰ")));
    }

    #[test]
    fn test_parse_keyword() {
        assert_err!(":", ParserError::Eof);
        assert_err!(": foo", ParserError::InvalidToken(' '));
        assert_val!(":foo", Value::Keyword(Ident::simple("foo")));
        assert_val!(":-foo", Value::Keyword(Ident::simple("-foo")));
        assert_val!(":1234", Value::Keyword(Ident::simple("1234")));
        assert_val!(":12aaa", Value::Keyword(Ident::simple("12aaa")));
    }
}
<|endoftext|>