<commit_before>// extern crate nom;
// extern crate wasm;
// extern crate wasm_spec;

// use nom::{IResult,Err};
// use std::str;

// fn print(mut err: Err<&[u8]>) {
//     loop {
//         match err {
//             Err::Code(kind) => { println!("Kind {:?}.", kind); return; }
//             Err::Node(kind, rest) => { println!("Nested kind {:?}" , kind); err = *rest }
//             Err::Position(kind,pos) => { println!("Kind {:?} at {}...", kind, str::from_utf8(&pos[..32]).unwrap()); return; }
//             Err::NodePosition(kind, pos, rest) => { println!("Nested kind {:?} at {}...", kind, str::from_utf8(&pos[..32]).unwrap()); err = *rest }
//         }
//     }
// }

// #[test]
// fn spec_tests() {
//     for (test_name, test_wast) in wasm_spec::tests() {
//         match wasm::parser::text::top_level(test_wast.as_bytes()) {
//             IResult::Done(_,_) => (),
//             IResult::Error(err) => { print(err); panic!("Parse error in {}", test_name) },
//             IResult::Incomplete(need) => panic!("Incomplete parse in {}, {:?}.", test_name, need),
//         }
//     }
// }
<commit_msg>Removed wasm tests.<commit_after><|endoftext|>


<commit_before>extern crate serde_json;
extern crate calx;
extern crate rand;

use calx::WeightedChoice;
use rand::{Rng, SeedableRng, XorShiftRng};
use std::collections::HashMap;

#[test]
fn test_serialize_rng() {
    use calx::EncodeRng;

    let mut rng: EncodeRng<XorShiftRng> = SeedableRng::from_seed([1, 2, 3, 4]);

    let saved = serde_json::to_string(&rng).expect("Serialization failed");
    let mut rng2: EncodeRng<XorShiftRng> =
        serde_json::from_str(&saved).expect("Deserialization failed");

    assert_eq!(rng.next_u32(), rng2.next_u32());
}

#[test]
fn test_noise() {
    use calx::noise;

    for i in 0i32..100 {
        assert!(noise(i) >= -1.0 && noise(i) <= 1.0);
    }
}

fn splits_into(space: usize, line: &str, parts: &[&str]) {
    use calx::split_line;

    split_line(line, |_| 1.0, space as f32).zip(parts).all(
        |(actual, &expected)| {
            assert_eq!(expected, actual);
            true
        },
    );

    assert_eq!(parts.len(), split_line(line, |_| 1.0, space as f32).count());
}

#[test]
fn test_split_line() {
    splits_into(10, "", &[""]);
    splits_into(0, "", &[""]);
    splits_into(0, "abc", &["a", "b", "c"]);
    splits_into(10, "abc", &["abc"]);
    splits_into(6, "the cat", &["the", "cat"]);
    splits_into(7, "the cat", &["the cat"]);
    splits_into(10, "the   cat", &["the   cat"]);
    splits_into(5, "the     cat", &["the", "cat"]);
    splits_into(5, "the \t cat", &["the", "cat"]);
    splits_into(4, "deadbeef", &["dead", "beef"]);
    splits_into(5, "the \t cat", &["the", "cat"]);
}

#[test]
fn test_weighted_choice() {
    let mut histogram: HashMap<u32, f32> = HashMap::new();
    let mut rng: XorShiftRng = SeedableRng::from_seed([1, 2, 3, 4]);
    let items = vec![1u32, 2, 3, 4];
    let n = 1000;

    for _ in 0..n {
        let choice = *items
            .iter()
            .weighted_choice(&mut rng, |&&x| x as f32)
            .unwrap();
        *histogram.entry(choice).or_insert(0.0) += 1.0;
    }

    let measurement = vec![
        histogram[&1] / n as f32,
        histogram[&2] / n as f32,
        histogram[&3] / n as f32,
        histogram[&4] / n as f32,
    ];

    // The weights match the values because 1+2+3+4 = 10.
    let ideal = vec![0.1, 0.2, 0.3, 0.4];

    let err = measurement
        .iter()
        .zip(ideal)
        .map(|(x, y)| (x - y) * (x - y))
        .sum::<f32>() / measurement.len() as f32;
    println!("Mean square error from expected: {}", err);
    assert!(err < 0.0001);
}

#[test]
fn test_random_permutation() {
    use calx::RandomPermutation;
    let perm: Vec<usize> = RandomPermutation::new(&mut rand::thread_rng(), 100).collect();
    let mut sorted = perm.clone();
    sorted.sort();
    assert_eq!(sorted, (0..100).collect::<Vec<usize>>());

    // XXX: It is technically possible to get the unpermutating permutation and fail here.
    // Not very likely though.
    assert_ne!(perm, sorted);
    sorted.reverse();
    assert_ne!(perm, sorted);
}

#[test]
fn test_bit_spread() {
    use calx::{compact_bits_by_2, spread_bits_by_2};
    let mut rng = rand::thread_rng();

    for _ in 0..1000 {
        let x = rng.gen::<u16>() as u32;
        assert!(x == 0 || spread_bits_by_2(x) != x);
        assert_eq!(compact_bits_by_2(spread_bits_by_2(x)), x);
    }
}

#[test]
fn test_retry_gen() {
    use calx::retry_gen;

    fn failing_gen<R: Rng>(rng: &mut R) -> Result<f32, ()> {
        let x = rng.next_f32();
        if x < 0.1 { Ok(x) } else { Err(()) }
    }

    assert!(retry_gen(1000, &mut rand::thread_rng(), failing_gen).is_ok());
}
<commit_msg>Fix unit test, would fail for x==1<commit_after>extern crate serde_json;
extern crate calx;
extern crate rand;

use calx::WeightedChoice;
use rand::{Rng, SeedableRng, XorShiftRng};
use std::collections::HashMap;

#[test]
fn test_serialize_rng() {
    use calx::EncodeRng;

    let mut rng: EncodeRng<XorShiftRng> = SeedableRng::from_seed([1, 2, 3, 4]);

    let saved = serde_json::to_string(&rng).expect("Serialization failed");
    let mut rng2: EncodeRng<XorShiftRng> =
        serde_json::from_str(&saved).expect("Deserialization failed");

    assert_eq!(rng.next_u32(), rng2.next_u32());
}

#[test]
fn test_noise() {
    use calx::noise;

    for i in 0i32..100 {
        assert!(noise(i) >= -1.0 && noise(i) <= 1.0);
    }
}

fn splits_into(space: usize, line: &str, parts: &[&str]) {
    use calx::split_line;

    split_line(line, |_| 1.0, space as f32).zip(parts).all(
        |(actual, &expected)| {
            assert_eq!(expected, actual);
            true
        },
    );

    assert_eq!(parts.len(), split_line(line, |_| 1.0, space as f32).count());
}

#[test]
fn test_split_line() {
    splits_into(10, "", &[""]);
    splits_into(0, "", &[""]);
    splits_into(0, "abc", &["a", "b", "c"]);
    splits_into(10, "abc", &["abc"]);
    splits_into(6, "the cat", &["the", "cat"]);
    splits_into(7, "the cat", &["the cat"]);
    splits_into(10, "the   cat", &["the   cat"]);
    splits_into(5, "the     cat", &["the", "cat"]);
    splits_into(5, "the \t cat", &["the", "cat"]);
    splits_into(4, "deadbeef", &["dead", "beef"]);
    splits_into(5, "the \t cat", &["the", "cat"]);
}

#[test]
fn test_weighted_choice() {
    let mut histogram: HashMap<u32, f32> = HashMap::new();
    let mut rng: XorShiftRng = SeedableRng::from_seed([1, 2, 3, 4]);
    let items = vec![1u32, 2, 3, 4];
    let n = 1000;

    for _ in 0..n {
        let choice = *items
            .iter()
            .weighted_choice(&mut rng, |&&x| x as f32)
            .unwrap();
        *histogram.entry(choice).or_insert(0.0) += 1.0;
    }

    let measurement = vec![
        histogram[&1] / n as f32,
        histogram[&2] / n as f32,
        histogram[&3] / n as f32,
        histogram[&4] / n as f32,
    ];

    // The weights match the values because 1+2+3+4 = 10.
    let ideal = vec![0.1, 0.2, 0.3, 0.4];

    let err = measurement
        .iter()
        .zip(ideal)
        .map(|(x, y)| (x - y) * (x - y))
        .sum::<f32>() / measurement.len() as f32;
    println!("Mean square error from expected: {}", err);
    assert!(err < 0.0001);
}

#[test]
fn test_random_permutation() {
    use calx::RandomPermutation;
    let perm: Vec<usize> = RandomPermutation::new(&mut rand::thread_rng(), 100).collect();
    let mut sorted = perm.clone();
    sorted.sort();
    assert_eq!(sorted, (0..100).collect::<Vec<usize>>());

    // XXX: It is technically possible to get the unpermutating permutation and fail here.
    // Not very likely though.
    assert_ne!(perm, sorted);
    sorted.reverse();
    assert_ne!(perm, sorted);
}

#[test]
fn test_bit_spread() {
    use calx::{compact_bits_by_2, spread_bits_by_2};
    use std::u16;

    for x in 0..(u16::MAX as u32 + 1) {
        if x > 1 {
            assert_ne!(x, spread_bits_by_2(x));
        }
        assert_eq!(compact_bits_by_2(spread_bits_by_2(x)), x);
    }
}

#[test]
fn test_retry_gen() {
    use calx::retry_gen;

    fn failing_gen<R: Rng>(rng: &mut R) -> Result<f32, ()> {
        let x = rng.next_f32();
        if x < 0.1 { Ok(x) } else { Err(()) }
    }

    assert!(retry_gen(1000, &mut rand::thread_rng(), failing_gen).is_ok());
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

extern crate rebind;
extern crate input;
extern crate window;

use input::Input;
use input::Button::Keyboard;
use input::keyboard::Key;
use rebind::{Action, Builder, ButtonTuple, InputRebind, InputTranslator, Translated};
use window::Size;

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
enum TestAction {
    Action1,
    Action2,
    Action3,
    Action4,
    Action5,
    Action6,
    Action7,
    Action8,
    Action9,
    Action10,
}

impl Action for TestAction { }

type TestBuilder = Builder<TestAction>;
type TestTranslator = InputTranslator<TestAction>;
type TestRebind = InputRebind<TestAction>;

fn create_prepopulated_builder_with_size(s: Size) -> TestBuilder {
    populate_builder(Builder::new(s))
}

fn create_prepopulated_builder() -> TestBuilder {
    populate_builder(Builder::default())
}

fn populate_builder(builder: TestBuilder) -> TestBuilder {
    builder.with_mapping(TestAction::Action1, Keyboard(Key::Up))
           .with_mapping(TestAction::Action1, Keyboard(Key::W))
           .with_mapping(TestAction::Action2, Keyboard(Key::Down))
           .with_mapping(TestAction::Action2, Keyboard(Key::S))
           .with_mapping(TestAction::Action3, Keyboard(Key::Left))
           .with_mapping(TestAction::Action3, Keyboard(Key::A))
           .with_mapping(TestAction::Action4, Keyboard(Key::Right))
           .with_mapping(TestAction::Action4, Keyboard(Key::D))
}

#[test]
fn test_translator_get_action_from_buttonpress() {
    let translator = create_prepopulated_builder().build_translator();

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::Down))).unwrap(),
               Translated::Press(TestAction::Action2));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::D))).unwrap(),
               Translated::Press(TestAction::Action4));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::Left))).unwrap(),
               Translated::Press(TestAction::Action3));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::W))).unwrap(),
               Translated::Press(TestAction::Action1));
}

#[test]
fn test_conversion_from_rebind_to_translator() {
    let translator = create_prepopulated_builder().build_translator();

    let translator_clone = translator.clone();
    let converted_translator = Into::<TestTranslator>::into(Into::<TestRebind>::into(translator));

    assert_eq!(translator_clone, converted_translator);
}

#[test]
fn test_add_button_to_translator_using_rebind() {
    use input::Button;
    const Q_KEY: Button = Keyboard(Key::Q);
    const E_KEY: Button = Keyboard(Key::E);

    let translator = create_prepopulated_builder().build_translator();
    let mut rebind = translator.into_rebind();
    rebind.insert_action_with_buttons(TestAction::Action5,
                                      ButtonTuple(Some(Q_KEY), Some(E_KEY), None));

    let translator = rebind.into_translator();

    assert_eq!(translator.translate(&Input::Press(Q_KEY)),
               Some(Translated::Press(TestAction::Action5)));
    assert_eq!(translator.translate(&Input::Press(E_KEY)),
               Some(Translated::Press(TestAction::Action5)));
}

#[test]
fn test_unmodified_mouse_input_works() {
    const TEST_SIZE: Size = Size { width: 800, height: 600 };

    let translator = create_prepopulated_builder_with_size(TEST_SIZE).build_translator();
    unimplemented!();
    // assert_eq!(translator.translate(&Input::))
}

#[test]
fn test_mirror_mouse_input_along_x_axis() {
    const TEST_SIZE: Size = Size { width: 800, height: 600 };

    let translator = create_prepopulated_builder_with_size(TEST_SIZE).build_translator();
    unimplemented!();
    // assert_eq!(translator.translate(&Input::))
}

#[test]
fn test_mirror_mouse_input_along_y_axis() {
    const TEST_SIZE: Size = Size { width: 800, height: 600 };

    let translator = create_prepopulated_builder_with_size(TEST_SIZE).build_translator();
    unimplemented!();
    // assert_eq!(translator.translate(&Input::))
}

#[test]
fn test_get_num_buttons_set() {
    let mut bt = ButtonTuple::new();
    assert_eq!(bt.num_buttons_set(), 0);

    bt.0 = Some(Keyboard(Key::Z));
    assert_eq!(bt.num_buttons_set(), 1);

    bt.1 = Some(Keyboard(Key::Q));
    assert_eq!(bt.num_buttons_set(), 2);

    bt.2 = Some(Keyboard(Key::D0));
    assert_eq!(bt.num_buttons_set(), 3);
}

#[test]
fn test_get_button_iter_len() {
    let bt = ButtonTuple(Some(Keyboard(Key::B)), None, None);
    let mut bti = bt.iter();
    assert_eq!(bti.len(), 3);
    let _ = bti.next();
    assert_eq!(bti.len(), 2);
    let _ = bti.next();
    assert_eq!(bti.len(), 1);
    let _ = bti.next();
    assert_eq!(bti.len(), 0);
    let _ = bti.next();
    assert_eq!(bti.len(), 0);
}
<commit_msg>Add leading underscore to unused variables and lift out common const `TEST_SIZE` to global scope<commit_after>#![allow(dead_code)]

extern crate rebind;
extern crate input;
extern crate window;

use input::Input;
use input::Button::Keyboard;
use input::keyboard::Key;
use rebind::{Action, Builder, ButtonTuple, InputRebind, InputTranslator, Translated};
use window::Size;

#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Ord, PartialOrd)]
enum TestAction {
    Action1,
    Action2,
    Action3,
    Action4,
    Action5,
    Action6,
    Action7,
    Action8,
    Action9,
    Action10,
}

impl Action for TestAction { }

type TestBuilder = Builder<TestAction>;
type TestTranslator = InputTranslator<TestAction>;
type TestRebind = InputRebind<TestAction>;

fn create_prepopulated_builder_with_size(s: Size) -> TestBuilder {
    populate_builder(Builder::new(s))
}

fn create_prepopulated_builder() -> TestBuilder {
    populate_builder(Builder::default())
}

fn populate_builder(builder: TestBuilder) -> TestBuilder {
    builder.with_mapping(TestAction::Action1, Keyboard(Key::Up))
           .with_mapping(TestAction::Action1, Keyboard(Key::W))
           .with_mapping(TestAction::Action2, Keyboard(Key::Down))
           .with_mapping(TestAction::Action2, Keyboard(Key::S))
           .with_mapping(TestAction::Action3, Keyboard(Key::Left))
           .with_mapping(TestAction::Action3, Keyboard(Key::A))
           .with_mapping(TestAction::Action4, Keyboard(Key::Right))
           .with_mapping(TestAction::Action4, Keyboard(Key::D))
}

#[test]
fn test_translator_get_action_from_buttonpress() {
    let translator = create_prepopulated_builder().build_translator();

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::Down))).unwrap(),
               Translated::Press(TestAction::Action2));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::D))).unwrap(),
               Translated::Press(TestAction::Action4));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::Left))).unwrap(),
               Translated::Press(TestAction::Action3));

    assert_eq!(translator.translate(&Input::Press(Keyboard(Key::W))).unwrap(),
               Translated::Press(TestAction::Action1));
}

#[test]
fn test_conversion_from_rebind_to_translator() {
    let translator = create_prepopulated_builder().build_translator();

    let translator_clone = translator.clone();
    let converted_translator = Into::<TestTranslator>::into(Into::<TestRebind>::into(translator));

    assert_eq!(translator_clone, converted_translator);
}

#[test]
fn test_add_button_to_translator_using_rebind() {
    use input::Button;
    const Q_KEY: Button = Keyboard(Key::Q);
    const E_KEY: Button = Keyboard(Key::E);

    let translator = create_prepopulated_builder().build_translator();
    let mut rebind = translator.into_rebind();
    rebind.insert_action_with_buttons(TestAction::Action5,
                                      ButtonTuple(Some(Q_KEY), Some(E_KEY), None));

    let translator = rebind.into_translator();

    assert_eq!(translator.translate(&Input::Press(Q_KEY)),
               Some(Translated::Press(TestAction::Action5)));
    assert_eq!(translator.translate(&Input::Press(E_KEY)),
               Some(Translated::Press(TestAction::Action5)));
}

const TEST_SIZE: Size = Size { width: 800, height: 600 };

#[test]
fn test_unmodified_mouse_input_works() {
    let _translator = create_prepopulated_builder_with_size(TEST_SIZE).build_translator();
    unimplemented!();
    // assert_eq!(translator.translate(&Input::))
}

#[test]
fn test_mirror_mouse_input_along_x_axis() {
    let _translator = create_prepopulated_builder_with_size(TEST_SIZE).build_translator();
    unimplemented!();
    // assert_eq!(translator.translate(&Input::))
}

#[test]
fn test_mirror_mouse_input_along_y_axis() {
    let _translator = create_prepopulated_builder_with_size(TEST_SIZE).build_translator();
    unimplemented!();
    // assert_eq!(translator.translate(&Input::))
}

#[test]
fn test_get_num_buttons_set() {
    let mut bt = ButtonTuple::new();
    assert_eq!(bt.num_buttons_set(), 0);

    bt.0 = Some(Keyboard(Key::Z));
    assert_eq!(bt.num_buttons_set(), 1);

    bt.1 = Some(Keyboard(Key::Q));
    assert_eq!(bt.num_buttons_set(), 2);

    bt.2 = Some(Keyboard(Key::D0));
    assert_eq!(bt.num_buttons_set(), 3);
}

#[test]
fn test_get_button_iter_len() {
    let bt = ButtonTuple(Some(Keyboard(Key::B)), None, None);
    let mut bti = bt.iter();
    assert_eq!(bti.len(), 3);
    let _ = bti.next();
    assert_eq!(bti.len(), 2);
    let _ = bti.next();
    assert_eq!(bti.len(), 1);
    let _ = bti.next();
    assert_eq!(bti.len(), 0);
    let _ = bti.next();
    assert_eq!(bti.len(), 0);
}
<|endoftext|>


<commit_before>use std::ops::{Add};

/// A pair of coordinates
#[derive(Clone, Copy)]
pub struct Vec2(pub usize, pub usize);

/// A structure of values
pub struct Matrix<T> {
    /// 2 dimensional array of rows and columns
    dim: Vec2,
    /// `Vector` of values in the `Matrix`
    buffer: Vec<T>,
}

impl <T> Matrix<T> {
    /// Returns a new `Matrix`
    ///
    /// # Arguments
    ///
    /// - `dimensions` - 2 dimensional array of rows and columns
    /// - `buffer` - `Vector` of values
    ///
    /// # Example
    ///
    /// ```
    /// let matrix = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0, 1, 2, 3, 4, 5]);
    /// ```
    pub fn new(dimensions: Vec2, buffer: Vec<T>) -> Matrix<T> {
        Matrix {
            dim: dimensions,
            buffer: buffer,
        }
    }
}

impl <T> Matrix<T> where T: Copy {
    /// Returns reference to value at `Vec2`
    ///
    /// # Arguments
    ///
    /// - `Vec2` - coordinates of the value in the `Matrix`
    ///
    /// # Example
    ///
    /// ```
    /// let matrix = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0, 1, 2, 3, 4, 5]);
    /// assert_eq!(matrix.get(ktensor::math::Vec2(1, 2)), 5);
    /// assert_eq!(matrix.get(ktensor::math::Vec2(1, 2)), 5);
    /// ```
    pub fn get(&self, Vec2(x, y): Vec2) -> T {
        self.buffer[x * self.dim.1 + y]
    }
}

/// Add Matricies
///
/// # Arguments
///
/// - `self` - this matrix
/// - `rhs` - another matrix
///
/// # Example
///
/// ```
/// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
/// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
/// let matrix3 = matrix1 + matrix2;
/// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
/// ```
impl<T> Add<Matrix<T>> for Matrix<T> where T: Add + Copy {
    type Output = Matrix<<T as Add>::Output>;
    fn add(self, rhs: Matrix<T>) -> Matrix<<T as Add>::Output> {
        let mut buffer = Vec::new();
        for (&i, &j) in self.buffer.iter().zip(rhs.buffer.iter()) {
            buffer.push(i + j);
        }
        Matrix::new(self.dim, buffer)
    }
}

/// Add Matricies by reference
///
/// # Arguments
///
/// - `self` - this matrix reference
/// - `rhs` - another matrix reference
///
/// # Example
///
/// ```
/// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
/// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
/// let matrix3 = &matrix1 + &matrix2;
/// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 0)), 0.0);
/// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 5.0);
/// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
/// ```
impl<'a, 'b, T> Add<&'b Matrix<T>> for &'a Matrix<T> where T: Add + Copy {
    type Output = Matrix<<T as Add>::Output>;
    fn add(self, rhs: &'b Matrix<T>) -> Matrix<<T as Add>::Output> {
        let mut buffer = Vec::new();
        for (&i, &j) in self.buffer.iter().zip(rhs.buffer.iter()) {
            buffer.push(i + j);
        }
        Matrix::new(self.dim, buffer)
    }
}

/// Add Matrix and a constant
///
/// # Arguments
///
/// - `self` - this matrix
/// - `rhs` - a constant
///
/// # Example
///
/// ```
/// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
/// let float = 1.0;
/// let matrix2 = matrix1 + float;
/// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 1.0);
/// ```
impl<T> Add<T> for Matrix<T> where T: Add + Copy {
    type Output = Matrix<<T as Add>::Output>;
    fn add(self, rhs: T) -> Matrix<<T as Add>::Output> {
        let mut buffer = Vec::new();
        for &i in self.buffer.iter() {
            buffer.push(i + rhs);
        }
        Matrix::new(self.dim, buffer)
    }
}

/// Add Matrix and a constant
///
/// # Arguments
///
/// - `self` - this matrix reference
/// - `rhs` - a constant reference
///
/// # Example
///
/// ```
/// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
/// let float = 1.0;
/// let matrix2 = &matrix1 + &float;
/// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 0)), 0.0);
/// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 1.0);
/// assert_eq!(float, 1.0);
/// ```
impl<'a, 'b, T> Add<&'b T> for &'a Matrix<T> where T: Add + Copy {
    type Output = Matrix<<T as Add>::Output>;
    fn add(self, &rhs: &'b T) -> Matrix<<T as Add>::Output> {
        let mut buffer = Vec::new();
        for &i in self.buffer.iter() {
            buffer.push(i + rhs);
        }
        Matrix::new(self.dim, buffer)
    }
}
<commit_msg>proper doc comments<commit_after>use std::ops::{Add};

/// A pair of coordinates
#[derive(Clone, Copy)]
pub struct Vec2(pub usize, pub usize);

/// A structure of values
pub struct Matrix<T> {
    /// 2 dimensional array of rows and columns
    dim: Vec2,
    /// `Vector` of values in the `Matrix`
    buffer: Vec<T>,
}

impl <T> Matrix<T> {
    /// Returns a new `Matrix`
    ///
    /// # Arguments
    ///
    /// - `dimensions` - 2 dimensional array of rows and columns
    /// - `buffer` - `Vector` of values
    ///
    /// # Example
    ///
    /// ```
    /// let matrix = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0, 1, 2, 3, 4, 5]);
    /// ```
    pub fn new(dimensions: Vec2, buffer: Vec<T>) -> Matrix<T> {
        Matrix {
            dim: dimensions,
            buffer: buffer,
        }
    }
}

impl <T> Matrix<T> where T: Copy {
    /// Returns reference to value at `Vec2`
    ///
    /// # Arguments
    ///
    /// - `Vec2` - coordinates of the value in the `Matrix`
    ///
    /// # Example
    ///
    /// ```
    /// let matrix = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0, 1, 2, 3, 4, 5]);
    /// assert_eq!(matrix.get(ktensor::math::Vec2(1, 2)), 5);
    /// assert_eq!(matrix.get(ktensor::math::Vec2(1, 2)), 5);
    /// ```
    pub fn get(&self, Vec2(x, y): Vec2) -> T {
        self.buffer[x * self.dim.1 + y]
    }
}

impl<T> Add<Matrix<T>> for Matrix<T> where T: Add + Copy {
    type Output = Matrix<<T as Add>::Output>;

    /// Add Matricies
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix
    /// - `rhs` - another matrix
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
    /// let matrix3 = matrix1 + matrix2;
    /// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// ```
    fn add(self, rhs: Matrix<T>) -> Matrix<<T as Add>::Output> {
        let mut buffer = Vec::new();
        for (&i, &j) in self.buffer.iter().zip(rhs.buffer.iter()) {
            buffer.push(i + j);
        }
        Matrix::new(self.dim, buffer)
    }
}

impl<'a, 'b, T> Add<&'b Matrix<T>> for &'a Matrix<T> where T: Add + Copy {
    type Output = Matrix<<T as Add>::Output>;

    /// Add Matricies by reference
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix reference
    /// - `rhs` - another matrix reference
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let matrix2 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![5.0, 4.0, 3.0, 2.0, 1.0, 0.0]);
    /// let matrix3 = &matrix1 + &matrix2;
    /// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 0)), 0.0);
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// assert_eq!(matrix3.get(ktensor::math::Vec2(0, 0)), 5.0);
    /// ```
    fn add(self, rhs: &'b Matrix<T>) -> Matrix<<T as Add>::Output> {
        let mut buffer = Vec::new();
        for (&i, &j) in self.buffer.iter().zip(rhs.buffer.iter()) {
            buffer.push(i + j);
        }
        Matrix::new(self.dim, buffer)
    }
}

impl<T> Add<T> for Matrix<T> where T: Add + Copy {
    type Output = Matrix<<T as Add>::Output>;

    /// Add Matrix and a constant
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix
    /// - `rhs` - a constant
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let float = 1.0;
    /// let matrix2 = matrix1 + float;
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 1.0);
    /// ```
    fn add(self, rhs: T) -> Matrix<<T as Add>::Output> {
        let mut buffer = Vec::new();
        for &i in self.buffer.iter() {
            buffer.push(i + rhs);
        }
        Matrix::new(self.dim, buffer)
    }
}

impl<'a, 'b, T> Add<&'b T> for &'a Matrix<T> where T: Add + Copy {
    type Output = Matrix<<T as Add>::Output>;

    /// Add Matrix and a constant
    ///
    /// # Arguments
    ///
    /// - `self` - this matrix reference
    /// - `rhs` - a constant reference
    ///
    /// # Example
    ///
    /// ```
    /// let matrix1 = ktensor::math::Matrix::new(ktensor::math::Vec2(2, 3), vec![0.0, 1.0, 2.0, 3.0, 4.0, 5.0]);
    /// let float = 1.0;
    /// let matrix2 = &matrix1 + &float;
    /// assert_eq!(matrix1.get(ktensor::math::Vec2(0, 0)), 0.0);
    /// assert_eq!(matrix2.get(ktensor::math::Vec2(0, 0)), 1.0);
    /// assert_eq!(float, 1.0);
    /// ```
    fn add(self, &rhs: &'b T) -> Matrix<<T as Add>::Output> {
        let mut buffer = Vec::new();
        for &i in self.buffer.iter() {
            buffer.push(i + rhs);
        }
        Matrix::new(self.dim, buffer)
    }
}
<|endoftext|>


<commit_before>//#![crate_name = "mesh"]
#![feature(old_io)]
//mod mesh;

use std::cmp::*;
use std::collections::HashMap;
use std::f32::NAN;
use std::fmt;
use std::num::Float;
use std::old_io::{BufferedReader,IoResult,Reader};
use std::hash::{Hash, Hasher};
use std::mem::{transmute};
use std::vec::Vec;

#[derive(PartialEq, PartialOrd, Copy)] //Show,
pub struct Vector3D {
    x: f32,
    y: f32,
    z: f32,
}

// PartialEq is derived above, but we need to impl Eq since floats don't get
// it by default. This function is just a
impl Eq for Vector3D {
    #[inline(always)]
    fn assert_receiver_is_total_eq(&self) {}
}

impl fmt::Debug for Vector3D {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({},{},{})", self.x, self.y, self.z)
    }
}

impl Vector3D {
    fn read(r: &mut Reader) -> IoResult<Vector3D> {
        let xr = try!(r.read_le_f32());
        let yr = try!(r.read_le_f32());
        let zr = try!(r.read_le_f32());
        return Ok(Vector3D { x: xr, y: yr, z: zr });
    }
    fn minus(&self, o: Vector3D) -> Vector3D {
        let x = self.x - o.x;
        let y = self.y - o.y;
        let z = self.z - o.z;
        Vector3D {
            x: x,
            y: y,
            z: z
        }
    }

    fn cross(a: Vector3D, b:Vector3D) -> Vector3D {
        let cx = a.y * b.z - a.z * b.y;
        let cy = a.z * b.x - a.x * b.z;
        let cz = a.x * b.y - a.y * b.x;
        Vector3D {
        x: cx,
        y: cy,
        z: cz
        }
    }

    fn normalize(&self) -> Vector3D {
        // length = sqrt((ax * ax) + (ay * ay) + (az * az))
        let length = (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
        let x = self.x / length;
        let y = self.y / length;
        let z = self.z / length;
        Vector3D {
            x: x,
            y: y,
            z: z
        }
    }
}

#[test]
fn vectors_can_be_subtracted() {
    //let l = Vector3D{1,1,1}
    //let r = Vector3D{2,3,4}
    assert!(false);
}

// Implement Hash since there is no default for f32. We'll just hash the bits
// since we know the f32s will all be canonical from reading.
impl Hash for Vector3D {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        //println!("V3D hash {:p}", self);
        let x: u32 = unsafe { transmute(self.x) };
        x.hash(state);
        let y: u32 = unsafe { transmute(self.y) };
        y.hash(state);
        let z: u32 = unsafe { transmute(self.z) };
        z.hash(state);
        //println!("V3D hash done {:p}", self);
    }
}

pub struct StlHeader {
    header: [u8; 80],
}

#[derive(PartialEq, Eq, Hash, Copy)]
pub struct StlFacet {
    n : Vector3D,
    v1: Vector3D,
    v2: Vector3D,
    v3: Vector3D,
    abc: u16,
}

impl fmt::Debug for StlFacet {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[{:?}]({:?}-{:?}-{:?})[{:X}]",
            &self.n, &self.v1, &self.v2, &self.v3, self.abc)
    }
}

impl StlFacet {
    fn read(r: &mut Reader) -> IoResult<StlFacet> {
        let n = try!(Vector3D::read(r));
        let v1 = try!(Vector3D::read(r));
        let v2 = try!(Vector3D::read(r));
        let v3 = try!(Vector3D::read(r));
        let abc = try!(r.read_le_u16());
        return Ok(StlFacet { n:n, v1:v1, v2:v2, v3:v3, abc:abc });
    }

    fn calculate_normal_vector(&self) -> Vector3D {
        // Dir = (B - A) x (C - A)
        // Norm = Dir / len(Dir)
        let direction = Vector3D::cross( self.v2.minus(self.v1), self.v3.minus(self.v1) );

        // Normalize is optional in our use case
        direction.normalize()
    }
}

pub struct VertexMap {
    vertices: HashMap<Vector3D,usize>,
}

impl VertexMap {
    pub fn new() -> VertexMap {
        VertexMap {
            vertices: HashMap::new(),
        }
    }

    pub fn len(&self) -> usize {
        self.vertices.len()
    }

    pub fn get(&self, v3d: &Vector3D) -> usize {
        *self.vertices.get(v3d).unwrap()
    }

    pub fn add(&mut self, vertex: Vector3D) -> usize {
        if self.vertices.contains_key(&vertex) {
            //println!("add existing {}", vector3d_str(&vertex));
            *self.vertices.get(&vertex).unwrap()
        } else {
            //println!("add new {}", vector3d_str(&vertex));
            let idx = self.vertices.len();
            self.vertices.insert(vertex, idx);
            idx
        }
    }

    pub fn vector(&self) -> Vec<Vector3D> {
        let mut v: Vec<Vector3D> = Vec::with_capacity(self.vertices.len());
        for (v3d, idx) in self.vertices.iter() {
            v.push(*v3d);  // Funkiness just to get v expanded. Below writes the real values.
        }
        for (v3d, idx) in self.vertices.iter() {
            //println!("v3d:{:?} idx:{}", v3d, idx);
            v[*idx] = *v3d;
        }
        //for i in 0..v.len() {
        //    println!("v3d[{}]: {:?}", i, v[i]);
        //}
        v
    }
}

#[derive(PartialEq, Debug, Eq, Hash, Copy)]
pub struct Facet {
    v1: usize,
    v2: usize,
    v3: usize,
    n: Vector3D
}

pub struct Mesh {
    vertices: Vec<Vector3D>,
    facets: Vec<Facet>,
}

impl Mesh {
    pub fn new() -> Mesh {
        Mesh {
            vertices: Vec::new(),
            facets: Vec::new(),
        }
    }

    fn indexed_vertices(fv: &Vec<StlFacet>, vm: &VertexMap) -> Vec<Facet> {
        let mut v: Vec<Facet> = Vec::with_capacity(fv.len());
        for f in fv.iter() {
            let v1 = vm.get(&f.v1);
            let v2 = vm.get(&f.v2);
            let v3 = vm.get(&f.v3);
            // I wish there was a better place to put this
            let n = f.calculate_normal_vector();
            v.push(Facet{
                v1: v1,
                v2: v2,
                v3: v3,
                n: n,
            })
        }
        v
    }

    pub fn new_from_stl(fv: &Vec<StlFacet>, vm: &VertexMap) -> Mesh {
        let vs = vm.vector();
        let fs = Mesh::indexed_vertices(fv, vm);
        Mesh {
            vertices: vs,
            facets: fs,
        }
    }

    pub fn read<R: Reader>(r: &mut R) -> IoResult<Mesh> {

        let mut header = StlHeader { header: [0u8; 80] };
        try!(r.read_at_least(header.header.len(), &mut header.header));

        let hs = String::from_utf8_lossy(&header.header);
        if hs.starts_with("solid ") {
            println!("Is ASCII STL");
        } else {
            println!("Is binary STL");
        }

        Mesh::read_binary(r)
    }

    /*
    fn read_ascii(r: &mut Reader) -> IoResult<Mesh> {
        //solid vcg
        //  facet normal 7.733874e-001 -3.151335e-002 6.331499e-001
        //    outer loop
        //      vertex  2.137833e+001 5.385936e+001 1.350253e+001
        //      vertex  2.341920e+001 4.700068e+001 1.066826e+001
        //      vertex  2.859041e+001 5.985682e+001 4.991545e+000
        //    endloop
        //  endfacet
        //endsolid vcg
        for line in r.lines() {
            print!("{}", line.unwrap());
        }
        Mesh::new() // TODO
    }
    */

    fn read_binary(r: &mut Reader) -> IoResult<Mesh> {
        let facet_count = match r.read_le_u32() {
            Ok(c) => { println!("Facets: {}", c); c},
            Err(e) => { println!("Truncated file: {}", e); 0},
        };

        let mut facets: Vec<StlFacet> = Vec::with_capacity(facet_count as usize);
        let mut vertices = VertexMap::new();
        println!("Collections ready");

        for fi in range(0, facet_count) {
            let f = match StlFacet::read(r) {
                Ok(x) => x,
                Err(e) => panic!("file error: {}", e),
            };
            let v1i = vertices.add(f.v1);
            let v2i = vertices.add(f.v2);
            let v3i = vertices.add(f.v3);
            println!("  Facet[{}]: {:?} => {}-{}-{}", fi, f, v1i, v2i, v3i);
            facets.push(f);
        }
        println!("Vertices: {}", vertices.len());

        Ok(Mesh::new_from_stl(&facets, &vertices))
    }
}
<commit_msg>A test for subtract<commit_after>//#![crate_name = "mesh"]
#![feature(old_io)]
//mod mesh;

use std::cmp::*;
use std::collections::HashMap;
use std::f32::NAN;
use std::fmt;
use std::num::Float;
use std::old_io::{BufferedReader,IoResult,Reader};
use std::hash::{Hash, Hasher};
use std::mem::{transmute};
use std::vec::Vec;

#[derive(PartialEq, PartialOrd, Copy)] //Show,
pub struct Vector3D {
    x: f32,
    y: f32,
    z: f32,
}

// PartialEq is derived above, but we need to impl Eq since floats don't get
// it by default. This function is just a
impl Eq for Vector3D {
    #[inline(always)]
    fn assert_receiver_is_total_eq(&self) {}
}

impl fmt::Debug for Vector3D {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "({},{},{})", self.x, self.y, self.z)
    }
}

impl Vector3D {
    fn read(r: &mut Reader) -> IoResult<Vector3D> {
        let xr = try!(r.read_le_f32());
        let yr = try!(r.read_le_f32());
        let zr = try!(r.read_le_f32());
        return Ok(Vector3D { x: xr, y: yr, z: zr });
    }
    fn minus(&self, o: Vector3D) -> Vector3D {
        let x = self.x - o.x;
        let y = self.y - o.y;
        let z = self.z - o.z;
        Vector3D {
            x: x,
            y: y,
            z: z
        }
    }

    fn cross(a: Vector3D, b:Vector3D) -> Vector3D {
        let cx = a.y * b.z - a.z * b.y;
        let cy = a.z * b.x - a.x * b.z;
        let cz = a.x * b.y - a.y * b.x;
        Vector3D {
        x: cx,
        y: cy,
        z: cz
        }
    }

    fn normalize(&self) -> Vector3D {
        // length = sqrt((ax * ax) + (ay * ay) + (az * az))
        let length = (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
        let x = self.x / length;
        let y = self.y / length;
        let z = self.z / length;
        Vector3D {
            x: x,
            y: y,
            z: z
        }
    }
}

#[test]
fn vectors_can_be_subtracted() {
    let l = Vector3D {x:1.0, y:1.0, z:1.0};
    let r = Vector3D {x:2.0, y:3.0, z:4.0};
    let result = l.minus(r);
    assert_eq!(result.x, -1.0);
    assert_eq!(result.y, -2.0);
    assert_eq!(result.z, -3.0);
}

// Implement Hash since there is no default for f32. We'll just hash the bits
// since we know the f32s will all be canonical from reading.
impl Hash for Vector3D {
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        //println!("V3D hash {:p}", self);
        let x: u32 = unsafe { transmute(self.x) };
        x.hash(state);
        let y: u32 = unsafe { transmute(self.y) };
        y.hash(state);
        let z: u32 = unsafe { transmute(self.z) };
        z.hash(state);
        //println!("V3D hash done {:p}", self);
    }
}

pub struct StlHeader {
    header: [u8; 80],
}

#[derive(PartialEq, Eq, Hash, Copy)]
pub struct StlFacet {
    n : Vector3D,
    v1: Vector3D,
    v2: Vector3D,
    v3: Vector3D,
    abc: u16,
}

impl fmt::Debug for StlFacet {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "[{:?}]({:?}-{:?}-{:?})[{:X}]",
            &self.n, &self.v1, &self.v2, &self.v3, self.abc)
    }
}

impl StlFacet {
    fn read(r: &mut Reader) -> IoResult<StlFacet> {
        let n = try!(Vector3D::read(r));
        let v1 = try!(Vector3D::read(r));
        let v2 = try!(Vector3D::read(r));
        let v3 = try!(Vector3D::read(r));
        let abc = try!(r.read_le_u16());
        return Ok(StlFacet { n:n, v1:v1, v2:v2, v3:v3, abc:abc });
    }

    fn calculate_normal_vector(&self) -> Vector3D {
        // Dir = (B - A) x (C - A)
        // Norm = Dir / len(Dir)
        let direction = Vector3D::cross( self.v2.minus(self.v1), self.v3.minus(self.v1) );

        // Normalize is optional in our use case
        direction.normalize()
    }
}

pub struct VertexMap {
    vertices: HashMap<Vector3D,usize>,
}

impl VertexMap {
    pub fn new() -> VertexMap {
        VertexMap {
            vertices: HashMap::new(),
        }
    }

    pub fn len(&self) -> usize {
        self.vertices.len()
    }

    pub fn get(&self, v3d: &Vector3D) -> usize {
        *self.vertices.get(v3d).unwrap()
    }

    pub fn add(&mut self, vertex: Vector3D) -> usize {
        if self.vertices.contains_key(&vertex) {
            //println!("add existing {}", vector3d_str(&vertex));
            *self.vertices.get(&vertex).unwrap()
        } else {
            //println!("add new {}", vector3d_str(&vertex));
            let idx = self.vertices.len();
            self.vertices.insert(vertex, idx);
            idx
        }
    }

    pub fn vector(&self) -> Vec<Vector3D> {
        let mut v: Vec<Vector3D> = Vec::with_capacity(self.vertices.len());
        for (v3d, idx) in self.vertices.iter() {
            v.push(*v3d);  // Funkiness just to get v expanded. Below writes the real values.
        }
        for (v3d, idx) in self.vertices.iter() {
            //println!("v3d:{:?} idx:{}", v3d, idx);
            v[*idx] = *v3d;
        }
        //for i in 0..v.len() {
        //    println!("v3d[{}]: {:?}", i, v[i]);
        //}
        v
    }
}

#[derive(PartialEq, Debug, Eq, Hash, Copy)]
pub struct Facet {
    v1: usize,
    v2: usize,
    v3: usize,
    n: Vector3D
}

pub struct Mesh {
    vertices: Vec<Vector3D>,
    facets: Vec<Facet>,
}

impl Mesh {
    pub fn new() -> Mesh {
        Mesh {
            vertices: Vec::new(),
            facets: Vec::new(),
        }
    }

    fn indexed_vertices(fv: &Vec<StlFacet>, vm: &VertexMap) -> Vec<Facet> {
        let mut v: Vec<Facet> = Vec::with_capacity(fv.len());
        for f in fv.iter() {
            let v1 = vm.get(&f.v1);
            let v2 = vm.get(&f.v2);
            let v3 = vm.get(&f.v3);
            // I wish there was a better place to put this
            let n = f.calculate_normal_vector();
            v.push(Facet{
                v1: v1,
                v2: v2,
                v3: v3,
                n: n,
            })
        }
        v
    }

    pub fn new_from_stl(fv: &Vec<StlFacet>, vm: &VertexMap) -> Mesh {
        let vs = vm.vector();
        let fs = Mesh::indexed_vertices(fv, vm);
        Mesh {
            vertices: vs,
            facets: fs,
        }
    }

    pub fn read<R: Reader>(r: &mut R) -> IoResult<Mesh> {

        let mut header = StlHeader { header: [0u8; 80] };
        try!(r.read_at_least(header.header.len(), &mut header.header));

        let hs = String::from_utf8_lossy(&header.header);
        if hs.starts_with("solid ") {
            println!("Is ASCII STL");
        } else {
            println!("Is binary STL");
        }

        Mesh::read_binary(r)
    }

    /*
    fn read_ascii(r: &mut Reader) -> IoResult<Mesh> {
        //solid vcg
        //  facet normal 7.733874e-001 -3.151335e-002 6.331499e-001
        //    outer loop
        //      vertex  2.137833e+001 5.385936e+001 1.350253e+001
        //      vertex  2.341920e+001 4.700068e+001 1.066826e+001
        //      vertex  2.859041e+001 5.985682e+001 4.991545e+000
        //    endloop
        //  endfacet
        //endsolid vcg
        for line in r.lines() {
            print!("{}", line.unwrap());
        }
        Mesh::new() // TODO
    }
    */

    fn read_binary(r: &mut Reader) -> IoResult<Mesh> {
        let facet_count = match r.read_le_u32() {
            Ok(c) => { println!("Facets: {}", c); c},
            Err(e) => { println!("Truncated file: {}", e); 0},
        };

        let mut facets: Vec<StlFacet> = Vec::with_capacity(facet_count as usize);
        let mut vertices = VertexMap::new();
        println!("Collections ready");

        for fi in range(0, facet_count) {
            let f = match StlFacet::read(r) {
                Ok(x) => x,
                Err(e) => panic!("file error: {}", e),
            };
            let v1i = vertices.add(f.v1);
            let v2i = vertices.add(f.v2);
            let v3i = vertices.add(f.v3);
            println!("  Facet[{}]: {:?} => {}-{}-{}", fi, f, v1i, v2i, v3i);
            facets.push(f);
        }
        println!("Vertices: {}", vertices.len());

        Ok(Mesh::new_from_stl(&facets, &vertices))
    }
}
<|endoftext|>


<commit_before>//! Reading and writing of the rustc metadata for rlibs and dylibs

use std::fs::File;
use std::ops::Deref;
use std::path::Path;

use rustc_codegen_ssa::METADATA_FILENAME;
use rustc_data_structures::owning_ref::{OwningRef, StableAddress};
use rustc_data_structures::rustc_erase_owner;
use rustc_data_structures::sync::MetadataRef;
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader};
use rustc_middle::ty::TyCtxt;
use rustc_session::config;
use rustc_target::spec::Target;

use crate::backend::WriteMetadata;

pub(crate) struct CraneliftMetadataLoader;

struct StableMmap(memmap2::Mmap);

impl Deref for StableMmap {
    type Target = [u8];

    fn deref(&self) -> &[u8] {
        &*self.0
    }
}

unsafe impl StableAddress for StableMmap {}

fn load_metadata_with(
    path: &Path,
    f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>,
) -> Result<MetadataRef, String> {
    let file = File::open(path).map_err(|e| format!("{:?}", e))?;
    let data = unsafe { memmap2::MmapOptions::new().map_copy_read_only(&file) }
        .map_err(|e| format!("{:?}", e))?;
    let metadata = OwningRef::new(StableMmap(data)).try_map(f)?;
    return Ok(rustc_erase_owner!(metadata.map_owner_box()));
}

impl MetadataLoader for CraneliftMetadataLoader {
    fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> {
        load_metadata_with(path, |data| {
            let archive = object::read::archive::ArchiveFile::parse(&*data)
                .map_err(|e| format!("{:?}", e))?;

                for entry_result in archive.members() {
                let entry = entry_result.map_err(|e| format!("{:?}", e))?;
                if entry.name() == METADATA_FILENAME.as_bytes() {
                    return Ok(entry.data());
                }
            }

            Err("couldn't find metadata entry".to_string())
        })
    }

    fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> {
        use object::{Object, ObjectSection};

        load_metadata_with(path, |data| {
            let file = object::File::parse(&data).map_err(|e| format!("parse: {:?}", e))?;
            file.section_by_name(".rustc")
                .ok_or("no .rustc section")?
                .data()
                .map_err(|e| format!("failed to read .rustc section: {:?}", e))
        })
    }
}

// Adapted from https://github.com/rust-lang/rust/blob/da573206f87b5510de4b0ee1a9c044127e409bd3/src/librustc_codegen_llvm/base.rs#L47-L112
pub(crate) fn write_metadata<P: WriteMetadata>(
    tcx: TyCtxt<'_>,
    product: &mut P,
) -> EncodedMetadata {
    use snap::write::FrameEncoder;
    use std::io::Write;

    #[derive(PartialEq, Eq, PartialOrd, Ord)]
    enum MetadataKind {
        None,
        Uncompressed,
        Compressed,
    }

    let kind = tcx
        .sess
        .crate_types()
        .iter()
        .map(|ty| match *ty {
            config::CrateType::Executable
            | config::CrateType::Staticlib
            | config::CrateType::Cdylib => MetadataKind::None,

            config::CrateType::Rlib => MetadataKind::Uncompressed,

            config::CrateType::Dylib | config::CrateType::ProcMacro => MetadataKind::Compressed,
        })
        .max()
        .unwrap_or(MetadataKind::None);

    if kind == MetadataKind::None {
        return EncodedMetadata::new();
    }

    let metadata = tcx.encode_metadata();
    if kind == MetadataKind::Uncompressed {
        return metadata;
    }

    assert!(kind == MetadataKind::Compressed);
    let mut compressed = tcx.metadata_encoding_version();
    FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();

    product.add_rustc_section(
        rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx),
        compressed,
        tcx.sess.target.is_like_osx,
    );

    metadata
}
<commit_msg>Rustfmt<commit_after>//! Reading and writing of the rustc metadata for rlibs and dylibs

use std::fs::File;
use std::ops::Deref;
use std::path::Path;

use rustc_codegen_ssa::METADATA_FILENAME;
use rustc_data_structures::owning_ref::{OwningRef, StableAddress};
use rustc_data_structures::rustc_erase_owner;
use rustc_data_structures::sync::MetadataRef;
use rustc_middle::middle::cstore::{EncodedMetadata, MetadataLoader};
use rustc_middle::ty::TyCtxt;
use rustc_session::config;
use rustc_target::spec::Target;

use crate::backend::WriteMetadata;

pub(crate) struct CraneliftMetadataLoader;

struct StableMmap(memmap2::Mmap);

impl Deref for StableMmap {
    type Target = [u8];

    fn deref(&self) -> &[u8] {
        &*self.0
    }
}

unsafe impl StableAddress for StableMmap {}

fn load_metadata_with(
    path: &Path,
    f: impl for<'a> FnOnce(&'a [u8]) -> Result<&'a [u8], String>,
) -> Result<MetadataRef, String> {
    let file = File::open(path).map_err(|e| format!("{:?}", e))?;
    let data = unsafe { memmap2::MmapOptions::new().map_copy_read_only(&file) }
        .map_err(|e| format!("{:?}", e))?;
    let metadata = OwningRef::new(StableMmap(data)).try_map(f)?;
    return Ok(rustc_erase_owner!(metadata.map_owner_box()));
}

impl MetadataLoader for CraneliftMetadataLoader {
    fn get_rlib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> {
        load_metadata_with(path, |data| {
            let archive = object::read::archive::ArchiveFile::parse(&*data)
                .map_err(|e| format!("{:?}", e))?;

            for entry_result in archive.members() {
                let entry = entry_result.map_err(|e| format!("{:?}", e))?;
                if entry.name() == METADATA_FILENAME.as_bytes() {
                    return Ok(entry.data());
                }
            }

            Err("couldn't find metadata entry".to_string())
        })
    }

    fn get_dylib_metadata(&self, _target: &Target, path: &Path) -> Result<MetadataRef, String> {
        use object::{Object, ObjectSection};

        load_metadata_with(path, |data| {
            let file = object::File::parse(&data).map_err(|e| format!("parse: {:?}", e))?;
            file.section_by_name(".rustc")
                .ok_or("no .rustc section")?
                .data()
                .map_err(|e| format!("failed to read .rustc section: {:?}", e))
        })
    }
}

// Adapted from https://github.com/rust-lang/rust/blob/da573206f87b5510de4b0ee1a9c044127e409bd3/src/librustc_codegen_llvm/base.rs#L47-L112
pub(crate) fn write_metadata<P: WriteMetadata>(
    tcx: TyCtxt<'_>,
    product: &mut P,
) -> EncodedMetadata {
    use snap::write::FrameEncoder;
    use std::io::Write;

    #[derive(PartialEq, Eq, PartialOrd, Ord)]
    enum MetadataKind {
        None,
        Uncompressed,
        Compressed,
    }

    let kind = tcx
        .sess
        .crate_types()
        .iter()
        .map(|ty| match *ty {
            config::CrateType::Executable
            | config::CrateType::Staticlib
            | config::CrateType::Cdylib => MetadataKind::None,

            config::CrateType::Rlib => MetadataKind::Uncompressed,

            config::CrateType::Dylib | config::CrateType::ProcMacro => MetadataKind::Compressed,
        })
        .max()
        .unwrap_or(MetadataKind::None);

    if kind == MetadataKind::None {
        return EncodedMetadata::new();
    }

    let metadata = tcx.encode_metadata();
    if kind == MetadataKind::Uncompressed {
        return metadata;
    }

    assert!(kind == MetadataKind::Compressed);
    let mut compressed = tcx.metadata_encoding_version();
    FrameEncoder::new(&mut compressed).write_all(&metadata.raw_data).unwrap();

    product.add_rustc_section(
        rustc_middle::middle::exported_symbols::metadata_symbol_name(tcx),
        compressed,
        tcx.sess.target.is_like_osx,
    );

    metadata
}
<|endoftext|>


<commit_before>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    test_utils::{naive_smt::NaiveSmt, proof_reader::ProofReader},
    SparseMerkleTree,
};
use diem_crypto::{hash::SPARSE_MERKLE_PLACEHOLDER_HASH, HashValue};
use diem_types::account_state_blob::AccountStateBlob;
use proptest::{
    collection::{hash_set, vec},
    prelude::*,
    sample::Index,
};

type TxnOutput = Vec<(HashValue, AccountStateBlob)>;
type BlockOutput = Vec<TxnOutput>;

pub fn arb_smt_correctness_case() -> impl Strategy<Value = Vec<(BlockOutput, bool)>> {
    (
        hash_set(any::<HashValue>(), 1..100), // keys
        vec(
            // blocks
            (
                vec(
                    // txns
                    vec(
                        // txn updates
                        (any::<Index>(), any::<Vec<u8>>()),
                        1..4,
                    ),
                    1..10,
                ),
                any::<bool>(), // commit
            ),
            1..10,
        ),
    )
        .prop_map(|(keys, blocks)| {
            let keys: Vec<_> = keys.into_iter().collect();
            blocks
                .into_iter()
                .map(|(txns, commit)| {
                    (
                        txns.into_iter()
                            .map(|updates| {
                                updates
                                    .into_iter()
                                    .map(|(k_idx, v)| (*k_idx.get(&keys), v.to_vec().into()))
                                    .collect()
                            })
                            .collect::<Vec<_>>(),
                        commit,
                    )
                })
                .collect::<Vec<_>>()
        })
}

pub fn test_smt_correctness_impl(input: Vec<(BlockOutput, bool)>) {
    let mut persisted_smt = NaiveSmt::new::<AccountStateBlob>(&[]);
    let mut naive_smt = persisted_smt.clone();

    let mut serial_smt = SparseMerkleTree::new(*SPARSE_MERKLE_PLACEHOLDER_HASH);
    let mut batches_smt = SparseMerkleTree::new(*SPARSE_MERKLE_PLACEHOLDER_HASH);
    let mut batch_smt = SparseMerkleTree::new(*SPARSE_MERKLE_PLACEHOLDER_HASH);
    let mut updater_smt = SparseMerkleTree::new(*SPARSE_MERKLE_PLACEHOLDER_HASH);

    for (block, commit) in input {
        let updates = block
            .iter()
            .map(|txn_updates| txn_updates.iter().map(|(k, v)| (*k, v)).collect())
            .collect::<Vec<_>>();
        let updates_flat_batch = updates.iter().flatten().cloned().collect::<Vec<_>>();

        let proofs = updates_flat_batch
            .iter()
            .map(|(k, _)| (*k, persisted_smt.get_proof(k)))
            .collect();
        let proof_reader = ProofReader::new(proofs);

        naive_smt = naive_smt.update(&updates_flat_batch);
        serial_smt = serial_smt
            .serial_update(updates.clone(), &proof_reader)
            .unwrap()
            .1;
        batches_smt = batches_smt
            .batches_update(updates, &proof_reader)
            .unwrap()
            .1;
        batch_smt = batch_smt
            .batch_update(updates_flat_batch.clone(), &proof_reader)
            .unwrap();
        updater_smt = updater_smt
            .batch_update_by_updater(updates_flat_batch, &proof_reader)
            .unwrap();

        assert_eq!(serial_smt.root_hash(), naive_smt.get_root_hash());
        assert_eq!(batches_smt.root_hash(), naive_smt.get_root_hash());
        assert_eq!(batch_smt.root_hash(), naive_smt.get_root_hash());
        assert_eq!(updater_smt.root_hash(), naive_smt.get_root_hash());

        if commit {
            persisted_smt = naive_smt.clone();
            serial_smt.prune();
            batches_smt.prune();
            batch_smt.prune();
            updater_smt.prune();
        }
    }
}
<commit_msg>[scratchpad] add test for strong refs<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{
    sparse_merkle::node::{Node, NodeHandle, SubTree},
    test_utils::{naive_smt::NaiveSmt, proof_reader::ProofReader},
    SparseMerkleTree,
};
use diem_crypto::{hash::SPARSE_MERKLE_PLACEHOLDER_HASH, HashValue};
use diem_types::account_state_blob::AccountStateBlob;
use proptest::{
    collection::{hash_set, vec},
    prelude::*,
    sample::Index,
};
use std::{borrow::Borrow, sync::Arc};

type TxnOutput = Vec<(HashValue, AccountStateBlob)>;
type BlockOutput = Vec<TxnOutput>;

pub fn arb_smt_correctness_case() -> impl Strategy<Value = Vec<(BlockOutput, bool)>> {
    (
        hash_set(any::<HashValue>(), 1..100), // keys
        vec(
            // blocks
            (
                vec(
                    // txns
                    vec(
                        // txn updates
                        (any::<Index>(), any::<Vec<u8>>()),
                        1..4,
                    ),
                    1..10,
                ),
                any::<bool>(), // commit
            ),
            1..10,
        ),
    )
        .prop_map(|(keys, blocks)| {
            let keys: Vec<_> = keys.into_iter().collect();
            blocks
                .into_iter()
                .map(|(txns, commit)| {
                    (
                        txns.into_iter()
                            .map(|updates| {
                                updates
                                    .into_iter()
                                    .map(|(k_idx, v)| (*k_idx.get(&keys), v.to_vec().into()))
                                    .collect()
                            })
                            .collect::<Vec<_>>(),
                        commit,
                    )
                })
                .collect::<Vec<_>>()
        })
}

pub fn test_smt_correctness_impl(input: Vec<(BlockOutput, bool)>) {
    let mut persisted_smt = NaiveSmt::new::<AccountStateBlob>(&[]);
    let mut naive_smt = persisted_smt.clone();

    let mut serial_smt = SparseMerkleTree::new(*SPARSE_MERKLE_PLACEHOLDER_HASH);
    let mut batches_smt = SparseMerkleTree::new(*SPARSE_MERKLE_PLACEHOLDER_HASH);
    let mut batch_smt = SparseMerkleTree::new(*SPARSE_MERKLE_PLACEHOLDER_HASH);
    let mut updater_smt = SparseMerkleTree::new(*SPARSE_MERKLE_PLACEHOLDER_HASH);

    for (block, commit) in input {
        let updates = block
            .iter()
            .map(|txn_updates| txn_updates.iter().map(|(k, v)| (*k, v)).collect())
            .collect::<Vec<_>>();
        let updates_flat_batch = updates.iter().flatten().cloned().collect::<Vec<_>>();

        let proofs = updates_flat_batch
            .iter()
            .map(|(k, _)| (*k, persisted_smt.get_proof(k)))
            .collect();
        let proof_reader = ProofReader::new(proofs);
        naive_smt = naive_smt.update(&updates_flat_batch);

        let upd_serial_smt = serial_smt
            .serial_update(updates.clone(), &proof_reader)
            .unwrap()
            .1;
        serial_smt.assert_no_external_strong_ref();
        serial_smt = upd_serial_smt;

        let upd_batches_smt = batches_smt
            .batches_update(updates, &proof_reader)
            .unwrap()
            .1;
        batches_smt.assert_no_external_strong_ref();
        batches_smt = upd_batches_smt;

        let upd_batch_smt = batch_smt
            .batch_update(updates_flat_batch.clone(), &proof_reader)
            .unwrap();
        batch_smt.assert_no_external_strong_ref();
        batch_smt = upd_batch_smt;

        let upd_updater_smt = updater_smt
            .batch_update_by_updater(updates_flat_batch, &proof_reader)
            .unwrap();
        updater_smt.assert_no_external_strong_ref();
        updater_smt = upd_updater_smt;

        assert_eq!(serial_smt.root_hash(), naive_smt.get_root_hash());
        assert_eq!(batches_smt.root_hash(), naive_smt.get_root_hash());
        assert_eq!(batch_smt.root_hash(), naive_smt.get_root_hash());
        assert_eq!(updater_smt.root_hash(), naive_smt.get_root_hash());

        if commit {
            persisted_smt = naive_smt.clone();
            serial_smt.prune();
            batches_smt.prune();
            batch_smt.prune();
            updater_smt.prune();
        }
    }
}

trait AssertNoExternalStrongRef {
    fn assert_no_external_strong_ref(&self);
}

impl<V> AssertNoExternalStrongRef for SparseMerkleTree<V> {
    fn assert_no_external_strong_ref(&self) {
        assert_subtree_sole_strong_ref(&self.inner.root.load());
    }
}

fn assert_subtree_sole_strong_ref<V>(subtree: &SubTree<V>) {
    if let SubTree::NonEmpty {
        root: NodeHandle::Shared(arc),
        ..
    } = subtree
    {
        assert_eq!(Arc::strong_count(arc), 1);
        if let Node::Internal(internal_node) = arc.borrow() {
            assert_subtree_sole_strong_ref(&internal_node.left);
            assert_subtree_sole_strong_ref(&internal_node.right);
        }
    }
}
<|endoftext|>


<commit_before>use std::mem;

pub struct Any {
    ptr: *mut (),
    drop: fn(*mut ()),
    fingerprint: Fingerprint,
}

impl Any {
    pub fn new<T>(t: T) -> Self {
        let ptr = Box::into_raw(Box::new(t));
        Any {
            ptr: ptr as *mut (),
            drop: |ptr| drop(unsafe { Box::from_raw(ptr as *mut T) }),
            fingerprint: Fingerprint::of::<T>(),
        }
    }

    pub fn view<T>(&mut self) -> &mut T {
        if self.fingerprint != Fingerprint::of::<T>() {
            panic!("invalid cast");
        }
        let ptr = self.ptr as *mut T;
        unsafe { &mut *ptr }
    }

    pub fn take<T>(self) -> T {
        if self.fingerprint != Fingerprint::of::<T>() {
            panic!("invalid cast");
        }
        let ptr = self.ptr as *mut T;
        let box_t = unsafe { Box::from_raw(ptr) };
        mem::forget(self);
        *box_t
    }
}

impl Drop for Any {
    fn drop(&mut self) {
        (self.drop)(self.ptr);
    }
}

#[derive(Eq, PartialEq)]
struct Fingerprint {
    size: usize,
    align: usize,
    id: usize,
}

impl Fingerprint {
    fn of<T>() -> Fingerprint {
        Fingerprint {
            size: mem::size_of::<T>(),
            align: mem::align_of::<T>(),
            // This is not foolproof -- theoretically Rust or LLVM could
            // deduplicate some or all of these methods. But in practice it's
            // great and I am comfortable relying on this in debug mode to catch
            // bugs early.
            id: Fingerprint::of::<T> as usize,
        }
    }
}
<commit_msg>Any is unsafe<commit_after>use std::mem;

pub struct Any {
    ptr: *mut (),
    drop: fn(*mut ()),
    fingerprint: Fingerprint,
}

// These functions are all unsafe. They are not exposed to the user. Declaring
// them as `unsafe fn` would not make the rest of erased-serde any safer or more
// readable.
impl Any {
    // This is unsafe -- caller must not hold on to the Any beyond the lifetime
    // of T.
    //
    // Example of bad code:
    //
    //    let s = "bad".to_owned();
    //    let a = Any::new(&s);
    //    drop(s);
    //
    // Now `a.view()` and `a.take()` return references to a dead String.
    pub(crate) fn new<T>(t: T) -> Self {
        let ptr = Box::into_raw(Box::new(t));
        Any {
            ptr: ptr as *mut (),
            drop: |ptr| drop(unsafe { Box::from_raw(ptr as *mut T) }),
            fingerprint: Fingerprint::of::<T>(),
        }
    }

    // This is unsafe -- caller is responsible that T is the correct type.
    pub(crate) fn view<T>(&mut self) -> &mut T {
        if self.fingerprint != Fingerprint::of::<T>() {
            panic!("invalid cast");
        }
        let ptr = self.ptr as *mut T;
        unsafe { &mut *ptr }
    }

    // This is unsafe -- caller is responsible that T is the correct type.
    pub(crate) fn take<T>(self) -> T {
        if self.fingerprint != Fingerprint::of::<T>() {
            panic!("invalid cast");
        }
        let ptr = self.ptr as *mut T;
        let box_t = unsafe { Box::from_raw(ptr) };
        mem::forget(self);
        *box_t
    }
}

impl Drop for Any {
    fn drop(&mut self) {
        (self.drop)(self.ptr);
    }
}

#[derive(Eq, PartialEq)]
struct Fingerprint {
    size: usize,
    align: usize,
    id: usize,
}

impl Fingerprint {
    fn of<T>() -> Fingerprint {
        Fingerprint {
            size: mem::size_of::<T>(),
            align: mem::align_of::<T>(),
            // This is not foolproof -- theoretically Rust or LLVM could
            // deduplicate some or all of these methods. But in practice it's
            // great and I am comfortable relying on this in debug mode to catch
            // bugs early.
            id: Fingerprint::of::<T> as usize,
        }
    }
}
<|endoftext|>


<commit_before>use quote::{ToTokens, Tokens};

use metadata::Metadata;
use parse::Entry;
use request::Request;
use response::Response;

#[derive(Debug)]
pub struct Api {
    metadata: Metadata,
    request: Request,
    response: Response,
}

impl ToTokens for Api {
    fn to_tokens(&self, tokens: &mut Tokens) {
        let description = &self.metadata.description;
        let method = &self.metadata.method;
        let name = &self.metadata.name;
        let path = &self.metadata.path;
        let rate_limited = &self.metadata.rate_limited;
        let requires_authentication = &self.metadata.requires_authentication;

        let request_types = {
            let mut tokens = Tokens::new();
            self.request.to_tokens(&mut tokens);
            tokens
        };
        let response_types = {
            let mut tokens = Tokens::new();
            self.response.to_tokens(&mut tokens);
            tokens
        };

        let add_body_to_request = if self.request.has_body_fields() {
            let request_body_init_fields = self.request.request_body_init_fields();

            quote! {
                let request_body = RequestBody {
                    #request_body_init_fields
                };

                hyper_request.set_body(::serde_json::to_vec(&request_body)?);
            }
        } else {
            Tokens::new()
        };

        let deserialize_response_body = if self.response.has_body_fields() {
            let mut tokens = Tokens::new();

            tokens.append(quote! {
                hyper_response.body()
                    .fold::<_, _, Result<_, ::std::io::Error>>(Vec::new(), |mut bytes, chunk| {
                        bytes.write_all(&chunk)?;

                        Ok(bytes)
                    })
                    .map_err(::ruma_api::Error::from)
                    .and_then(|bytes| {
                        ::serde_json::from_slice::<ResponseBody>(bytes.as_slice())
                            .map_err(::ruma_api::Error::from)
                    })
            });

            tokens.append(".and_then(|response_body| {");

            tokens
        } else {
            let mut tokens = Tokens::new();

            tokens.append(quote! {
                ::futures::future::ok(())
            });

            tokens.append(".and_then(|_| {");

            tokens
        };

        let mut closure_end = Tokens::new();
        closure_end.append("})");

        let response_init_fields = if self.response.has_fields() {
            self.response.init_fields()
        } else {
            Tokens::new()
        };

        tokens.append(quote! {
            use std::io::Write as _Write;

            use ::futures::{Future as _Future, Stream as _Stream};
            use ::ruma_api::Endpoint as _RumaApiEndpoint;

            /// The API endpoint.
            #[derive(Debug)]
            pub struct Endpoint;

            #request_types

            impl ::std::convert::TryFrom<Request> for ::hyper::Request {
                type Error = ::ruma_api::Error;

                #[allow(unused_mut, unused_variables)]
                fn try_from(request: Request) -> Result<Self, Self::Error> {
                    let metadata = Endpoint::METADATA;

                    let mut hyper_request = ::hyper::Request::new(
                        metadata.method,
                        metadata.path.parse()?,
                    );

                    #add_body_to_request

                    Ok(hyper_request)
                }
            }

            #response_types

            impl ::std::convert::TryFrom<::hyper::Response> for Response {
                type Error = ::ruma_api::Error;

                fn try_from(hyper_response: ::hyper::Response) -> Result<Self, Self::Error> {
                    #deserialize_response_body

                    let response = Response {
                        #response_init_fields
                    };

                    Ok(response)
                    #closure_end
                    .wait()
                }
            }

            impl ::ruma_api::Endpoint for Endpoint {
                type Request = Request;
                type Response = Response;

                const METADATA: ::ruma_api::Metadata = ::ruma_api::Metadata {
                    description: #description,
                    method: ::hyper::#method,
                    name: #name,
                    path: #path,
                    rate_limited: #rate_limited,
                    requires_authentication: #requires_authentication,
                };
            }
        });
    }
}

impl From<Vec<Entry>> for Api {
    fn from(entries: Vec<Entry>) -> Api {
        if entries.len() != 3 {
            panic!("ruma_api! expects 3 blocks: metadata, request, and response");
        }

        let mut metadata = None;
        let mut request = None;
        let mut response = None;

        for entry in entries {
            match entry {
                Entry::Metadata(fields) => metadata = Some(Metadata::from(fields)),
                Entry::Request(fields) => request = Some(Request::from(fields)),
                Entry::Response(fields) => response = Some(Response::from(fields)),
            }
        }

        Api {
            metadata: metadata.expect("ruma_api! is missing metadata"),
            request: request.expect("ruma_api! is missing request"),
            response: response.expect("ruma_api! is missing response"),
        }
    }
}
<commit_msg>Use FutureFrom instead of TryFrom for responses.<commit_after>use quote::{ToTokens, Tokens};

use metadata::Metadata;
use parse::Entry;
use request::Request;
use response::Response;

#[derive(Debug)]
pub struct Api {
    metadata: Metadata,
    request: Request,
    response: Response,
}

impl ToTokens for Api {
    fn to_tokens(&self, tokens: &mut Tokens) {
        let description = &self.metadata.description;
        let method = &self.metadata.method;
        let name = &self.metadata.name;
        let path = &self.metadata.path;
        let rate_limited = &self.metadata.rate_limited;
        let requires_authentication = &self.metadata.requires_authentication;

        let request_types = {
            let mut tokens = Tokens::new();
            self.request.to_tokens(&mut tokens);
            tokens
        };
        let response_types = {
            let mut tokens = Tokens::new();
            self.response.to_tokens(&mut tokens);
            tokens
        };

        let add_body_to_request = if self.request.has_body_fields() {
            let request_body_init_fields = self.request.request_body_init_fields();

            quote! {
                let request_body = RequestBody {
                    #request_body_init_fields
                };

                hyper_request.set_body(::serde_json::to_vec(&request_body)?);
            }
        } else {
            Tokens::new()
        };

        let deserialize_response_body = if self.response.has_body_fields() {
            let mut tokens = Tokens::new();

            tokens.append(quote! {
                let future_response = hyper_response.body()
                    .fold::<_, _, Result<_, ::std::io::Error>>(Vec::new(), |mut bytes, chunk| {
                        bytes.write_all(&chunk)?;

                        Ok(bytes)
                    })
                    .map_err(::ruma_api::Error::from)
                    .and_then(|bytes| {
                        ::serde_json::from_slice::<ResponseBody>(bytes.as_slice())
                            .map_err(::ruma_api::Error::from)
                    })
            });

            tokens.append(".and_then(|response_body| {");

            tokens
        } else {
            let mut tokens = Tokens::new();

            tokens.append(quote! {
                ::futures::future::ok(())
            });

            tokens.append(".and_then(|_| {");

            tokens
        };

        let mut closure_end = Tokens::new();
        closure_end.append("});");

        let response_init_fields = if self.response.has_fields() {
            self.response.init_fields()
        } else {
            Tokens::new()
        };

        tokens.append(quote! {
            use std::io::Write as _Write;

            use ::futures::{Future as _Future, Stream as _Stream};
            use ::ruma_api::Endpoint as _RumaApiEndpoint;

            /// The API endpoint.
            #[derive(Debug)]
            pub struct Endpoint;

            #request_types

            impl ::std::convert::TryFrom<Request> for ::hyper::Request {
                type Error = ::ruma_api::Error;

                #[allow(unused_mut, unused_variables)]
                fn try_from(request: Request) -> Result<Self, Self::Error> {
                    let metadata = Endpoint::METADATA;

                    let mut hyper_request = ::hyper::Request::new(
                        metadata.method,
                        metadata.path.parse()?,
                    );

                    #add_body_to_request

                    Ok(hyper_request)
                }
            }

            #response_types

            impl ::futures::future::FutureFrom<::hyper::Response> for Response {
                type Future = Box<_Future<Item = Self, Error = Self::Error>>;
                type Error = ::ruma_api::Error;

                fn future_from(hyper_response: ::hyper::Response)
                -> Box<_Future<Item = Self, Error = Self::Error>> {
                    #deserialize_response_body

                    let response = Response {
                        #response_init_fields
                    };

                    Ok(response)
                    #closure_end

                    Box::new(future_response)
                }
            }

            impl ::ruma_api::Endpoint for Endpoint {
                type Request = Request;
                type Response = Response;

                const METADATA: ::ruma_api::Metadata = ::ruma_api::Metadata {
                    description: #description,
                    method: ::hyper::#method,
                    name: #name,
                    path: #path,
                    rate_limited: #rate_limited,
                    requires_authentication: #requires_authentication,
                };
            }
        });
    }
}

impl From<Vec<Entry>> for Api {
    fn from(entries: Vec<Entry>) -> Api {
        if entries.len() != 3 {
            panic!("ruma_api! expects 3 blocks: metadata, request, and response");
        }

        let mut metadata = None;
        let mut request = None;
        let mut response = None;

        for entry in entries {
            match entry {
                Entry::Metadata(fields) => metadata = Some(Metadata::from(fields)),
                Entry::Request(fields) => request = Some(Request::from(fields)),
                Entry::Response(fields) => response = Some(Response::from(fields)),
            }
        }

        Api {
            metadata: metadata.expect("ruma_api! is missing metadata"),
            request: request.expect("ruma_api! is missing request"),
            response: response.expect("ruma_api! is missing response"),
        }
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! An example of using perlin noise

extern mod noise;

use std::rand::rng;
use noise::perlin::*;

static WIDTH: uint = 100;
static HEIGHT: uint = 100;

static GRADIENT: [&'static str, ..6] = [" ", "░", "▒", "▓", "█", "█"];

fn main() {
    let ctx = PerlinContext::new(&mut rng());

    for y in range(0, HEIGHT) {
        for x in range(0, WIDTH) {
            let val = [x as f32 * 0.1,
                       y as f32 * 0.1].perlin(&ctx) * 0.5 + 0.5;
            print(GRADIENT[(val / 0.2) as int]);
        }
        println("");
    }
}
<commit_msg>Halve the height of the perlin noise example<commit_after>// Copyright 2013 The noise-rs developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! An example of using perlin noise

extern mod noise;

use std::rand::rng;
use noise::perlin::*;

static WIDTH: uint = 100;
static HEIGHT: uint = 100;

static GRADIENT: [&'static str, ..6] = [" ", "░", "▒", "▓", "█", "█"];

fn main() {
    let ctx = PerlinContext::new(&mut rng());

    for y in range(0, HEIGHT / 2) {
        for x in range(0, WIDTH) {
            let val = [x as f32 * 0.1,
                       y as f32 * 0.1 * 2.0].perlin(&ctx) * 0.5 + 0.5;
            print(GRADIENT[(val / 0.2) as int]);
        }
        println("");
    }
}
<|endoftext|>


<commit_before>#[allow(dead_code)]
extern crate c_ares_sys;

bitflags!(
    #[doc = "Flags that may be provided on a call to `get_name_info()`."]
    flags NIFlags: i32 {
        #[doc = "Only the nodename portion of the FQDN is returned for local"]
        #[doc = "hosts."]
        const NOFQDN = c_ares_sys::ARES_NI_NOFQDN,

        #[doc = "he numeric form of the hostname is returned rather than the"]
        #[doc = "name."]
        const NUMERICHOST = c_ares_sys::ARES_NI_NUMERICHOST,

        #[doc = "An error is returned if the hostname cannot be found in the"]
        #[doc = "DNS."]
        const NAMEREQD = c_ares_sys::ARES_NI_NAMEREQD,

        #[doc = "The numeric form of the service is returned rather than the"]
        #[doc = "name."]
        const NUMERICSERV = c_ares_sys::ARES_NI_NUMERICSERV,

        #[doc = "The service name is to be looked up for the TCP protocol."]
        const TCP = c_ares_sys::ARES_NI_TCP,

        #[doc = "The service name is to be looked up for the UDP protocol."]
        const UDP = c_ares_sys::ARES_NI_UDP,

        #[doc = "The service name is to be looked up for the SCTP protocol."]
        const SCTP = c_ares_sys::ARES_NI_SCTP,

        #[doc = "The service name is to be looked up for the DCCP protocol."]
        const DCCP = c_ares_sys::ARES_NI_DCCP,

        #[doc = "The numeric form of the scope ID is returned rather than"]
        #[doc = "the name."]
        const NUMERICSCOPE = c_ares_sys::ARES_NI_NUMERICSCOPE,

        #[doc = "A hostname lookup is being requested."]
        const LOOKUPHOST = c_ares_sys::ARES_NI_LOOKUPHOST,

        #[doc = "A service name lookup is being requested."]
        const LOOKUPSERVICE = c_ares_sys::ARES_NI_LOOKUPSERVICE,
    }
);
<commit_msg>Missing letter<commit_after>#[allow(dead_code)]
extern crate c_ares_sys;

bitflags!(
    #[doc = "Flags that may be provided on a call to `get_name_info()`."]
    flags NIFlags: i32 {
        #[doc = "Only the nodename portion of the FQDN is returned for local"]
        #[doc = "hosts."]
        const NOFQDN = c_ares_sys::ARES_NI_NOFQDN,

        #[doc = "The numeric form of the hostname is returned rather than the"]
        #[doc = "name."]
        const NUMERICHOST = c_ares_sys::ARES_NI_NUMERICHOST,

        #[doc = "An error is returned if the hostname cannot be found in the"]
        #[doc = "DNS."]
        const NAMEREQD = c_ares_sys::ARES_NI_NAMEREQD,

        #[doc = "The numeric form of the service is returned rather than the"]
        #[doc = "name."]
        const NUMERICSERV = c_ares_sys::ARES_NI_NUMERICSERV,

        #[doc = "The service name is to be looked up for the TCP protocol."]
        const TCP = c_ares_sys::ARES_NI_TCP,

        #[doc = "The service name is to be looked up for the UDP protocol."]
        const UDP = c_ares_sys::ARES_NI_UDP,

        #[doc = "The service name is to be looked up for the SCTP protocol."]
        const SCTP = c_ares_sys::ARES_NI_SCTP,

        #[doc = "The service name is to be looked up for the DCCP protocol."]
        const DCCP = c_ares_sys::ARES_NI_DCCP,

        #[doc = "The numeric form of the scope ID is returned rather than"]
        #[doc = "the name."]
        const NUMERICSCOPE = c_ares_sys::ARES_NI_NUMERICSCOPE,

        #[doc = "A hostname lookup is being requested."]
        const LOOKUPHOST = c_ares_sys::ARES_NI_LOOKUPHOST,

        #[doc = "A service name lookup is being requested."]
        const LOOKUPSERVICE = c_ares_sys::ARES_NI_LOOKUPSERVICE,
    }
);
<|endoftext|>


<commit_before>//! Implements parsing of various chess notations.

use regex::Regex;
use basetypes::*;

/// Represents a parse error.
pub struct ParseError;

/// Parses a square in lowercase algebraic notation.
pub fn parse_square(s: &str) -> Result<Square, ParseError> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"^[a-h][1-8]$").unwrap();
    }

    if RE.is_match(s) {
        let mut chars = s.chars();
        let file = (chars.next().unwrap().to_digit(18).unwrap() - 10) as File;
        let rank = (chars.next().unwrap().to_digit(9).unwrap() - 1) as Rank;
        Ok(square(file, rank))
    } else {
        Err(ParseError)
    }
}

/// Parses a Forsyth–Edwards Notation (FEN) string.
///
/// A FEN string defines a particular position using only the ASCII
/// character set. A FEN string contains six fields separated by a
/// space. The fields are:
///
/// 1) Piece placement (from white's perspective). Each rank is
///    described, starting with rank 8 and ending with rank 1. Within
///    each rank, the contents of each square are described from file A
///    through file H. Following the Standard Algebraic Notation (SAN),
///    each piece is identified by a single letter taken from the
///    standard English names. White pieces are designated using
///    upper-case letters ("PNBRQK") whilst Black uses lowercase
///    ("pnbrqk"). Blank squares are noted using digits 1 through 8
///    (the number of blank squares), and "/" separates ranks.
///
/// 2) Active color. "w" means white moves next, "b" means black.
///
/// 3) Castling availability. If neither side can castle, this is
///    "-". Otherwise, this has one or more letters: "K" (White can
///    castle kingside), "Q" (White can castle queenside), "k" (Black
///    can castle kingside), and/or "q" (Black can castle queenside).
///
/// 4) En passant target square (in algebraic notation). If there's no
///    en passant target square, this is "-". If a pawn has just made a
///    2-square move, this is the position "behind" the pawn. This is
///    recorded regardless of whether there is a pawn in position to
///    make an en passant capture.
///
/// 5) Halfmove clock. This is the number of halfmoves since the last
///    pawn advance or capture. This is used to determine if a draw can
///    be claimed under the fifty-move rule.
///
/// 6) Fullmove number. The number of the full move. It starts at 1,
///    and is incremented after Black's move.
///
/// # Example:
/// The starting position: `rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w QKqk - 0 1`
pub fn parse_fen
    (s: &str)
     -> Result<(PiecesPlacement, Color, CastlingRights, Option<Square>, u8, u16), ParseError> {

    let fileds: Vec<_> = s.split_whitespace().collect();
    if fileds.len() == 6 {
        Ok((try!(parse_fen_piece_placement(fileds[0])),
            try!(parse_fen_active_color(fileds[1])),
            try!(parse_fen_castling_rights(fileds[2])),
            try!(parse_fen_enpassant_square(fileds[3])),
            try!(fileds[4].parse::<u8>().map_err(|_| ParseError)),
            match try!(fileds[5].parse::<u16>().map_err(|_| ParseError)) {
            x if x == 0 || x > 9000 => return Err(ParseError),
            x => x,
        }))
    } else {
        Err(ParseError)
    }
}

fn parse_fen_piece_placement(s: &str) -> Result<PiecesPlacement, ParseError> {

    // We start with an empty board. FEN describes the board
    // starting at A8 and going toward H1.
    let mut piece_type = [0u64; 6];
    let mut color = [0u64; 2];
    let mut file = 0;
    let mut rank = 7;

    // These are the possible productions in the grammar.
    enum Token {
        Piece(Color, PieceType),
        EmptySquares(u32),
        Separator,
    }

    for c in s.chars() {

        // Parse the next character.
        let token = match c {
            'K' => Token::Piece(WHITE, KING),
            'Q' => Token::Piece(WHITE, QUEEN),
            'R' => Token::Piece(WHITE, ROOK),
            'B' => Token::Piece(WHITE, BISHOP),
            'N' => Token::Piece(WHITE, KNIGHT),
            'P' => Token::Piece(WHITE, PAWN),
            'k' => Token::Piece(BLACK, KING),
            'q' => Token::Piece(BLACK, QUEEN),
            'r' => Token::Piece(BLACK, ROOK),
            'b' => Token::Piece(BLACK, BISHOP),
            'n' => Token::Piece(BLACK, KNIGHT),
            'p' => Token::Piece(BLACK, PAWN),
            n @ '1'...'8' => Token::EmptySquares(n.to_digit(9).unwrap()),
            '/' => Token::Separator,
            _ => return Err(ParseError),
        };

        // Update the board accordting to the token.
        match token {
            Token::Piece(_color, _piece) => {
                if file > 7 {
                    return Err(ParseError);
                }
                let mask = 1 << square(file, rank);
                piece_type[_piece] |= mask;
                color[_color] |= mask;
                file += 1;
            }
            Token::EmptySquares(n) => {
                file += n as File;
                if file > 8 {
                    return Err(ParseError);
                }
            }
            Token::Separator => {
                if file == 8 && rank > 0 {
                    file = 0;
                    rank -= 1;
                } else {
                    return Err(ParseError);
                }
            }
        }
    }

    // Ensure the piece placement field had the right length.
    if file == 8 && rank == 0 {
        Ok(PiecesPlacement {
            piece_type: piece_type,
            color: color,
        })
    } else {
        Err(ParseError)
    }
}

fn parse_fen_active_color(s: &str) -> Result<Color, ParseError> {
    match s {
        "w" => Ok(WHITE),
        "b" => Ok(BLACK),
        _ => Err(ParseError),
    }
}

fn parse_fen_castling_rights(s: &str) -> Result<CastlingRights, ParseError> {

    // We start with no caltling allowed.
    let mut rights = CastlingRights::new(0);

    // Then we parse the content and update the castling rights.
    if s != "-" {
        for c in s.chars() {
            match c {
                'K' => {
                    if rights.grant(WHITE, KINGSIDE) {
                        return Err(ParseError);
                    }
                }
                'Q' => {
                    if rights.grant(WHITE, QUEENSIDE) {
                        return Err(ParseError);
                    }
                }
                'k' => {
                    if rights.grant(BLACK, KINGSIDE) {
                        return Err(ParseError);
                    }
                }
                'q' => {
                    if rights.grant(BLACK, QUEENSIDE) {
                        return Err(ParseError);
                    }
                }
                _ => {
                    return Err(ParseError);
                }
            };
        }
    }

    // Successfully parsed.
    Ok(rights)
}

fn parse_fen_enpassant_square(s: &str) -> Result<Option<Square>, ParseError> {
    match s {
        "-" => Ok(None),
        _ => Ok(Some(try!(parse_square(s).map_err(|_| ParseError)))),
    }
}
<commit_msg>beautify<commit_after>//! Implements parsing of various chess notations.

use regex::Regex;
use basetypes::*;

/// Represents a parse error.
pub struct ParseError;

/// Parses a square in lowercase algebraic notation.
pub fn parse_square(s: &str) -> Result<Square, ParseError> {
    lazy_static! {
        static ref RE: Regex = Regex::new(r"^[a-h][1-8]$").unwrap();
    }

    if RE.is_match(s) {
        let mut chars = s.chars();
        let file = (chars.next().unwrap().to_digit(18).unwrap() - 10) as File;
        let rank = (chars.next().unwrap().to_digit(9).unwrap() - 1) as Rank;
        Ok(square(file, rank))
    } else {
        Err(ParseError)
    }
}

/// Parses a Forsyth–Edwards Notation (FEN) string.
///
/// A FEN string defines a particular position using only the ASCII
/// character set. A FEN string contains six fields separated by a
/// space. The fields are:
///
/// 1) Piece placement (from white's perspective). Each rank is
///    described, starting with rank 8 and ending with rank 1. Within
///    each rank, the contents of each square are described from file A
///    through file H. Following the Standard Algebraic Notation (SAN),
///    each piece is identified by a single letter taken from the
///    standard English names. White pieces are designated using
///    upper-case letters ("PNBRQK") whilst Black uses lowercase
///    ("pnbrqk"). Blank squares are noted using digits 1 through 8
///    (the number of blank squares), and "/" separates ranks.
///
/// 2) Active color. "w" means white moves next, "b" means black.
///
/// 3) Castling availability. If neither side can castle, this is
///    "-". Otherwise, this has one or more letters: "K" (White can
///    castle kingside), "Q" (White can castle queenside), "k" (Black
///    can castle kingside), and/or "q" (Black can castle queenside).
///
/// 4) En passant target square (in algebraic notation). If there's no
///    en passant target square, this is "-". If a pawn has just made a
///    2-square move, this is the position "behind" the pawn. This is
///    recorded regardless of whether there is a pawn in position to
///    make an en passant capture.
///
/// 5) Halfmove clock. This is the number of halfmoves since the last
///    pawn advance or capture. This is used to determine if a draw can
///    be claimed under the fifty-move rule.
///
/// 6) Fullmove number. The number of the full move. It starts at 1,
///    and is incremented after Black's move.
///
/// # Example:
/// The starting position: `rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w QKqk - 0 1`
pub fn parse_fen
    (s: &str)
     -> Result<(PiecesPlacement, Color, CastlingRights, Option<Square>, u8, u16), ParseError> {

    let fileds: Vec<_> = s.split_whitespace().collect();
    if fileds.len() == 6 {
        Ok((try!(parse_fen_piece_placement(fileds[0])),
            try!(parse_fen_active_color(fileds[1])),
            try!(parse_fen_castling_rights(fileds[2])),
            try!(parse_fen_enpassant_square(fileds[3])),
            try!(fileds[4].parse::<u8>().map_err(|_| ParseError)),
            match try!(fileds[5].parse::<u16>().map_err(|_| ParseError)) {
            x @ 1...9000 => x,
            _ => return Err(ParseError),
        }))
    } else {
        Err(ParseError)
    }
}

fn parse_fen_piece_placement(s: &str) -> Result<PiecesPlacement, ParseError> {

    // We start with an empty board. FEN describes the board
    // starting at A8 and going toward H1.
    let mut piece_type = [0u64; 6];
    let mut color = [0u64; 2];
    let mut file = 0;
    let mut rank = 7;

    // These are the possible productions in the grammar.
    enum Token {
        Piece(Color, PieceType),
        EmptySquares(u32),
        Separator,
    }

    for c in s.chars() {

        // Parse the next character.
        let token = match c {
            'K' => Token::Piece(WHITE, KING),
            'Q' => Token::Piece(WHITE, QUEEN),
            'R' => Token::Piece(WHITE, ROOK),
            'B' => Token::Piece(WHITE, BISHOP),
            'N' => Token::Piece(WHITE, KNIGHT),
            'P' => Token::Piece(WHITE, PAWN),
            'k' => Token::Piece(BLACK, KING),
            'q' => Token::Piece(BLACK, QUEEN),
            'r' => Token::Piece(BLACK, ROOK),
            'b' => Token::Piece(BLACK, BISHOP),
            'n' => Token::Piece(BLACK, KNIGHT),
            'p' => Token::Piece(BLACK, PAWN),
            n @ '1'...'8' => Token::EmptySquares(n.to_digit(9).unwrap()),
            '/' => Token::Separator,
            _ => return Err(ParseError),
        };

        // Update the board accordting to the token.
        match token {
            Token::Piece(_color, _piece) => {
                if file > 7 {
                    return Err(ParseError);
                }
                let mask = 1 << square(file, rank);
                piece_type[_piece] |= mask;
                color[_color] |= mask;
                file += 1;
            }
            Token::EmptySquares(n) => {
                file += n as File;
                if file > 8 {
                    return Err(ParseError);
                }
            }
            Token::Separator => {
                if file == 8 && rank > 0 {
                    file = 0;
                    rank -= 1;
                } else {
                    return Err(ParseError);
                }
            }
        }
    }

    // Ensure the piece placement field had the right length.
    if file == 8 && rank == 0 {
        Ok(PiecesPlacement {
            piece_type: piece_type,
            color: color,
        })
    } else {
        Err(ParseError)
    }
}

fn parse_fen_active_color(s: &str) -> Result<Color, ParseError> {
    match s {
        "w" => Ok(WHITE),
        "b" => Ok(BLACK),
        _ => Err(ParseError),
    }
}

fn parse_fen_castling_rights(s: &str) -> Result<CastlingRights, ParseError> {

    // We start with no caltling allowed.
    let mut rights = CastlingRights::new(0);

    // Then we parse the content and update the castling rights.
    if s != "-" {
        for c in s.chars() {
            match c {
                'K' => {
                    if rights.grant(WHITE, KINGSIDE) {
                        return Err(ParseError);
                    }
                }
                'Q' => {
                    if rights.grant(WHITE, QUEENSIDE) {
                        return Err(ParseError);
                    }
                }
                'k' => {
                    if rights.grant(BLACK, KINGSIDE) {
                        return Err(ParseError);
                    }
                }
                'q' => {
                    if rights.grant(BLACK, QUEENSIDE) {
                        return Err(ParseError);
                    }
                }
                _ => {
                    return Err(ParseError);
                }
            };
        }
    }

    Ok(rights)
}

fn parse_fen_enpassant_square(s: &str) -> Result<Option<Square>, ParseError> {
    match s {
        "-" => Ok(None),
        _ => Ok(Some(try!(parse_square(s).map_err(|_| ParseError)))),
    }
}
<|endoftext|>


<commit_before>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

pub struct SubFrame {
  pub data: Data,
  pub wasted_bits: u32,
}

#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  Constant(i32),
  Verbatim(Vec<i32>),
  Fixed(Fixed),
  LPC(LPC),
}

#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub warmup: [i32; MAX_FIXED_ORDER],
  pub residual: Vec<i32>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub qlp_coeff_precision: u8,
  pub quantization_level: i8,
  pub qlp_coefficients: [i32; MAX_LPC_ORDER],
  pub warmup: [i32; MAX_LPC_ORDER],
  pub residual: Vec<i32>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  pub method_type: CodingMethod,
  pub data: PartitionedRice,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  PartitionedRice,
  PartitionedRice2,
}

#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  pub order: u32,
  pub contents: PartitionedRiceContents,
}

#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  pub parameters: Vec<u32>,
  pub raw_bits: Vec<u32>,
  pub capacity_by_order: u32,
}

impl PartitionedRiceContents {
  pub fn new(capacity_by_order: u32) -> PartitionedRiceContents {
    let capacity       = 2_usize.pow(capacity_by_order);
    let mut parameters = Vec::with_capacity(capacity);
    let mut raw_bits   = Vec::with_capacity(capacity);

    unsafe {
      parameters.set_len(capacity);
      raw_bits.set_len(capacity);
    }

    PartitionedRiceContents {
      parameters: parameters,
      raw_bits: raw_bits,
      capacity_by_order: capacity_by_order,
    }
  }
}
<commit_msg>Add documentation for `SubFrame`<commit_after>/// Maximum order of the fixed predictors permitted by the format.
pub const MAX_FIXED_ORDER: usize = 4;

/// Maximum LPC order permitted by the format.
pub const MAX_LPC_ORDER: usize   = 32;

/// A single channel of audio data.
pub struct SubFrame {
  pub data: Data,
  pub wasted_bits: u32,
}

#[derive(Debug, PartialEq, Eq)]
pub enum Data {
  Constant(i32),
  Verbatim(Vec<i32>),
  Fixed(Fixed),
  LPC(LPC),
}

#[derive(Debug, PartialEq, Eq)]
pub struct Fixed {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub warmup: [i32; MAX_FIXED_ORDER],
  pub residual: Vec<i32>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct LPC {
  pub entropy_coding_method: EntropyCodingMethod,
  pub order: u8,
  pub qlp_coeff_precision: u8,
  pub quantization_level: i8,
  pub qlp_coefficients: [i32; MAX_LPC_ORDER],
  pub warmup: [i32; MAX_LPC_ORDER],
  pub residual: Vec<i32>,
}

#[derive(Debug, PartialEq, Eq)]
pub struct EntropyCodingMethod {
  pub method_type: CodingMethod,
  pub data: PartitionedRice,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum CodingMethod {
  PartitionedRice,
  PartitionedRice2,
}

#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRice {
  pub order: u32,
  pub contents: PartitionedRiceContents,
}

#[derive(Debug, PartialEq, Eq)]
pub struct PartitionedRiceContents {
  pub parameters: Vec<u32>,
  pub raw_bits: Vec<u32>,
  pub capacity_by_order: u32,
}

impl PartitionedRiceContents {
  pub fn new(capacity_by_order: u32) -> PartitionedRiceContents {
    let capacity       = 2_usize.pow(capacity_by_order);
    let mut parameters = Vec::with_capacity(capacity);
    let mut raw_bits   = Vec::with_capacity(capacity);

    unsafe {
      parameters.set_len(capacity);
      raw_bits.set_len(capacity);
    }

    PartitionedRiceContents {
      parameters: parameters,
      raw_bits: raw_bits,
      capacity_by_order: capacity_by_order,
    }
  }
}
<|endoftext|>