<commit_before>#[macro_use]
extern crate nom;

use std::str;

pub mod terminal {
    pub mod pn;
    pub mod literal;
    pub mod primitive;
}
use terminal::pn;
use terminal::primitive;

#[derive(PartialEq, Debug)]
pub enum Plx<'a> {
    Percent(&'a str),
    PnLocalEsc(&'a str),
}
/* [169s] PLX */
named!(pub plx<&str, Plx>, alt!(
    map!(primitive::percent, Plx::Percent   ) |
    map!(pn::pn_local_esc  , Plx::PnLocalEsc)
));

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

    #[test]
    fn plx_test() {
        assert_eq!(plx("%2Arest"), IResult::Done("rest", Plx::Percent("2A")));
        assert_eq!(plx("\\.rest"), IResult::Done("rest", Plx::PnLocalEsc("\\.")));
    }
}
<commit_msg>Add test for pest<commit_after>#[macro_use]
extern crate pest;
#[macro_use]
extern crate pest_derive;

#[cfg(debug_assertions)]
const _GRAMMER: &'static str = include_str!("grammer.pest");

#[derive(Parser)]
#[grammar = "grammer.pest"]
struct TurtleParser;

#[test]
fn iri_test() {
    parses_to! {
        parser: TurtleParser,
        input: "<http://www.example.com>",
        rule: Rule::iri,
        tokens: [
            iri(0, 24, [
                iriref(0, 24)
            ])
        ]
    };

    parses_to! {
        parser: TurtleParser,
        input: "foaf:Person",
        rule: Rule::iri,
        tokens: [
            iri(0, 11, [
                prefixed_name(0, 11, [
                    pname_ln(0, 11)
                ])
            ])
        ]
    };
}

#[test]
fn prefixd_name_test() {
    parses_to! {
        parser: TurtleParser,
        input: "foaf:",
        rule: Rule::prefixed_name,
        tokens: [
            prefixed_name(0, 5, [
                pname_ns(0, 5)
            ])
        ]
    };

    parses_to! {
        parser: TurtleParser,
        input: "foaf:Person",
        rule: Rule::prefixed_name,
        tokens: [
            prefixed_name(0, 11, [
                pname_ln(0, 11)
            ])
        ]
    };
}

#[test]
fn blank_node_test() {
    parses_to! {
        parser: TurtleParser,
        input: "_:blank",
        rule: Rule::blank_node,
        tokens: [
            blank_node(0, 7, [
                blank_node_label(0, 7)
            ])
        ]
    };

    parses_to! {
        parser: TurtleParser,
        input: "[     ]",
        rule: Rule::blank_node,
        tokens: [
            blank_node(0, 7, [
                anon(0, 7)
            ])
        ]
    };
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Yusuke Sasaki
//
// This software is released under the MIT License.
// See http://opensource.org/licenses/mit-license.php or <LICENSE>.

//! A crate which provides low-level Rust API of Gurobi Optimizer.
//!
//! This crate provides wrappers of the Gurobi solver which supports some
//! types of mathematical programming problems (e.g. Linear programming; LP,
//! Mixed Integer Linear Programming; MILP, and so on).
//!
//! ## Installation
//! Before using this crate, you should install Gurobi and obtain a license.
//! The instruction can be found
//! [here](http://www.gurobi.com/downloads/licenses/license-center).
//!
//! ## Examples
//!
//! ```
//! extern crate gurobi;
//! use gurobi::*;
//!
//! fn main() {
//!   let env = Env::new("logfile.log").unwrap();
//!
//!   // create an empty model which associated with `env`:
//!   let mut model = env.new_model("model1").unwrap();
//!
//!   // add decision variables.
//!   let x = model.add_var("x", Binary).unwrap();
//!   let y = model.add_var("y", Continuous(-10.0, 10.0)).unwrap();
//!   let z = model.add_var("z", Continuous(-INFINITY, INFINITY)).unwrap();
//!
//!   // integrate all the variables into the model.
//!   model.update().unwrap();
//!
//!   // add a linear constraint
//!   model.add_constr("c0", &x - &y + 2.0 * &z, Equal, 0.0).unwrap();
//!   // ...
//!
//!   model.set_objective(&x, Maximize).unwrap();
//!
//!   // optimize the model.
//!   model.optimize().unwrap();
//!   assert_eq!(model.status().unwrap(), Status::Optimal);
//!
//!   assert_eq!(model.get(attr::ObjVal).unwrap() , 0.0);
//!
//!   let val = model.get_values(attr::X, &[x, y, z]).unwrap();
//!   assert_eq!(val, [0.0, -10.0, -5.0]);
//! }
//! ```

extern crate gurobi_sys as ffi;
extern crate itertools;

mod env;
mod model;
mod error;
mod util;

// re-exports
pub use env::{param, Env};
pub use model::{attr, Model, Var, Constr, QConstr, SOS, LinExpr, QuadExpr, Proxy};

pub use model::{VarType, ConstrSense, ModelSense, SOSType, Status, RelaxType};
pub use model::VarType::*;
pub use model::ConstrSense::*;
pub use model::ModelSense::*;
pub use model::SOSType::*;
pub use model::RelaxType::*;

pub use error::{Error, Result};

/// Large number used in C API
pub const INFINITY: f64 = 1e100;
<commit_msg>add notices into documentation<commit_after>// Copyright (c) 2016 Yusuke Sasaki
//
// This software is released under the MIT License.
// See http://opensource.org/licenses/mit-license.php or <LICENSE>.

//! This crate provides primitive Rust APIs for Gurobi Optimizer.
//!
//! It supports some types of mathematical programming problems (e.g. Linear programming; LP,
//! Mixed Integer Linear Programming; MILP, and so on).
//!
//! ## Notices
//!
//! * Before using this crate, you should install Gurobi and obtain a license.
//!   The instruction can be found
//!   [here](http://www.gurobi.com/downloads/licenses/license-center).
//!
//! * Make sure that the environment variable `GUROBI_HOME` is set to the installation path of Gurobi
//!   (like `C:\gurobi652\win64`, `/opt/gurobi652/linux64`).
//!
//! * On Windows, the toolchain should be MSVC ABI (it also requires Visual Studio or
//!   Visual C++ Build Tools).
//!   If you want to use GNU ABI with MinGW-w64/MSYS2 toolchain, you should create the import
//!   library for Gurobi runtime DLL (e.g. `gurobi65.dll`) and put it into `GUROBI_HOME/lib`.
//!   Procedure of creating import library is as follows:
//!
//!   ```shell-session
//!   $ pacman -S mingw-w64-x86_64-tools-git
//!   $ gendef - $(cygpath $GUROBI_HOME)/bin/gurobi65.dll > gurobi65.def
//!   $ dlltool --dllname gurobi65.dll --def gurobi65.def --output-lib $(cygpath $GUROBI}HOME)/lib/libgurobi65.dll.a
//!   ```
//!
//! ## Examples
//!
//! ```
//! extern crate gurobi;
//! use gurobi::*;
//!
//! fn main() {
//!   let env = Env::new("logfile.log").unwrap();
//!
//!   // create an empty model which associated with `env`:
//!   let mut model = env.new_model("model1").unwrap();
//!
//!   // add decision variables.
//!   let x = model.add_var("x", Binary).unwrap();
//!   let y = model.add_var("y", Continuous(-10.0, 10.0)).unwrap();
//!   let z = model.add_var("z", Continuous(-INFINITY, INFINITY)).unwrap();
//!
//!   // integrate all the variables into the model.
//!   model.update().unwrap();
//!
//!   // add a linear constraint
//!   model.add_constr("c0", &x - &y + 2.0 * &z, Equal, 0.0).unwrap();
//!   // ...
//!
//!   model.set_objective(&x, Maximize).unwrap();
//!
//!   // optimize the model.
//!   model.optimize().unwrap();
//!   assert_eq!(model.status().unwrap(), Status::Optimal);
//!
//!   assert_eq!(model.get(attr::ObjVal).unwrap() , 0.0);
//!
//!   let val = model.get_values(attr::X, &[x, y, z]).unwrap();
//!   assert_eq!(val, [0.0, -10.0, -5.0]);
//! }
//! ```

extern crate gurobi_sys as ffi;
extern crate itertools;

mod env;
mod model;
mod error;
mod util;

// re-exports
pub use env::{param, Env};
pub use model::{attr, Model, Var, Constr, QConstr, SOS, LinExpr, QuadExpr, Proxy};

pub use model::{VarType, ConstrSense, ModelSense, SOSType, Status, RelaxType};
pub use model::VarType::*;
pub use model::ConstrSense::*;
pub use model::ModelSense::*;
pub use model::SOSType::*;
pub use model::RelaxType::*;

pub use error::{Error, Result};

/// Large number used in C API
pub const INFINITY: f64 = 1e100;
<|endoftext|>


<commit_before>/// Calculate the crc64 checksum of the given data, starting with the given crc.
///
/// Implements the CRC64 used by Redis, which is the variant with "Jones" coefficients and init value of 0.
///
/// Specification of this CRC64 variant follows:
///
/// ```text
/// Name: crc-64-jones
/// Width: 64 bites
/// Poly: 0xad93d23594c935a9
/// Reflected In: True
/// Xor_In: 0xffffffffffffffff
/// Reflected_Out: True
/// Xor_Out: 0x0
/// Check("123456789"): 0xe9c6d914c4b8d9ca
/// ```
///
/// Example:
///
/// ```rust
/// crc64::crc64(0, "123456789".as_bytes());
/// ```

use std::io;
use std::io::Write;
use std::mem;
use crc_table::CRC64_TAB;
mod crc_table;

fn crc_reflect(data: u64, len: usize) -> u64 {
    let mut data = data;
    let mut ret = data & 0x01;

    let mut i = 1usize;
    while i < len {
        data >>= 1;
        ret = (ret << 1) | (data & 0x01);
        i+=1;
    }

    ret
}

fn crc64_trivial(crc: u64, in_data: &[u8]) -> u64 {
    let mut crc = crc;
    let len = in_data.len();

    let poly : u64 = 0xad93d23594c935a9;

    let mut bit : bool;

    let mut offset = 0usize;

    while offset < len {
        let c = in_data[offset];
        let mut i = 0x01;
        while i & 0xff != 0x0 {
            bit = crc & 0x8000000000000000 != 0x0;
            if c & i != 0x0 {
                bit = !bit;
            }
            crc <<= 1;
            if bit {
                crc ^= poly;
            }
            i <<= 1;
        }
        crc &= 0xffffffffffffffff;
        offset+=1;
    }
    crc = crc & 0xffffffffffffffff;

    return crc_reflect(crc, 64) ^ 0x0000000000000000;
}

pub fn crc64_init() -> Vec<Vec<u64>> {
    let mut crc : u64;

    let mut table : Vec<Vec<u64>> = Vec::with_capacity(8);

    for _ in (0..8) {
        table.push(Vec::with_capacity(256));
    };

    for n in (0usize..256) {
        table[0].push(crc64_trivial(0, &vec![n as u8]));
        table[1].push(0);
        table[2].push(0);
        table[3].push(0);
        table[4].push(0);
        table[5].push(0);
        table[6].push(0);
        table[7].push(0);
    }

    for n in (0usize..256) {
        crc = table[0][n];
        for k in (1usize..8) {
            let idx  = (crc as usize) & 0xff;
            crc = table[0][idx] ^ (crc >> 8);
            table[k][n] = crc;
        }
    };

    table
}

// transmute slice of 8 u8 values to one u64 (drop the length)
macro_rules! slice_to_long {
    ($curVec:expr) => {
        {
            unsafe {
                let (tmp, _) : (*const u64, usize) = mem::transmute(&$curVec);
                *tmp
            }
        }
    }
}

pub fn crc64(crc: u64, data: &[u8]) -> u64 {
    let mut crc = crc;
    let mut len = data.len();
    let mut offset = 0usize;

    while len >= 8 {
        crc ^= slice_to_long!(data[offset..(offset+8)]);
        crc = CRC64_TAB[7][(crc & 0xff) as usize] ^
              CRC64_TAB[6][((crc >> 8) & 0xff) as usize] ^
              CRC64_TAB[5][((crc >> 16) & 0xff) as usize] ^
              CRC64_TAB[4][((crc >> 24) & 0xff) as usize] ^
              CRC64_TAB[3][((crc >> 32) & 0xff) as usize] ^
              CRC64_TAB[2][((crc >> 40) & 0xff) as usize] ^
              CRC64_TAB[1][((crc >> 48) & 0xff) as usize] ^
              CRC64_TAB[0][(crc >> 56) as usize];

        offset += 8;
        len -= 8;
    }

    while len > 0 {
        crc = CRC64_TAB[0][((crc ^ data[offset] as u64) & 0xff) as usize] ^ (crc >> 8);
        offset += 1;
        len -= 1;
    }

    crc
}

pub struct Crc64 {
    crc64: u64,
}

impl Crc64 {
    pub fn new() -> Crc64 {
        Crc64 { crc64: 0 }
    }
    pub fn get(&self) -> u64 {
        self.crc64
    }
}

impl Write for Crc64 {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.crc64 = crc64(self.crc64, buf);
        Ok(buf.len())
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

#[test]
fn test_crc64_works() {
    assert_eq!(0xe9c6d914c4b8d9ca, crc64(0, "123456789".as_bytes()))
}

#[test]
fn test_crc64_write() {
    let step1 = "12345".as_bytes();
    let step2 = "6789".as_bytes();
    let value1 = 17326901458626182669;
    let value2 = 16845390139448941002;
    assert_eq!(value1, crc64(0, &step1));
    assert_eq!(value2, crc64(value1, &step2));

    let mut crc = Crc64::new();
    assert_eq!(crc.write(&step1).unwrap(), step1.len());
    assert_eq!(value1, crc.get());
    assert_eq!(crc.write(&step2).unwrap(), step2.len());
    assert_eq!(value2, crc.get());
}
<commit_msg>chore: Remove useless syntax<commit_after>/// Calculate the crc64 checksum of the given data, starting with the given crc.
///
/// Implements the CRC64 used by Redis, which is the variant with "Jones" coefficients and init value of 0.
///
/// Specification of this CRC64 variant follows:
///
/// ```text
/// Name: crc-64-jones
/// Width: 64 bites
/// Poly: 0xad93d23594c935a9
/// Reflected In: True
/// Xor_In: 0xffffffffffffffff
/// Reflected_Out: True
/// Xor_Out: 0x0
/// Check("123456789"): 0xe9c6d914c4b8d9ca
/// ```
///
/// Example:
///
/// ```rust
/// crc64::crc64(0, "123456789".as_bytes());
/// ```

use std::io;
use std::io::Write;
use std::mem;
use crc_table::CRC64_TAB;
mod crc_table;

fn crc_reflect(data: u64, len: usize) -> u64 {
    let mut data = data;
    let mut ret = data & 0x01;

    let mut i = 1;
    while i < len {
        data >>= 1;
        ret = (ret << 1) | (data & 0x01);
        i+=1;
    }

    ret
}

fn crc64_trivial(crc: u64, in_data: &[u8]) -> u64 {
    let mut crc = crc;
    let len = in_data.len();

    let poly : u64 = 0xad93d23594c935a9;

    let mut bit : bool;

    let mut offset = 0;

    while offset < len {
        let c = in_data[offset];
        let mut i = 0x01;
        while i & 0xff != 0x0 {
            bit = crc & 0x8000000000000000 != 0x0;
            if c & i != 0x0 {
                bit = !bit;
            }
            crc <<= 1;
            if bit {
                crc ^= poly;
            }
            i <<= 1;
        }
        crc &= 0xffffffffffffffff;
        offset+=1;
    }
    crc = crc & 0xffffffffffffffff;

    return crc_reflect(crc, 64) ^ 0x0000000000000000;
}

pub fn crc64_init() -> Vec<Vec<u64>> {
    let mut crc : u64;

    let mut table : Vec<Vec<u64>> = Vec::with_capacity(8);

    for _ in 0..8 {
        table.push(Vec::with_capacity(256));
    };

    for n in 0..256 {
        table[0].push(crc64_trivial(0, &vec![n as u8]));
        table[1].push(0);
        table[2].push(0);
        table[3].push(0);
        table[4].push(0);
        table[5].push(0);
        table[6].push(0);
        table[7].push(0);
    }

    for n in 0..256 {
        crc = table[0][n];
        for k in 1..8 {
            let idx  = (crc as usize) & 0xff;
            crc = table[0][idx] ^ (crc >> 8);
            table[k][n] = crc;
        }
    };

    table
}

// transmute slice of 8 u8 values to one u64 (drop the length)
macro_rules! slice_to_long {
    ($curVec:expr) => {
        {
            unsafe {
                let (tmp, _) : (*const u64, usize) = mem::transmute(&$curVec);
                *tmp
            }
        }
    }
}

pub fn crc64(crc: u64, data: &[u8]) -> u64 {
    let mut crc = crc;
    let mut len = data.len();
    let mut offset = 0usize;

    while len >= 8 {
        crc ^= slice_to_long!(data[offset..(offset+8)]);
        crc = CRC64_TAB[7][(crc & 0xff) as usize] ^
              CRC64_TAB[6][((crc >> 8) & 0xff) as usize] ^
              CRC64_TAB[5][((crc >> 16) & 0xff) as usize] ^
              CRC64_TAB[4][((crc >> 24) & 0xff) as usize] ^
              CRC64_TAB[3][((crc >> 32) & 0xff) as usize] ^
              CRC64_TAB[2][((crc >> 40) & 0xff) as usize] ^
              CRC64_TAB[1][((crc >> 48) & 0xff) as usize] ^
              CRC64_TAB[0][(crc >> 56) as usize];

        offset += 8;
        len -= 8;
    }

    while len > 0 {
        crc = CRC64_TAB[0][((crc ^ data[offset] as u64) & 0xff) as usize] ^ (crc >> 8);
        offset += 1;
        len -= 1;
    }

    crc
}

pub struct Crc64 {
    crc64: u64,
}

impl Crc64 {
    pub fn new() -> Crc64 {
        Crc64 { crc64: 0 }
    }
    pub fn get(&self) -> u64 {
        self.crc64
    }
}

impl Write for Crc64 {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.crc64 = crc64(self.crc64, buf);
        Ok(buf.len())
    }
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

#[test]
fn test_crc64_works() {
    assert_eq!(0xe9c6d914c4b8d9ca, crc64(0, "123456789".as_bytes()))
}

#[test]
fn test_crc64_write() {
    let step1 = "12345".as_bytes();
    let step2 = "6789".as_bytes();
    let value1 = 17326901458626182669;
    let value2 = 16845390139448941002;
    assert_eq!(value1, crc64(0, &step1));
    assert_eq!(value2, crc64(value1, &step2));

    let mut crc = Crc64::new();
    assert_eq!(crc.write(&step1).unwrap(), step1.len());
    assert_eq!(value1, crc.get());
    assert_eq!(crc.write(&step2).unwrap(), step2.len());
    assert_eq!(value2, crc.get());
}
<|endoftext|>


<commit_before>#![warn(trivial_casts, trivial_numeric_casts, unused_import_braces, unused_qualifications)]

extern crate block;
extern crate cocoa;
extern crate core_foundation;
extern crate metal_sys;
#[macro_use]
extern crate objc;

#[macro_use]
mod raw;

#[macro_use]
mod internal;

#[cfg(feature = "extras")]
pub mod extras;

mod argument;
mod array_type;
mod blit_command_encoder;
mod buffer;
mod command_buffer;
mod command_encoder;
mod command_queue;
mod compile_options;
mod compute_command_encoder;
mod constants;
mod depth_stencil_state;
mod device;
mod drawable;
mod error;
mod function;
mod library;
mod objc_bringup;
mod parallel_render_command_encoder;
mod render_command_encoder;
mod render_pass_attachment_descriptor;
mod render_pass_color_attachment_descriptor;
mod render_pass_depth_attachment_descriptor;
mod render_pass_descriptor;
mod render_pass_stencil_attachment_descriptor;
mod render_pipeline_state;
mod resource;
mod sampler_state;
mod stencil_descriptor;
mod struct_member;
mod struct_type;
mod texture;
mod value_types;

pub mod sys {
    pub use metal_sys::*;
}

pub use argument::{Argument, ArgumentAccess, ArgumentType, DataType};
pub use array_type::ArrayType;
pub use blit_command_encoder::BlitCommandEncoder;
pub use buffer::Buffer;
pub use command_buffer::{CommandBuffer, CommandBufferError};
pub use command_encoder::CommandEncoder;
pub use command_queue::{CommandQueue, CommandQueueError};
pub use compile_options::{CompileOptions, LanguageVersion, PreprocessorMacroValue,
                          SpecificLanguageVersion};
pub use compute_command_encoder::ComputeCommandEncoder;
pub use constants::{CompareFunction, PipelineOption, PixelFormat};
pub use depth_stencil_state::{DepthStencilDescriptor, DepthStencilState};
pub use device::{BufferRef, Device, DeviceError, FeatureSet};
pub use drawable::Drawable;
pub use error::NSError;
pub use function::{Function, FunctionType};
pub use library::{Library, LibraryError};
pub use parallel_render_command_encoder::ParallelRenderCommandEncoder;
pub use raw::{AsRaw, FromRaw, FromRawError, IntoRaw, StrongPtr};
pub use render_command_encoder::{CullMode, DepthClipMode, IndexType, PrimitiveType,
                                 RenderCommandEncoder, TriangleFillModeFill, VisibilityResultMode,
                                 Winding};
pub use render_pass_attachment_descriptor::{LoadAction, RenderPassAttachmentDescriptor,
                                            StoreAction};
pub use render_pass_color_attachment_descriptor::{RenderPassColorAttachmentDescriptor,
                                                  RenderPassColorAttachmentDescriptorArray};
pub use render_pass_depth_attachment_descriptor::RenderPassDepthAttachmentDescriptor;
pub use render_pass_descriptor::RenderPassDescriptor;
pub use render_pass_stencil_attachment_descriptor::RenderPassStencilAttachmentDescriptor;
pub use render_pipeline_state::RenderPipelineState;
pub use resource::{CpuCacheMode, PurgeableState, Resource, ResourceOptions, StorageMode};
pub use sampler_state::{SamplerDescriptor, SamplerState};
pub use stencil_descriptor::StencilDescriptor;
pub use struct_member::StructMember;
pub use struct_type::StructType;
pub use texture::{Texture, TextureDescriptor, TextureType, TextureUsage};
pub use value_types::{ClearColor, Origin, Region, ScissorRect, Size, Viewport};
<commit_msg>Enable collections and collections_range features<commit_after>#![feature(collections, collections_range)]
#![warn(trivial_casts, trivial_numeric_casts, unused_import_braces, unused_qualifications)]

extern crate block;
extern crate cocoa;
extern crate core_foundation;
extern crate metal_sys;
#[macro_use]
extern crate objc;

#[macro_use]
mod raw;

#[macro_use]
mod internal;

#[cfg(feature = "extras")]
pub mod extras;

mod argument;
mod array_type;
mod blit_command_encoder;
mod buffer;
mod command_buffer;
mod command_encoder;
mod command_queue;
mod compile_options;
mod compute_command_encoder;
mod constants;
mod depth_stencil_state;
mod device;
mod drawable;
mod error;
mod function;
mod library;
mod objc_bringup;
mod parallel_render_command_encoder;
mod render_command_encoder;
mod render_pass_attachment_descriptor;
mod render_pass_color_attachment_descriptor;
mod render_pass_depth_attachment_descriptor;
mod render_pass_descriptor;
mod render_pass_stencil_attachment_descriptor;
mod render_pipeline_state;
mod resource;
mod sampler_state;
mod stencil_descriptor;
mod struct_member;
mod struct_type;
mod texture;
mod value_types;

pub mod sys {
    pub use metal_sys::*;
}

pub use argument::{Argument, ArgumentAccess, ArgumentType, DataType};
pub use array_type::ArrayType;
pub use blit_command_encoder::BlitCommandEncoder;
pub use buffer::Buffer;
pub use command_buffer::{CommandBuffer, CommandBufferError};
pub use command_encoder::CommandEncoder;
pub use command_queue::{CommandQueue, CommandQueueError};
pub use compile_options::{CompileOptions, LanguageVersion, PreprocessorMacroValue,
                          SpecificLanguageVersion};
pub use compute_command_encoder::ComputeCommandEncoder;
pub use constants::{CompareFunction, PipelineOption, PixelFormat};
pub use depth_stencil_state::{DepthStencilDescriptor, DepthStencilState};
pub use device::{BufferRef, Device, DeviceError, FeatureSet};
pub use drawable::Drawable;
pub use error::NSError;
pub use function::{Function, FunctionType};
pub use library::{Library, LibraryError};
pub use parallel_render_command_encoder::ParallelRenderCommandEncoder;
pub use raw::{AsRaw, FromRaw, FromRawError, IntoRaw, StrongPtr};
pub use render_command_encoder::{CullMode, DepthClipMode, IndexType, PrimitiveType,
                                 RenderCommandEncoder, TriangleFillModeFill, VisibilityResultMode,
                                 Winding};
pub use render_pass_attachment_descriptor::{LoadAction, RenderPassAttachmentDescriptor,
                                            StoreAction};
pub use render_pass_color_attachment_descriptor::{RenderPassColorAttachmentDescriptor,
                                                  RenderPassColorAttachmentDescriptorArray};
pub use render_pass_depth_attachment_descriptor::RenderPassDepthAttachmentDescriptor;
pub use render_pass_descriptor::RenderPassDescriptor;
pub use render_pass_stencil_attachment_descriptor::RenderPassStencilAttachmentDescriptor;
pub use render_pipeline_state::RenderPipelineState;
pub use resource::{CpuCacheMode, PurgeableState, Resource, ResourceOptions, StorageMode};
pub use sampler_state::{SamplerDescriptor, SamplerState};
pub use stencil_descriptor::StencilDescriptor;
pub use struct_member::StructMember;
pub use struct_type::StructType;
pub use texture::{Texture, TextureDescriptor, TextureType, TextureUsage};
pub use value_types::{ClearColor, Origin, Region, ScissorRect, Size, Viewport};
<|endoftext|>


<commit_before>use std::collections::HashMap;

pub fn puzzle(input: &str) -> usize {
    let mut br = BotRouter {
        bots: HashMap::new(),
        output_bins: HashMap::new(),
    };

    for line in input.lines() {
        br.exec_command(line);
    }
    0
}

#[derive(PartialEq, Debug, Clone, Copy)]
pub enum BotOrOutput {
    Bot,
    Output,
}

#[derive(PartialEq, Debug)]
pub struct Bot {
    key: usize,
    chip1: Option<usize>,
    chip2: Option<usize>,
    low: Option<usize>,
    low_bot_or_output: Option<BotOrOutput>,
    high: Option<usize>,
    high_bot_or_output: Option<BotOrOutput>,
}

impl Bot {
    pub fn new(key: usize) -> Bot {
        Bot {
            key: key,
            chip1: None, chip2: None,
            low: None, high: None,
            low_bot_or_output: None,
            high_bot_or_output: None,
        }
    }

    pub fn has_two_chips(&self) -> bool {
        match (self.chip1, self.chip2) {
            (Some(_), Some(_)) => true,
            _ => false,
        }
    }

    pub fn receive_chip(&mut self, chip: usize)
           -> Vec<(usize, BotOrOutput, usize)> {
        if self.chip1.is_none() {
            println!("bot {}, chip1 = {}", self.key, chip);
            self.chip1 = Some(chip);
            vec![]
        } else if self.chip2.is_none() {
            println!("bot {}, chip2 = {}", self.key, chip);
            self.chip2 = Some(chip);
            if let (Some(lo), Some(hi)) = (self.low, self.high) {
                println!("bot {} has 2 chips; low to {:?} {}, high to {:?} {}", self.key, self.low_bot_or_output, lo, self.high_bot_or_output, hi);
                let return_commands = if self.chip1 < self.chip2 {
                    println!("bot {} finds {:?} < {:?}", self.key, self.chip1, self.chip2);
                    if self.chip1 == Some(17) && self.chip2 == Some(61) {
                        panic!("The bot you are looking for is {}", self.key);
                    }

                    vec![
                        (
                            lo,
                            self.low_bot_or_output.unwrap(),
                            self.chip1.unwrap()
                        ),
                        (
                            hi,
                            self.high_bot_or_output.unwrap(),
                            self.chip2.unwrap()
                        ),
                    ]
                } else {
                    println!("bot {} finds {:?} < {:?}", self.key, self.chip2, self.chip1);
                    if self.chip2 == Some(17) && self.chip1 == Some(61) {
                        panic!("The bot you are looking for is {}", self.key);
                    }

                    vec![
                        (
                            lo,
                            self.low_bot_or_output.unwrap(),
                            self.chip2.unwrap()
                        ),
                        (
                            hi,
                            self.high_bot_or_output.unwrap(),
                            self.chip1.unwrap()
                        ),
                    ]
                };
                self.chip1 = None;
                self.chip2 = None;
                self.low = None;
                self.high = None;
                self.low_bot_or_output = None;
                self.high_bot_or_output = None;
                return_commands
            } else {
                vec![]
            }
        } else {
            panic!("Cannot hold more than two chips");
        }
    }

    pub fn receive_command(&mut self, low_bot_or_output: &str, low: usize,
                                      high_bot_or_output: &str, high: usize) {
        println!("bot {} storing command low to {} {}, high to {} {}", self.key, low_bot_or_output, low, high_bot_or_output, high);
        self.low = Some(low);
        if low_bot_or_output == "bot" {
            self.low_bot_or_output = Some(BotOrOutput::Bot);
        } else {
            self.low_bot_or_output = Some(BotOrOutput::Output);
        }
        self.high = Some(high);
        if high_bot_or_output == "bot" {
            self.high_bot_or_output = Some(BotOrOutput::Bot);
        } else {
            self.high_bot_or_output = Some(BotOrOutput::Output);
        }
    }
}

pub struct BotRouter {
    bots: HashMap<usize, Bot>,
    output_bins: HashMap<usize, Vec<usize>>,
}

impl BotRouter {
    pub fn exec_command(&mut self, input: &str) {
        println!("COMMAND: {}", input);
        let pieces: Vec<&str> = input.split_whitespace().collect();

        if pieces[0] == "value" {
            self.value_to_bot(
                pieces[5].parse().expect("can't parse bot key"),
                pieces[1].parse().expect("can't parse chip value")
            );
        } else if pieces[0] == "bot" {
            self.command_to_bot(
                pieces[1].parse().expect("can't parse bot key"),
                pieces[5],
                pieces[6].parse().expect("can't parse low key"),
                pieces[10],
                pieces[11].parse().expect("can't parse high key"),
            );
        }
    }

    pub fn value_to_bot(&mut self, bot_key: usize, value: usize) {
        println!("ROUTER sending value {} to bot {}", value, bot_key);
        let return_commands = self.bots
                                  .entry(bot_key)
                                  .or_insert(Bot::new(bot_key))
                                  .receive_chip(value);
        for &(key, bot_or_output, chip_value) in return_commands.iter() {
            match bot_or_output {
                BotOrOutput::Bot => self.value_to_bot(key, chip_value),
                BotOrOutput::Output => self.value_to_output(key, chip_value),
            }
        }
    }

    pub fn value_to_output(&mut self, output_key: usize, value: usize) {
        println!("ROUTER sending value {} to output {}", value, output_key);
        self.output_bins.entry(output_key).or_insert(Vec::new()).push(value);
    }

    pub fn command_to_bot(&mut self, bot_key: usize,
                          low_bot_or_output: &str, low_key: usize,
                          high_bot_or_output: &str, high_key: usize) {
        let bot = self.bots.entry(bot_key).or_insert(Bot::new(bot_key));
        bot.receive_command(
            low_bot_or_output,
            low_key,
            high_bot_or_output,
            high_key
        );
    }
}

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

    #[test]
    fn new_bot_does_not_have_two_chips() {
        let bot = Bot::new(0);
        assert!( ! bot.has_two_chips() );
    }

    #[test]
    fn bot_gets_a_chip_still_not_two() {
        let mut bot = Bot::new(0);
        bot.receive_chip(1);
        assert!( ! bot.has_two_chips() );
    }

    #[test]
    fn bot_gets_two_chips() {
        let mut bot = Bot::new(0);
        bot.receive_chip(1);
        bot.receive_chip(4);
        assert!(bot.has_two_chips());
    }

    #[test]
    fn router_can_give_values() {
        let mut br = BotRouter {
            bots: HashMap::new(),
            output_bins: HashMap::new(),
        };
        br.exec_command("value 5 goes to bot 2");
        assert_eq!(
            br.bots.get(&2).unwrap().chip1,
            Some(5)
        );
    }

    #[test]
    fn router_can_give_commands_that_get_stored() {
        let mut br = BotRouter {
            bots: HashMap::new(),
            output_bins: HashMap::new(),
        };
        br.exec_command("bot 2 gives low to bot 1 and high to bot 0");
        assert_eq!(
            br.bots.get(&2).unwrap().low,
            Some(1)
        );
        assert_eq!(
            br.bots.get(&2).unwrap().high,
            Some(0)
        );
    }

    #[test]
    fn router_adds_two_values_so_commands_get_executed() {
        let mut br = BotRouter {
            bots: HashMap::new(),
            output_bins: HashMap::new(),
        };
        br.exec_command("value 5 goes to bot 2");
        br.exec_command("bot 2 gives low to bot 1 and high to bot 0");
        br.exec_command("value 2 goes to bot 2");

        assert_eq!(
            br.bots.get(&2).unwrap().chip1,
            None
        );
        assert_eq!(
            br.bots.get(&2).unwrap().chip2,
            None
        );

        assert_eq!(
            br.bots.get(&1).unwrap().chip1,
            Some(2)
        );
        assert_eq!(
            br.bots.get(&1).unwrap().chip2,
            None
        );

        assert_eq!(
            br.bots.get(&0).unwrap().chip1,
            Some(5)
        );
        assert_eq!(
            br.bots.get(&0).unwrap().chip2,
            None
        );
    }

    #[test]
    fn test_sample() {
        let mut br = BotRouter {
            bots: HashMap::new(),
            output_bins: HashMap::new(),
        };
        br.exec_command("value 5 goes to bot 2");
        br.exec_command("bot 2 gives low to bot 1 and high to bot 0");
        br.exec_command("value 3 goes to bot 1");
        br.exec_command("bot 1 gives low to output 1 and high to bot 0");
        br.exec_command("bot 0 gives low to output 2 and high to output 0");
        br.exec_command("value 2 goes to bot 2");

        assert_eq!(
            br.output_bins.get(&0),
            Some(&vec![5])
        );

        assert_eq!(
            br.output_bins.get(&1),
            Some(&vec![2])
        );

        assert_eq!(
            br.output_bins.get(&2),
            Some(&vec![3])
        )
    }
}
<commit_msg>Argh start over<commit_after>
pub fn puzzle(input: &str) -> usize {
    0
}

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

        // br.exec_command("value 5 goes to bot 2");
        // br.exec_command("bot 2 gives low to bot 1 and high to bot 0");
        // br.exec_command("value 3 goes to bot 1");
        // br.exec_command("bot 1 gives low to output 1 and high to bot 0");
        // br.exec_command("bot 0 gives low to output 2 and high to output 0");
        // br.exec_command("value 2 goes to bot 2");
}
<|endoftext|>


<commit_before>#![crate_name = "neovim"]
#![crate_type = "lib"]
#![crate_type = "rlib"]

extern crate libc;

use std::c_str::CString;
use std::string::String;
use std::vec::Vec;

#[cfg(target_os="macos")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    #[link(name = "iconv")]
    extern{}
}

#[cfg(target_os="linux")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

#[cfg(target_os="windows")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

mod ffi {
    pub use libc::{c_char, c_int, c_void, uint64_t};

    extern "C" {
        pub fn channel_from_fds (read_fd: c_int, write_fd: c_int) -> uint64_t;
        pub fn channel_subscribe (id: uint64_t, event: *const c_char);
        pub fn nvim_main (argc: c_int, argv: *const *const c_char,
                          callback: Option<extern "C" fn(c_int, c_int)>,
                          read_fs: c_int, write_fs: c_int) -> c_int;
    }
}

pub struct Channel {
    id: ffi::uint64_t
}

impl Channel {
    pub fn new_with_fds(read_fd: i32, write_fd: i32) -> Channel {
        Channel {
            id: unsafe { ffi::channel_from_fds(read_fd, write_fd) }
        }
    }

    pub fn subscribe(&mut self, event: &str) {
        unsafe { ffi::channel_subscribe(self.id, event.to_c_str().as_ptr()) }
    }
}

pub fn run_with_callback(
    args: Vec<String>,
    callback: Option<extern "C" fn(i32, i32)>,
    read_fs: i32,
    write_fs: i32) -> i32
{
    let v: Vec<CString> = args.iter().map(|s| s.as_slice().to_c_str()).collect();
    let vp: Vec<*const ffi::c_char> = v.iter().map(|s| s.as_ptr()).collect();
    let p_vp: *const *const ffi::c_char = vp.as_ptr();

    unsafe { ffi::nvim_main(vp.len() as i32, p_vp, callback, read_fs, write_fs) }
}

pub fn run(args: Vec<String>) -> i32
{
    run_with_callback(args, None, -1, -1)
}
<commit_msg>Fix bracket placement<commit_after>#![crate_name = "neovim"]
#![crate_type = "lib"]
#![crate_type = "rlib"]

extern crate libc;

use std::c_str::CString;
use std::string::String;
use std::vec::Vec;

#[cfg(target_os="macos")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    #[link(name = "iconv")]
    extern{}
}

#[cfg(target_os="linux")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

#[cfg(target_os="windows")]
mod platform {
    #[link(name = "nvim")]
    #[link(name = "uv")]
    #[link(name = "msgpack")]
    #[link(name = "curses")]
    extern{}
}

mod ffi {
    pub use libc::{c_char, c_int, c_void, uint64_t};

    extern "C" {
        pub fn channel_from_fds (read_fd: c_int, write_fd: c_int) -> uint64_t;
        pub fn channel_subscribe (id: uint64_t, event: *const c_char);
        pub fn nvim_main (argc: c_int, argv: *const *const c_char,
                          callback: Option<extern "C" fn(c_int, c_int)>,
                          read_fs: c_int, write_fs: c_int) -> c_int;
    }
}

pub struct Channel {
    id: ffi::uint64_t
}

impl Channel {
    pub fn new_with_fds(read_fd: i32, write_fd: i32) -> Channel {
        Channel {
            id: unsafe { ffi::channel_from_fds(read_fd, write_fd) }
        }
    }

    pub fn subscribe(&mut self, event: &str) {
        unsafe { ffi::channel_subscribe(self.id, event.to_c_str().as_ptr()) }
    }
}

pub fn run_with_callback(
    args: Vec<String>,
    callback: Option<extern "C" fn(i32, i32)>,
    read_fs: i32,
    write_fs: i32) -> i32
{
    let v: Vec<CString> = args.iter().map(|s| s.as_slice().to_c_str()).collect();
    let vp: Vec<*const ffi::c_char> = v.iter().map(|s| s.as_ptr()).collect();
    let p_vp: *const *const ffi::c_char = vp.as_ptr();

    unsafe { ffi::nvim_main(vp.len() as i32, p_vp, callback, read_fs, write_fs) }
}

pub fn run(args: Vec<String>) -> i32 {
    run_with_callback(args, None, -1, -1)
}
<|endoftext|>


<commit_before>//! It can be useful to not have to worry about missing keys in a map.
//! If a key is requested that doesn't have a value a default value is simply returned.
//! This is exactly what this library provides.
//!
//! ## Examples

//! ### Counter
//! A clear use case of this is when counting the unique elements in a list.
//! Here you want to add one to the existing value in the map for that key.
//! This is a problem for the first addition when there's no value for the key yet.
//! With this library you can specify when creating the map that the default value should be zero.
//!

//! ```rust
//! # use defaultmap::*;
//! let nums = [1, 4, 3, 3, 4, 2, 4];
//! let mut counts:  DefaultHashMap<i32, i32> = DefaultHashMap::new(0);
//! // DefaultHashMap::default() is equivalent.
//!
//! for num in nums.into_iter() {
//!     counts[*num] += 1;
//! }
//!
//! println!("{:?}", counts);
//! // DefaultHashMap { map: {1: 1, 3: 2, 2: 1, 4: 3}, default: 0 }
//!
//! # assert_eq!(1, counts[1]);
//! # assert_eq!(1, counts[2]);
//! # assert_eq!(2, counts[3]);
//! # assert_eq!(3, counts[4]);
//! ```
//!

//! ### Synonym lists
//!
//! Another way the default map can be used is using a map filled with other collections, such as a
//! a `Vec`, a `HashMap` or even another default map.
//! Next follows some code to create a map where we start with tuples of synonyms and we end with a
//! map that contains the list of synonyms for each word.
//!
//! ```rust
//! # use defaultmap::*;
//!
//! let synonym_tuples = [
//!     ("nice", "sweet"),
//!     ("sweet", "candy"),
//!     ("nice", "entertaining"),
//!     ("nice", "good"),
//!     ("entertaining", "absorbing"),
//! ];
//!
//! let mut synonym_map: DefaultHashMap<&str, Vec<&str>> = DefaultHashMap::new(vec![]);
//! // DefaultHashMap::default() is equivalent.
//!
//! for &(l, r) in synonym_tuples.into_iter() {
//!     synonym_map[l].push(r);
//!     synonym_map[r].push(l);
//! }
//!
//! assert_eq!(synonym_map["good"], vec!["nice"]);
//! assert_eq!(synonym_map["nice"], vec!["sweet", "entertaining", "good"]);
//! assert_eq!(synonym_map["evil"], Vec::<&str>::new());
//! ```
//!

pub use hashmap::DefaultHashMap;

mod hashmap {
    use std::hash::Hash;
    use std::collections::HashMap;
    use std::collections::hash_map::*;
    use std::borrow::Borrow;
    use std::ops::{Index, IndexMut};

    /// A `HashMap` that has returns a default when keys are accessed that are not present.
    #[derive(PartialEq, Eq, Debug)]
    pub struct DefaultHashMap<K: Eq + Hash, V: Clone> {
        map: HashMap<K, V>,
        default: V,
    }

    impl<K: Eq + Hash, V: Default + Clone> Default for DefaultHashMap<K, V> {
        fn default() -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: HashMap::default(),
                default: V::default(),
            }
        }
    }

    impl<K: Eq + Hash, V: Clone> DefaultHashMap<K, V> {
        /// Creates an empty `DefaultHashmap` with `default` as the default for missing keys.
        /// When the provided `default` is equivalent to `V::default()` it is preferred to use
        /// `DefaultHashMap::default()` instead.
        pub fn new(default: V) -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: HashMap::new(),
                default: default,
            }
        }

        /// Creates a `DefaultHashMap` based on a default and an already existiting `HashMap`.
        pub fn new_with_map(default: V, map: HashMap<K, V>) -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: map,
                default: default,
            }
        }

        /// Returns a reference to the value stored for the provided key.
        /// If the key is not in the `DefaultHashMap` a reference to the default value is returned.
        /// Usually the `map[key]` method of retrieving keys is prefered over using `get` directly.
        /// This method accepts both references and owned values as the key.
        pub fn get<Q, QB: Borrow<Q>>(&self, key: QB) -> &V
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.get(key.borrow()).unwrap_or(&self.default)
        }

        /// Returns a mutable reference to the value stored for the provided key.
        /// If there is no value stored for the key the default value is first inserted for this
        /// key before returning the reference.
        /// Usually the `map[key] = new_val` is prefered over using `get_mut` directly.
        /// This method only accepts owned values as the key.
        pub fn get_mut(&mut self, key: K) -> &mut V {
            self.map.entry(key).or_insert(self.default.clone())
        }
    }

    /// Implements the `Index` trait so you can do `map[key]`.
    /// Nonmutable indexing can be done both by passing a reference or an owned value as the key.
    impl<'a, K: Eq + Hash, KB: Borrow<K>, V: Clone> Index<KB> for DefaultHashMap<K, V> {
        type Output = V;

        fn index(&self, index: KB) -> &V {
            self.get(index)
        }
    }

    /// Implements the `IndexMut` trait so you can do `map[key] = val`.
    /// Mutably indexing can only be done when passing an owned value as the key.
    impl<K: Eq + Hash, V: Clone> IndexMut<K> for DefaultHashMap<K, V> {
        #[inline]
        fn index_mut(&mut self, index: K) -> &mut V {
            self.get_mut(index)
        }
    }

    /// These methods simply forward to the underlying `HashMap`, see that
    /// [documentation](https://doc.rust-lang.org/std/collections/struct.HashMap.html) for
    /// the usage of these methods.
    impl<K: Eq + Hash, V: Clone> DefaultHashMap<K, V> {
        pub fn capacity(&self) -> usize {
            self.map.capacity()
        }
        #[inline]
        pub fn reserve(&mut self, additional: usize) {
            self.map.reserve(additional)
        }
        #[inline]
        pub fn shrink_to_fit(&mut self) {
            self.map.shrink_to_fit()
        }
        #[inline]
        pub fn keys(&self) -> Keys<K, V> {
            self.map.keys()
        }
        #[inline]
        pub fn values(&self) -> Values<K, V> {
            self.map.values()
        }
        #[inline]
        pub fn values_mut(&mut self) -> ValuesMut<K, V> {
            self.map.values_mut()
        }
        #[inline]
        pub fn iter(&self) -> Iter<K, V> {
            self.map.iter()
        }
        #[inline]
        pub fn iter_mut(&mut self) -> IterMut<K, V> {
            self.map.iter_mut()
        }
        #[inline]
        pub fn entry(&mut self, key: K) -> Entry<K, V> {
            self.map.entry(key)
        }
        #[inline]
        pub fn len(&self) -> usize {
            self.map.len()
        }
        #[inline]
        pub fn is_empty(&self) -> bool {
            self.map.is_empty()
        }
        #[inline]
        pub fn drain(&mut self) -> Drain<K, V> {
            self.map.drain()
        }
        #[inline]
        pub fn clear(&mut self) {
            self.map.clear()
        }
        #[inline]
        pub fn insert(&mut self, k: K, v: V) -> Option<V> {
            self.map.insert(k, v)
        }
        #[inline]
        pub fn contains_key<Q>(&self, k: &Q) -> (bool)
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.contains_key(k)
        }
        #[inline]
        pub fn remove<Q>(&mut self, k: &Q) -> (Option<V>)
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.remove(k)
        }
    }

}

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

    #[test]
    fn add() {
        let mut map: DefaultHashMap<i32, i32> = DefaultHashMap::default();
        *map.get_mut(0) += 1;
        map[1] += 4;
        map[2] = map[0] + map.get(&1);
        assert_eq!(*map.get(0), 1);
        assert_eq!(*map.get(&0), 1);
        assert_eq!(map[0], 1);
        assert_eq!(map[&0], 1);
        assert_eq!(*map.get(&1), 4);
        assert_eq!(*map.get(&2), 5);
        assert_eq!(*map.get(999), 0);
        assert_eq!(*map.get(&999), 0);
        assert_eq!(map[999], 0);
        assert_eq!(map[&999], 0);
    }

    #[test]
    fn counter() {
        let nums = [1, 4, 3, 3, 4, 2, 4];
        let mut counts: DefaultHashMap<i32, i32> = DefaultHashMap::default();
        for num in nums.into_iter() {
            counts[*num] += 1;
        }

        assert_eq!(1, counts[1]);
        assert_eq!(1, counts[2]);
        assert_eq!(2, counts[3]);
        assert_eq!(3, counts[4]);
        assert_eq!(0, counts[5]);
    }

    #[test]
    fn synonyms() {
        let synonym_tuples = [
            ("nice", "sweet"),
            ("sweet", "candy"),
            ("nice", "entertaining"),
            ("nice", "good"),
            ("entertaining", "absorbing"),
        ];

        let mut synonym_map: DefaultHashMap<&str, Vec<&str>> = DefaultHashMap::default();

        for &(l, r) in synonym_tuples.into_iter() {
            synonym_map[l].push(r);
            synonym_map[r].push(l);
        }

        println!("{:#?}", synonym_map);
        assert_eq!(synonym_map["good"], vec!["nice"]);
        assert_eq!(synonym_map["nice"], vec!["sweet", "entertaining", "good"]);
        assert_eq!(synonym_map["evil"], Vec::<&str>::new());
        // assert!(false)
    }

    #[derive(Clone)]
    struct Clonable;

    #[derive(Default, Clone)]
    struct DefaultableValue;

    #[derive(Hash, Eq, PartialEq)]
    struct Hashable(i32);

    #[test]
    fn minimal_derives() {
        let minimal: DefaultHashMap<Hashable, Clonable> = DefaultHashMap::new(Clonable);
        let clonable: DefaultHashMap<Hashable, DefaultableValue> = DefaultHashMap::default();
    }

}
<commit_msg>Docs: Fix typos and add docs for new default constructor<commit_after>//! It can be useful to not have to worry about missing keys in a map.
//! If a key is requested that doesn't have a value a default value is simply returned.
//! This is exactly what this library provides.
//!
//! ## Examples

//! ### Counter
//! A clear use case of this is when counting the unique elements in a list.
//! Here you want to add one to the existing value in the map for that key.
//! This is a problem for the first addition when there's no value for the key yet.
//! With this library you can specify when creating the map that the default value should be zero.
//!

//! ```rust
//! # use defaultmap::*;
//! let nums = [1, 4, 3, 3, 4, 2, 4];
//! let mut counts:  DefaultHashMap<i32, i32> = DefaultHashMap::new(0);
//! // DefaultHashMap::default() is equivalent.
//!
//! for num in nums.into_iter() {
//!     counts[*num] += 1;
//! }
//!
//! println!("{:?}", counts);
//! // DefaultHashMap { map: {1: 1, 3: 2, 2: 1, 4: 3}, default: 0 }
//!
//! # assert_eq!(1, counts[1]);
//! # assert_eq!(1, counts[2]);
//! # assert_eq!(2, counts[3]);
//! # assert_eq!(3, counts[4]);
//! ```
//!

//! ### Synonym lists
//!
//! Another way the default map can be used is using a map filled with other collections, such as a
//! `Vec`, a `HashMap` or even another default map.
//! Next follows some code to create a map where we start with tuples of synonyms and we end with a
//! map that contains the list of synonyms for each word.
//!
//! ```rust
//! # use defaultmap::*;
//!
//! let synonym_tuples = [
//!     ("nice", "sweet"),
//!     ("sweet", "candy"),
//!     ("nice", "entertaining"),
//!     ("nice", "good"),
//!     ("entertaining", "absorbing"),
//! ];
//!
//! let mut synonym_map: DefaultHashMap<&str, Vec<&str>> = DefaultHashMap::new(vec![]);
//! // DefaultHashMap::default() is equivalent.
//!
//! for &(l, r) in synonym_tuples.into_iter() {
//!     synonym_map[l].push(r);
//!     synonym_map[r].push(l);
//! }
//!
//! assert_eq!(synonym_map["good"], vec!["nice"]);
//! assert_eq!(synonym_map["nice"], vec!["sweet", "entertaining", "good"]);
//! assert_eq!(synonym_map["evil"], Vec::<&str>::new());
//! ```
//!

pub use hashmap::DefaultHashMap;

mod hashmap {
    use std::hash::Hash;
    use std::collections::HashMap;
    use std::collections::hash_map::*;
    use std::borrow::Borrow;
    use std::ops::{Index, IndexMut};

    /// A `HashMap` that has returns a default when keys are accessed that are not present.
    #[derive(PartialEq, Eq, Debug)]
    pub struct DefaultHashMap<K: Eq + Hash, V: Clone> {
        map: HashMap<K, V>,
        default: V,
    }

    impl<K: Eq + Hash, V: Default + Clone> Default for DefaultHashMap<K, V> {
        /// The `default()` constructor creates an empty DefaultHashMap with the default of `V`
        /// as the default for missing keys.
        /// This is desired default for most use cases, if your case requires a
        /// different default you should use the `new()` constructor.
        fn default() -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: HashMap::default(),
                default: V::default(),
            }
        }
    }

    impl<K: Eq + Hash, V: Clone> DefaultHashMap<K, V> {
        /// Creates an empty `DefaultHashmap` with `default` as the default for missing keys.
        /// When the provided `default` is equivalent to `V::default()` it is preferred to use
        /// `DefaultHashMap::default()` instead.
        pub fn new(default: V) -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: HashMap::new(),
                default: default,
            }
        }

        /// Creates a `DefaultHashMap` based on a default and an already existing `HashMap`.
        pub fn new_with_map(default: V, map: HashMap<K, V>) -> DefaultHashMap<K, V> {
            DefaultHashMap {
                map: map,
                default: default,
            }
        }

        /// Returns a reference to the value stored for the provided key.
        /// If the key is not in the `DefaultHashMap` a reference to the default value is returned.
        /// Usually the `map[key]` method of retrieving keys is prefered over using `get` directly.
        /// This method accepts both references and owned values as the key.
        pub fn get<Q, QB: Borrow<Q>>(&self, key: QB) -> &V
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.get(key.borrow()).unwrap_or(&self.default)
        }

        /// Returns a mutable reference to the value stored for the provided key.
        /// If there is no value stored for the key the default value is first inserted for this
        /// key before returning the reference.
        /// Usually the `map[key] = new_val` is prefered over using `get_mut` directly.
        /// This method only accepts owned values as the key.
        pub fn get_mut(&mut self, key: K) -> &mut V {
            self.map.entry(key).or_insert(self.default.clone())
        }
    }

    /// Implements the `Index` trait so you can do `map[key]`.
    /// Nonmutable indexing can be done both by passing a reference or an owned value as the key.
    impl<'a, K: Eq + Hash, KB: Borrow<K>, V: Clone> Index<KB> for DefaultHashMap<K, V> {
        type Output = V;

        fn index(&self, index: KB) -> &V {
            self.get(index)
        }
    }

    /// Implements the `IndexMut` trait so you can do `map[key] = val`.
    /// Mutably indexing can only be done when passing an owned value as the key.
    impl<K: Eq + Hash, V: Clone> IndexMut<K> for DefaultHashMap<K, V> {
        #[inline]
        fn index_mut(&mut self, index: K) -> &mut V {
            self.get_mut(index)
        }
    }

    /// These methods simply forward to the underlying `HashMap`, see that
    /// [documentation](https://doc.rust-lang.org/std/collections/struct.HashMap.html) for
    /// the usage of these methods.
    impl<K: Eq + Hash, V: Clone> DefaultHashMap<K, V> {
        pub fn capacity(&self) -> usize {
            self.map.capacity()
        }
        #[inline]
        pub fn reserve(&mut self, additional: usize) {
            self.map.reserve(additional)
        }
        #[inline]
        pub fn shrink_to_fit(&mut self) {
            self.map.shrink_to_fit()
        }
        #[inline]
        pub fn keys(&self) -> Keys<K, V> {
            self.map.keys()
        }
        #[inline]
        pub fn values(&self) -> Values<K, V> {
            self.map.values()
        }
        #[inline]
        pub fn values_mut(&mut self) -> ValuesMut<K, V> {
            self.map.values_mut()
        }
        #[inline]
        pub fn iter(&self) -> Iter<K, V> {
            self.map.iter()
        }
        #[inline]
        pub fn iter_mut(&mut self) -> IterMut<K, V> {
            self.map.iter_mut()
        }
        #[inline]
        pub fn entry(&mut self, key: K) -> Entry<K, V> {
            self.map.entry(key)
        }
        #[inline]
        pub fn len(&self) -> usize {
            self.map.len()
        }
        #[inline]
        pub fn is_empty(&self) -> bool {
            self.map.is_empty()
        }
        #[inline]
        pub fn drain(&mut self) -> Drain<K, V> {
            self.map.drain()
        }
        #[inline]
        pub fn clear(&mut self) {
            self.map.clear()
        }
        #[inline]
        pub fn insert(&mut self, k: K, v: V) -> Option<V> {
            self.map.insert(k, v)
        }
        #[inline]
        pub fn contains_key<Q>(&self, k: &Q) -> (bool)
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.contains_key(k)
        }
        #[inline]
        pub fn remove<Q>(&mut self, k: &Q) -> (Option<V>)
            where K: Borrow<Q>,
                  Q: ?Sized + Hash + Eq
        {
            self.map.remove(k)
        }
    }

}

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

    #[test]
    fn add() {
        let mut map: DefaultHashMap<i32, i32> = DefaultHashMap::default();
        *map.get_mut(0) += 1;
        map[1] += 4;
        map[2] = map[0] + map.get(&1);
        assert_eq!(*map.get(0), 1);
        assert_eq!(*map.get(&0), 1);
        assert_eq!(map[0], 1);
        assert_eq!(map[&0], 1);
        assert_eq!(*map.get(&1), 4);
        assert_eq!(*map.get(&2), 5);
        assert_eq!(*map.get(999), 0);
        assert_eq!(*map.get(&999), 0);
        assert_eq!(map[999], 0);
        assert_eq!(map[&999], 0);
    }

    #[test]
    fn counter() {
        let nums = [1, 4, 3, 3, 4, 2, 4];
        let mut counts: DefaultHashMap<i32, i32> = DefaultHashMap::default();
        for num in nums.into_iter() {
            counts[*num] += 1;
        }

        assert_eq!(1, counts[1]);
        assert_eq!(1, counts[2]);
        assert_eq!(2, counts[3]);
        assert_eq!(3, counts[4]);
        assert_eq!(0, counts[5]);
    }

    #[test]
    fn synonyms() {
        let synonym_tuples = [
            ("nice", "sweet"),
            ("sweet", "candy"),
            ("nice", "entertaining"),
            ("nice", "good"),
            ("entertaining", "absorbing"),
        ];

        let mut synonym_map: DefaultHashMap<&str, Vec<&str>> = DefaultHashMap::default();

        for &(l, r) in synonym_tuples.into_iter() {
            synonym_map[l].push(r);
            synonym_map[r].push(l);
        }

        println!("{:#?}", synonym_map);
        assert_eq!(synonym_map["good"], vec!["nice"]);
        assert_eq!(synonym_map["nice"], vec!["sweet", "entertaining", "good"]);
        assert_eq!(synonym_map["evil"], Vec::<&str>::new());
        // assert!(false)
    }

    #[derive(Clone)]
    struct Clonable;

    #[derive(Default, Clone)]
    struct DefaultableValue;

    #[derive(Hash, Eq, PartialEq)]
    struct Hashable(i32);

    #[test]
    fn minimal_derives() {
        let minimal: DefaultHashMap<Hashable, Clonable> = DefaultHashMap::new(Clonable);
        let clonable: DefaultHashMap<Hashable, DefaultableValue> = DefaultHashMap::default();
    }

}
<|endoftext|>


<commit_before>#![feature(unboxed_closures, macro_rules, globs)]

extern crate shader_version;
extern crate event;
extern crate event_loop;
extern crate conrod;
extern crate graphics;
extern crate window;
extern crate opengl_graphics;
extern crate current;
extern crate sdl2_window;

use conrod::*;

use current::Set;
use event::Event;
use event_loop::{Events, Ups, MaxFps};
use opengl_graphics::Gl;
use opengl_graphics::glyph_cache::GlyphCache;
use shader_version::opengl::OpenGL;
use sdl2_window::Sdl2Window;
use window::WindowSettings;

use std::borrow::ToOwned;
use std::default::Default;
use std::io::fs::{mod, PathExtensions};
use std::io::IoResult;
use std::thread::{Thread, JoinGuard};
use std::os;

pub struct FileDialog {
    title: String,
    dimen: [u32, ..2],
    samples: u8,
    background: Color,
    select: SelectType,
    starting_path: Path,
    font: Path,
    filter_hidden: bool,
}

impl FileDialog {
    pub fn new<'a, S: IntoCow<'a, String, str>>(title: S, font: Path) -> FileDialog {
        FileDialog {
            title: title.into_cow().into_owned(),
            dimen: [640, 480],
            samples: 4,
            background: Color::new(0.9, 0.9, 0.9, 1.0), // Should be a nice light-grey
            select: SelectType::File,
            // Possible panic! here, but unlikely.
            starting_path: os::homedir().unwrap_or_else(|| os::getcwd().unwrap()),
            font: font,
            filter_hidden: true,
        }
    }

    pub fn width(mut self, width: u32) -> FileDialog {
        self.dimen[0] = width;
        self
    }

    pub fn height(mut self, height: u32) -> FileDialog {
        self.dimen[1] = height;
        self
    }

    pub fn dimensions(mut self, width: u32, height: u32) -> FileDialog {
        self.dimen = [width, height];
        self
    }

    pub fn set_samples(mut self, samples: u8) -> FileDialog {
        self.samples = samples;
        self
    }

    pub fn set_background(mut self, background: Color) -> FileDialog {
        self.background = background;
        self
    }

    pub fn set_select(mut self, select: SelectType) -> FileDialog {
        self.select = select;
        self
    }

    pub fn set_starting_path(mut self, starting_path: Path) -> FileDialog {
        self.starting_path = starting_path;
        self
    }

    pub fn set_filter_hidden(mut self, filter_hidden: bool) -> FileDialog {
        self.filter_hidden = filter_hidden;
        self
    }

    // How should we format the trait bounds here?
    /// Show the dialog
    pub fn show(self, gl: OpenGL) -> JoinGuard<Option<Path>> {

        Thread::spawn(move || {
            let dialog = DialogSettings {
                background: self.background,
                select: self.select,
                starting_path: self.starting_path,
                font: GlyphCache::new(&self.font).unwrap(),
                filter_hidden: self.filter_hidden,
            };

            let window =  WindowSettings {
                title: self.title,
                size: self.dimen,
                samples: self.samples,
                fullscreen: false,
                exit_on_esc: true,
            };

            render_file_dialog(dialog, window, gl)
        })
    }
}

unsafe impl Send for FileDialog {}

/// An enum describing the file selection behavior.
#[deriving(PartialEq, Eq)]
pub enum SelectType {
    /// User must select an existing file on the filesystem.
    File,
    /// User must select an existing folder on the filesystem, or create a new one.
    Folder,
    /// User must select the location to save a file, and the filename.
    /// The contained `Option<String>` is the default filename, if any.
    SaveFile(Option<String>),
}

impl SelectType {
    fn show_files(&self) -> bool {
        match *self {
            SelectType::File | SelectType::SaveFile(_) => true,
            _ => false,
        }
    }
}

struct DialogSettings {
    background: Color,
    select: SelectType,
    starting_path: Path,
    font: GlyphCache,
    filter_hidden: bool,
}

impl DialogSettings {
    fn into_state(self) -> (DialogState, GlyphCache) {
        (
            DialogState {
                dir: self.starting_path,
                selected: None,
                result: None,
                exit: false,
                paths: Vec::new(),
                background: self.background,
                select: self.select,
                dir_changed: true,
                pages: 0,
                cur_page: 0,
                filter_hidden: self.filter_hidden,
            },
            self.font,
        )
    }
}

fn render_file_dialog(dialog: DialogSettings, window: WindowSettings, gl: OpenGL) -> Option<Path> {
    let (mut state, font) = dialog.into_state();
    state.update_paths();

    let window = Sdl2Window::new(gl, window);
    let mut event_loop = Events::new(window).set(Ups(120)).set(MaxFps(60));
    let mut gl = Gl::new(gl);

    let ref mut uic = UiContext::new(font, Theme::default());
    let ref mut buf: Buffers = Default::default();

    if let SelectType::SaveFile(ref mut opt_file) = state.select {
        opt_file.take().map(|s: String| buf.filename = s);
    }

    for event in event_loop {
        if state.exit { break; }

        uic.handle_event(&event);
        match event {
            Event::Render(args) => {
                gl.draw([0, 0, args.width as i32, args.height as i32], |_, gl| {
                    draw_dialog_ui(gl, uic, &mut state, buf);
                });
            },
            _ => {}
        }
    }

    state.result
}

/// Like format! except writes to an existing string.
macro_rules! write_str(
    ($s:expr, $fmt:expr, $($arg:expr),+) => (
        {
            let vec = unsafe { $s.as_mut_vec() };
            // Should always be `Ok(())` unless something went wrong.
            (write!(vec, $fmt, $($arg),+)).unwrap();
        }
    )
);

#[deriving(Default)]
struct Buffers {
    dir: String,
    page: String,
    filename: String,
    selected: String,
}

impl Buffers {
    fn set_page(&mut self, page: uint, total: uint) {
        self.page.clear();
        write_str!(self.page, "Page: {} Total: {}", page, total);
    }

    fn set_selected(&mut self, selected: &Path) {
        self.selected.clear();
        write_str!(self.selected, "Selected: {}", selected.filename_display());
    }

    fn set_dir(&mut self, dir: &Path) {
        self.dir.clear();
        write_str!(self.dir, "{}", dir.display());
    }
}

struct DialogState {
    dir: Path,
    selected: Option<uint>,
    result: Option<Path>,
    exit: bool,
    paths: Vec<Path>,
    background: Color,
    select: SelectType,
    dir_changed: bool,
    pages: uint,
    cur_page: uint,
    filter_hidden: bool,
}

impl DialogState {
    fn update_dir(&mut self, new_dir: Path) {
        self.dir_changed = if new_dir.is_dir() {
            self.dir = new_dir;
            self.update_paths();
            true
        } else {
            false
        }
    }

    fn update_paths(&mut self) {
        self.selected = None;
        self.paths = entries(&self.dir, self.select.show_files(), self.filter_hidden).unwrap();

        let count = self.paths.len();
        self.pages = count / PER_PAGE;
        self.cur_page = 1;

        if count % PER_PAGE != 0 { self.pages += 1; }
    }

    fn up_dir(&mut self) {
        self.dir_changed = self.dir.pop();
        self.update_paths();
    }

    fn select(&mut self, num: uint, buf: &mut Buffers) {
        // Double-clicked
        if self.selected == Some(num) {
            let path = self.paths.remove(num);

            if self.select.show_files() && !path.is_dir() {
                self.result = Some(path);
                self.exit = true;
            } else {
                self.update_dir(path);
            }
        } else {
            self.selected = Some(num);
            buf.set_selected(&self.paths[num]);
        }
    }

    fn save(&mut self, filename: &str) {
        self.result = Some(self.dir.join(filename));
        self.exit = true;
    }

    fn next_page(&mut self, buf: &mut Buffers) {
        if self.cur_page < self.pages {
            self.cur_page += 1;
            buf.set_page(self.cur_page, self.pages);
        }
    }

    fn prev_page(&mut self, buf: &mut Buffers) {
        if self.cur_page > 1 {
            self.cur_page -= 1;
            buf.set_page(self.cur_page, self.pages);
        }
    }
}

const COLS: uint = 5;
const ROWS: uint = 8;
const PER_PAGE: uint = COLS * ROWS;
const CHAR_LIMIT: uint = 24;

fn draw_dialog_ui(gl: &mut Gl, uic: &mut UiContext, state: &mut DialogState, buf: &mut Buffers) {
    uic.background().color(state.background).draw(gl);

    if state.dir_changed {
        buf.set_dir(&state.dir);
        buf.set_page(state.cur_page, state.pages);
        state.dir_changed = false;
    }

    const UP_DIR: u64 = 78;

    uic.button(UP_DIR)
        .position(605.0, 5.0)
        .dimensions(30.0, 30.0)
        .label("Up")
        .callback(|| state.up_dir())
        .draw(gl);

    uic.label(&*buf.dir)
        .position(5.0, 5.0)
        .size(24)
        .draw(gl);

    const PREV_PAGE: u64 = 199;

    uic.button(PREV_PAGE)
        .position(5.0, 445.0)
        .dimensions(90.0, 30.0)
        .label("Previous")
        .callback(|| state.prev_page(buf))
        .draw(gl);

    const NEXT_PAGE: u64 = PREV_PAGE + 1;

    uic.button(NEXT_PAGE)
        .right_from(PREV_PAGE, 125.0)
        .dimensions(90.0, 30.0)
        .label("Next")
        .callback(|| state.next_page(buf))
        .draw(gl);

    uic.label(&*buf.page)
        .right_from(PREV_PAGE, 15.0)
        .size(24)
        .draw(gl);

    const FILE_START_ID: u64 = 365;
    uic.widget_matrix(COLS, ROWS)
        .position(5.0, 35.0)
        .dimensions(600.0, 400.0)
        .cell_padding(5.0, 5.0)
        .each_widget(|uic, _, x, y, pt, dimen| {
            use std::cmp;
            let idx = (y * COLS * state.cur_page) + x;

            if idx >= state.paths.len() { return; }

            let label = state.paths[idx].filename_str().unwrap().to_owned();

            let button = uic.button(FILE_START_ID + idx as u64)
                .point(pt)
                .dimensions(dimen[0], dimen[1])
                .label(label.slice_to(cmp::min(label.len(), CHAR_LIMIT))).label_font_size(18);

                if state.selected == Some(idx) {
                    button.color(Color::new(0.5, 0.9, 0.5, 1.0))
                } else { button }
                .callback(|| state.select(idx, buf))
                .draw(gl);
        });

    const CANCEL: u64 = 205;
    const CONFIRM: u64 = 206;

    uic.button(CANCEL)
        .right_from(NEXT_PAGE, 140.0)
        .dimensions(90.0, 30.0)
        .callback(|| state.exit = true)
        .label("Cancel")
        .draw(gl);

    {
        let confirm = uic.button(CONFIRM)
            .right_from(CANCEL, 5.0)
            .dimensions(90.0, 30.0);

        if let Some(idx) = state.selected {
            confirm.label(match state.select {
                    SelectType::SaveFile(_) if !state.paths[idx].is_dir() => "Save",
                    _ => "Open",
                })
                .callback(|| state.select(idx, buf))
                .draw(gl);
        } else if state.select == SelectType::Folder {
            confirm.label("Select Folder")
                .callback(|| {
                    state.result = Some(state.dir.clone());
                    state.exit = true
                })
                .draw(gl);
        } else if let SelectType::SaveFile(_) = state.select {
            let confirm = confirm.label("Save");

            if !buf.filename.is_empty() {
                confirm.callback(|| state.save(&*buf.filename))
            } else {
                confirm
            }.draw(gl);
        } else {
            confirm.label("Open").draw(gl);
        }
    }

    const FILENAME: u64 = 210;
    if let SelectType::SaveFile(_) = state.select {
        uic.text_box(FILENAME, &mut buf.filename)
            .right_from(NEXT_PAGE, 5.0)
            .dimensions(130.0, 30.0)
            .draw(gl);
    } else if let Some(_) = state.selected {
        uic.label(&*buf.selected)
            .right_from(NEXT_PAGE, 5.0)
            .size(18)
            .draw(gl);
    }
}

fn entries(path: &Path, keep_files: bool, filter_hidden: bool) -> IoResult<Vec<Path>> {
    let mut entries = try!(fs::readdir(path));
    entries.retain(|file|
        (filter_hidden && !file.filename_str().unwrap().starts_with(".")) &&
        (keep_files || file.is_dir())
    );
    entries.sort();

    Ok(entries)
}

<commit_msg>Update to latest Piston<commit_after>#![feature(unboxed_closures, macro_rules, globs)]

extern crate shader_version;
extern crate event;
extern crate event_loop;
extern crate conrod;
extern crate graphics;
extern crate window;
extern crate opengl_graphics;
extern crate quack;
extern crate sdl2_window;

use conrod::*;

use quack::Set;
use event::Event;
use event_loop::{Events, Ups, MaxFps};
use opengl_graphics::Gl;
use opengl_graphics::glyph_cache::GlyphCache;
use shader_version::opengl::OpenGL;
use sdl2_window::Sdl2Window;
use window::WindowSettings;

use std::borrow::ToOwned;
use std::default::Default;
use std::io::fs::{mod, PathExtensions};
use std::io::IoResult;
use std::thread::{Thread, JoinGuard};
use std::os;

pub struct FileDialog {
    title: String,
    dimen: [u32, ..2],
    samples: u8,
    background: Color,
    select: SelectType,
    starting_path: Path,
    font: Path,
    filter_hidden: bool,
}

impl FileDialog {
    pub fn new<'a, S: IntoCow<'a, String, str>>(title: S, font: Path) -> FileDialog {
        FileDialog {
            title: title.into_cow().into_owned(),
            dimen: [640, 480],
            samples: 4,
            background: Color::new(0.9, 0.9, 0.9, 1.0), // Should be a nice light-grey
            select: SelectType::File,
            // Possible panic! here, but unlikely.
            starting_path: os::homedir().unwrap_or_else(|| os::getcwd().unwrap()),
            font: font,
            filter_hidden: true,
        }
    }

    pub fn width(mut self, width: u32) -> FileDialog {
        self.dimen[0] = width;
        self
    }

    pub fn height(mut self, height: u32) -> FileDialog {
        self.dimen[1] = height;
        self
    }

    pub fn dimensions(mut self, width: u32, height: u32) -> FileDialog {
        self.dimen = [width, height];
        self
    }

    pub fn set_samples(mut self, samples: u8) -> FileDialog {
        self.samples = samples;
        self
    }

    pub fn set_background(mut self, background: Color) -> FileDialog {
        self.background = background;
        self
    }

    pub fn set_select(mut self, select: SelectType) -> FileDialog {
        self.select = select;
        self
    }

    pub fn set_starting_path(mut self, starting_path: Path) -> FileDialog {
        self.starting_path = starting_path;
        self
    }

    pub fn set_filter_hidden(mut self, filter_hidden: bool) -> FileDialog {
        self.filter_hidden = filter_hidden;
        self
    }

    // How should we format the trait bounds here?
    /// Show the dialog
    pub fn show(self, gl: OpenGL) -> JoinGuard<Option<Path>> {

        Thread::spawn(move || {
            let dialog = DialogSettings {
                background: self.background,
                select: self.select,
                starting_path: self.starting_path,
                font: GlyphCache::new(&self.font).unwrap(),
                filter_hidden: self.filter_hidden,
            };

            let window =  WindowSettings {
                title: self.title,
                size: self.dimen,
                samples: self.samples,
                fullscreen: false,
                exit_on_esc: true,
            };

            render_file_dialog(dialog, window, gl)
        })
    }
}

unsafe impl Send for FileDialog {}

/// An enum describing the file selection behavior.
#[deriving(PartialEq, Eq)]
pub enum SelectType {
    /// User must select an existing file on the filesystem.
    File,
    /// User must select an existing folder on the filesystem, or create a new one.
    Folder,
    /// User must select the location to save a file, and the filename.
    /// The contained `Option<String>` is the default filename, if any.
    SaveFile(Option<String>),
}

impl SelectType {
    fn show_files(&self) -> bool {
        match *self {
            SelectType::File | SelectType::SaveFile(_) => true,
            _ => false,
        }
    }
}

struct DialogSettings {
    background: Color,
    select: SelectType,
    starting_path: Path,
    font: GlyphCache,
    filter_hidden: bool,
}

impl DialogSettings {
    fn into_state(self) -> (DialogState, GlyphCache) {
        (
            DialogState {
                dir: self.starting_path,
                selected: None,
                result: None,
                exit: false,
                paths: Vec::new(),
                background: self.background,
                select: self.select,
                dir_changed: true,
                pages: 0,
                cur_page: 0,
                filter_hidden: self.filter_hidden,
            },
            self.font,
        )
    }
}

fn render_file_dialog(dialog: DialogSettings, window: WindowSettings, gl: OpenGL) -> Option<Path> {
    let (mut state, font) = dialog.into_state();
    state.update_paths();

    let window = Sdl2Window::new(gl, window);
    let mut event_loop = Events::new(window).set(Ups(120)).set(MaxFps(60));
    let mut gl = Gl::new(gl);

    let ref mut uic = UiContext::new(font, Theme::default());
    let ref mut buf: Buffers = Default::default();

    if let SelectType::SaveFile(ref mut opt_file) = state.select {
        opt_file.take().map(|s: String| buf.filename = s);
    }

    for event in event_loop {
        if state.exit { break; }

        uic.handle_event(&event);
        match event {
            Event::Render(args) => {
                gl.draw([0, 0, args.width as i32, args.height as i32], |_, gl| {
                    draw_dialog_ui(gl, uic, &mut state, buf);
                });
            },
            _ => {}
        }
    }

    state.result
}

/// Like format! except writes to an existing string.
macro_rules! write_str(
    ($s:expr, $fmt:expr, $($arg:expr),+) => (
        {
            let vec = unsafe { $s.as_mut_vec() };
            // Should always be `Ok(())` unless something went wrong.
            (write!(vec, $fmt, $($arg),+)).unwrap();
        }
    )
);

#[deriving(Default)]
struct Buffers {
    dir: String,
    page: String,
    filename: String,
    selected: String,
}

impl Buffers {
    fn set_page(&mut self, page: uint, total: uint) {
        self.page.clear();
        write_str!(self.page, "Page: {} Total: {}", page, total);
    }

    fn set_selected(&mut self, selected: &Path) {
        self.selected.clear();
        write_str!(self.selected, "Selected: {}", selected.filename_display());
    }

    fn set_dir(&mut self, dir: &Path) {
        self.dir.clear();
        write_str!(self.dir, "{}", dir.display());
    }
}

struct DialogState {
    dir: Path,
    selected: Option<uint>,
    result: Option<Path>,
    exit: bool,
    paths: Vec<Path>,
    background: Color,
    select: SelectType,
    dir_changed: bool,
    pages: uint,
    cur_page: uint,
    filter_hidden: bool,
}

impl DialogState {
    fn update_dir(&mut self, new_dir: Path) {
        self.dir_changed = if new_dir.is_dir() {
            self.dir = new_dir;
            self.update_paths();
            true
        } else {
            false
        }
    }

    fn update_paths(&mut self) {
        self.selected = None;
        self.paths = entries(&self.dir, self.select.show_files(), self.filter_hidden).unwrap();

        let count = self.paths.len();
        self.pages = count / PER_PAGE;
        self.cur_page = 1;

        if count % PER_PAGE != 0 { self.pages += 1; }
    }

    fn up_dir(&mut self) {
        self.dir_changed = self.dir.pop();
        self.update_paths();
    }

    fn select(&mut self, num: uint, buf: &mut Buffers) {
        // Double-clicked
        if self.selected == Some(num) {
            let path = self.paths.remove(num);

            if self.select.show_files() && !path.is_dir() {
                self.result = Some(path);
                self.exit = true;
            } else {
                self.update_dir(path);
            }
        } else {
            self.selected = Some(num);
            buf.set_selected(&self.paths[num]);
        }
    }

    fn save(&mut self, filename: &str) {
        self.result = Some(self.dir.join(filename));
        self.exit = true;
    }

    fn next_page(&mut self, buf: &mut Buffers) {
        if self.cur_page < self.pages {
            self.cur_page += 1;
            buf.set_page(self.cur_page, self.pages);
        }
    }

    fn prev_page(&mut self, buf: &mut Buffers) {
        if self.cur_page > 1 {
            self.cur_page -= 1;
            buf.set_page(self.cur_page, self.pages);
        }
    }
}

const COLS: uint = 5;
const ROWS: uint = 8;
const PER_PAGE: uint = COLS * ROWS;
const CHAR_LIMIT: uint = 24;

fn draw_dialog_ui(gl: &mut Gl, uic: &mut UiContext, state: &mut DialogState, buf: &mut Buffers) {
    uic.background().color(state.background).draw(gl);

    if state.dir_changed {
        buf.set_dir(&state.dir);
        buf.set_page(state.cur_page, state.pages);
        state.dir_changed = false;
    }

    const UP_DIR: u64 = 78;

    uic.button(UP_DIR)
        .position(605.0, 5.0)
        .dimensions(30.0, 30.0)
        .label("Up")
        .callback(|| state.up_dir())
        .draw(gl);

    uic.label(&*buf.dir)
        .position(5.0, 5.0)
        .size(24)
        .draw(gl);

    const PREV_PAGE: u64 = 199;

    uic.button(PREV_PAGE)
        .position(5.0, 445.0)
        .dimensions(90.0, 30.0)
        .label("Previous")
        .callback(|| state.prev_page(buf))
        .draw(gl);

    const NEXT_PAGE: u64 = PREV_PAGE + 1;

    uic.button(NEXT_PAGE)
        .right_from(PREV_PAGE, 125.0)
        .dimensions(90.0, 30.0)
        .label("Next")
        .callback(|| state.next_page(buf))
        .draw(gl);

    uic.label(&*buf.page)
        .right_from(PREV_PAGE, 15.0)
        .size(24)
        .draw(gl);

    const FILE_START_ID: u64 = 365;
    uic.widget_matrix(COLS, ROWS)
        .position(5.0, 35.0)
        .dimensions(600.0, 400.0)
        .cell_padding(5.0, 5.0)
        .each_widget(|uic, _, x, y, pt, dimen| {
            use std::cmp;
            let idx = (y * COLS * state.cur_page) + x;

            if idx >= state.paths.len() { return; }

            let label = state.paths[idx].filename_str().unwrap().to_owned();

            let button = uic.button(FILE_START_ID + idx as u64)
                .point(pt)
                .dimensions(dimen[0], dimen[1])
                .label(label.slice_to(cmp::min(label.len(), CHAR_LIMIT))).label_font_size(18);

                if state.selected == Some(idx) {
                    button.color(Color::new(0.5, 0.9, 0.5, 1.0))
                } else { button }
                .callback(|| state.select(idx, buf))
                .draw(gl);
        });

    const CANCEL: u64 = 205;
    const CONFIRM: u64 = 206;

    uic.button(CANCEL)
        .right_from(NEXT_PAGE, 140.0)
        .dimensions(90.0, 30.0)
        .callback(|| state.exit = true)
        .label("Cancel")
        .draw(gl);

    {
        let confirm = uic.button(CONFIRM)
            .right_from(CANCEL, 5.0)
            .dimensions(90.0, 30.0);

        if let Some(idx) = state.selected {
            confirm.label(match state.select {
                    SelectType::SaveFile(_) if !state.paths[idx].is_dir() => "Save",
                    _ => "Open",
                })
                .callback(|| state.select(idx, buf))
                .draw(gl);
        } else if state.select == SelectType::Folder {
            confirm.label("Select Folder")
                .callback(|| {
                    state.result = Some(state.dir.clone());
                    state.exit = true
                })
                .draw(gl);
        } else if let SelectType::SaveFile(_) = state.select {
            let confirm = confirm.label("Save");

            if !buf.filename.is_empty() {
                confirm.callback(|| state.save(&*buf.filename))
            } else {
                confirm
            }.draw(gl);
        } else {
            confirm.label("Open").draw(gl);
        }
    }

    const FILENAME: u64 = 210;
    if let SelectType::SaveFile(_) = state.select {
        uic.text_box(FILENAME, &mut buf.filename)
            .right_from(NEXT_PAGE, 5.0)
            .dimensions(130.0, 30.0)
            .draw(gl);
    } else if let Some(_) = state.selected {
        uic.label(&*buf.selected)
            .right_from(NEXT_PAGE, 5.0)
            .size(18)
            .draw(gl);
    }
}

fn entries(path: &Path, keep_files: bool, filter_hidden: bool) -> IoResult<Vec<Path>> {
    let mut entries = try!(fs::readdir(path));
    entries.retain(|file|
        (filter_hidden && !file.filename_str().unwrap().starts_with(".")) &&
        (keep_files || file.is_dir())
    );
    entries.sort();

    Ok(entries)
}

<|endoftext|>


<commit_before>extern crate ansi_term;
extern crate hyper;
extern crate hyper_openssl;
extern crate pbr;
extern crate rayon;

use std::sync::{Arc, Mutex};

#[macro_use]
pub mod logs;

pub mod authorization;
pub mod bench;
pub mod cargo_helper;
pub mod client;
pub mod contentlength;
pub mod download;
pub mod filesize;
pub mod http_version;
pub mod response;
pub mod util;
pub mod write;

/// Represents a number of bytes, as `u64`.
pub type Bytes = u64;
/// Represents a 'chunk', which is just a piece of bytes.
type Chunk = Vec<u8>;
/// Represents a list of chunks
pub type Chunks = Vec<Chunk>;
/// Represents a shared mutable reference of chunks
pub type SChunks = Arc<Mutex<Chunks>>;
/// Represents an URL
pub type URL<'a> = &'a str;
/// MirrorsList is an alias that contain fast URLs to download the file
type MirrorsList<'a> = Vec<URL<'a>>;
<commit_msg>Add the protocol module<commit_after>extern crate ansi_term;
extern crate hyper;
extern crate hyper_openssl;
extern crate pbr;
extern crate rayon;

use std::sync::{Arc, Mutex};

#[macro_use]
pub mod logs;

pub mod authorization;
pub mod bench;
pub mod cargo_helper;
pub mod client;
pub mod contentlength;
pub mod download;
pub mod filesize;
pub mod http_version;
pub mod protocol;
pub mod response;
pub mod util;
pub mod write;

/// Represents a number of bytes, as `u64`.
pub type Bytes = u64;
/// Represents a 'chunk', which is just a piece of bytes.
type Chunk = Vec<u8>;
/// Represents a list of chunks
pub type Chunks = Vec<Chunk>;
/// Represents a shared mutable reference of chunks
pub type SChunks = Arc<Mutex<Chunks>>;
/// Represents an URL
pub type URL<'a> = &'a str;
/// MirrorsList is an alias that contain fast URLs to download the file
type MirrorsList<'a> = Vec<URL<'a>>;
<|endoftext|>