<commit_before>extern crate regex;
#[macro_use]
extern crate lazy_static;

pub mod lexer;
pub mod parser;

#[cfg(test)]
mod tests {
    use parser;
    use std::f64;
    #[test]
    fn addition() {
        let input = String::from("1 + 2");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (1+2) as f64);
    }
    #[test]
    fn subtraction() {
        let input = String::from("18 - 4");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (18-4) as f64);
    }
    #[test]
    fn multiplication() {
        let input = String::from("3 * 6");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (3*6) as f64);
    }
    #[test]
    fn divide() {
        let input = String::from("15 / 3");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (15.0/3.0) as f64);
    }
    #[test]
    fn power() {
        let input = String::from("4 ^ 7");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (f64::powf(4.0, 7.0)) as f64);
        let input = String::from("4 ^ 7 ^ 8");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (f64::powf(f64::powf(4.0, 7.0), 8.0) as f64));
    }
    #[test]
    fn numerical_negation() {
        let input = String::from("-2");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (-2 as f64));
        let input = String::from("-(2)");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (-2 as f64));
    }
    #[test]
    fn expression_negation() {
        let input = String::from("-(2+3)");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((-1*(2+3)) as f64));
        let input = String::from("15-(-(2+3))");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((15-(-1*(2+3))) as f64));
    }
    #[test]
    fn basic_modulo() {
        let input = String::from("0 % 7");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((0 % 7) as f64));
        let input = String::from("1 % 7");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((1 % 7) as f64));
    }
    #[test]
    fn negative_modulo() {
        let input = String::from("-1 % 7");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((-1 % 7) as f64));
        let input = String::from("(-1) % 7");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (((-1) % 7) as f64));
    }
    #[test]
    fn order_of_operations() {
        let input = String::from("4+5*7");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((4+(5*7)) as f64));
        let input = String::from("-15/7");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (((-15.0)/7.0) as f64));
        let input = String::from("-2^0.5");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((-1.0*f64::powf(2.0, 0.5)) as f64));
        let input = String::from("(-2)^0.5");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap().is_nan(), ((f64::powf(-2.0, 0.5)) as f64).is_nan());
    }
    #[test]
    fn end() {
        let input = String::from("");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).is_err());
    }
    #[test]
    fn ignore_whitespace() {
        let input = String::from("   12        -  8   ");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (12-8) as f64);
        let input = String::from("142        -9   ");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (142-9) as f64);
        let input = String::from("72+  15");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (72+15) as f64);
        let input = String::from(" 12*  4");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (12*4) as f64);
        let input = String::from(" 50/10");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (50.0/10.0) as f64);
    }
    #[test]
    fn long_add_expressions() {
        let input = String::from("2 -4 +6 -1 -1- 0 +8");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2-4+6-1-1-0+8) as f64);
        let input = String::from("1 -1   + 2   - 2   +  4 - 4 +    6");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (1-1+2-2+4-4+6) as f64);
    }
    #[test]
    fn long_mult_expressions() {
        let input = String::from("2 *4 *6 *1 *1* 0 *8");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2*4*6*1*1*0*8) as f64);
        let input = String::from("1 *1   * 2   * 2   *  4 * 4 *    6");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (1*1*2*2*4*4*6) as f64);
    }
    #[test]
    fn long_mixed() {
        let input = String::from(" 2*3 - 4*5 + 6/3 ");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2.0*3.0-4.0*5.0+6.0/3.0) as f64);
        let input = String::from("2*3*4/8 -   5/2*4 +  6 + 0/3   ");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2.0*3.0*4.0/8.0-5.0/2.0*4.0+6.0+0.0/3.0) as f64);
    }
    #[test]
    fn floating() {
        let input = String::from("10/4");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (10.0/4.0) as f64);
        let input = String::from("5/3");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (5.0/3.0) as f64);
        let input = String::from("3 + 8/5 -1 -2*5");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (3.0+8.0/5.0-1.0-2.0*5.0) as f64);
        let input = String::from(".67");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (0.67) as f64);
        let input = String::from("5+.67");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (5.0+0.67) as f64);
    }
    #[test]
    fn bad_tokens() {
        let input = String::from("  6 + c");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).is_err());
        let input = String::from("  7 & 2");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).is_err());
        let input = String::from("  %");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).is_err());
    }
    #[test]
    fn syntax_error() {
        let input = String::from(" 5 + + 6");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).is_err());
        let input = String::from(" 5 * / 6");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).is_err());
    }
    #[test]
    fn divide_zero() {
        let input = String::from("5/0");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).unwrap().is_infinite());
        let input = String::from(" 2 - 1 + 14/0 + 7");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).unwrap().is_infinite());
    }
    #[test]
    fn unused_parens() {
        let input = String::from(" (2) ");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2) as f64);
    }
    #[test]
    fn enclosing_parens() {
        let input = String::from("(5 + 2*3 - 1 + 7 * 8)");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (5.0+2.0*3.0-1.0+7.0*8.0) as f64);
        let input = String::from("(67 + 2 * 3 - 67 + 2/1 - 7)");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (67.0+2.0*3.0-67.0+2.0/1.0-7.0) as f64);
    }
    #[test]
    fn sub_expressions() {
        let input = String::from("(2) + (17*2-30) * (5)+2 - (8/2)*4");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((2.0)+(17.0*2.0-30.0)*(5.0)+2.0-(8.0/2.0)*4.0) as f64);
        let input = String::from("(5*7/5) + (23) - 5 * (98-4)/(6*7-42)");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((5.0*7.0/5.0)+(23.0)-5.0*(98.0-4.0)/(6.0*7.0-42.0)) as f64);
    }
    #[test]
    fn nested_parens() {
        let input = String::from("(((((5)))))");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((((((5)))))) as f64);
        let input = String::from("(( ((2)) + 4))*((5))");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (((((2.0))+4.0))*((5.0))) as f64);
    }
    #[test]
    fn unbalanced_parens() {
        let input = String::from("2 + (5 * 2");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2.0+(5.0*2.0)) as f64);
        let input = String::from("(((((4))))");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (4.0) as f64);
        let input = String::from("((2)) * ((3");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2.0*3.0) as f64);
        let input = String::from("((9)) * ((1)");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (9.0*1.0) as f64);
    }
}
<commit_msg>Added tests for variables. Also removed uneeded re-creation of the parser in test functions<commit_after>extern crate regex;
#[macro_use]
extern crate lazy_static;

pub mod lexer;
pub mod parser;

#[cfg(test)]
mod tests {
    use parser;
    use std::f64;
    #[test]
    fn addition() {
        let input = String::from("1 + 2");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (1+2) as f64);
    }
    #[test]
    fn subtraction() {
        let input = String::from("18 - 4");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (18-4) as f64);
    }
    #[test]
    fn multiplication() {
        let input = String::from("3 * 6");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (3*6) as f64);
    }
    #[test]
    fn divide() {
        let input = String::from("15 / 3");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (15.0/3.0) as f64);
    }
    #[test]
    fn power() {
        let input = String::from("4 ^ 7");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (f64::powf(4.0, 7.0)) as f64);
        let input = String::from("4 ^ 7 ^ 8");
        assert_eq!(my_parser.parse(input).unwrap(), (f64::powf(f64::powf(4.0, 7.0), 8.0) as f64));
    }
    #[test]
    fn numerical_negation() {
        let input = String::from("-2");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (-2 as f64));
        let input = String::from("-(2)");
        assert_eq!(my_parser.parse(input).unwrap(), (-2 as f64));
    }
    #[test]
    fn expression_negation() {
        let input = String::from("-(2+3)");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((-1*(2+3)) as f64));
        let input = String::from("15-(-(2+3))");
        assert_eq!(my_parser.parse(input).unwrap(), ((15-(-1*(2+3))) as f64));
    }
    #[test]
    fn basic_modulo() {
        let input = String::from("0 % 7");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((0 % 7) as f64));
        let input = String::from("1 % 7");
        assert_eq!(my_parser.parse(input).unwrap(), ((1 % 7) as f64));
    }
    #[test]
    fn negative_modulo() {
        let input = String::from("-1 % 7");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((-1 % 7) as f64));
        let input = String::from("(-1) % 7");
        assert_eq!(my_parser.parse(input).unwrap(), (((-1) % 7) as f64));
    }
    #[test]
    fn order_of_operations() {
        let input = String::from("4+5*7");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((4+(5*7)) as f64));
        let input = String::from("-15/7");
        assert_eq!(my_parser.parse(input).unwrap(), (((-15.0)/7.0) as f64));
        let input = String::from("-2^0.5");
        assert_eq!(my_parser.parse(input).unwrap(), ((-1.0*f64::powf(2.0, 0.5)) as f64));
        let input = String::from("(-2)^0.5");
        assert_eq!(my_parser.parse(input).unwrap().is_nan(), ((f64::powf(-2.0, 0.5)) as f64).is_nan());
    }
    #[test]
    fn end() {
        let input = String::from("");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).is_err());
    }
    #[test]
    fn ignore_whitespace() {
        let input = String::from("   12        -  8   ");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (12-8) as f64);
        let input = String::from("142        -9   ");
        assert_eq!(my_parser.parse(input).unwrap(), (142-9) as f64);
        let input = String::from("72+  15");
        assert_eq!(my_parser.parse(input).unwrap(), (72+15) as f64);
        let input = String::from(" 12*  4");
        assert_eq!(my_parser.parse(input).unwrap(), (12*4) as f64);
        let input = String::from(" 50/10");
        assert_eq!(my_parser.parse(input).unwrap(), (50.0/10.0) as f64);
    }
    #[test]
    fn long_add_expressions() {
        let input = String::from("2 -4 +6 -1 -1- 0 +8");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2-4+6-1-1-0+8) as f64);
        let input = String::from("1 -1   + 2   - 2   +  4 - 4 +    6");
        assert_eq!(my_parser.parse(input).unwrap(), (1-1+2-2+4-4+6) as f64);
    }
    #[test]
    fn long_mult_expressions() {
        let input = String::from("2 *4 *6 *1 *1* 0 *8");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2*4*6*1*1*0*8) as f64);
        let input = String::from("1 *1   * 2   * 2   *  4 * 4 *    6");
        assert_eq!(my_parser.parse(input).unwrap(), (1*1*2*2*4*4*6) as f64);
    }
    #[test]
    fn long_mixed() {
        let input = String::from(" 2*3 - 4*5 + 6/3 ");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2.0*3.0-4.0*5.0+6.0/3.0) as f64);
        let input = String::from("2*3*4/8 -   5/2*4 +  6 + 0/3   ");
        assert_eq!(my_parser.parse(input).unwrap(), (2.0*3.0*4.0/8.0-5.0/2.0*4.0+6.0+0.0/3.0) as f64);
    }
    #[test]
    fn floating() {
        let input = String::from("10/4");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (10.0/4.0) as f64);
        let input = String::from("5/3");
        assert_eq!(my_parser.parse(input).unwrap(), (5.0/3.0) as f64);
        let input = String::from("3 + 8/5 -1 -2*5");
        assert_eq!(my_parser.parse(input).unwrap(), (3.0+8.0/5.0-1.0-2.0*5.0) as f64);
        let input = String::from(".67");
        assert_eq!(my_parser.parse(input).unwrap(), (0.67) as f64);
        let input = String::from("5+.67");
        assert_eq!(my_parser.parse(input).unwrap(), (5.0+0.67) as f64);
    }
    #[test]
    fn bad_tokens() {
        let input = String::from("  6 + c");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).is_err());
        let input = String::from("  7 & 2");
        assert!(my_parser.parse(input).is_err());
        let input = String::from("  %");
        assert!(my_parser.parse(input).is_err());
    }
    #[test]
    fn syntax_error() {
        let input = String::from(" 5 + + 6");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).is_err());
        let input = String::from(" 5 * / 6");
        assert!(my_parser.parse(input).is_err());
    }
    #[test]
    fn divide_zero() {
        let input = String::from("5/0");
        let mut my_parser = parser::Parser::new();
        assert!(my_parser.parse(input).unwrap().is_infinite());
        let input = String::from(" 2 - 1 + 14/0 + 7");
        assert!(my_parser.parse(input).unwrap().is_infinite());
    }
    #[test]
    fn unused_parens() {
        let input = String::from(" (2) ");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2) as f64);
    }
    #[test]
    fn enclosing_parens() {
        let input = String::from("(5 + 2*3 - 1 + 7 * 8)");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (5.0+2.0*3.0-1.0+7.0*8.0) as f64);
        let input = String::from("(67 + 2 * 3 - 67 + 2/1 - 7)");
        assert_eq!(my_parser.parse(input).unwrap(), (67.0+2.0*3.0-67.0+2.0/1.0-7.0) as f64);
    }
    #[test]
    fn sub_expressions() {
        let input = String::from("(2) + (17*2-30) * (5)+2 - (8/2)*4");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((2.0)+(17.0*2.0-30.0)*(5.0)+2.0-(8.0/2.0)*4.0) as f64);
        let input = String::from("(5*7/5) + (23) - 5 * (98-4)/(6*7-42)");
        assert_eq!(my_parser.parse(input).unwrap(), ((5.0*7.0/5.0)+(23.0)-5.0*(98.0-4.0)/(6.0*7.0-42.0)) as f64);
    }
    #[test]
    fn nested_parens() {
        let input = String::from("(((((5)))))");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), ((((((5)))))) as f64);
        let input = String::from("(( ((2)) + 4))*((5))");
        assert_eq!(my_parser.parse(input).unwrap(), (((((2.0))+4.0))*((5.0))) as f64);
    }
    #[test]
    fn unbalanced_parens() {
        let input = String::from("2 + (5 * 2");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (2.0+(5.0*2.0)) as f64);
        let input = String::from("(((((4))))");
        assert_eq!(my_parser.parse(input).unwrap(), (4.0) as f64);
        let input = String::from("((2)) * ((3");
        assert_eq!(my_parser.parse(input).unwrap(), (2.0*3.0) as f64);
        let input = String::from("((9)) * ((1)");
        assert_eq!(my_parser.parse(input).unwrap(), (9.0*1.0) as f64);
    }
    #[test]
    fn variables() {
        let input = String::from("x = 5");
        let mut my_parser = parser::Parser::new();
        assert_eq!(my_parser.parse(input).unwrap(), (5.0) as f64);
        let input = String::from("x");
        assert_eq!(my_parser.parse(input).unwrap(), (5.0) as f64);
        let input = String::from("y");
        assert!(my_parser.parse(input).is_err());
        let input = String::from("y = x ^ 5");
        assert_eq!(my_parser.parse(input).unwrap(), (f64::powf(5.0, 5.0)) as f64);
        let input = String::from("x = x + 1");
        assert_eq!(my_parser.parse(input).unwrap(), (5.0 + 1.0) as f64);
        let input = String::from("x");
        assert_eq!(my_parser.parse(input).unwrap(), (6.0) as f64);
        let input = String::from("y % x");
        assert_eq!(my_parser.parse(input).unwrap(), (f64::powf(5.0, 5.0) % 6.0) as f64);
    }
}
<|endoftext|>


<commit_before>extern crate pulse;
extern crate threadpool;

use std::any::{Any, TypeId};
use std::cell::RefCell;
use std::collections::HashMap;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
use pulse::{Pulse, Signal};
use threadpool::ThreadPool;

pub use storage::{Storage, VecStorage, HashMapStorage};

mod storage;

/// Index generation. When a new entity is placed at the old index,
/// it bumps the generation by 1. This allows to avoid using components
/// from the entities that were deleted.
/// G<=0 - the entity of generation G is dead
/// G >0 - the entity of generation G is alive
pub type Generation = i32;
/// Index type is arbitrary. It doesn't show up in any interfaces.
/// Keeping it 32bit allows for a single 64bit word per entity.
pub type Index = u32;
/// Entity type, as seen by the user.
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct Entity(Index, Generation);

impl Entity {
    pub fn get_id(&self) -> usize { self.0 as usize }
    pub fn get_gen(&self) -> Generation { self.1 }
}

pub trait Component: Any + Sized {
    type Storage: Storage<Self> + Any + Send + Sync;
}

pub struct World {
    entities: RwLock<Vec<Entity>>,
    generations: RwLock<Vec<Generation>>,
    components: HashMap<TypeId, Box<Any+Send+Sync>>,
}

impl World {
    pub fn new() -> World {
        World {
            entities: RwLock::new(Vec::new()),
            generations: RwLock::new(Vec::new()),
            components: HashMap::new(),
        }
    }
    pub fn register<T: Component>(&mut self) {
        let any = RwLock::new(T::Storage::new());
        self.components.insert(TypeId::of::<T>(), Box::new(any));
    }
    fn lock<T: Component>(&self) -> &RwLock<T::Storage> {
        use std::ops::Deref;
        let boxed = self.components.get(&TypeId::of::<T>()).unwrap();
        (boxed.deref() as &Any).downcast_ref().unwrap()
    }
}

pub struct EntityIter<'a> {
    guard: RwLockReadGuard<'a, Vec<Generation>>,
    index: usize,
}

impl<'a> Iterator for EntityIter<'a> {
    type Item = Entity;
    fn next(&mut self) -> Option<Entity> {
        loop {
            match self.guard.get(self.index) {
                Some(&gen) if gen > 0 => {
                    let ent = Entity(self.index as Index, gen);
                    self.index += 1;
                    return Some(ent)
                },
                Some(_) => self.index += 1, // continue
                None => return None,
            }
        }
    }
}

#[derive(Copy, Clone)]
pub struct Components<'a>(&'a World);

impl<'a> Components<'a> {
    pub fn read<T: Component>(self) -> RwLockReadGuard<'a, T::Storage> {
        self.0.lock::<T>().read().unwrap()
    }
    pub fn write<T: Component>(self) -> RwLockWriteGuard<'a, T::Storage> {
        self.0.lock::<T>().write().unwrap()
    }
    pub fn entities(self) -> EntityIter<'a> {
        EntityIter {
            guard: self.0.generations.read().unwrap(),
            index: 0,
        }
    }
}

pub struct WorldArg(Arc<World>, RefCell<Option<Pulse>>);

impl WorldArg {
    pub fn fetch<'a, U, F>(&'a self, f: F) -> U
        where F: FnOnce(Components<'a>) -> U
    {
        let pulse = self.1.borrow_mut().take().expect("fetch may only be called once.");
        let u = f(Components(&self.0));
        pulse.pulse();
        u
    }
}

pub struct EntityBuilder<'a>(Entity, &'a World);

impl<'a> EntityBuilder<'a> {
    pub fn with<T: Component>(self, value: T) -> EntityBuilder<'a> {
        self.1.lock::<T>().write().unwrap().add(self.0, value);
        self
    }
    pub fn build(self) -> Entity {
        self.1.entities.write().unwrap().push(self.0);
        self.0
    }
}

pub struct Scheduler {
    world: Arc<World>,
    threads: ThreadPool,
    first_free: Index,
}

fn find_free<'a>(mut gens: RwLockWriteGuard<'a, Vec<Generation>>, base: usize) -> Index {
    match gens[base..].iter().position(|g| *g <= 0) {
        Some(pos) => (base + pos) as Index,
        None => {
            gens.push(0);
            (gens.len() - 1) as Index
        },
    }
}

impl Scheduler {
    pub fn new(world: World, num_threads: usize) -> Scheduler {
        let ff = find_free(world.generations.write().unwrap(), 0);
        Scheduler {
            world: Arc::new(world),
            threads: ThreadPool::new(num_threads),
            first_free: ff,
        }
    }
    pub fn get_components<'a>(&'a self) -> Components<'a> {
        //println!("{:?}", &*self.world.generations.read().unwrap());
        Components(&*self.world)
    }
    pub fn run<F>(&mut self, functor: F) where
        F: 'static + Send + FnOnce(WorldArg)
    {
        let (signal, pulse) = Signal::new();
        let world = self.world.clone();
        self.threads.execute(|| {
            let warg = WorldArg(world, RefCell::new(Some(pulse)));
            functor(warg);
        });
        signal.wait().unwrap();
    }
    pub fn add_entity<'a>(&'a mut self) -> EntityBuilder<'a> {
        let mut gens = self.world.generations.write().unwrap();
        let ent = {
            let gen = &mut gens[self.first_free as usize];
            assert!(*gen <= 0);
            *gen = 1 - *gen;
            Entity(self.first_free, *gen)
        };
        self.first_free = find_free(gens, (self.first_free + 1) as usize);
        EntityBuilder(ent, &self.world)
    }
    pub fn del_entity(&mut self, entity: Entity) {
        for _boxed in self.world.components.values() {
            //TODO!
            //let lock = (boxed.deref() as &Any).downcast_ref().unwrap();
        }
        let mut gens = self.world.generations.write().unwrap();
        let mut gen = &mut gens[entity.get_id() as usize];
        assert!(*gen > 0);
        *gen *= -1;
    }
    pub fn wait(&self) {
        while self.threads.active_count() > 0 {} //TODO
    }
}

macro_rules! impl_run {
    ($name:ident [$( $write:ident ),*] [$( $read:ident ),*]) => (impl Scheduler {
        #[allow(non_snake_case, unused_mut)]
        pub fn $name<
            $($write:Component,)* $($read:Component,)*
            F: 'static + Send + FnMut( $(&mut $write,)* $(&$read,)* )
        >(&mut self, functor: F) {
            self.run(|warg| {
                let mut fun = functor;
                let ($(mut $write,)* $($read,)* entities) = warg.fetch(|comp|
                    ($(comp.write::<$write>(),)*
                     $(comp.read::<$read>(),)*
                       comp.entities())
                );
                for ent in entities {
                    if let ( $( Some($write), )* $( Some($read), )* ) =
                        ( $( $write.get_mut(ent), )* $( $read.get(ent), )* ) {
                        fun( $($write,)* $($read,)* );
                    }
                }
            });
        }
    })
}

impl_run!( run0w1r [] [R0] );
impl_run!( run0w2r [] [R0, R1] );
impl_run!( run1w0r [W0] [] );
impl_run!( run1w1r [W0] [R0] );
impl_run!( run1w2r [W0] [R0, R1] );
impl_run!( run1w3r [W0] [R0, R1, R2] );
impl_run!( run1w4r [W0] [R0, R1, R2, R3] );
impl_run!( run1w5r [W0] [R0, R1, R2, R3, R4] );
impl_run!( run1w6r [W0] [R0, R1, R2, R3, R4, R5] );
impl_run!( run1w7r [W0] [R0, R1, R2, R3, R5, R6, R7] );
impl_run!( run2w0r [W0, W1] [] );
impl_run!( run2w1r [W0, W1] [R0] );
impl_run!( run2w2r [W0, W1] [R0, R1] );
<commit_msg>Removed the old entity vector<commit_after>extern crate pulse;
extern crate threadpool;

use std::any::{Any, TypeId};
use std::cell::RefCell;
use std::collections::HashMap;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
use pulse::{Pulse, Signal};
use threadpool::ThreadPool;

pub use storage::{Storage, VecStorage, HashMapStorage};

mod storage;

/// Index generation. When a new entity is placed at the old index,
/// it bumps the generation by 1. This allows to avoid using components
/// from the entities that were deleted.
/// G<=0 - the entity of generation G is dead
/// G >0 - the entity of generation G is alive
pub type Generation = i32;
/// Index type is arbitrary. It doesn't show up in any interfaces.
/// Keeping it 32bit allows for a single 64bit word per entity.
pub type Index = u32;
/// Entity type, as seen by the user.
#[derive(Clone, Copy, Debug, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct Entity(Index, Generation);

impl Entity {
    pub fn get_id(&self) -> usize { self.0 as usize }
    pub fn get_gen(&self) -> Generation { self.1 }
}

pub trait Component: Any + Sized {
    type Storage: Storage<Self> + Any + Send + Sync;
}

pub struct World {
    generations: RwLock<Vec<Generation>>,
    components: HashMap<TypeId, Box<Any+Send+Sync>>,
}

impl World {
    pub fn new() -> World {
        World {
            generations: RwLock::new(Vec::new()),
            components: HashMap::new(),
        }
    }
    pub fn register<T: Component>(&mut self) {
        let any = RwLock::new(T::Storage::new());
        self.components.insert(TypeId::of::<T>(), Box::new(any));
    }
    fn lock<T: Component>(&self) -> &RwLock<T::Storage> {
        use std::ops::Deref;
        let boxed = self.components.get(&TypeId::of::<T>()).unwrap();
        (boxed.deref() as &Any).downcast_ref().unwrap()
    }
}

pub struct EntityIter<'a> {
    guard: RwLockReadGuard<'a, Vec<Generation>>,
    index: usize,
}

impl<'a> Iterator for EntityIter<'a> {
    type Item = Entity;
    fn next(&mut self) -> Option<Entity> {
        loop {
            match self.guard.get(self.index) {
                Some(&gen) if gen > 0 => {
                    let ent = Entity(self.index as Index, gen);
                    self.index += 1;
                    return Some(ent)
                },
                Some(_) => self.index += 1, // continue
                None => return None,
            }
        }
    }
}

#[derive(Copy, Clone)]
pub struct Components<'a>(&'a World);

impl<'a> Components<'a> {
    pub fn read<T: Component>(self) -> RwLockReadGuard<'a, T::Storage> {
        self.0.lock::<T>().read().unwrap()
    }
    pub fn write<T: Component>(self) -> RwLockWriteGuard<'a, T::Storage> {
        self.0.lock::<T>().write().unwrap()
    }
    pub fn entities(self) -> EntityIter<'a> {
        EntityIter {
            guard: self.0.generations.read().unwrap(),
            index: 0,
        }
    }
}

pub struct WorldArg(Arc<World>, RefCell<Option<Pulse>>);

impl WorldArg {
    pub fn fetch<'a, U, F>(&'a self, f: F) -> U
        where F: FnOnce(Components<'a>) -> U
    {
        let pulse = self.1.borrow_mut().take().expect("fetch may only be called once.");
        let u = f(Components(&self.0));
        pulse.pulse();
        u
    }
}

pub struct EntityBuilder<'a>(Entity, &'a World);

impl<'a> EntityBuilder<'a> {
    pub fn with<T: Component>(self, value: T) -> EntityBuilder<'a> {
        self.1.lock::<T>().write().unwrap().add(self.0, value);
        self
    }
    pub fn build(self) -> Entity {
        self.0
    }
}

pub struct Scheduler {
    world: Arc<World>,
    threads: ThreadPool,
    first_free: Index,
}

fn find_free<'a>(mut gens: RwLockWriteGuard<'a, Vec<Generation>>, base: usize) -> Index {
    match gens[base..].iter().position(|g| *g <= 0) {
        Some(pos) => (base + pos) as Index,
        None => {
            gens.push(0);
            (gens.len() - 1) as Index
        },
    }
}

impl Scheduler {
    pub fn new(world: World, num_threads: usize) -> Scheduler {
        let ff = find_free(world.generations.write().unwrap(), 0);
        Scheduler {
            world: Arc::new(world),
            threads: ThreadPool::new(num_threads),
            first_free: ff,
        }
    }
    pub fn get_components<'a>(&'a self) -> Components<'a> {
        //println!("{:?}", &*self.world.generations.read().unwrap());
        Components(&*self.world)
    }
    pub fn run<F>(&mut self, functor: F) where
        F: 'static + Send + FnOnce(WorldArg)
    {
        let (signal, pulse) = Signal::new();
        let world = self.world.clone();
        self.threads.execute(|| {
            let warg = WorldArg(world, RefCell::new(Some(pulse)));
            functor(warg);
        });
        signal.wait().unwrap();
    }
    pub fn add_entity<'a>(&'a mut self) -> EntityBuilder<'a> {
        let mut gens = self.world.generations.write().unwrap();
        let ent = {
            let gen = &mut gens[self.first_free as usize];
            assert!(*gen <= 0);
            *gen = 1 - *gen;
            Entity(self.first_free, *gen)
        };
        self.first_free = find_free(gens, (self.first_free + 1) as usize);
        EntityBuilder(ent, &self.world)
    }
    pub fn del_entity(&mut self, entity: Entity) {
        for _boxed in self.world.components.values() {
            //TODO!
            //let lock = (boxed.deref() as &Any).downcast_ref().unwrap();
        }
        let mut gens = self.world.generations.write().unwrap();
        let mut gen = &mut gens[entity.get_id() as usize];
        assert!(*gen > 0);
        *gen *= -1;
    }
    pub fn wait(&self) {
        while self.threads.active_count() > 0 {} //TODO
    }
}

macro_rules! impl_run {
    ($name:ident [$( $write:ident ),*] [$( $read:ident ),*]) => (impl Scheduler {
        #[allow(non_snake_case, unused_mut)]
        pub fn $name<
            $($write:Component,)* $($read:Component,)*
            F: 'static + Send + FnMut( $(&mut $write,)* $(&$read,)* )
        >(&mut self, functor: F) {
            self.run(|warg| {
                let mut fun = functor;
                let ($(mut $write,)* $($read,)* entities) = warg.fetch(|comp|
                    ($(comp.write::<$write>(),)*
                     $(comp.read::<$read>(),)*
                       comp.entities())
                );
                for ent in entities {
                    if let ( $( Some($write), )* $( Some($read), )* ) =
                        ( $( $write.get_mut(ent), )* $( $read.get(ent), )* ) {
                        fun( $($write,)* $($read,)* );
                    }
                }
            });
        }
    })
}

impl_run!( run0w1r [] [R0] );
impl_run!( run0w2r [] [R0, R1] );
impl_run!( run1w0r [W0] [] );
impl_run!( run1w1r [W0] [R0] );
impl_run!( run1w2r [W0] [R0, R1] );
impl_run!( run1w3r [W0] [R0, R1, R2] );
impl_run!( run1w4r [W0] [R0, R1, R2, R3] );
impl_run!( run1w5r [W0] [R0, R1, R2, R3, R4] );
impl_run!( run1w6r [W0] [R0, R1, R2, R3, R4, R5] );
impl_run!( run1w7r [W0] [R0, R1, R2, R3, R5, R6, R7] );
impl_run!( run2w0r [W0, W1] [] );
impl_run!( run2w1r [W0, W1] [R0] );
impl_run!( run2w2r [W0, W1] [R0, R1] );
<|endoftext|>


<commit_before>// Copyright 2016 Mozilla
//
// 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.

#![recursion_limit="128"]

#[macro_use]
extern crate failure_derive;
extern crate failure;

#[macro_use]
extern crate lazy_static;

extern crate rusqlite;

extern crate uuid;

pub extern crate edn;
extern crate mentat_core;
extern crate mentat_db;
extern crate mentat_query;
extern crate mentat_query_algebrizer;
extern crate mentat_query_projector;
extern crate mentat_query_pull;
extern crate mentat_query_translator;
extern crate mentat_sql;
extern crate mentat_tolstoy;

pub use mentat_core::{
    Attribute,
    Entid,
    DateTime,
    HasSchema,
    KnownEntid,
    Keyword,
    Schema,
    Binding,
    TypedValue,
    Uuid,
    Utc,
    ValueType,
};

pub use mentat_query::{
    FindSpec,
};

pub use mentat_db::{
    CORE_SCHEMA_VERSION,
    DB_SCHEMA_CORE,
    AttributeSet,
    TxObserver,
    TxReport,
    new_connection,
};

#[cfg(feature = "sqlcipher")]
pub use mentat_db::{
    new_connection_with_key,
    change_encryption_key,
};

/// Produce the appropriate `Variable` for the provided valid ?-prefixed name.
/// This lives here because we can't re-export macros:
/// https://github.com/rust-lang/rust/issues/29638.
#[macro_export]
macro_rules! var {
    ( ? $var:ident ) => {
        $crate::Variable::from_valid_name(concat!("?", stringify!($var)))
    };
}

/// Produce the appropriate `Keyword` for the provided namespace and name.
/// This lives here because we can't re-export macros:
/// https://github.com/rust-lang/rust/issues/29638.
#[macro_export]
macro_rules! kw {
    ( : $n:ident ) => {
        $crate::Keyword::plain(
            stringify!($n)
        )
    };

    ( : $ns:ident / $n:ident ) => {
        $crate::Keyword::namespaced(
            stringify!($ns),
            stringify!($n)
        )
    };

    ( : $ns:ident$(. $nss:ident)+ / $n:ident ) => {
        $crate::Keyword::namespaced(
            concat!(stringify!($ns) $(, ".", stringify!($nss))+),
            stringify!($n)
        )
    };
}

#[macro_use]
pub mod errors;
pub use errors::{
    MentatError,
    Result,
};
pub mod conn;
pub mod entity_builder;
pub mod query;
pub mod query_builder;
pub mod store;
pub mod vocabulary;

pub use query::{
    IntoResult,
    PlainSymbol,
    QueryExecutionResult,
    QueryExplanation,
    QueryInputs,
    QueryOutput,
    QueryPlanStep,
    QueryResults,
    RelResult,
    Variable,
    q_once,
};

pub use query_builder::{
    QueryBuilder,
};

pub use conn::{
    CacheAction,
    CacheDirection,
    Conn,
    InProgress,
    Metadata,
    Pullable,
    Queryable,
    Syncable,
};

pub use store::{
    Store,
};

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

    #[test]
    fn can_import_edn() {
        assert_eq!(":foo", &Keyword::plain("foo").to_string());
    }

    #[test]
    fn test_kw() {
        assert_eq!(kw!(:foo/bar), Keyword::namespaced("foo", "bar"));
        assert_eq!(kw!(:org.mozilla.foo/bar_baz), Keyword::namespaced("org.mozilla.foo", "bar_baz"));
    }

    #[test]
    fn test_var() {
        let foo_baz = var!(?foo_baz);
        let vu = var!(?vü);
        assert_eq!(foo_baz, Variable::from_valid_name("?foo_baz"));
        assert_eq!(vu, Variable::from_valid_name("?vü"));
        assert_eq!(foo_baz.as_str(), "?foo_baz");
    }
}
<commit_msg>Expose sub-crate *Error types at top-level.<commit_after>// Copyright 2016 Mozilla
//
// 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.

#![recursion_limit="128"]

#[macro_use]
extern crate failure_derive;
extern crate failure;

#[macro_use]
extern crate lazy_static;

extern crate rusqlite;

extern crate uuid;

pub extern crate edn;
extern crate mentat_core;
extern crate mentat_db;
extern crate mentat_query;
extern crate mentat_query_algebrizer;
extern crate mentat_query_projector;
extern crate mentat_query_pull;
extern crate mentat_query_translator;
extern crate mentat_sql;
extern crate mentat_tolstoy;

pub use mentat_core::{
    Attribute,
    Entid,
    DateTime,
    HasSchema,
    KnownEntid,
    Keyword,
    Schema,
    Binding,
    TypedValue,
    Uuid,
    Utc,
    ValueType,
};

pub use mentat_query::{
    FindSpec,
};

pub use mentat_db::{
    CORE_SCHEMA_VERSION,
    DB_SCHEMA_CORE,
    AttributeSet,
    TxObserver,
    TxReport,
    new_connection,
};

#[cfg(feature = "sqlcipher")]
pub use mentat_db::{
    new_connection_with_key,
    change_encryption_key,
};

/// Produce the appropriate `Variable` for the provided valid ?-prefixed name.
/// This lives here because we can't re-export macros:
/// https://github.com/rust-lang/rust/issues/29638.
#[macro_export]
macro_rules! var {
    ( ? $var:ident ) => {
        $crate::Variable::from_valid_name(concat!("?", stringify!($var)))
    };
}

/// Produce the appropriate `Keyword` for the provided namespace and name.
/// This lives here because we can't re-export macros:
/// https://github.com/rust-lang/rust/issues/29638.
#[macro_export]
macro_rules! kw {
    ( : $n:ident ) => {
        $crate::Keyword::plain(
            stringify!($n)
        )
    };

    ( : $ns:ident / $n:ident ) => {
        $crate::Keyword::namespaced(
            stringify!($ns),
            stringify!($n)
        )
    };

    ( : $ns:ident$(. $nss:ident)+ / $n:ident ) => {
        $crate::Keyword::namespaced(
            concat!(stringify!($ns) $(, ".", stringify!($nss))+),
            stringify!($n)
        )
    };
}

#[macro_use]
pub mod errors;
pub use errors::{
    MentatError,
    Result,
};

pub use edn::ParseError;
pub use mentat_db::DbError;
pub use mentat_query_algebrizer::AlgebrizerError;
pub use mentat_query_projector::ProjectorError;
pub use mentat_query_pull::PullError;
pub use mentat_sql::SQLError;

pub mod conn;
pub mod entity_builder;
pub mod query;
pub mod query_builder;
pub mod store;
pub mod vocabulary;

pub use query::{
    IntoResult,
    PlainSymbol,
    QueryExecutionResult,
    QueryExplanation,
    QueryInputs,
    QueryOutput,
    QueryPlanStep,
    QueryResults,
    RelResult,
    Variable,
    q_once,
};

pub use query_builder::{
    QueryBuilder,
};

pub use conn::{
    CacheAction,
    CacheDirection,
    Conn,
    InProgress,
    Metadata,
    Pullable,
    Queryable,
    Syncable,
};

pub use store::{
    Store,
};

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

    #[test]
    fn can_import_edn() {
        assert_eq!(":foo", &Keyword::plain("foo").to_string());
    }

    #[test]
    fn test_kw() {
        assert_eq!(kw!(:foo/bar), Keyword::namespaced("foo", "bar"));
        assert_eq!(kw!(:org.mozilla.foo/bar_baz), Keyword::namespaced("org.mozilla.foo", "bar_baz"));
    }

    #[test]
    fn test_var() {
        let foo_baz = var!(?foo_baz);
        let vu = var!(?vü);
        assert_eq!(foo_baz, Variable::from_valid_name("?foo_baz"));
        assert_eq!(vu, Variable::from_valid_name("?vü"));
        assert_eq!(foo_baz.as_str(), "?foo_baz");
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate log;
extern crate serial;

use std::io;
use std::io::{Write};
use std::sync::{Mutex, Arc};
use std::time::Duration;

use serial::prelude::*;

pub mod prelude {
    pub use ::{Printer, Print, Command, Justification};
}

#[derive(Debug)]
pub enum Command {
    ESC = 27,
    DC2 = 18,
    LF = 10,
    DASH = 45,
    EXCL = 69,
    DOTS0 = 0xB0,
    DOTS1 = 0xB1,
    DOTS2 = 0xB2,
    SPACE = 0x20
}

#[derive(Debug)]
pub enum Justification {
    Left = 0,
    Center = 1,
    Right = 2
}

#[derive(Clone)]
pub struct Printer {
    port: Arc<Mutex<Box<SerialPort + Send>>>
}

impl Printer {
    pub fn new(dev_path: &str) -> io::Result<Printer> {
        let port = Printer::open_serial_port(dev_path)?;

        let mut printer = Printer{port: Arc::new(Mutex::new(port))};

        trace!("Configuring printer");
        printer.configure(7, 120, 4)?;

        trace!("Feeding line on start");
        printer.feed()?;

        return Ok(printer);
    }

    fn open_serial_port(dev_path: &str) -> io::Result<Box<SerialPort + Send>> {
        trace!("Opening serial port at {}", dev_path);

        let mut port = serial::open(dev_path)?;
        trace!("Configuring serial port");
        port.reconfigure(&|settings| {
            settings.set_baud_rate(serial::Baud19200)?;
            settings.set_char_size(serial::Bits8);
            settings.set_parity(serial::ParityNone);
            settings.set_stop_bits(serial::Stop1);
            settings.set_flow_control(serial::FlowNone);
            Ok(())
        })?;

        port.set_timeout(Duration::from_millis(1000))?;

        Ok(Box::new(port))
    }

    pub fn configure(&mut self, dots: u8, time: u8, interval: u8) -> io::Result<()> {
        // LF 7
        let cmd = [Command::ESC as u8, 55u8, dots, time, interval];
        self.write(&cmd)?;
        self.flush()
    }

    pub fn print<T: Print>(&mut self, item: T) -> io::Result<()> {
        item.print(self)
    }

    pub fn run_test(&mut self) -> io::Result<()> {
        trace!("Triggering test page");
        self.justify(Justification::Center)?;

        let out = [Command::DOTS2 as u8; 30];
        self.write(&out)?;
        self.feed()?;
        self.feed()
    }

    pub fn justify(&mut self, just: Justification) -> io::Result<()> {
        trace!("Setting justification {:?}", just);
        let cmd = [Command::ESC as u8, 97u8, just as u8];

        self.write(&cmd)?;
        self.flush()
    }

    pub fn feed(&mut self) -> io::Result<()> {
        self.feed_n(1)
    }

    pub fn feed_n(&mut self, n: u8) -> io::Result<()> {
        for _ in 0..n {
            self.write(&[Command::LF as u8])?;
        }
        self.flush()
    }

    pub fn set_underline(&mut self, n: u8) -> io::Result<()> {
        let cmd = [Command::ESC as u8, Command::DASH as u8, n];
        self.write(&cmd)?;
        self.flush()
    }

    pub fn set_bold(&mut self, flag: bool) -> io::Result<()> {
        let cmd = [Command::ESC as u8, Command::EXCL as u8, flag as u8];
        self.write(&cmd)?;
        self.flush()
    }
}

impl Write for Printer {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let port_lock = self.port.clone();
        let mut port = port_lock.lock().unwrap();

        port.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        let port_lock = self.port.clone();
        let mut port = port_lock.lock().unwrap();

        port.flush()
    }
}

pub trait Print {
    fn print(&self, printer: &mut Printer) -> io::Result<()>;
}
<commit_msg>fix test page method<commit_after>#[macro_use]
extern crate log;
extern crate serial;

use std::io;
use std::io::{Write};
use std::sync::{Mutex, Arc};
use std::time::Duration;

use serial::prelude::*;

pub mod prelude {
    pub use ::{Printer, Print, Command, Justification};
}

#[derive(Debug)]
pub enum Command {
    ESC = 27,
    DC2 = 18,
    LF = 10,
    DASH = 45,
    EXCL = 69,
    SPACE = 0x20
}

#[derive(Debug)]
pub enum Justification {
    Left = 0,
    Center = 1,
    Right = 2
}

#[derive(Clone)]
pub struct Printer {
    port: Arc<Mutex<Box<SerialPort + Send>>>
}

impl Printer {
    pub fn new(dev_path: &str) -> io::Result<Printer> {
        let port = Printer::open_serial_port(dev_path)?;

        let mut printer = Printer{port: Arc::new(Mutex::new(port))};

        trace!("Configuring printer");

        trace!("Feeding line on start");
        printer.feed()?;

        return Ok(printer);
    }

    fn open_serial_port(dev_path: &str) -> io::Result<Box<SerialPort + Send>> {
        trace!("Opening serial port at {}", dev_path);

        let mut port = serial::open(dev_path)?;
        trace!("Configuring serial port");
        port.reconfigure(&|settings| {
            settings.set_baud_rate(serial::Baud19200)?;
            settings.set_char_size(serial::Bits8);
            settings.set_parity(serial::ParityNone);
            settings.set_stop_bits(serial::Stop1);
            settings.set_flow_control(serial::FlowNone);
            Ok(())
        })?;

        port.set_timeout(Duration::from_millis(1000))?;

        Ok(Box::new(port))
    }

    pub fn configure(&mut self, dots: u8, time: u8, interval: u8) -> io::Result<()> {
        // LF 7
        let cmd = [Command::ESC as u8, 55u8, dots, time, interval];
        self.write(&cmd)?;
        self.flush()
    }

    pub fn print<T: Print>(&mut self, item: T) -> io::Result<()> {
        item.print(self)
    }

    pub fn run_test(&mut self) -> io::Result<()> {
        trace!("Triggering test page");
        self.justify(Justification::Center)?;

        let out = [Command::DC2 as u8, 'T' as u8];
        self.write(&out)?;
        self.flush()
    }

    pub fn justify(&mut self, just: Justification) -> io::Result<()> {
        trace!("Setting justification {:?}", just);
        let cmd = [Command::ESC as u8, 97u8, just as u8];

        self.write(&cmd)?;
        self.flush()
    }

    pub fn feed(&mut self) -> io::Result<()> {
        self.feed_n(1)
    }

    pub fn feed_n(&mut self, n: u8) -> io::Result<()> {
        for _ in 0..n {
            self.write(&[Command::LF as u8])?;
        }
        self.flush()
    }

    pub fn set_underline(&mut self, n: u8) -> io::Result<()> {
        let cmd = [Command::ESC as u8, Command::DASH as u8, n];
        self.write(&cmd)?;
        self.flush()
    }

    pub fn set_bold(&mut self, flag: bool) -> io::Result<()> {
        let cmd = [Command::ESC as u8, Command::EXCL as u8, flag as u8];
        self.write(&cmd)?;
        self.flush()
    }
}

impl Write for Printer {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        let port_lock = self.port.clone();
        let mut port = port_lock.lock().unwrap();

        port.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        let port_lock = self.port.clone();
        let mut port = port_lock.lock().unwrap();

        port.flush()
    }
}

pub trait Print {
    fn print(&self, printer: &mut Printer) -> io::Result<()>;
}
<|endoftext|>


<commit_before>//!
//! A Decimal implementation written in pure Rust suitable
//! for financial calculations that require significant integral
//! and fractional digits with no round-off errors.
//!
//! The binary representation consists of a 96 bit integer number,
//! a scaling factor used to specify the decimal fraction and a 1
//! bit sign. Because of this representation, trailing zeros are
//! preserved and may be exposed when in string form. These can be
//! truncated using the `normalize` or `round_dp` functions.
//!
//! ## Usage
//!
//! Decimal numbers can be created in a few distinct ways, depending
//! on the rust compiler version you're targeting.
//!
//! The stable version of rust requires you to create a Decimal number
//! using one of it's convenience methods.
//!
//! ```rust
//! use rust_decimal::Decimal;
//! use std::str::FromStr;
//!
//! // Using an integer followed by the decimal points
//! let scaled = Decimal::new(202, 2); // 2.02
//!
//! // From a string representation
//! let from_string = Decimal::from_str("2.02").unwrap(); // 2.02
//!
//! // Using the `Into` trait
//! let my_int : Decimal = 3i32.into();
//!
//! // Using the raw decimal representation
//! // 3.1415926535897932384626433832
//! let pi = Decimal::from_parts(1102470952, 185874565, 1703060790, false, 28);
//! ```
//!
extern crate num;
#[cfg(not(feature = "const_fn"))]
#[macro_use]
extern crate lazy_static;

#[cfg(feature = "postgres")]
#[macro_use]
extern crate postgres as pg_crate;

#[cfg(feature = "serde")]
extern crate serde;
#[cfg(feature = "serde")]
#[cfg(test)]
extern crate serde_json;
#[cfg(feature = "serde")]
#[cfg(test)]
#[macro_use]
extern crate serde_derive;

mod decimal;
mod error;

#[cfg(feature = "postgres")]
mod postgres;
#[cfg(feature = "serde")]
mod serde_types;

pub use decimal::{Decimal, RoundingStrategy};
pub use error::Error;
<commit_msg>Add num trait prelude<commit_after>//!
//! A Decimal implementation written in pure Rust suitable
//! for financial calculations that require significant integral
//! and fractional digits with no round-off errors.
//!
//! The binary representation consists of a 96 bit integer number,
//! a scaling factor used to specify the decimal fraction and a 1
//! bit sign. Because of this representation, trailing zeros are
//! preserved and may be exposed when in string form. These can be
//! truncated using the `normalize` or `round_dp` functions.
//!
//! ## Usage
//!
//! Decimal numbers can be created in a few distinct ways, depending
//! on the rust compiler version you're targeting.
//!
//! The stable version of rust requires you to create a Decimal number
//! using one of it's convenience methods.
//!
//! ```rust
//! use rust_decimal::Decimal;
//! use std::str::FromStr;
//!
//! // Using an integer followed by the decimal points
//! let scaled = Decimal::new(202, 2); // 2.02
//!
//! // From a string representation
//! let from_string = Decimal::from_str("2.02").unwrap(); // 2.02
//!
//! // Using the `Into` trait
//! let my_int : Decimal = 3i32.into();
//!
//! // Using the raw decimal representation
//! // 3.1415926535897932384626433832
//! let pi = Decimal::from_parts(1102470952, 185874565, 1703060790, false, 28);
//! ```
//!
extern crate num;
#[cfg(not(feature = "const_fn"))]
#[macro_use]
extern crate lazy_static;

#[cfg(feature = "postgres")]
#[macro_use]
extern crate postgres as pg_crate;

#[cfg(feature = "serde")]
extern crate serde;
#[cfg(feature = "serde")]
#[cfg(test)]
extern crate serde_json;
#[cfg(feature = "serde")]
#[cfg(test)]
#[macro_use]
extern crate serde_derive;

mod decimal;
mod error;

#[cfg(feature = "postgres")]
mod postgres;
#[cfg(feature = "serde")]
mod serde_types;

pub use decimal::{Decimal, RoundingStrategy};
pub use error::Error;

pub mod prelude {
    pub use num::{FromPrimitive, One, ToPrimitive, Zero};
}
<|endoftext|>


<commit_before>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is(atty::Stream::Stdout) {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt(atty::Stream::Stdout) {
//!   println!("i'm not a tty")
//! }
//! ```

#![cfg_attr(unix, no_std)]

#[cfg(windows)]
extern crate kernel32;
#[cfg(unix)]
extern crate libc;
#[cfg(windows)]
extern crate winapi;
#[cfg(target_os = "redox")]
extern crate termion;

#[cfg(windows)]
use winapi::minwindef::DWORD;

/// possible stream sources
#[derive(Clone, Copy, Debug)]
pub enum Stream {
    Stdout,
    Stderr,
    Stdin,
}

/// returns true if this is a tty
#[cfg(unix)]
pub fn is(stream: Stream) -> bool {
    extern crate libc;

    let fd = match stream {
        Stream::Stdout => libc::STDOUT_FILENO,
        Stream::Stderr => libc::STDERR_FILENO,
        Stream::Stdin => libc::STDIN_FILENO,
    };
    unsafe { libc::isatty(fd) != 0 }
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is(stream: Stream) -> bool {
    use winapi::{
        STD_INPUT_HANDLE as STD_INPUT,
        STD_ERROR_HANDLE as STD_ERROR,
        STD_OUTPUT_HANDLE as STD_OUTPUT
    };

    let (fd, others) = match stream {
        Stream::Stdin => (STD_INPUT, [STD_ERROR, STD_OUTPUT]),
        Stream::Stderr => (STD_ERROR, [STD_INPUT, STD_OUTPUT]),
        Stream::Stdout => (STD_OUTPUT, [STD_INPUT, STD_ERROR]),
    };
    if unsafe { console_on_any(&[fd]) } {
        // False positives aren't possible. If we got a console then
        // we definitely have a tty on stdin.
        return true;
    }

    // At this point, we *could* have a false negative. We can determine that
    // this is true negative if we can detect the presence of a console on
    // any of the other streams. If another stream has a console, then we know
    // we're in a Windows console and can therefore trust the negative.
    if unsafe { console_on_any(&others) } {
        return false;
    }

    // Otherwise, we fall back to a very strange msys hack to see if we can
    // sneakily detect the presence of a tty.
    unsafe { msys_tty_on(fd) }
}

/// returns true if this is _not_ a tty
pub fn isnt(stream: Stream) -> bool {
    !is(stream)
}

/// Returns true if any of the given fds are on a console.
#[cfg(windows)]
unsafe fn console_on_any(fds: &[DWORD]) -> bool {
    for &fd in fds {
        let mut out = 0;
        let handle = kernel32::GetStdHandle(fd);
        if kernel32::GetConsoleMode(handle, &mut out) != 0 {
            return true;
        }
    }
    false
}

/// Returns true if there is an MSYS tty on the given handle.
#[cfg(windows)]
unsafe fn msys_tty_on(fd: DWORD) -> bool {
    use std::ffi::OsString;
    use std::mem;
    use std::os::raw::c_void;
    use std::os::windows::ffi::OsStringExt;
    use std::slice;

    use kernel32::GetFileInformationByHandleEx;
    use winapi::fileapi::FILE_NAME_INFO;
    use winapi::minwinbase::FileNameInfo;
    use winapi::minwindef::MAX_PATH;

    let size = mem::size_of::<FILE_NAME_INFO>();
    let mut name_info_bytes = vec![0u8; size + MAX_PATH];
    let res = GetFileInformationByHandleEx(
        kernel32::GetStdHandle(fd),
        FileNameInfo,
        &mut *name_info_bytes as *mut _ as *mut c_void,
        name_info_bytes.len() as u32);
    if res == 0 {
        return true;
    }
    let name_info: FILE_NAME_INFO =
        *(name_info_bytes[0..size].as_ptr() as *const FILE_NAME_INFO);
    let name_bytes =
        &name_info_bytes[size..size + name_info.FileNameLength as usize];
    let name_u16 = slice::from_raw_parts(
        name_bytes.as_ptr() as *const u16, name_bytes.len() / 2);
    let name = OsString::from_wide(name_u16)
        .as_os_str().to_string_lossy().into_owned();
    name.contains("msys-") || name.contains("-pty")
}

/// returns true if this is a tty
#[cfg(target_os = "redox")]
pub fn is(stream: Stream) -> bool {
    use std::io;
    use termion::is_tty;

    match stream {
        Stream::Stdin => is_tty(&io::stdin()),
        Stream::Stdout => is_tty(&io::stdout()),
        Stream::Stderr => is_tty(&io::stderr())
    }
}

#[cfg(test)]
mod tests {
    use super::{is, Stream};

    #[test]
    #[cfg(windows)]
    fn is_err() {
        // appveyor pipes its output
        assert!(!is(Stream::Stderr))
    }

    #[test]
    #[cfg(windows)]
    fn is_out() {
        // appveyor pipes its output
        assert!(!is(Stream::Stdout))
    }

    #[test]
    #[cfg(windows)]
    fn is_in() {
        assert!(is(Stream::Stdin))
    }

    #[test]
    #[cfg(unix)]
    fn is_err() {
        assert!(is(Stream::Stderr))
    }

    #[test]
    #[cfg(unix)]
    fn is_out() {
        assert!(is(Stream::Stdout))
    }

    #[test]
    #[cfg(target_os = "macos")]
    fn is_in() {
        // macos on travis seems to pipe its input
        assert!(!is(Stream::Stdin))
    }

    #[test]
    #[cfg(all(not(target_os = "macos"), unix))]
    fn is_in() {
        assert!(is(Stream::Stdin))
    }
}
<commit_msg>style<commit_after>//! atty is a simple utility that answers one question
//! > is this a tty?
//!
//! usage is just as simple
//!
//! ```
//! if atty::is(atty::Stream::Stdout) {
//!   println!("i'm a tty")
//! }
//! ```
//!
//! ```
//! if atty::isnt(atty::Stream::Stdout) {
//!   println!("i'm not a tty")
//! }
//! ```

#![cfg_attr(unix, no_std)]

#[cfg(windows)]
extern crate kernel32;
#[cfg(unix)]
extern crate libc;
#[cfg(windows)]
extern crate winapi;
#[cfg(target_os = "redox")]
extern crate termion;

#[cfg(windows)]
use winapi::minwindef::DWORD;

/// possible stream sources
#[derive(Clone, Copy, Debug)]
pub enum Stream {
    Stdout,
    Stderr,
    Stdin,
}

/// returns true if this is a tty
#[cfg(unix)]
pub fn is(stream: Stream) -> bool {
    extern crate libc;

    let fd = match stream {
        Stream::Stdout => libc::STDOUT_FILENO,
        Stream::Stderr => libc::STDERR_FILENO,
        Stream::Stdin => libc::STDIN_FILENO,
    };
    unsafe { libc::isatty(fd) != 0 }
}

/// returns true if this is a tty
#[cfg(windows)]
pub fn is(stream: Stream) -> bool {
    use winapi::{STD_ERROR_HANDLE as STD_ERROR, STD_INPUT_HANDLE as STD_INPUT,
                 STD_OUTPUT_HANDLE as STD_OUTPUT};

    let (fd, others) = match stream {
        Stream::Stdin => (STD_INPUT, [STD_ERROR, STD_OUTPUT]),
        Stream::Stderr => (STD_ERROR, [STD_INPUT, STD_OUTPUT]),
        Stream::Stdout => (STD_OUTPUT, [STD_INPUT, STD_ERROR]),
    };
    if unsafe { console_on_any(&[fd]) } {
        // False positives aren't possible. If we got a console then
        // we definitely have a tty on stdin.
        return true;
    }

    // At this point, we *could* have a false negative. We can determine that
    // this is true negative if we can detect the presence of a console on
    // any of the other streams. If another stream has a console, then we know
    // we're in a Windows console and can therefore trust the negative.
    if unsafe { console_on_any(&others) } {
        return false;
    }

    // Otherwise, we fall back to a very strange msys hack to see if we can
    // sneakily detect the presence of a tty.
    unsafe { msys_tty_on(fd) }
}

/// returns true if this is _not_ a tty
pub fn isnt(stream: Stream) -> bool {
    !is(stream)
}

/// Returns true if any of the given fds are on a console.
#[cfg(windows)]
unsafe fn console_on_any(fds: &[DWORD]) -> bool {
    for &fd in fds {
        let mut out = 0;
        let handle = kernel32::GetStdHandle(fd);
        if kernel32::GetConsoleMode(handle, &mut out) != 0 {
            return true;
        }
    }
    false
}

/// Returns true if there is an MSYS tty on the given handle.
#[cfg(windows)]
unsafe fn msys_tty_on(fd: DWORD) -> bool {
    use std::ffi::OsString;
    use std::mem;
    use std::os::raw::c_void;
    use std::os::windows::ffi::OsStringExt;
    use std::slice;

    use kernel32::GetFileInformationByHandleEx;
    use winapi::fileapi::FILE_NAME_INFO;
    use winapi::minwinbase::FileNameInfo;
    use winapi::minwindef::MAX_PATH;

    let size = mem::size_of::<FILE_NAME_INFO>();
    let mut name_info_bytes = vec![0u8; size + MAX_PATH];
    let res = GetFileInformationByHandleEx(
        kernel32::GetStdHandle(fd),
        FileNameInfo,
        &mut *name_info_bytes as *mut _ as *mut c_void,
        name_info_bytes.len() as u32,
    );
    if res == 0 {
        return true;
    }
    let name_info: FILE_NAME_INFO = *(name_info_bytes[0..size].as_ptr() as
                                          *const FILE_NAME_INFO);
    let name_bytes =
        &name_info_bytes[size..size + name_info.FileNameLength as usize];
    let name_u16 = slice::from_raw_parts(
        name_bytes.as_ptr() as *const u16,
        name_bytes.len() / 2,
    );
    let name = OsString::from_wide(name_u16)
        .as_os_str()
        .to_string_lossy()
        .into_owned();
    name.contains("msys-") || name.contains("-pty")
}

/// returns true if this is a tty
#[cfg(target_os = "redox")]
pub fn is(stream: Stream) -> bool {
    use std::io;
    use termion::is_tty;

    match stream {
        Stream::Stdin => is_tty(&io::stdin()),
        Stream::Stdout => is_tty(&io::stdout()),
        Stream::Stderr => is_tty(&io::stderr()),
    }
}

#[cfg(test)]
mod tests {
    use super::{Stream, is};

    #[test]
    #[cfg(windows)]
    fn is_err() {
        // appveyor pipes its output
        assert!(!is(Stream::Stderr))
    }

    #[test]
    #[cfg(windows)]
    fn is_out() {
        // appveyor pipes its output
        assert!(!is(Stream::Stdout))
    }

    #[test]
    #[cfg(windows)]
    fn is_in() {
        assert!(is(Stream::Stdin))
    }

    #[test]
    #[cfg(unix)]
    fn is_err() {
        assert!(is(Stream::Stderr))
    }

    #[test]
    #[cfg(unix)]
    fn is_out() {
        assert!(is(Stream::Stdout))
    }

    #[test]
    #[cfg(target_os = "macos")]
    fn is_in() {
        // macos on travis seems to pipe its input
        assert!(is(Stream::Stdin))
    }

    #[test]
    #[cfg(all(not(target_os = "macos"), unix))]
    fn is_in() {
        assert!(is(Stream::Stdin))
    }
}
<|endoftext|>


<commit_before>#[crate_id = "github.com/lfairy/rose"];
#[license = "MIT"];
#[comment = "Super simple regular expression library"];

//!
//! ~~~
//! extern mod rose;
//!
//! let names = rose::compile(r"Bon Bon|Lyra");
//! match names.exec("Lyra Heartstrings") {
//!     Some(result) => println!("Found: {}", result.group(0)),
//!     None => fail!("Oh noes!")
//! }
//! ~~~
//!
//!
//! # A simple regular expression engine
//!
//! Rose is a library that executes regular expressions.  A subset of
//! PCRE notation is supported, excluding backreferences and lookaround
//! which cannot be implemented efficiently.
//!
//! To get started, prepare a pattern using [compile](fn.compile.html).
//! This creates a [Regex](struct.Regex.html) object, which can then be
//! run using its `exec` and `search` methods.
//!

mod charclass;
pub mod compile;
pub mod parse;
pub mod vm;

/// A compiled regular expression.  Use [compile](fn.compile.html) to
/// create one of these.
pub struct Regex {
    priv program: vm::Program
}

impl Regex {
    /// Create a `Regex` from a code block.
    pub fn from_program(program: vm::Program) -> Regex {
        Regex {
            program: program
        }
    }

    /// Check if the regex matches the given string.
    pub fn matches(&self, s: &str) -> bool {
        let mut vm = vm::VM::new(&self.program);
        for c in s.chars() {
            vm.feed(c);
            if vm.is_match() {
                return true;
            }
        }
        false
    }
}

/// Compile a regular expression.  Fails on invalid syntax.
pub fn compile(regex: &str) -> Regex {
    Regex::from_program(compile::compile(&parse::parse(regex)))
}
<commit_msg>Make docs build again (mozilla/rust#11178)<commit_after>#[crate_id = "github.com/lfairy/rose"];
#[license = "MIT"];
#[comment = "Super simple regular expression library"];

//!
//! ~~~
//! extern mod rose;
//!
//! let names = rose::compile(r"Bon Bon|Lyra");
//! match names.exec("Lyra Heartstrings") {
//!     Some(result) => println!("Found: {}", result.group(0)),
//!     None => fail!("Oh noes!")
//! }
//! ~~~
//!
//!
//! # A simple regular expression engine
//!
//! Rose is a library that executes regular expressions.  A subset of
//! PCRE notation is supported, excluding backreferences and lookaround
//! which cannot be implemented efficiently.
//!
//! To get started, prepare a pattern using [compile](fn.compile.html).
//! This creates a [Regex](struct.Regex.html) object, which can then be
//! run using its `exec` and `search` methods.
//!

pub mod compile;
pub mod parse;
pub mod vm;
mod charclass;

/// A compiled regular expression.  Use [compile](fn.compile.html) to
/// create one of these.
pub struct Regex {
    priv program: vm::Program
}

impl Regex {
    /// Create a `Regex` from a code block.
    pub fn from_program(program: vm::Program) -> Regex {
        Regex {
            program: program
        }
    }

    /// Check if the regex matches the given string.
    pub fn matches(&self, s: &str) -> bool {
        let mut vm = vm::VM::new(&self.program);
        for c in s.chars() {
            vm.feed(c);
            if vm.is_match() {
                return true;
            }
        }
        false
    }
}

/// Compile a regular expression.  Fails on invalid syntax.
pub fn compile(regex: &str) -> Regex {
    Regex::from_program(compile::compile(&parse::parse(regex)))
}
<|endoftext|>


<commit_before>//! A library for interacting with Twitter.
//!
//! Please see [the repository][] and its enclosed examples for tips on working with this library
//! while it's still in progress.
//!
//! [the repository]: https://github.com/icesoldier/twitter-rs
//!
//! ## Getting Started
//!
//! The very first thing you'll need to do to get access to the Twitter API is to head to
//! [Twitter's Application Manager][twitter-apps] and create an app. Once you've done that, there
//! are two sets of keys immediately available to you. First are the "consumer key" and "consumer
//! secret", that are used to represent you as the application author when signing requests. These
//! keys are given to every single API call regardless of permission level. Related are an "access
//! token" and "access token secret", that can be used to skip the authentication steps if you're
//! only interacting with your own account or with no account in particular. Generally, if you want
//! to read or write to a particular user's stream, you'll need to request authorization and get an
//! access token to work on their behalf.
//!
//! [twitter-apps]: https://apps.twitter.com/
//!
//! The process to get an access token for a specific user (with this library) has three basic
//! steps:
//!
//! 1. Log your request with Twitter by getting a [request token][].
//! 2. Direct the user to grant permission to your application by sending them to an
//!    [authenticate][] or [authorize][] URL, depending on the nature of your app.
//! 3. Convert the verifier given by the permission request into an [access token][].
//!
//! [request token]: fn.request_token.html
//! [authorize]: fn.authorize_url.html
//! [authenticate]: fn.authenticate_url.html
//! [access token]: fn.access_token.html
//!
//! The process changes some smaller details depending on whether your application is web- or
//! mobile-based, as opposed to desktop-based or in another situation where redirecting users to a
//! web browser and back automatically is difficult or impossible. In the former case where URLs
//! can be used to direct the user into and out of your app, give Twitter a "callback URL" when
//! setting up your request token, and redirect the user to an [authenticate][] URL to grant your
//! app permissions. When the user accepts the request, they will be redirected back to this URL to
//! get back to your app, with the original request token and a verifier given to your app to
//! signify their acceptance.
//!
//! On the other hand, if you can't use the callback URL in this fashion, you can instead use the
//! "PIN-based Auth" version of the flow. In this version, give a "callback URL" of "oob" when
//! setting up your request token, and use an [authorize][] URL. When the user grants the
//! permissions request in this fashion, they are given a numeric PIN that can be given back to
//! your app to use as a verifier.
//!
//! Either way, when you have a "verifier" from either of these methods, you can use your Tokens
//! from earlier in the process with that verifier to request an [access token][]. This access
//! token can then be saved and cached for future use.
//!
//! ## `Response<T>`
//!
//! Every method that calls Twitter and carries rate-limit information wraps its return value in a
//! [`Response`][] struct, that transmits this information to your app. From there, you can handle
//! the rate-limit information to hold off on that kind of request, or simply grab its `response`
//! field to get the output of whatever method you called.
//!
//! [`Response`]: struct.Response.html

#![warn(missing_docs)]
#![warn(unused_extern_crates)]
#![warn(unused_qualifications)]

#[macro_use] extern crate hyper;
extern crate url;
extern crate time;
extern crate rand;
extern crate crypto;
extern crate rustc_serialize;
extern crate mime;

mod auth;
pub mod error;
pub mod user;
mod links;
mod common;

pub use auth::{Token, request_token, authorize_url, authenticate_url, access_token};
pub use common::{Response, TwitterErrors, TwitterErrorCode, UserID};
<commit_msg>change repo link to use my new github username<commit_after>//! A library for interacting with Twitter.
//!
//! Please see [the repository][] and its enclosed examples for tips on working with this library
//! while it's still in progress.
//!
//! [the repository]: https://github.com/QuietMisdreavus/twitter-rs
//!
//! ## Getting Started
//!
//! The very first thing you'll need to do to get access to the Twitter API is to head to
//! [Twitter's Application Manager][twitter-apps] and create an app. Once you've done that, there
//! are two sets of keys immediately available to you. First are the "consumer key" and "consumer
//! secret", that are used to represent you as the application author when signing requests. These
//! keys are given to every single API call regardless of permission level. Related are an "access
//! token" and "access token secret", that can be used to skip the authentication steps if you're
//! only interacting with your own account or with no account in particular. Generally, if you want
//! to read or write to a particular user's stream, you'll need to request authorization and get an
//! access token to work on their behalf.
//!
//! [twitter-apps]: https://apps.twitter.com/
//!
//! The process to get an access token for a specific user (with this library) has three basic
//! steps:
//!
//! 1. Log your request with Twitter by getting a [request token][].
//! 2. Direct the user to grant permission to your application by sending them to an
//!    [authenticate][] or [authorize][] URL, depending on the nature of your app.
//! 3. Convert the verifier given by the permission request into an [access token][].
//!
//! [request token]: fn.request_token.html
//! [authorize]: fn.authorize_url.html
//! [authenticate]: fn.authenticate_url.html
//! [access token]: fn.access_token.html
//!
//! The process changes some smaller details depending on whether your application is web- or
//! mobile-based, as opposed to desktop-based or in another situation where redirecting users to a
//! web browser and back automatically is difficult or impossible. In the former case where URLs
//! can be used to direct the user into and out of your app, give Twitter a "callback URL" when
//! setting up your request token, and redirect the user to an [authenticate][] URL to grant your
//! app permissions. When the user accepts the request, they will be redirected back to this URL to
//! get back to your app, with the original request token and a verifier given to your app to
//! signify their acceptance.
//!
//! On the other hand, if you can't use the callback URL in this fashion, you can instead use the
//! "PIN-based Auth" version of the flow. In this version, give a "callback URL" of "oob" when
//! setting up your request token, and use an [authorize][] URL. When the user grants the
//! permissions request in this fashion, they are given a numeric PIN that can be given back to
//! your app to use as a verifier.
//!
//! Either way, when you have a "verifier" from either of these methods, you can use your Tokens
//! from earlier in the process with that verifier to request an [access token][]. This access
//! token can then be saved and cached for future use.
//!
//! ## `Response<T>`
//!
//! Every method that calls Twitter and carries rate-limit information wraps its return value in a
//! [`Response`][] struct, that transmits this information to your app. From there, you can handle
//! the rate-limit information to hold off on that kind of request, or simply grab its `response`
//! field to get the output of whatever method you called.
//!
//! [`Response`]: struct.Response.html

#![warn(missing_docs)]
#![warn(unused_extern_crates)]
#![warn(unused_qualifications)]

#[macro_use] extern crate hyper;
extern crate url;
extern crate time;
extern crate rand;
extern crate crypto;
extern crate rustc_serialize;
extern crate mime;

mod auth;
pub mod error;
pub mod user;
mod links;
mod common;

pub use auth::{Token, request_token, authorize_url, authenticate_url, access_token};
pub use common::{Response, TwitterErrors, TwitterErrorCode, UserID};
<|endoftext|>


<commit_before>extern crate time;

use std::iter::Iterator;

use time::{now_utc, Tm, Duration};

pub struct ProgressRecord {

    /// How many elements before this
    num: usize,

    iterating_for: Duration,
    size_hint: (usize, Option<usize>),

    recent_rate: f32,

}

impl ProgressRecord {
    /// Returns a basic log message of where we are now. You can construct this yourself, but this
    /// is a helpful convience method.
    pub fn message(&self) -> String {
        format!("{} - Seen {} Rate {}/sec", self.duration_since_start().num_seconds(), self.num_done(), self.recent_rate())
    }

    /// Duration since iteration started
    pub fn duration_since_start(&self) -> Duration {
        self.iterating_for
    }

    /// Number of items we've generated so far
    pub fn num_done(&self) -> usize {
        self.num
    }

    /// Prints a basic message
    pub fn print_message(&self) {
        println!("{}", self.message());
    }

    /// Number of items per second
    pub fn rate(&self) -> f32 {
        // number of items per second
        (self.num_done() as f32) / (self.duration_since_start().num_seconds() as f32)
    }

    /// None if we don't know how much we've done (as a fraction), otherwise a value form 0 to 1
    /// for what fraction along we are.
    pub fn fraction(&self) -> Option<f32> {
        if self.is_size_known() {
            let remaining = self.size_hint.0;
            let done = self.num_done();
            Some(( done as f32 ) / ( (remaining+done) as f32 ))
        } else {
            None
        }
    }

    /// None if we don't know how much we've done, otherwise value for 0 to 100 representing how
    /// far along as a percentage we are.
    pub fn percent(&self) -> Option<f32> {
        match self.fraction() {
            None => { None }
            Some(f) => { Some(f * 100.0) }
        }
    }

    /// If we want to print every `n` items, should we print now?
    pub fn should_print_every_items(&self, n: usize) -> bool {
        (self.num_done() - 1) % n == 0
    }

    /// Print out `msg`, but only if there has been `n` items.
    /// Often you want to print out a debug message every 1,000 items or so. This function does
    /// that.
    pub fn print_every<T: std::fmt::Display>(&self, n: usize, msg: T) {
        if self.should_print_every_items(n) {
            print!("{}", msg);
        }
    }

    /// Does the size_hint tell us exactly how many items are left? False iff there is some
    /// ambiguity/unknown
    fn is_size_known(&self) -> bool {
        match self.size_hint.1 {
            None => { false },
            Some(x) => { self.size_hint.0 == x },
        }
    }

    /// The rate of the last few items.
    pub fn recent_rate(&self) -> f32 {
        self.recent_rate
    }

}

/// Wraps an iterator and keeps track of state used for `ProgressRecord`'s
pub struct ProgressRecorderIter<I> {

    /// The iterator that we are iteating on
    iter: I,

    /// How many items have been seen
    count: usize,

    /// When did we start iterating
    started_iterating: Tm,

    /// Keeps track of recent times
    recent_times: Vec<Tm>
}

impl<I: Iterator> ProgressRecorderIter<I> {
    /// Create a new `ProgressRecorderIter` from another iterator.
    pub fn new(iter: I) -> ProgressRecorderIter<I> {
        ProgressRecorderIter{ iter: iter, count: 0, started_iterating: now_utc(), recent_times: Vec::with_capacity(5) }
    }

    /// Calculate the current `ProgressRecord` for where we are now.
    fn generate_record(&mut self) -> ProgressRecord {
        let now = now_utc();
        self.recent_times.push(now);
        while self.recent_times.len() > 100 {
            self.recent_times.remove(0);
        }

        //println!("\n");
        //println!("Recents {:?} now {:?}", self.recent_times.iter().map(|&d| { (now - d).num_seconds() }).collect::<Vec<_>>(), now);
        let recent_rate = match self.recent_times.get(0) { None => { ::std::f32::INFINITY }, Some(&first) => {
            //println!("{} {}", self.recent_times.len() as f32, (now - first).num_seconds() as f32);
            (self.recent_times.len() as f32 ) / ((now - first).num_seconds() as f32)
        }, };

        self.count += 1;
        ProgressRecord{ num: self.count, iterating_for: now - self.started_iterating, size_hint: self.iter.size_hint(), recent_rate: recent_rate }
    }

}

/// An iterator that records it's progress as it goes along
pub trait ProgressableIter<I> {
    fn progress(self) -> ProgressRecorderIter<I>;
}

impl<I> ProgressableIter<I> for I where I: Iterator {
    /// Convert an iterator into a `ProgressRecorderIter`.
    fn progress(self) -> ProgressRecorderIter<I> {
        ProgressRecorderIter::new(self)
    }
}

impl<I> Iterator for ProgressRecorderIter<I> where I: Iterator {
    type Item = (ProgressRecord, <I as Iterator>::Item);

    #[inline]
    fn next(&mut self) -> Option<(ProgressRecord, <I as Iterator>::Item)> {
        self.iter.next().map(|a| {
            (self.generate_record(), a)
        })
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }

    #[inline]
    fn count(self) -> usize {
        self.iter.count()
    }
}

mod test {
    #[test]
    fn test_simple() {
        use super::ProgressableIter;
        use std::thread::sleep_ms;
        use time::Duration;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "0 - Seen 1 Rate inf/sec");
        // It'll always print on the first one
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), true);
        assert_eq!(state.rate(), ::std::f32::INFINITY);
        assert_eq!(state.recent_rate(), ::std::f32::INFINITY);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 2 Rate 2/sec");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);
        //assert_eq!(state.recent_rate(), 2.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 3 Rate 3/sec");
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 3.);
        assert_eq!(state.recent_rate(), 3.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "2 - Seen 4 Rate 2/sec");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);
        assert_eq!(state.recent_rate(), 2.);
    }

    #[test]
    fn test_size_hint() {
        use super::ProgressableIter;
        use time::Duration;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.2));
        assert_eq!(state.percent(), Some(20.));

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.4));
        assert_eq!(state.percent(), Some(40.));

        let mut progressor = (0..).progress();

        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 0);
        assert_eq!(state.fraction(), None);
        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 1);
        assert_eq!(state.fraction(), None);

    }
}

<commit_msg>docs: Add doccomments<commit_after>extern crate time;

use std::iter::Iterator;

use time::{now_utc, Tm, Duration};

pub struct ProgressRecord {

    /// How many elements before this
    num: usize,

    /// How long since we started iterating.
    iterating_for: Duration,
    size_hint: (usize, Option<usize>),

    recent_rate: f32,

}

impl ProgressRecord {
    /// Returns a basic log message of where we are now. You can construct this yourself, but this
    /// is a helpful convience method.
    pub fn message(&self) -> String {
        format!("{} - Seen {} Rate {}/sec", self.duration_since_start().num_seconds(), self.num_done(), self.recent_rate())
    }

    /// Duration since iteration started
    pub fn duration_since_start(&self) -> Duration {
        self.iterating_for
    }

    /// Number of items we've generated so far
    pub fn num_done(&self) -> usize {
        self.num
    }

    /// Prints a basic message
    pub fn print_message(&self) {
        println!("{}", self.message());
    }

    /// Number of items per second
    pub fn rate(&self) -> f32 {
        // number of items per second
        (self.num_done() as f32) / (self.duration_since_start().num_seconds() as f32)
    }

    /// None if we don't know how much we've done (as a fraction), otherwise a value form 0 to 1
    /// for what fraction along we are.
    pub fn fraction(&self) -> Option<f32> {
        if self.is_size_known() {
            let remaining = self.size_hint.0;
            let done = self.num_done();
            Some(( done as f32 ) / ( (remaining+done) as f32 ))
        } else {
            None
        }
    }

    /// None if we don't know how much we've done, otherwise value for 0 to 100 representing how
    /// far along as a percentage we are.
    pub fn percent(&self) -> Option<f32> {
        match self.fraction() {
            None => { None }
            Some(f) => { Some(f * 100.0) }
        }
    }

    /// If we want to print every `n` items, should we print now?
    pub fn should_print_every_items(&self, n: usize) -> bool {
        (self.num_done() - 1) % n == 0
    }

    /// Print out `msg`, but only if there has been `n` items.
    /// Often you want to print out a debug message every 1,000 items or so. This function does
    /// that.
    pub fn print_every<T: std::fmt::Display>(&self, n: usize, msg: T) {
        if self.should_print_every_items(n) {
            print!("{}", msg);
        }
    }

    /// Does the size_hint tell us exactly how many items are left? False iff there is some
    /// ambiguity/unknown
    fn is_size_known(&self) -> bool {
        match self.size_hint.1 {
            None => { false },
            Some(x) => { self.size_hint.0 == x },
        }
    }

    /// The rate of the last few items.
    pub fn recent_rate(&self) -> f32 {
        self.recent_rate
    }

}

/// Wraps an iterator and keeps track of state used for `ProgressRecord`'s
pub struct ProgressRecorderIter<I> {

    /// The iterator that we are iteating on
    iter: I,

    /// How many items have been seen
    count: usize,

    /// When did we start iterating
    started_iterating: Tm,

    /// Keeps track of recent times
    recent_times: Vec<Tm>
}

impl<I: Iterator> ProgressRecorderIter<I> {
    /// Create a new `ProgressRecorderIter` from another iterator.
    pub fn new(iter: I) -> ProgressRecorderIter<I> {
        ProgressRecorderIter{ iter: iter, count: 0, started_iterating: now_utc(), recent_times: Vec::with_capacity(5) }
    }

    /// Calculate the current `ProgressRecord` for where we are now.
    fn generate_record(&mut self) -> ProgressRecord {
        let now = now_utc();
        self.recent_times.push(now);
        while self.recent_times.len() > 100 {
            self.recent_times.remove(0);
        }

        //println!("\n");
        //println!("Recents {:?} now {:?}", self.recent_times.iter().map(|&d| { (now - d).num_seconds() }).collect::<Vec<_>>(), now);
        let recent_rate = match self.recent_times.get(0) { None => { ::std::f32::INFINITY }, Some(&first) => {
            //println!("{} {}", self.recent_times.len() as f32, (now - first).num_seconds() as f32);
            (self.recent_times.len() as f32 ) / ((now - first).num_seconds() as f32)
        }, };

        self.count += 1;
        ProgressRecord{ num: self.count, iterating_for: now - self.started_iterating, size_hint: self.iter.size_hint(), recent_rate: recent_rate }
    }

}

/// An iterator that records it's progress as it goes along
pub trait ProgressableIter<I> {
    fn progress(self) -> ProgressRecorderIter<I>;
}

impl<I> ProgressableIter<I> for I where I: Iterator {
    /// Convert an iterator into a `ProgressRecorderIter`.
    fn progress(self) -> ProgressRecorderIter<I> {
        ProgressRecorderIter::new(self)
    }
}

impl<I> Iterator for ProgressRecorderIter<I> where I: Iterator {
    type Item = (ProgressRecord, <I as Iterator>::Item);

    #[inline]
    fn next(&mut self) -> Option<(ProgressRecord, <I as Iterator>::Item)> {
        self.iter.next().map(|a| {
            (self.generate_record(), a)
        })
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }

    #[inline]
    fn count(self) -> usize {
        self.iter.count()
    }
}

mod test {
    #[test]
    fn test_simple() {
        use super::ProgressableIter;
        use std::thread::sleep_ms;
        use time::Duration;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "0 - Seen 1 Rate inf/sec");
        // It'll always print on the first one
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), true);
        assert_eq!(state.rate(), ::std::f32::INFINITY);
        assert_eq!(state.recent_rate(), ::std::f32::INFINITY);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 2 Rate 2/sec");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);
        //assert_eq!(state.recent_rate(), 2.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "1 - Seen 3 Rate 3/sec");
        assert_eq!(state.should_print_every_items(2), true);
        assert_eq!(state.should_print_every_items(3), false);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 3.);
        assert_eq!(state.recent_rate(), 3.);

        sleep_ms(500);
        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.message(), "2 - Seen 4 Rate 2/sec");
        assert_eq!(state.should_print_every_items(2), false);
        assert_eq!(state.should_print_every_items(3), true);
        assert_eq!(state.should_print_every_items(5), false);
        assert_eq!(state.rate(), 2.);
        assert_eq!(state.recent_rate(), 2.);
    }

    #[test]
    fn test_size_hint() {
        use super::ProgressableIter;
        use time::Duration;

        let vec: Vec<u8> = vec![0, 1, 2, 3, 4];
        let mut progressor = vec.iter().progress();

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.2));
        assert_eq!(state.percent(), Some(20.));

        let (state, _) = progressor.next().unwrap();
        assert_eq!(state.fraction(), Some(0.4));
        assert_eq!(state.percent(), Some(40.));

        let mut progressor = (0..).progress();

        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 0);
        assert_eq!(state.fraction(), None);
        let (state, val) = progressor.next().unwrap();
        assert_eq!(val, 1);
        assert_eq!(state.fraction(), None);

    }
}

<|endoftext|>