<commit_before>use super::models::{LanguageModel, WordVec};
use self::Token::*;
use super::mayberef::MaybeRef::{self, Val, Ref};

pub fn parse(expr: &str, model: &LanguageModel) -> WordVec {
    expression(&mut Tokens::from(expr.chars()), model).take()
}

#[derive(PartialEq, Eq, Debug)]
enum Token {
    RParen,
    LParen,
    Plus,
    Minus,
    Word(String),
}

fn expression<'a, I>(tokens: &mut Tokens<I>, model: &'a LanguageModel) -> MaybeRef<'a, WordVec>
    where I: Iterator<Item = char>
{
    let token = tokens.next().expect("An expression may not be empty");
    match token {
        LParen => {
            let vec = expression(tokens, model);
            assert_eq!(RParen, tokens.next().expect("Unbalanced parentheses"));
            rhs(vec, tokens, model)
        },
        Word(word) => {
            let vec = model.get(&*word).unwrap_or_else(||
                panic!("'{}' is not present in the language model", &word)
            );
            rhs(Ref(vec), tokens, model)
        },
        _ => panic!("An expression may not start with {:?}", token),
    }
}

fn rhs<'a, I>(lhs: MaybeRef<'a, WordVec>, tokens: &mut Tokens<I>, model: &LanguageModel) -> MaybeRef<'a, WordVec>
    where I: Iterator<Item = char>
{
    match tokens.peek() {
        Some(&RParen) | None => return lhs,
        _ => {}
    }

    let token = tokens.next().unwrap();
    match tokens.next().unwrap() {
        Plus => Val(lhs.take() + expression(tokens, model).deref()),
        Minus => Val(lhs.take() - expression(tokens, model).deref()),
        Word(_) | LParen => panic!("'{:?}' found in invalid position", token),
        RParen => unreachable!(),
    }
}

struct Tokens<I> {
    iter: I,
    next_char: Option<Option<char>>,
    next_token: Option<Option<Token>>
}

impl<I> Tokens<I> where I: Iterator<Item = char> {
    fn from(iter: I) -> Tokens<I> {
        Tokens {
            iter: iter,
            next_char: None,
            next_token: None,
        }
    }

    fn get_next_token(&mut self) -> Option<Token> {
        while let Some(' ') = self.peek_char() {
            self.take();
        }

        match self.peek_char() {
            Some('a'...'z') => return Some(self.word()),
            // Some('0'..'9') | Some('.') => return Some(self.number()),
            None => return None,
            _ => {}
        }

        Some(match self.take().unwrap() {
            '+' => Plus,
            '-' => Minus,
            '(' => LParen,
            ')' => RParen,
            c => panic!("{} was not expected", c)
        })
    }

    fn peek(&mut self) -> Option<&Token> {
        if let Some(ref t) = self.next_token {
            return t.as_ref();
        }

        self.next_token = Some(self.get_next_token());
        return self.next_token.as_ref().unwrap().as_ref();
    }

    fn peek_char(&mut self) -> Option<char> {
        match self.next_char {
            Some(x) => x,
            None => {
                let next = self.iter.next();
                self.next_char = Some(next);
                next
            }
        }
    }

    fn take(&mut self) -> Option<char> {
        self.peek_char();
        self.next_char.take().unwrap()
    }

    fn word(&mut self) -> Token {
        let mut token = String::new();
        while let Some('a'...'z') = self.peek_char() {
            token.push(self.take().unwrap());
        }

        Word(token)
    }

    fn single_char(&mut self) -> String {
        let mut token = String::new();
        token.push(self.take().unwrap());
        token
    }

}

impl<I> Iterator for Tokens<I> where I: Iterator<Item = char> {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        self.peek();
        self.next_token.take().unwrap()
    }
}

mod test {
    use super::Tokens;
    use super::Token::*;
    #[test]
    fn single_character() {
        let c = Tokens::from("a".chars()).next().unwrap();
        assert_eq!(c, Word("a".to_string()));
    }

    #[test]
    fn single_token() {
        let s = Tokens::from("abc".chars()).next().unwrap();
        assert_eq!(s, Word("abc".to_string()));
    }

    #[test]
    fn two_tokens() {
        let s = Tokens::from("abc def".chars()).collect::<Vec<_>>();
        assert_eq!(s, vec![Word("abc".to_string()), Word("def".to_string())]);
    }

    #[test]
    fn plus_tokens() {
        let s = Tokens::from("   abc  +def".chars()).collect::<Vec<_>>();
        assert_eq!(s, vec![Word("abc".to_string()), Plus, Word("def".to_string())]);
    }

        #[test]
    fn bracket_tokens() {
        let s = Tokens::from(" ()  (abc  +)def".chars()).collect::<Vec<_>>();
        assert_eq!(s, vec![LParen, RParen, LParen, Word("abc".to_string()),
            Plus, RParen, Word("def".to_string())]);
    }
}<commit_msg>Use result in the parser instead of panicing everywhere<commit_after>use super::models::{LanguageModel, WordVec};
use self::Token::*;
use super::mayberef::MaybeRef::{self, Val, Ref};

pub fn parse(expr: &str, model: &LanguageModel) -> Result<WordVec, String> {
    expression(&mut Tokens::from(expr.chars()), model).map(|w| w.take())
}

#[derive(PartialEq, Eq, Debug)]
enum Token {
    RParen,
    LParen,
    Plus,
    Minus,
    Word(String),
    Invalid(String),
}

fn expression<'a, I>(tokens: &mut Tokens<I>, model: &'a LanguageModel)
    -> Result<MaybeRef<'a, WordVec>, String>
    where I: Iterator<Item = char>
{
    let token = try!(tokens.next().ok_or("An expression may not be empty"));
    match token {
        LParen => {
            let vec = try!(expression(tokens, model));
            let rparen = try!(tokens.next().ok_or("Unbalanced parentheses"));
            if rparen != RParen {
                return Err(format!("Expected ')', found {:?}", rparen))
            }
            rhs(vec, tokens, model)
        },
        Word(word) => {
            let vec = try!(model.get(&*word).ok_or_else(||
                format!("'{}' is not present in the language model", &word)
            ));
            rhs(Ref(vec), tokens, model)
        },
        _ => Err(format!("An expression may not start with {:?}", token)),
    }
}

fn rhs<'a, I>(lhs: MaybeRef<'a, WordVec>, tokens: &mut Tokens<I>, model: &LanguageModel)
    -> Result<MaybeRef<'a, WordVec>, String>
    where I: Iterator<Item = char>
{
    match tokens.peek() {
        Some(&RParen) | None => return Ok(lhs),
        _ => {}
    }

    let token = tokens.next().unwrap();
    match token {
        Plus => Ok(Val(lhs.take() + try!(expression(tokens, model)).deref())),
        Minus => Ok(Val(lhs.take() - try!(expression(tokens, model)).deref())),
        Word(_) | LParen => Err(format!("'{:?}' found in invalid position", token)),
        Invalid(message) => Err(message),
        RParen => unreachable!(),
    }
}

struct Tokens<I> {
    iter: I,
    next_char: Option<Option<char>>,
    next_token: Option<Option<Token>>
}

impl<I> Tokens<I> where I: Iterator<Item = char> {
    fn from(iter: I) -> Tokens<I> {
        Tokens {
            iter: iter,
            next_char: None,
            next_token: None,
        }
    }

    fn get_next_token(&mut self) -> Option<Token> {
        while let Some(' ') = self.peek_char() {
            self.take();
        }

        match self.peek_char() {
            Some('a'...'z') => return Some(self.word()),
            // Some('0'..'9') | Some('.') => return Some(self.number()),
            None => return None,
            _ => {}
        }

        Some(match self.take().unwrap() {
            '+' => Plus,
            '-' => Minus,
            '(' => LParen,
            ')' => RParen,
            c => Invalid(format!("{} was not expected", c)),
        })
    }

    fn peek(&mut self) -> Option<&Token> {
        if let Some(ref t) = self.next_token {
            return t.as_ref();
        }

        self.next_token = Some(self.get_next_token());
        return self.next_token.as_ref().unwrap().as_ref();
    }

    fn peek_char(&mut self) -> Option<char> {
        match self.next_char {
            Some(x) => x,
            None => {
                let next = self.iter.next();
                self.next_char = Some(next);
                next
            }
        }
    }

    fn take(&mut self) -> Option<char> {
        self.peek_char();
        self.next_char.take().unwrap()
    }

    fn word(&mut self) -> Token {
        let mut token = String::new();
        while let Some('a'...'z') = self.peek_char() {
            token.push(self.take().unwrap());
        }

        Word(token)
    }

    fn single_char(&mut self) -> String {
        let mut token = String::new();
        token.push(self.take().unwrap());
        token
    }

}

impl<I> Iterator for Tokens<I> where I: Iterator<Item = char> {
    type Item = Token;

    fn next(&mut self) -> Option<Token> {
        self.peek();
        self.next_token.take().unwrap()
    }
}

mod test {
    use super::Tokens;
    use super::Token::*;
    #[test]
    fn single_character() {
        let c = Tokens::from("a".chars()).next().unwrap();
        assert_eq!(c, Word("a".to_string()));
    }

    #[test]
    fn single_token() {
        let s = Tokens::from("abc".chars()).next().unwrap();
        assert_eq!(s, Word("abc".to_string()));
    }

    #[test]
    fn two_tokens() {
        let s = Tokens::from("abc def".chars()).collect::<Vec<_>>();
        assert_eq!(s, vec![Word("abc".to_string()), Word("def".to_string())]);
    }

    #[test]
    fn plus_tokens() {
        let s = Tokens::from("   abc  +def".chars()).collect::<Vec<_>>();
        assert_eq!(s, vec![Word("abc".to_string()), Plus, Word("def".to_string())]);
    }

        #[test]
    fn bracket_tokens() {
        let s = Tokens::from(" ()  (abc  +)def".chars()).collect::<Vec<_>>();
        assert_eq!(s, vec![LParen, RParen, LParen, Word("abc".to_string()),
            Plus, RParen, Word("def".to_string())]);
    }
}<|endoftext|>


<commit_before>use nom::{alpha, alphanumeric, rest};
use std::vec::Vec;

use template::Chunk;

named!(var_name<Vec<u8>>,
    map!(
        recognize!(
            do_parse!(
                alpha >>
                many0!(alt!(alphanumeric | tag!("_"))) >>
                ()
            )
        ), Vec::from
    )
);

named!(var<Chunk>,
    map!(
        ws!(
            delimited!(
                tag!("{%"),
                var_name,
                tag!("%}")
            )
        ),
        |v| Chunk::Var(Vec::from(v))
    )
);

named!(escaped<Chunk>,
    do_parse!(
        tag!("{%%") >>
        (Chunk::Str(b"{%".to_vec()))
    )
);

named!(literal<Chunk>,
    map!(
        alt_complete!(take_until!("{%") | rest),
        |s| Chunk::Str(Vec::from(s))
    )
);

named!(pub template<Vec<Chunk>>,
    many0!(
        alt!(var | escaped | literal)
    )
);

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

    macro_rules! str {
        ($s: expr) => (Chunk::Str($s.to_vec()))
    }

    macro_rules! var {
        ($s: expr) => (Chunk::Var($s.to_vec()))
    }

    #[test]
    fn basic_parsing() {
        let (_, parsed) = template(b"Hello, {% who %}!").unwrap();
        let chunks = vec![str!(b"Hello, "), var!(b"who"), str!(b"!")];
        assert_eq!(chunks, parsed);
    }

    #[test]
    fn escaped_parsing() {
        let (_, parsed) = template(b"Hello, {%% who %}!").unwrap();
        let chunks = vec![str!(b"Hello, "), str!(b"{%"), str!(b" who %}!")];
        assert_eq!(chunks, parsed)
    }
}
<commit_msg>Remove common denominator from names<commit_after>use nom::{alpha, alphanumeric, rest};
use std::vec::Vec;

use template::Chunk;

named!(var_name<Vec<u8>>,
    map!(
        recognize!(
            do_parse!(
                alpha >>
                many0!(alt!(alphanumeric | tag!("_"))) >>
                ()
            )
        ), Vec::from
    )
);

named!(var<Chunk>,
    map!(
        ws!(
            delimited!(
                tag!("{%"),
                var_name,
                tag!("%}")
            )
        ),
        |v| Chunk::Var(Vec::from(v))
    )
);

named!(escaped<Chunk>,
    do_parse!(
        tag!("{%%") >>
        (Chunk::Str(b"{%".to_vec()))
    )
);

named!(literal<Chunk>,
    map!(
        alt_complete!(take_until!("{%") | rest),
        |s| Chunk::Str(Vec::from(s))
    )
);

named!(pub template<Vec<Chunk>>,
    many0!(
        alt!(var | escaped | literal)
    )
);

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

    macro_rules! str {
        ($s: expr) => (Chunk::Str($s.to_vec()))
    }

    macro_rules! var {
        ($s: expr) => (Chunk::Var($s.to_vec()))
    }

    #[test]
    fn basic() {
        let (_, parsed) = template(b"Hello, {% who %}!").unwrap();
        let chunks = vec![str!(b"Hello, "), var!(b"who"), str!(b"!")];
        assert_eq!(chunks, parsed);
    }

    #[test]
    fn escaped() {
        let (_, parsed) = template(b"Hello, {%% who %}!").unwrap();
        let chunks = vec![str!(b"Hello, "), str!(b"{%"), str!(b" who %}!")];
        assert_eq!(chunks, parsed)
    }
}
<|endoftext|>


<commit_before>use std;
pub fn prime_filter(iter_size: usize) -> std::vec::Vec<bool>{
    if iter_size < 5 {
         let mut ret = vec![false, false, true, true];
         ret.truncate(iter_size);
         return ret
     }
    let mut prime_filter = vec![true; iter_size];
    prime_filter[0] = false;
    prime_filter[1] = false;
    let mut cur_num = 2;
    'outer: loop{
        for i in (cur_num+1)..iter_size{
            if 0 == i%cur_num { prime_filter[i] = false; }
        }
        cur_num += 1;
        while !prime_filter[cur_num]{
            if cur_num*cur_num > iter_size {
                break 'outer
            }
            cur_num += 1;
        }
    }
    prime_filter
}
<commit_msg>untested sieve of atkin<commit_after>use std;
pub fn prime_filter(iter_size: usize) -> std::vec::Vec<bool>{
    //Sieve of Atkin
    if iter_size < 100 {
        old_prime_filter(iter_size)
    }else{
        let mut prime_filter = vec![false; iter_size];
        prime_filter[2] = true;
        prime_filter[3] = true;
        prime_filter[5] = true;
        let mut y_sq = 1;
        let mut to_next_y_sq = 3;
        while y_sq<iter_size {
            if y_sq%2 == 1 {
                //n_1 = 4x^2 + y^2 === 1 (mod 4)
                let (mut n_1, mut to_next_n_1) = (4 + y_sq, 12);
                while n_1<iter_size{
                    prime_filter[n_1] ^= true;
                    while{ //Do-while
                        n_1 += to_next_n_1;
                        to_next_n_1 *= 8;
                        to_next_n_1 += 4;
                        (n_1%3 == 0) | (n_1%5 == 0)
                    } {}
                };
            };
            if y_sq%3 == 1 {
                //n_2 = 3x^2 + y^2 === 1 (mod 6)
                let (mut n_2, mut to_next_n_2) = ((y_sq%2)*9+3 + y_sq, (y_sq%2)*12+24);
                while n_2<iter_size {
                    prime_filter[n_2] ^= true;
                    while{ //Do-while
                        n_2 += to_next_n_2;
                        to_next_n_2 += 1;
                        to_next_n_2 *= 12;
                        n_2%5==0
                    } {}
                };
            };
            if y_sq%12 == 1 {
                //n_3 = 3x^2 - y^2 === 11 (mod 12)
                let (mut n_3, mut to_next_n_3) = (2*y_sq + 3*to_next_y_sq, 24);
                while n_3<iter_size {
                    prime_filter[n_3] ^= true;
                    while{ //Do-while
                        n_3 += to_next_n_3;
                        to_next_n_3 += 1;
                        to_next_n_3 *= 12;
                        n_3%5==0
                    } {};
                };
            };
            while{ //Do-while
                y_sq += to_next_y_sq;
                to_next_y_sq += 2;
                y_sq%6 == 0
            } {};
        };
        //Eliminate non-squarefree numbers
        let mut n_sq = 49; // 7^2
        let mut next_n_sq = 32; //9^2 - 7^2, skip even numbers.
        while n_sq < iter_size {
            let mut non_sq_free = n_sq;
            while non_sq_free < iter_size {
                prime_filter[non_sq_free] = false;
                while{ //Do-while
                    non_sq_free += n_sq + n_sq;
                    (non_sq_free%3==0) | (non_sq_free%5==0)
                } {};
            };
            while{ //Do-while
                n_sq += next_n_sq;
                next_n_sq += 1;
                next_n_sq *= 4;
                (n_sq%3==0) | (n_sq%5 == 0)
            } {};
        }
        prime_filter
    }
}

fn old_prime_filter(iter_size: usize) -> std::vec::Vec<bool>{
    if iter_size < 5 {
         let mut ret = vec![false, false, true, true];
         ret.truncate(iter_size);
         return ret
     }
    let mut prime_filter = vec![true; iter_size];
    prime_filter[0] = false;
    prime_filter[1] = false;
    let mut cur_num = 2;
    'outer: loop{
        for i in (cur_num+1)..iter_size{
            if 0 == i%cur_num { prime_filter[i] = false; }
        }
        cur_num += 1;
        while !prime_filter[cur_num]{
            if cur_num*cur_num > iter_size {
                break 'outer
            }
            cur_num += 1;
        }
    }
    prime_filter
}
<|endoftext|>


<commit_before>use std::io;
use std::io::prelude::BufRead;

use error::*;
use types::*;

pub struct Reader<R> {
    reader: io::BufReader<R>,
}

impl<R: io::Read> Reader<R> {
    pub fn new(inner: R) -> Self {
        Reader {
            reader: io::BufReader::new(inner)
        }
    }

    pub fn snapshot(&mut self) -> Result<Snapshot> {
        let reader = &mut self.reader;
        let mut buffer = String::new();

        reader.read_line(&mut buffer)?;
        let num_atoms = buffer.parse::<i32>()?;

        let mut comment = String::new();
        reader.read_line(&mut comment)?;

        let mut atoms: Vec<Atom> = Vec::new();
        for _ in 0..num_atoms {
            reader.read_line(&mut buffer)?;
            atoms.push(buffer.parse::<Atom>()?);
        }

        Ok(Snapshot {
            comment: comment,
            atoms: atoms
        })
    }
}
<commit_msg>Define a macro parse_line!<commit_after>use std::io;
use std::io::prelude::BufRead;

use error::*;
use types::*;

pub struct Reader<R> {
    reader: io::BufReader<R>,
}

macro_rules! parse_line {
    ($reader:ident) => {{
        let mut buffer = String::new();
        $reader.read_line(&mut buffer)?;
        buffer
    }};
    ($reader:ident, $t:ty) => {{
        let mut buffer = String::new();
        $reader.read_line(&mut buffer)?;
        buffer.parse::<$t>()?
    }}
}

impl<R: io::Read> Reader<R> {
    pub fn new(inner: R) -> Self {
        Reader {
            reader: io::BufReader::new(inner)
        }
    }

    pub fn snapshot(&mut self) -> Result<Snapshot> {
        let reader = &mut self.reader;

        let num_atoms = parse_line!(reader, i32);
        let comment = parse_line!(reader);

        let mut atoms: Vec<Atom> = Vec::new();
        for _ in 0..num_atoms {
            atoms.push(parse_line!(reader, Atom));
        }

        Ok(Snapshot {
            comment: comment,
            atoms: atoms
        })
    }
}
<|endoftext|>


<commit_before>//! Implement record manupulation mechanisms.

use rustc_serialize::json;
use rustc_serialize::{Encodable, Encoder};
use rmp_serialize::encode;
use time::Tm;
use std::io;
use retry;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Record<T: Encodable> {
    tag: String,
    time: Tm,
    record: T,
}

pub enum FluentError {
    JsonEncode(json::EncoderError),
    MsgpackEncode(encode::Error),
    IO(io::Error),
    Retry(retry::RetryError),
}

impl From<io::Error> for FluentError {
    fn from(err: io::Error) -> FluentError {
        FluentError::IO(err)
    }
}

impl From<encode::Error> for FluentError {
    fn from(err: encode::Error) -> FluentError {
        FluentError::MsgpackEncode(err)
    }
}

impl From<retry::RetryError> for FluentError {
    fn from(err: retry::RetryError) -> FluentError {
        FluentError::Retry(err)
    }
}

impl From<json::EncoderError> for FluentError {
    fn from(err: json::EncoderError) -> FluentError {
        FluentError::JsonEncode(err)
    }
}

impl<T: Encodable> Record<T> {
    pub fn new(tag: String, time: Tm, record: T) -> Record<T> {
        Record {
            tag: tag,
            time: time,
            record: record,
        }
    }

    pub fn make_forwardable_json(self) -> Result<String, FluentError> {
        let message = try!(json::encode(&self));
        Ok(message)
    }
}

/// Construct custom encoding json/msgpack style.
///
/// Because `Record` struct should map following style json/msgpack:
///
/// `[tag, unixtime/eventtime, record]`
///
/// ref: https://github.com/fluent/fluentd/wiki/Forward-Protocol-Specification-v0#message-mode
impl<T: Encodable> Encodable for Record<T> {
    fn encode<S: Encoder>(&self, encoder: &mut S) -> Result<(), S::Error> {
        match *self {
            Record { tag: ref p_tag, time: ref p_time, record: ref p_record } => {
                encoder.emit_tuple(4, |encoder| {
                    try!(encoder.emit_tuple_arg(0, |encoder| p_tag.encode(encoder)));
                    try!(encoder.emit_tuple_arg(1, |encoder| {
                        p_time.to_timespec().sec.encode(encoder)
                    }));
                    try!(encoder.emit_tuple_arg(2, |encoder| p_record.encode(encoder)));
                    // Put `None::<T>` as-is for now.
                    try!(encoder.emit_tuple_arg(3, |encoder| None::<T>.encode(encoder)));
                    Ok(())
                })
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use time;
    use std::collections::HashMap;
    use rustc_serialize::json;
    use rustc_serialize::json::Json;

    #[test]
    fn test_json_format() {
        let tag = "fruently".to_string();
        let time = time::now();
        let mut obj: HashMap<String, String> = HashMap::new();
        obj.insert("name".to_string(), "fruently".to_string());
        let record = Record::new(tag.clone(), time, obj.clone());
        let forwardable_json = record.make_forwardable_json().ok().unwrap();
        let json_tag = json::encode(&tag.clone()).ok().unwrap();
        let json_obj = json::encode(&obj.clone()).ok().unwrap();
        let expected = format!("[{},{},{},{}]",
                               json_tag,
                               time.to_timespec().sec,
                               json_obj,
                               Json::Null);
        assert_eq!(expected, forwardable_json);
    }
}
<commit_msg>record: Add derive Debug<commit_after>//! Implement record manupulation mechanisms.

use rustc_serialize::json;
use rustc_serialize::{Encodable, Encoder};
use rmp_serialize::encode;
use time::Tm;
use std::io;
use retry;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Record<T: Encodable> {
    tag: String,
    time: Tm,
    record: T,
}

#[derive(Debug)]
pub enum FluentError {
    JsonEncode(json::EncoderError),
    MsgpackEncode(encode::Error),
    IO(io::Error),
    Retry(retry::RetryError),
}

impl From<io::Error> for FluentError {
    fn from(err: io::Error) -> FluentError {
        FluentError::IO(err)
    }
}

impl From<encode::Error> for FluentError {
    fn from(err: encode::Error) -> FluentError {
        FluentError::MsgpackEncode(err)
    }
}

impl From<retry::RetryError> for FluentError {
    fn from(err: retry::RetryError) -> FluentError {
        FluentError::Retry(err)
    }
}

impl From<json::EncoderError> for FluentError {
    fn from(err: json::EncoderError) -> FluentError {
        FluentError::JsonEncode(err)
    }
}

impl<T: Encodable> Record<T> {
    pub fn new(tag: String, time: Tm, record: T) -> Record<T> {
        Record {
            tag: tag,
            time: time,
            record: record,
        }
    }

    pub fn make_forwardable_json(self) -> Result<String, FluentError> {
        let message = try!(json::encode(&self));
        Ok(message)
    }
}

/// Construct custom encoding json/msgpack style.
///
/// Because `Record` struct should map following style json/msgpack:
///
/// `[tag, unixtime/eventtime, record]`
///
/// ref: https://github.com/fluent/fluentd/wiki/Forward-Protocol-Specification-v0#message-mode
impl<T: Encodable> Encodable for Record<T> {
    fn encode<S: Encoder>(&self, encoder: &mut S) -> Result<(), S::Error> {
        match *self {
            Record { tag: ref p_tag, time: ref p_time, record: ref p_record } => {
                encoder.emit_tuple(4, |encoder| {
                    try!(encoder.emit_tuple_arg(0, |encoder| p_tag.encode(encoder)));
                    try!(encoder.emit_tuple_arg(1, |encoder| {
                        p_time.to_timespec().sec.encode(encoder)
                    }));
                    try!(encoder.emit_tuple_arg(2, |encoder| p_record.encode(encoder)));
                    // Put `None::<T>` as-is for now.
                    try!(encoder.emit_tuple_arg(3, |encoder| None::<T>.encode(encoder)));
                    Ok(())
                })
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use time;
    use std::collections::HashMap;
    use rustc_serialize::json;
    use rustc_serialize::json::Json;

    #[test]
    fn test_json_format() {
        let tag = "fruently".to_string();
        let time = time::now();
        let mut obj: HashMap<String, String> = HashMap::new();
        obj.insert("name".to_string(), "fruently".to_string());
        let record = Record::new(tag.clone(), time, obj.clone());
        let forwardable_json = record.make_forwardable_json().ok().unwrap();
        let json_tag = json::encode(&tag.clone()).ok().unwrap();
        let json_obj = json::encode(&obj.clone()).ok().unwrap();
        let expected = format!("[{},{},{},{}]",
                               json_tag,
                               time.to_timespec().sec,
                               json_obj,
                               Json::Null);
        assert_eq!(expected, forwardable_json);
    }
}
<|endoftext|>


<commit_before>use std::fmt;

pub type NSSResult<T> = Result<T, NSSError>;

#[deriving(Copy)]
pub enum NSSError
{
    /// An error generated by NSPR or NSS
    NSS(i32),
}

impl fmt::Show for NSSError
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error>
    {
        match *self
        {
            NSSError::NSS(code) => {
                match ::ffi::nspr::get_error_message(code)
                {
                    Some(message) => formatter.write(message.as_bytes()),
                    None => write!(formatter, "Unknown error {}", code),
                }
            },
        }
    }
}
<commit_msg>Fix NSSError formatter<commit_after>use std::fmt;

pub type NSSResult<T> = Result<T, NSSError>;

#[deriving(Copy)]
pub enum NSSError
{
    /// An error generated by NSPR or NSS
    NSS(i32),
}

impl fmt::Show for NSSError
{
    fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error>
    {
        match *self
        {
            NSSError::NSS(code) => {
                match ::ffi::nspr::get_error_message(code)
                {
                    Some(message) => {
                        let message_str = String::from_utf8_lossy(message.as_bytes());
                        formatter.write_str(&*message_str)
                    },
                    None => write!(formatter, "Unknown error {}", code),
                }
            },
        }
    }
}
<|endoftext|>


<commit_before>// Claxon -- A FLAC decoding library in Rust
// Copyright (C) 2015 Ruud van Asseldonk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 3,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

use std::cmp::Eq;
use std::ops::{Add, BitAnd, BitOr, Neg, Shl, Shr, Sub};

/// An trait that allows for interegers to be generic in width.
pub trait Sample: Copy + Clone + Eq +
    Neg<Output = Self> +
    Add<Output = Self> +
    Sub<Output = Self> +
    Shl<usize, Output = Self> +
    Shr<usize, Output = Self> +
    BitOr<Self, Output = Self> +
    BitAnd<Self, Output = Self> {

    type Unsigned: BitAnd<<Self as Sample>::Unsigned,
                          Output = <Self as Sample>::Unsigned>
                 + BitOr<Output = <Self as Sample>::Unsigned>
                 + Shl<usize, Output = <Self as Sample>::Unsigned>
                 + Shr<usize, Output = <Self as Sample>::Unsigned>
                 + Add<Output = <Self as Sample>::Unsigned>
                 + Eq + Copy + Clone;

    /// Returns the maximal value that the type can contain.
    // TODO: is this actually required, can we do without in non-debug versions?
    fn max() -> Self;

    /// Returns the minimal value that the type can contain.
    // TODO: is this actually required, can we do without in non-debug versions?
    fn min() -> Self;

    /// Returns the maximal value that the `Unsigned` type can contain.
    // TODO: is this actually required, can we do without in non-debug versions?
    fn max_unsigned() -> <Self as Sample>::Unsigned;

    /// Returns 0.
    // TODO: could be an associated constant once those land.
    fn zero() -> Self;

    /// Returns 1.
    // TODO: could be an associated constant once those land.
    fn one() -> Self;

    /// Returns 0 as the unsigned type.
    // TODO: could be an associated constant once those land.
    fn zero_unsigned() -> <Self as Sample>::Unsigned;

    /// Returns 1 as the unsigned type.
    // TODO: could be an associated constant once those land.
    fn one_unsigned() -> <Self as Sample>::Unsigned;

    /// Interprets the unsigned value as a signed number.
    fn from_unsigned(unsigned: <Self as Sample>::Unsigned) -> Self;

    /// Converts an `u16` to the unsigned sample, assuming it will not overflow.
    fn from_u16_nofail(x: u16) -> <Self as Sample>::Unsigned;

    /// Converts an `i32` to the sample, assuming it will not overflow.
    fn from_i32_nofail(x: i32) -> Self;

    /// Converts an `i32` to the sample, returning `None` on overflow.
    fn from_i32(x: i32) -> Option<Self>;

    /// Converts an `i64` to the sample, returning `None` on overflow.
    fn from_i64(x: i64) -> Option<Self>;

    /// Converts the sample into an `i64`.
    ///
    /// All sample types are narrow enough to ensure that this cannot overflow.
    fn to_i64(self) -> i64;

    /// Adds with wraparound on overflow.
    fn wrapping_add(self, other: Self) -> Self;

    /// Subtracts with wraparound on overflow.
    fn wrapping_sub(self, other: Self) -> Self;
}

macro_rules! impl_sample {
    ($signed: ident, $unsigned: ident) => {
        impl Sample for $signed {

            type Unsigned = $unsigned;

            fn max() -> $signed {
                use std::$signed;
                $signed::MAX
            }

            fn min() -> $signed {
                use std::$signed;
                $signed::MIN
            }

            fn max_unsigned() -> $unsigned {
                use std::$unsigned;
                $unsigned::MAX
            }

            fn zero() -> $signed {
                0
            }

            fn one() -> $signed {
                1
            }

            fn zero_unsigned() -> $unsigned {
                0
            }

            fn one_unsigned() -> $unsigned {
                1
            }

            fn from_unsigned(unsigned: $unsigned) -> $signed {
                unsigned as $signed
            }

            fn from_u16_nofail(x: u16) -> $unsigned {
                x as $unsigned
            }

            fn from_i32_nofail(x: i32) -> $signed {
                x as $signed
            }

            fn from_i32(x: i32) -> Option<$signed> {
                use std::$signed;
                if x > $signed::MAX || x < $signed::MIN {
                    None
                } else {
                    x as $signed
                }
            }

            fn from_i64(x: i64) -> Option<$signed> {
                use std::$signed;
                if x > $signed::MAX || x < $signed::MIN {
                    None
                } else {
                    x as $signed
                }
            }

            fn to_i64(self) -> i64 {
                self as i64
            }

            fn wrapping_add(self, other: $signed) -> $signed {
                self.wrapping_add(other)
            }

            fn wrapping_sub(self, other: $signed) -> $signed {
                self.wrapping_sub(other)
            }
        }
    };
}

impl_sample!(i8, u8);
impl_sample!(i16, u16);
impl_sample!(i32, u32);
<commit_msg>fix Sample::from_* methods<commit_after>// Claxon -- A FLAC decoding library in Rust
// Copyright (C) 2015 Ruud van Asseldonk
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 3,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

use std::cmp::Eq;
use std::ops::{Add, BitAnd, BitOr, Neg, Shl, Shr, Sub};

/// An trait that allows for interegers to be generic in width.
pub trait Sample: Copy + Clone + Eq +
    Neg<Output = Self> +
    Add<Output = Self> +
    Sub<Output = Self> +
    Shl<usize, Output = Self> +
    Shr<usize, Output = Self> +
    BitOr<Self, Output = Self> +
    BitAnd<Self, Output = Self> {

    type Unsigned: BitAnd<<Self as Sample>::Unsigned,
                          Output = <Self as Sample>::Unsigned>
                 + BitOr<Output = <Self as Sample>::Unsigned>
                 + Shl<usize, Output = <Self as Sample>::Unsigned>
                 + Shr<usize, Output = <Self as Sample>::Unsigned>
                 + Add<Output = <Self as Sample>::Unsigned>
                 + Eq + Copy + Clone;

    /// Returns the maximal value that the type can contain.
    // TODO: is this actually required, can we do without in non-debug versions?
    fn max() -> Self;

    /// Returns the minimal value that the type can contain.
    // TODO: is this actually required, can we do without in non-debug versions?
    fn min() -> Self;

    /// Returns the maximal value that the `Unsigned` type can contain.
    // TODO: is this actually required, can we do without in non-debug versions?
    fn max_unsigned() -> <Self as Sample>::Unsigned;

    /// Returns 0.
    // TODO: could be an associated constant once those land.
    fn zero() -> Self;

    /// Returns 1.
    // TODO: could be an associated constant once those land.
    fn one() -> Self;

    /// Returns 0 as the unsigned type.
    // TODO: could be an associated constant once those land.
    fn zero_unsigned() -> <Self as Sample>::Unsigned;

    /// Returns 1 as the unsigned type.
    // TODO: could be an associated constant once those land.
    fn one_unsigned() -> <Self as Sample>::Unsigned;

    /// Interprets the unsigned value as a signed number.
    fn from_unsigned(unsigned: <Self as Sample>::Unsigned) -> Self;

    /// Converts an `u16` to the unsigned sample, assuming it will not overflow.
    fn from_u16_nofail(x: u16) -> <Self as Sample>::Unsigned;

    /// Converts an `i32` to the sample, assuming it will not overflow.
    fn from_i32_nofail(x: i32) -> Self;

    /// Converts an `i32` to the sample, returning `None` on overflow.
    fn from_i32(x: i32) -> Option<Self>;

    /// Converts an `i64` to the sample, returning `None` on overflow.
    fn from_i64(x: i64) -> Option<Self>;

    /// Converts the sample into an `i64`.
    ///
    /// All sample types are narrow enough to ensure that this cannot overflow.
    fn to_i64(self) -> i64;

    /// Adds with wraparound on overflow.
    fn wrapping_add(self, other: Self) -> Self;

    /// Subtracts with wraparound on overflow.
    fn wrapping_sub(self, other: Self) -> Self;
}

macro_rules! impl_sample {
    ($signed: ident, $unsigned: ident) => {
        impl Sample for $signed {

            type Unsigned = $unsigned;

            fn max() -> $signed {
                use std::$signed;
                $signed::MAX
            }

            fn min() -> $signed {
                use std::$signed;
                $signed::MIN
            }

            fn max_unsigned() -> $unsigned {
                use std::$unsigned;
                $unsigned::MAX
            }

            fn zero() -> $signed {
                0
            }

            fn one() -> $signed {
                1
            }

            fn zero_unsigned() -> $unsigned {
                0
            }

            fn one_unsigned() -> $unsigned {
                1
            }

            fn from_unsigned(unsigned: $unsigned) -> $signed {
                unsigned as $signed
            }

            fn from_u16_nofail(x: u16) -> $unsigned {
                x as $unsigned
            }

            fn from_i32_nofail(x: i32) -> $signed {
                x as $signed
            }

            fn from_i32(x: i32) -> Option<$signed> {
                use std::$signed;
                if x > $signed::MAX as i32 || x < $signed::MIN as i32 {
                    None
                } else {
                    Some(x as $signed)
                }
            }

            fn from_i64(x: i64) -> Option<$signed> {
                use std::$signed;
                if x > $signed::MAX as i64 || x < $signed::MIN as i64 {
                    None
                } else {
                    Some(x as $signed)
                }
            }

            fn to_i64(self) -> i64 {
                self as i64
            }

            fn wrapping_add(self, other: $signed) -> $signed {
                self.wrapping_add(other)
            }

            fn wrapping_sub(self, other: $signed) -> $signed {
                self.wrapping_sub(other)
            }
        }
    };
}

impl_sample!(i8, u8);
impl_sample!(i16, u16);
impl_sample!(i32, u32);
<|endoftext|>


<commit_before>use configuration::Configuration;
use search::Search;
use ansi::Ansi;
use tty::TTY;
use fake_tty::FakeIO;
use renderer::Renderer;
use text::Text;

pub struct Screen <'a> {
    ansi: Ansi<'a>,
}

impl <'a> Screen <'a>{
    pub fn new() -> Screen<'a>  {
        Screen { ansi: Ansi { io: Box::new(TTY::new()) } }
    }

    fn fake() -> Screen<'a> {
        Screen { ansi: Ansi { io: Box::new(FakeIO::new()) } }
    }

    pub fn handle_keystroke(&self, search: Search, input: &str) -> Search {
        match input {
           "\u{1b}" => search.abort(),
           "\u{e}" => search.down(),
           "\u{10}" => search.up(),
           "\u{7f}" => search.backspace(),
           "\n" => search.done(),
            _ => search.append_to_search(input),
        }
    }

    pub fn print(&mut self, search: &Search) {
        let renderer = Renderer;
        let result = renderer.render(search);
        for text in result.iter() {
            match *text {
                Text::Normal(ref t) => self.ansi.print(t.as_slice()),
                Text::Highlight(ref t) => self.ansi.inverted(t.as_slice()),
                Text::Blank => self.ansi.print("".as_slice()),
            };
        };
    }
}

#[cfg(test)]

#[test]
pub fn search_is_done_when_esc() {
    let input = blank_search();
    let screen = Screen::new();
    let result = screen.handle_keystroke(input, "\u{1b}");
    assert!(result.is_done());
}

#[test]
pub fn moves_the_selection_down_for_ctrl_n() {
    let input = blank_search();
    let screen = Screen::new();
    let result = screen.handle_keystroke(input, "\u{e}");
    assert_eq!(result.selection, Some("two".to_string()));
}

#[test]
pub fn moves_the_selection_up_for_ctrl_p() {
    let input = blank_search().down();
    let screen = Screen::new();
    let result = screen.handle_keystroke(input, "\u{10}");
    assert_eq!(result.selection, Some("one".to_string()));
}

#[test]
pub fn removes_the_last_character_for_delete() {
    let input = blank_search().append_to_search("w").append_to_search("x");
    let screen = Screen::new();
    let result = screen.handle_keystroke(input, "\u{7f}");
    assert_eq!(result.selection, Some("two".to_string()));
}

#[test]
pub fn marks_a_search_as_done_for_enter() {
    let input = blank_search();
    let screen = Screen::new();
    let result = screen.handle_keystroke(input, "\n");
    assert!(result.is_done());
}

#[test]
pub fn prints_max_number_of_lines() {
    let input = blank_search();
    let mut screen = Screen::fake();

    screen.print(&input);
    let result = screen.ansi.io.last();
    assert_eq!("", result.as_slice());
}

fn blank_search() -> Search {
    let input = vec!["one".to_string(), "two".to_string()];
    let config = Configuration::from_inputs(input, None, Some(10));
    Search::blank(config)
}

<commit_msg>Store height rather than accessing multiple times.<commit_after>use configuration::Configuration;
use search::Search;
use ansi::Ansi;
use tty::TTY;
use fake_tty::FakeIO;
use renderer::Renderer;
use text::Text;

pub struct Screen <'a> {
    pub ansi: Ansi<'a>,
    height: usize,
}

impl <'a> Screen <'a>{
    pub fn new() -> Screen<'a>  {
        let ansi = Ansi { io: Box::new(TTY::new()) };
        let (_, height) = ansi.io.dimensions();
        Screen {
            ansi: ansi,
            height: height,
        }
    }

    fn fake() -> Screen<'a> {
        Screen {
            ansi: Ansi { io: Box::new(FakeIO::new()) },
            height: 20,
        }
    }

    pub fn handle_keystroke(&self, search: Search, input: &str) -> Search {
        match input {
           "\u{1b}" => search.abort(),
           "\u{e}" => search.down(),
           "\u{10}" => search.up(),
           "\u{7f}" => search.backspace(),
           "\n" => search.done(),
            _ => search.append_to_search(input),
        }
    }

    pub fn print(&mut self, search: &Search) {
        let renderer = Renderer;
        let result = renderer.render(search);
        self.ansi.hide_cursor();

        let start_line = self.height - search.config.visible_limit -1;

        for (idx, text) in result.iter().enumerate() {
            self.write(start_line+idx, text);
        };
    }

    pub fn write(&mut self, line: usize, text: &Text) {
        self.ansi.blank_line(line);
        self.ansi.set_position(line,0);

        match *text {
            Text::Normal(ref t) => self.ansi.print(t.as_slice()),
            Text::Highlight(ref t) => self.ansi.inverted(t.as_slice()),
            Text::Blank => self.ansi.print("".as_slice()),
        };
    }
}

#[cfg(test)]

#[test]
pub fn search_is_done_when_esc() {
    let input = blank_search();
    let screen = Screen::new();
    let result = screen.handle_keystroke(input, "\u{1b}");
    assert!(result.is_done());
}

#[test]
pub fn moves_the_selection_down_for_ctrl_n() {
    let input = blank_search();
    let screen = Screen::new();
    let result = screen.handle_keystroke(input, "\u{e}");
    assert_eq!(result.selection, Some("two".to_string()));
}

#[test]
pub fn moves_the_selection_up_for_ctrl_p() {
    let input = blank_search().down();
    let screen = Screen::new();
    let result = screen.handle_keystroke(input, "\u{10}");
    assert_eq!(result.selection, Some("one".to_string()));
}

#[test]
pub fn removes_the_last_character_for_delete() {
    let input = blank_search().append_to_search("w").append_to_search("x");
    let screen = Screen::new();
    let result = screen.handle_keystroke(input, "\u{7f}");
    assert_eq!(result.selection, Some("two".to_string()));
}

#[test]
pub fn marks_a_search_as_done_for_enter() {
    let input = blank_search();
    let screen = Screen::new();
    let result = screen.handle_keystroke(input, "\n");
    assert!(result.is_done());
}

fn blank_search() -> Search {
    let input = vec!["one".to_string(), "two".to_string()];
    let config = Configuration::from_inputs(input, None, Some(10));
    Search::blank(config)
}

<|endoftext|>


<commit_before>use search::Search;
use ansi::Ansi;
use tty::TTY;
use fake_tty::FakeIO;
use renderer::Renderer;
use text::Text;

pub struct Screen <'a> {
    pub ansi: Ansi<'a>,
    height: usize,
}

impl <'a> Screen <'a>{
    pub fn new() -> Screen<'a> {
        let ansi = Ansi { io: Box::new(TTY::new()) };
        let (_, height) = ansi.io.dimensions();
        Screen {
            ansi: ansi,
            height: height,
        }
    }

    fn fake() -> Screen<'a> {
        Screen {
            ansi: Ansi { io: Box::new(FakeIO::new()) },
            height: 20,
        }
    }

    pub fn handle_keystroke(&self, search: Search, input: &str) -> Search {
        match input {
           "\u{1b}" => search.abort(),
           "\u{e}" => search.down(),
           "\u{10}" => search.up(),
           "\u{7f}" => search.backspace(),
           "\n" => search.done(),
            _ => search.append_to_search(input),
        }
    }

    pub fn print(&mut self, search: &Search) {
        let renderer = Renderer;
        let result = renderer.render(search);
        self.ansi.hide_cursor();

        let start_line = self.height - search.config.visible_limit - 1;

        for (idx, text) in result.iter().enumerate() {
            self.write(start_line + idx, text);
        };
    }

    pub fn write(&mut self, line: usize, text: &Text) {
        self.ansi.blank_line(line);
        self.ansi.set_position(line, 0);

        match *text {
            Text::Normal(ref t) => self.ansi.print(t.as_slice()),
            Text::Highlight(ref t) => self.ansi.inverted(t.as_slice()),
            Text::Blank => self.ansi.print("".as_slice()),
        };
    }
}

#[cfg(test)]
mod tests {
    use configuration::Configuration;
    use search::Search;
    use super::*;

    #[test]
    pub fn search_is_done_when_esc() {
        let input = blank_search();
        let screen = Screen::new();
        let result = screen.handle_keystroke(input, "\u{1b}");
        assert!(result.is_done());
    }

    #[test]
    pub fn moves_the_selection_down_for_ctrl_n() {
        let input = blank_search();
        let screen = Screen::new();
        let result = screen.handle_keystroke(input, "\u{e}");
        assert_eq!(result.selection, Some("two".to_string()));
    }

    #[test]
    pub fn moves_the_selection_up_for_ctrl_p() {
        let input = blank_search().down();
        let screen = Screen::new();
        let result = screen.handle_keystroke(input, "\u{10}");
        assert_eq!(result.selection, Some("one".to_string()));
    }

    #[test]
    pub fn removes_the_last_character_for_delete() {
        let input = blank_search().append_to_search("w").append_to_search("x");
        let screen = Screen::new();
        let result = screen.handle_keystroke(input, "\u{7f}");
        assert_eq!(result.selection, Some("two".to_string()));
    }

    #[test]
    pub fn marks_a_search_as_done_for_enter() {
        let input = blank_search();
        let screen = Screen::new();
        let result = screen.handle_keystroke(input, "\n");
        assert!(result.is_done());
    }

    fn blank_search() -> Search {
        let input = vec!["one".to_string(), "two".to_string()];
        let config = Configuration::from_inputs(input, None, Some(10));
        Search::blank(config)
    }
}
<commit_msg>I don't think these test fns need to be public<commit_after>use search::Search;
use ansi::Ansi;
use tty::TTY;
use fake_tty::FakeIO;
use renderer::Renderer;
use text::Text;

pub struct Screen <'a> {
    pub ansi: Ansi<'a>,
    height: usize,
}

impl <'a> Screen <'a>{
    pub fn new() -> Screen<'a> {
        let ansi = Ansi { io: Box::new(TTY::new()) };
        let (_, height) = ansi.io.dimensions();
        Screen {
            ansi: ansi,
            height: height,
        }
    }

    fn fake() -> Screen<'a> {
        Screen {
            ansi: Ansi { io: Box::new(FakeIO::new()) },
            height: 20,
        }
    }

    pub fn handle_keystroke(&self, search: Search, input: &str) -> Search {
        match input {
           "\u{1b}" => search.abort(),
           "\u{e}" => search.down(),
           "\u{10}" => search.up(),
           "\u{7f}" => search.backspace(),
           "\n" => search.done(),
            _ => search.append_to_search(input),
        }
    }

    pub fn print(&mut self, search: &Search) {
        let renderer = Renderer;
        let result = renderer.render(search);
        self.ansi.hide_cursor();

        let start_line = self.height - search.config.visible_limit - 1;

        for (idx, text) in result.iter().enumerate() {
            self.write(start_line + idx, text);
        };
    }

    pub fn write(&mut self, line: usize, text: &Text) {
        self.ansi.blank_line(line);
        self.ansi.set_position(line, 0);

        match *text {
            Text::Normal(ref t) => self.ansi.print(t.as_slice()),
            Text::Highlight(ref t) => self.ansi.inverted(t.as_slice()),
            Text::Blank => self.ansi.print("".as_slice()),
        };
    }
}

#[cfg(test)]
mod tests {
    use configuration::Configuration;
    use search::Search;
    use super::*;

    #[test]
    fn search_is_done_when_esc() {
        let input = blank_search();
        let screen = Screen::new();
        let result = screen.handle_keystroke(input, "\u{1b}");
        assert!(result.is_done());
    }

    #[test]
    fn moves_the_selection_down_for_ctrl_n() {
        let input = blank_search();
        let screen = Screen::new();
        let result = screen.handle_keystroke(input, "\u{e}");
        assert_eq!(result.selection, Some("two".to_string()));
    }

    #[test]
    fn moves_the_selection_up_for_ctrl_p() {
        let input = blank_search().down();
        let screen = Screen::new();
        let result = screen.handle_keystroke(input, "\u{10}");
        assert_eq!(result.selection, Some("one".to_string()));
    }

    #[test]
    fn removes_the_last_character_for_delete() {
        let input = blank_search().append_to_search("w").append_to_search("x");
        let screen = Screen::new();
        let result = screen.handle_keystroke(input, "\u{7f}");
        assert_eq!(result.selection, Some("two".to_string()));
    }

    #[test]
    fn marks_a_search_as_done_for_enter() {
        let input = blank_search();
        let screen = Screen::new();
        let result = screen.handle_keystroke(input, "\n");
        assert!(result.is_done());
    }

    fn blank_search() -> Search {
        let input = vec!["one".to_string(), "two".to_string()];
        let config = Configuration::from_inputs(input, None, Some(10));
        Search::blank(config)
    }
}
<|endoftext|>


<commit_before>use super::command::{Command, Query};
use super::command::Command::Select;
use std::collections::HashMap;
use util;
use command_query::CommandQuery;
use queryable::Queryable;
use commandable::Commandable;
use command_line::CommandLine;
use selectable::fragmentable::Fragmentable;
use selectable::fragmentable::{OrderedFragment, QueryFragment};
use selectable::drilldown::Drilldown;
use selectable::drilldownable::Drilldownable;
use selectable::drilldown_builder::DrilldownBuilder;
use std::ops::Add;
use extendable::Extendable;
use request_cancellable::RequestCancellable;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct SelectCommand {
    command: Command,
    table: String,
    arguments: HashMap<String, String>,
}

impl Default for SelectCommand {
    fn default() -> SelectCommand {
        SelectCommand {
            command: Select,
            table: "".to_string(),
            arguments: HashMap::new(),
        }
    }
}

impl SelectCommand {
    pub fn new(table: String) -> SelectCommand {
        let default: SelectCommand = Default::default();
        SelectCommand {
            command: default.command,
            table: table,
            arguments: default.arguments,
        }
    }

    pub fn filter(mut self, filter: String) -> SelectCommand {
        let encoded = format!("'{}'", filter);
        self.arguments.insert("filter".to_string(), encoded.clone());
        self
    }

    pub fn query(mut self, query: String) -> SelectCommand {
        let encoded = format!("'{}'", query);
        self.arguments.insert("query".to_string(), encoded.clone());
        self
    }

    pub fn match_columns(mut self, columns: Vec<String>) -> SelectCommand {
        let string = util::split_values_vec(columns);
        self.arguments.insert("match_columns".to_string(), string.clone());
        self
    }

    pub fn output_columns(mut self, columns: Vec<String>) -> SelectCommand {
        let string = util::split_values_vec(columns);
        self.arguments.insert("output_columns".to_string(), string.clone());
        self
    }

    pub fn offset(mut self, offset: i64) -> SelectCommand {
        let offset = format!("{}", offset);
        self.arguments.insert("offset".to_string(), offset.clone());
        self
    }

    pub fn limit(mut self, limit: i64) -> SelectCommand {
        let limit = format!("{}", limit);
        self.arguments.insert("limit".to_string(), limit.clone());
        self
    }

    pub fn cache(mut self, cache: bool) -> SelectCommand {
        let flag = match cache {
            true => "yes",
            false => "no",
        };
        self.arguments.insert("cache".to_string(), flag.to_string());
        self
    }

    pub fn build(self) -> (Command, Query) {
        let mut query: Query = vec![("table".to_string(), self.table)];
        for (key, value) in self.arguments.iter() {
            query.push((key.to_owned(), value.to_owned()));
        }
        (Select, query)
    }
}

impl Queryable for SelectCommand {
    fn to_query(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandQuery::new(command, query);
        command.encode()
    }
}

impl Commandable for SelectCommand {
    fn to_command(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandLine::new(command, query);
        command.encode()
    }
}

impl Fragmentable for SelectCommand {
    fn to_fragment(self) -> (OrderedFragment, QueryFragment) {
        let mut select_fragment = HashMap::new();
        let ordered_fragment = vec![("table".to_string(), self.table)];
        for (key, value) in self.arguments.clone() {
            select_fragment.insert(key, value);
        }
        (ordered_fragment, select_fragment)
    }
}

impl Add<Drilldown> for SelectCommand {
    type Output = DrilldownBuilder;

    fn add(self, rhs: Drilldown) -> DrilldownBuilder {
        let drilldown_builder = DrilldownBuilder::new(self, rhs);
        drilldown_builder
    }
}

impl Drilldownable for SelectCommand {
    fn with_drilldown(self, rhs: Drilldown) -> DrilldownBuilder {
        let drilldown_builder = DrilldownBuilder::new(self, rhs);
        drilldown_builder
    }
}

extendable!(SelectCommand);
request_cancellable!(SelectCommand);

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::Select;
    use std::collections::HashMap;
    use queryable::Queryable;
    use commandable::Commandable;
    use selectable::drilldown::Drilldown;
    use selectable::drilldownable::Drilldownable;
    use selectable::drilldown_builder::DrilldownBuilder;
    use extendable::Extendable;

    #[test]
    fn test_new() {
        let vanilla_select = SelectCommand::new("test".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: HashMap::new(),
        };
        assert_eq!(expected, vanilla_select);
    }

    #[test]
    fn test_filter() {
        let select = SelectCommand::new("test".to_string())
                         .filter("output_column @ \"type_safe\"".to_string());
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("filter".to_string(),
                   "'output_column @ \"type_safe\"'".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg,
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_query() {
        let select = SelectCommand::new("test".to_string())
                         .query("_key:\"http://example.org/\"".to_string());
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("query".to_string(),
                   "\'_key:\"http://example.org/\"\'".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg,
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_match_columns() {
        let select = SelectCommand::new("test".to_string())
                         .match_columns(vec!["test".to_string(), "piyo".to_string()]);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("match_columns".to_string(), "test,piyo".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg,
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_output_columns() {
        let select = SelectCommand::new("test".to_string())
                         .output_columns(vec!["test".to_string(), "piyo".to_string()]);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("output_columns".to_string(), "test,piyo".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg,
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_offset() {
        let select = SelectCommand::new("test".to_string()).offset(100);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("offset".to_string(), "100".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: arg,
            table: "test".to_string(),
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_limit() {
        let select = SelectCommand::new("test".to_string()).limit(50);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("limit".to_string(), "50".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg,
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_cache() {
        let select_yes = SelectCommand::new("test".to_string()).cache(true);
        let mut arg_yes: HashMap<String, String> = HashMap::new();
        arg_yes.insert("cache".to_string(), "yes".to_string());
        let expected_yes = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg_yes,
        };
        assert_eq!(expected_yes, select_yes);
        let select_no = SelectCommand::new("test".to_string()).cache(false);
        let mut arg_no: HashMap<String, String> = HashMap::new();
        arg_no.insert("cache".to_string(), "no".to_string());
        let expected_no = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg_no,
        };
        assert_eq!(expected_no, select_no);
    }

    #[test]
    fn test_build() {
        let actual = SelectCommand::new("test".to_string())
                         .filter("output_column @ \"type_safe\"".to_string())
                         .build();
        let expected_query: Query = vec![("table".to_string(), "test".to_string()),
                                         ("filter".to_string(),
                                          "'output_column @ \"type_safe\"'".to_string())];
        let expected = (Select, expected_query);
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_queryable() {
        let query = SelectCommand::new("Test".to_string())
                        .filter("output_column @ \"type_safe\"".to_string())
                        .to_query();
        let url_encoded = "/d/select?table=Test&filter=%27output_column+%40+%22type_safe%22%27";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_commandable() {
        let query = SelectCommand::new("Test".to_string())
                        .filter("output_column @ \"type_safe\"".to_string())
                        .to_command();
        let cli_encoded = "select --table Test --filter \'output_column @ \"type_safe\"\'";
        assert_eq!(cli_encoded.to_string(), query);
    }

    #[test]
    fn test_add_ops_drilldown() {
        let select = SelectCommand::new("Entries".to_string())
                         .filter("content @ \"fast\"".to_string());
        let drilldown = Drilldown::new().drilldown(vec![("tag".to_string())]);
        let ops_builder = (select.clone() + drilldown.clone()).build();
        let drilldown_builder = DrilldownBuilder::new(select.clone(), drilldown.clone()).build();
        assert_eq!(ops_builder, drilldown_builder);
    }

    #[test]
    fn test_with_drilldown() {
        let select = SelectCommand::new("Entries".to_string())
                         .filter("content @ \"fast\"".to_string());
        let drilldown = Drilldown::new().drilldown(vec![("tag".to_string())]);
        let drilldownable = select.clone().with_drilldown(drilldown.clone()).build();
        let drilldown_builder = DrilldownBuilder::new(select.clone(), drilldown.clone()).build();
        assert_eq!(drilldownable, drilldown_builder);
    }

    #[test]
    fn test_extendable() {
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("user".to_string(), "defined".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "Test".to_string(),
            arguments: arg.clone(),
        };
        let query = SelectCommand::new("Test".to_string());
        unsafe {
            let extended = query.set_arguments(arg.clone());
            assert_eq!(expected, extended);
        }
    }
}
<commit_msg>select: Define Add operator for LabeledDrilldownBuilder<commit_after>use super::command::{Command, Query};
use super::command::Command::Select;
use std::collections::HashMap;
use util;
use command_query::CommandQuery;
use queryable::Queryable;
use commandable::Commandable;
use command_line::CommandLine;
use selectable::fragmentable::Fragmentable;
use selectable::fragmentable::{OrderedFragment, QueryFragment};
use selectable::drilldown::Drilldown;
use selectable::drilldownable::Drilldownable;
use selectable::drilldown_builder::DrilldownBuilder;
use selectable::labeled_drilldown::LabeledDrilldown;
use selectable::labeled_drilldown_builder::LabeledDrilldownBuilder;
use std::ops::Add;
use extendable::Extendable;
use request_cancellable::RequestCancellable;

#[derive(Clone, PartialEq, Eq, Debug)]
pub struct SelectCommand {
    command: Command,
    table: String,
    arguments: HashMap<String, String>,
}

impl Default for SelectCommand {
    fn default() -> SelectCommand {
        SelectCommand {
            command: Select,
            table: "".to_string(),
            arguments: HashMap::new(),
        }
    }
}

impl SelectCommand {
    pub fn new(table: String) -> SelectCommand {
        let default: SelectCommand = Default::default();
        SelectCommand {
            command: default.command,
            table: table,
            arguments: default.arguments,
        }
    }

    pub fn filter(mut self, filter: String) -> SelectCommand {
        let encoded = format!("'{}'", filter);
        self.arguments.insert("filter".to_string(), encoded.clone());
        self
    }

    pub fn query(mut self, query: String) -> SelectCommand {
        let encoded = format!("'{}'", query);
        self.arguments.insert("query".to_string(), encoded.clone());
        self
    }

    pub fn match_columns(mut self, columns: Vec<String>) -> SelectCommand {
        let string = util::split_values_vec(columns);
        self.arguments.insert("match_columns".to_string(), string.clone());
        self
    }

    pub fn output_columns(mut self, columns: Vec<String>) -> SelectCommand {
        let string = util::split_values_vec(columns);
        self.arguments.insert("output_columns".to_string(), string.clone());
        self
    }

    pub fn offset(mut self, offset: i64) -> SelectCommand {
        let offset = format!("{}", offset);
        self.arguments.insert("offset".to_string(), offset.clone());
        self
    }

    pub fn limit(mut self, limit: i64) -> SelectCommand {
        let limit = format!("{}", limit);
        self.arguments.insert("limit".to_string(), limit.clone());
        self
    }

    pub fn cache(mut self, cache: bool) -> SelectCommand {
        let flag = match cache {
            true => "yes",
            false => "no",
        };
        self.arguments.insert("cache".to_string(), flag.to_string());
        self
    }

    pub fn build(self) -> (Command, Query) {
        let mut query: Query = vec![("table".to_string(), self.table)];
        for (key, value) in self.arguments.iter() {
            query.push((key.to_owned(), value.to_owned()));
        }
        (Select, query)
    }
}

impl Queryable for SelectCommand {
    fn to_query(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandQuery::new(command, query);
        command.encode()
    }
}

impl Commandable for SelectCommand {
    fn to_command(self) -> String {
        let (command, query) = self.build();
        let mut command = CommandLine::new(command, query);
        command.encode()
    }
}

impl Fragmentable for SelectCommand {
    fn to_fragment(self) -> (OrderedFragment, QueryFragment) {
        let mut select_fragment = HashMap::new();
        let ordered_fragment = vec![("table".to_string(), self.table)];
        for (key, value) in self.arguments.clone() {
            select_fragment.insert(key, value);
        }
        (ordered_fragment, select_fragment)
    }
}

impl Add<Drilldown> for SelectCommand {
    type Output = DrilldownBuilder;

    fn add(self, rhs: Drilldown) -> DrilldownBuilder {
        let drilldown_builder = DrilldownBuilder::new(self, rhs);
        drilldown_builder
    }
}

impl Add<LabeledDrilldown> for SelectCommand {
    type Output = LabeledDrilldownBuilder;

    fn add(self, rhs: LabeledDrilldown) -> LabeledDrilldownBuilder {
        let labeled_drilldown_builder = LabeledDrilldownBuilder::new(self, rhs);
        labeled_drilldown_builder
    }
}

impl Drilldownable for SelectCommand {
    fn with_drilldown(self, rhs: Drilldown) -> DrilldownBuilder {
        let drilldown_builder = DrilldownBuilder::new(self, rhs);
        drilldown_builder
    }
}

extendable!(SelectCommand);
request_cancellable!(SelectCommand);

#[cfg(test)]
mod test {
    use super::*;
    use command::Query;
    use command::Command::Select;
    use std::collections::HashMap;
    use queryable::Queryable;
    use commandable::Commandable;
    use selectable::drilldown::Drilldown;
    use selectable::drilldownable::Drilldownable;
    use selectable::drilldown_builder::DrilldownBuilder;
    use selectable::labeled_drilldown::LabeledDrilldown;
    use selectable::labeled_drilldown_builder::LabeledDrilldownBuilder;
    use extendable::Extendable;

    #[test]
    fn test_new() {
        let vanilla_select = SelectCommand::new("test".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: HashMap::new(),
        };
        assert_eq!(expected, vanilla_select);
    }

    #[test]
    fn test_filter() {
        let select = SelectCommand::new("test".to_string())
                         .filter("output_column @ \"type_safe\"".to_string());
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("filter".to_string(),
                   "'output_column @ \"type_safe\"'".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg,
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_query() {
        let select = SelectCommand::new("test".to_string())
                         .query("_key:\"http://example.org/\"".to_string());
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("query".to_string(),
                   "\'_key:\"http://example.org/\"\'".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg,
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_match_columns() {
        let select = SelectCommand::new("test".to_string())
                         .match_columns(vec!["test".to_string(), "piyo".to_string()]);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("match_columns".to_string(), "test,piyo".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg,
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_output_columns() {
        let select = SelectCommand::new("test".to_string())
                         .output_columns(vec!["test".to_string(), "piyo".to_string()]);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("output_columns".to_string(), "test,piyo".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg,
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_offset() {
        let select = SelectCommand::new("test".to_string()).offset(100);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("offset".to_string(), "100".to_string());
        let expected = SelectCommand {
            command: Select,
            arguments: arg,
            table: "test".to_string(),
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_limit() {
        let select = SelectCommand::new("test".to_string()).limit(50);
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("limit".to_string(), "50".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg,
        };
        assert_eq!(expected, select);
    }

    #[test]
    fn test_cache() {
        let select_yes = SelectCommand::new("test".to_string()).cache(true);
        let mut arg_yes: HashMap<String, String> = HashMap::new();
        arg_yes.insert("cache".to_string(), "yes".to_string());
        let expected_yes = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg_yes,
        };
        assert_eq!(expected_yes, select_yes);
        let select_no = SelectCommand::new("test".to_string()).cache(false);
        let mut arg_no: HashMap<String, String> = HashMap::new();
        arg_no.insert("cache".to_string(), "no".to_string());
        let expected_no = SelectCommand {
            command: Select,
            table: "test".to_string(),
            arguments: arg_no,
        };
        assert_eq!(expected_no, select_no);
    }

    #[test]
    fn test_build() {
        let actual = SelectCommand::new("test".to_string())
                         .filter("output_column @ \"type_safe\"".to_string())
                         .build();
        let expected_query: Query = vec![("table".to_string(), "test".to_string()),
                                         ("filter".to_string(),
                                          "'output_column @ \"type_safe\"'".to_string())];
        let expected = (Select, expected_query);
        assert_eq!(expected, actual);
    }

    #[test]
    fn test_queryable() {
        let query = SelectCommand::new("Test".to_string())
                        .filter("output_column @ \"type_safe\"".to_string())
                        .to_query();
        let url_encoded = "/d/select?table=Test&filter=%27output_column+%40+%22type_safe%22%27";
        assert_eq!(url_encoded.to_string(), query);
    }

    #[test]
    fn test_commandable() {
        let query = SelectCommand::new("Test".to_string())
                        .filter("output_column @ \"type_safe\"".to_string())
                        .to_command();
        let cli_encoded = "select --table Test --filter \'output_column @ \"type_safe\"\'";
        assert_eq!(cli_encoded.to_string(), query);
    }

    #[test]
    fn test_add_ops_drilldown() {
        let select = SelectCommand::new("Entries".to_string())
                         .filter("content @ \"fast\"".to_string());
        let drilldown = Drilldown::new().drilldown(vec![("tag".to_string())]);
        let ops_builder = (select.clone() + drilldown.clone()).build();
        let drilldown_builder = DrilldownBuilder::new(select.clone(), drilldown.clone()).build();
        assert_eq!(ops_builder, drilldown_builder);
    }

    #[test]
    fn test_add_ops_labedled_drilldown() {
        let select = SelectCommand::new("Entries".to_string())
                         .filter("content @ \"fast\"".to_string());
        let drilldown = LabeledDrilldown::new("labeled".to_string())
                            .keys(vec![("tag".to_string())]);
        let ops_builder = (select.clone() + drilldown.clone()).build();
        let drilldown_builder = LabeledDrilldownBuilder::new(select.clone(), drilldown.clone())
                                    .build();
        assert_eq!(ops_builder, drilldown_builder);
    }

    #[test]
    fn test_with_drilldown() {
        let select = SelectCommand::new("Entries".to_string())
                         .filter("content @ \"fast\"".to_string());
        let drilldown = Drilldown::new().drilldown(vec![("tag".to_string())]);
        let drilldownable = select.clone().with_drilldown(drilldown.clone()).build();
        let drilldown_builder = DrilldownBuilder::new(select.clone(), drilldown.clone()).build();
        assert_eq!(drilldownable, drilldown_builder);
    }

    #[test]
    fn test_extendable() {
        let mut arg: HashMap<String, String> = HashMap::new();
        arg.insert("user".to_string(), "defined".to_string());
        let expected = SelectCommand {
            command: Select,
            table: "Test".to_string(),
            arguments: arg.clone(),
        };
        let query = SelectCommand::new("Test".to_string());
        unsafe {
            let extended = query.set_arguments(arg.clone());
            assert_eq!(expected, extended);
        }
    }
}
<|endoftext|>


<commit_before>use std::thread;
use std::io::Write;
use std::fmt::Display;
use std::net::{TcpListener, TcpStream, SocketAddr};
use std::sync::Mutex;
use std::sync::mpsc;
use {SERVER_ADDRESS_INTERNAL, Request, Mock};
use response::{Chunked, Body};

impl Mock {
    fn method_matches(&self, request: &Request) -> bool {
        self.method == request.method
    }

    fn path_matches(&self, request: &Request) -> bool {
        self.path.matches_value(&request.path)
    }

    fn query_matches(&self, request: &Request) -> bool {
        self.query.matches_value(&request.query)
    }

    fn headers_match(&self, request: &Request) -> bool {
        self.headers.iter().all(|&(ref field, ref expected)| {
            expected.matches_values(&request.find_header_values(field))
        })
    }

    fn body_matches(&self, request: &Request) -> bool {
        self.body.matches_value(&String::from_utf8_lossy(&request.body))
    }
}

impl<'a> PartialEq<Request> for &'a mut Mock {
    fn eq(&self, other: &Request) -> bool {
        self.method_matches(other)
            && self.path_matches(other)
            && self.query_matches(other)
            && self.headers_match(other)
            && self.body_matches(other)
    }
}

pub struct State {
    pub listening_addr: Option<SocketAddr>,
    pub mocks: Vec<Mock>,
    pub unmatched_requests: Vec<Request>,
}

impl State {
    fn new() -> Self {
        Self {
            listening_addr: None,
            mocks: Vec::new(),
            unmatched_requests: Vec::new(),
        }
    }
}

lazy_static! {
    pub static ref STATE: Mutex<State> = Mutex::new(State::new());
}

/// Address and port of the local server.
/// Can be used with `std::net::TcpStream`.
///
/// The server will be started if necessary.
pub fn address() -> SocketAddr {
    try_start();

    let state = STATE.lock().map(|state| state.listening_addr);
    state.expect("state lock").expect("server should be listening")
}

/// A local `http://…` URL of the server.
///
/// The server will be started if necessary.
pub fn url() -> String {
    format!("http://{}", address())
}

pub fn try_start() {
    let mut state = STATE.lock().unwrap();

    if state.listening_addr.is_some() {
        return
    }

    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let res = TcpListener::bind(SERVER_ADDRESS_INTERNAL)
        .or_else(|err| {
            warn!("{}", err);
            TcpListener::bind("127.0.0.1:0")
        });
        let (listener, addr) = match res {
            Ok(listener) => {
                let addr = listener.local_addr().unwrap();
                tx.send(Some(addr)).unwrap();
                (listener, addr)
            },
            Err(err) => {
                error!("{}", err);
                tx.send(None).unwrap();
                return;
            },
        };

        debug!("Server is listening at {}", addr);
        for stream in listener.incoming() {
            if let Ok(stream) = stream{
                let request = Request::from(&stream);
                debug!("Request received: {}", request);
                if request.is_ok() {
                    handle_request(request, stream);
                } else {
                    let message = request.error().map_or("Could not parse the request.", |err| err.as_str());
                    debug!("Could not parse request because: {}", message);
                    respond_with_error(stream, request.version, message);
                }
            } else {
                debug!("Could not read from stream");
            }
        }
    });

    state.listening_addr = rx.recv().ok().and_then(|addr| addr);
}

fn handle_request(request: Request, stream: TcpStream) {
    handle_match_mock(request, stream);
}

fn handle_match_mock(request: Request, stream: TcpStream) {
    let found;

    let mut state = STATE.lock().unwrap();

    if let Some(mock) = state.mocks.iter_mut().rev().find(|mock| mock == &request) {
        debug!("Mock found");
        found = true;
        mock.hits += 1;
        respond_with_mock(stream, request.version, mock, request.is_head());
    } else {
        debug!("Mock not found");
        found = false;
        respond_with_mock_not_found(stream, request.version);
    }

    if !found { state.unmatched_requests.push(request); }
}

fn respond(
    stream: TcpStream,
    version: (u8, u8),
    status: impl Display,
    headers: Option<&Vec<(String, String)>>,
    body: Option<&str>
) {
    let body = body.map(|s| Body::Bytes(s.as_bytes().to_owned()));
    respond_bytes(stream, version, status, headers, body.as_ref())
}

fn respond_bytes(
    mut stream: TcpStream,
    version: (u8, u8),
    status: impl Display,
    headers: Option<&Vec<(String, String)>>,
    body: Option<&Body>
) {
    let mut response = Vec::from(format!("HTTP/{}.{} {}\r\n", version.0, version.1, status));
    let mut has_content_length_header = false;

    if let Some(headers) = headers {
        for &(ref key, ref value) in headers {
            response.extend(key.as_bytes());
            response.extend(b": ");
            response.extend(value.as_bytes());
            response.extend(b"\r\n");
        }

        has_content_length_header = headers.iter().any(|(key, _)| key == "content-length");
    }

    match body {
        Some(Body::Bytes(bytes)) => if !has_content_length_header {
            response.extend(format!("content-length: {}\r\n", bytes.len()).as_bytes());
        },
        Some(Body::Fn(_)) => {
            response.extend(b"transfer-encoding: chunked\r\n");
        },
        None => {},
    };
    response.extend(b"\r\n");
    let _ = stream.write(&response);
    match body {
        Some(Body::Bytes(bytes)) => {
            let _ = stream.write_all(bytes);
        },
        Some(Body::Fn(cb)) => {
            let mut chunked = Chunked::new(&mut stream);
            let _ = cb(&mut chunked);
            let _ = chunked.finish();
        },
        None => {},
    };
    let _ = stream.flush();
}

fn respond_with_mock(stream: TcpStream, version: (u8, u8), mock: &Mock, skip_body: bool) {
    let body =
        if skip_body {
            None
        } else {
            Some(&mock.response.body)
        };

    respond_bytes(stream, version, &mock.response.status, Some(&mock.response.headers), body);
}

fn respond_with_mock_not_found(stream: TcpStream, version: (u8, u8)) {
    respond(stream, version, "501 Mock Not Found", None, None);
}

fn respond_with_error(stream: TcpStream, version: (u8, u8), message: &str) {
    respond(stream, version, "422 Mock Error", None, Some(message));
}
<commit_msg>Log write errors<commit_after>use std::thread;
use std::io;
use std::io::Write;
use std::fmt::Display;
use std::net::{TcpListener, TcpStream, SocketAddr};
use std::sync::Mutex;
use std::sync::mpsc;
use {SERVER_ADDRESS_INTERNAL, Request, Mock};
use response::{Chunked, Body};

impl Mock {
    fn method_matches(&self, request: &Request) -> bool {
        self.method == request.method
    }

    fn path_matches(&self, request: &Request) -> bool {
        self.path.matches_value(&request.path)
    }

    fn query_matches(&self, request: &Request) -> bool {
        self.query.matches_value(&request.query)
    }

    fn headers_match(&self, request: &Request) -> bool {
        self.headers.iter().all(|&(ref field, ref expected)| {
            expected.matches_values(&request.find_header_values(field))
        })
    }

    fn body_matches(&self, request: &Request) -> bool {
        self.body.matches_value(&String::from_utf8_lossy(&request.body))
    }
}

impl<'a> PartialEq<Request> for &'a mut Mock {
    fn eq(&self, other: &Request) -> bool {
        self.method_matches(other)
            && self.path_matches(other)
            && self.query_matches(other)
            && self.headers_match(other)
            && self.body_matches(other)
    }
}

pub struct State {
    pub listening_addr: Option<SocketAddr>,
    pub mocks: Vec<Mock>,
    pub unmatched_requests: Vec<Request>,
}

impl State {
    fn new() -> Self {
        Self {
            listening_addr: None,
            mocks: Vec::new(),
            unmatched_requests: Vec::new(),
        }
    }
}

lazy_static! {
    pub static ref STATE: Mutex<State> = Mutex::new(State::new());
}

/// Address and port of the local server.
/// Can be used with `std::net::TcpStream`.
///
/// The server will be started if necessary.
pub fn address() -> SocketAddr {
    try_start();

    let state = STATE.lock().map(|state| state.listening_addr);
    state.expect("state lock").expect("server should be listening")
}

/// A local `http://…` URL of the server.
///
/// The server will be started if necessary.
pub fn url() -> String {
    format!("http://{}", address())
}

pub fn try_start() {
    let mut state = STATE.lock().unwrap();

    if state.listening_addr.is_some() {
        return
    }

    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        let res = TcpListener::bind(SERVER_ADDRESS_INTERNAL)
        .or_else(|err| {
            warn!("{}", err);
            TcpListener::bind("127.0.0.1:0")
        });
        let (listener, addr) = match res {
            Ok(listener) => {
                let addr = listener.local_addr().unwrap();
                tx.send(Some(addr)).unwrap();
                (listener, addr)
            },
            Err(err) => {
                error!("{}", err);
                tx.send(None).unwrap();
                return;
            },
        };

        debug!("Server is listening at {}", addr);
        for stream in listener.incoming() {
            if let Ok(stream) = stream{
                let request = Request::from(&stream);
                debug!("Request received: {}", request);
                if request.is_ok() {
                    handle_request(request, stream);
                } else {
                    let message = request.error().map_or("Could not parse the request.", |err| err.as_str());
                    debug!("Could not parse request because: {}", message);
                    respond_with_error(stream, request.version, message);
                }
            } else {
                debug!("Could not read from stream");
            }
        }
    });

    state.listening_addr = rx.recv().ok().and_then(|addr| addr);
}

fn handle_request(request: Request, stream: TcpStream) {
    handle_match_mock(request, stream);
}

fn handle_match_mock(request: Request, stream: TcpStream) {
    let found;

    let mut state = STATE.lock().unwrap();

    if let Some(mock) = state.mocks.iter_mut().rev().find(|mock| mock == &request) {
        debug!("Mock found");
        found = true;
        mock.hits += 1;
        respond_with_mock(stream, request.version, mock, request.is_head());
    } else {
        debug!("Mock not found");
        found = false;
        respond_with_mock_not_found(stream, request.version);
    }

    if !found { state.unmatched_requests.push(request); }
}

fn respond(
    stream: TcpStream,
    version: (u8, u8),
    status: impl Display,
    headers: Option<&Vec<(String, String)>>,
    body: Option<&str>
) {
    let body = body.map(|s| Body::Bytes(s.as_bytes().to_owned()));
    if let Err(e) = respond_bytes(stream, version, status, headers, body.as_ref()) {
        eprintln!("warning: Mock response write error: {}", e);
    }
}

fn respond_bytes(
    mut stream: TcpStream,
    version: (u8, u8),
    status: impl Display,
    headers: Option<&Vec<(String, String)>>,
    body: Option<&Body>
) -> io::Result<()> {
    let mut response = Vec::from(format!("HTTP/{}.{} {}\r\n", version.0, version.1, status));
    let mut has_content_length_header = false;

    if let Some(headers) = headers {
        for &(ref key, ref value) in headers {
            response.extend(key.as_bytes());
            response.extend(b": ");
            response.extend(value.as_bytes());
            response.extend(b"\r\n");
        }

        has_content_length_header = headers.iter().any(|(key, _)| key == "content-length");
    }

    match body {
        Some(Body::Bytes(bytes)) => if !has_content_length_header {
            response.extend(format!("content-length: {}\r\n", bytes.len()).as_bytes());
        },
        Some(Body::Fn(_)) => {
            response.extend(b"transfer-encoding: chunked\r\n");
        },
        None => {},
    };
    response.extend(b"\r\n");
    stream.write_all(&response)?;
    match body {
        Some(Body::Bytes(bytes)) => {
            stream.write_all(bytes)?;
        },
        Some(Body::Fn(cb)) => {
            let mut chunked = Chunked::new(&mut stream);
            cb(&mut chunked)?;
            chunked.finish()?;
        },
        None => {},
    };
    stream.flush()
}

fn respond_with_mock(stream: TcpStream, version: (u8, u8), mock: &Mock, skip_body: bool) {
    let body =
        if skip_body {
            None
        } else {
            Some(&mock.response.body)
        };

    if let Err(e) = respond_bytes(stream, version, &mock.response.status, Some(&mock.response.headers), body) {
        eprintln!("warning: Mock response write error: {}", e);
    }
}

fn respond_with_mock_not_found(stream: TcpStream, version: (u8, u8)) {
    respond(stream, version, "501 Mock Not Found", None, None);
}

fn respond_with_error(stream: TcpStream, version: (u8, u8), message: &str) {
    respond(stream, version, "422 Mock Error", None, Some(message));
}
<|endoftext|>


<commit_before>use serde::{ Serialize, Deserialize };

pub trait Cell: Clone + Serialize + Deserialize {
    type Coord: Coord;

    fn step<'a, I>(&'a self, neighbors: I) -> Self
        where I: Iterator<Item=Option<&'a Self>>;

    fn with_coord<C: Coord>(C) -> Self;
    fn coord(&self) -> &Self::Coord;
    fn set_coord<C: Coord>(&mut self, &C);
}

pub trait Nhood {
    type Coord: Coord;

    fn neighbors(&self, &Self::Coord) -> Vec<Self::Coord>;

    fn neighbors_count(&self) -> usize;
}

pub trait Coord: Clone + Serialize + Deserialize {
    fn from_2d(x: i32, y: i32) -> Self;

    fn x(&self) -> i32;
    fn y(&self) -> i32;
    fn z(&self) -> i32 { 0 }
}

pub trait Grid {
    type Cell: Cell;
    type Coord: Coord;

    fn step(&mut self);

    fn cells(&self) -> &Vec<Self::Cell>;
    fn dimensions(&self) -> Self::Coord;

    fn set_cells(&mut self, Vec<Self::Cell>);
}

pub trait Consumer {
    fn consume<G: Grid>(&mut self, repr: &G);
}

pub trait Engine {
    fn run_times(&mut self, times: i64);
}<commit_msg>Allow to change grid from consumer.<commit_after>use serde::{ Serialize, Deserialize };

pub trait Cell: Clone + Serialize + Deserialize {
    type Coord: Coord;

    fn step<'a, I>(&'a self, neighbors: I) -> Self
        where I: Iterator<Item=Option<&'a Self>>;

    fn with_coord<C: Coord>(C) -> Self;
    fn coord(&self) -> &Self::Coord;
    fn set_coord<C: Coord>(&mut self, &C);
}

pub trait Nhood {
    type Coord: Coord;

    fn neighbors(&self, &Self::Coord) -> Vec<Self::Coord>;

    fn neighbors_count(&self) -> usize;
}

pub trait Coord: Clone + Serialize + Deserialize {
    fn from_2d(x: i32, y: i32) -> Self;

    fn x(&self) -> i32;
    fn y(&self) -> i32;
    fn z(&self) -> i32 { 0 }
}

pub trait Grid {
    type Cell: Cell;
    type Coord: Coord;

    fn step(&mut self);

    fn cells(&self) -> &Vec<Self::Cell>;
    fn dimensions(&self) -> Self::Coord;

    fn set_cells(&mut self, Vec<Self::Cell>);
}

pub trait Consumer {
    type Cell: Cell;

    fn consume<G: Grid<Cell=Self::Cell>>(&mut self, repr: &G);
}

pub trait Engine {
    fn run_times(&mut self, times: i64);
}<|endoftext|>