<commit_before>use std::ops::{Add, Sub, Div};
use std::collections::HashMap;
use std::iter::FromIterator;
use std::collections::VecDeque;
use std::iter::repeat;
use std::fmt::{Debug, Formatter, Error};
use std::cmp::Ordering::Equal;
use std::f32;

#[derive(Clone,)]
pub struct WordVec {
    pub word: String,
    pub count: u64,
    vec: Vec<f32>,
}

impl PartialEq for WordVec {
    fn eq(&self, other: &WordVec) -> bool {
        self.vec == other.vec
    }
}

impl Debug for WordVec {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        try!(self.word.fmt(fmt));
        try!(fmt.write_str(": "));
        try!(self.count.fmt(fmt));
        try!(fmt.write_str(", "));
        self.vec.iter().take(5).collect::<Vec<_>>().fmt(fmt)
    }
}

impl WordVec {

    fn dot_prod(&self, other: &WordVec) -> f32 {
        self.vec.iter()
                .zip(other.vec.iter())
                .map(|(x, y)| x * y)
                .fold(0.0, |x, y| x + y)
    }

    fn magnitude(&self) -> f32 {
        self.vec.iter()
                .map(|x| x * x)
                .fold(0.0, |x, y| x + y)
                .sqrt()
    }

    pub fn distance(&self, other: &WordVec) -> f32 {
        self.dot_prod(other) / (self.magnitude() * other.magnitude())
    }

    fn new(word: String, num_words: usize) -> WordVec {
        WordVec {
            word: word,
            count: 0,
            vec: repeat(0.0).take(num_words).collect(),
        }
    }

    fn normalize(&mut self) {
        let count = self.count as f32;
        for f in &mut self.vec {
            *f /= count;
        }
    }

    fn rescale(&mut self, vec_scales: &Vec<(f32, f32)>) {
        for i in 0..self.vec.len() {
            let (min, max) = vec_scales[i];
            self.vec[i] = 2.0 * (self.vec[i] - min) / (max - min) - 1.0;
        }
    }

    fn inc(&mut self, i: usize) {
        self.vec[i] += 1.0;
    }

}

impl Div<i32> for WordVec {
    type Output = WordVec;

    fn div(mut self, i: i32) -> WordVec {
        for f in &mut self.vec {
            *f /= i as f32;
        }

        self
    }
}

impl<'a> Add<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn add(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} + {}", &self.word, &other.word),
            count: 0,
            vec: self.vec,
        };

        for i in 0..newvec.vec.len() {
            newvec.vec[i] += other.vec[i];
        }

        newvec
    }
}

impl<'a> Sub<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn sub(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} - {}", &self.word, &other.word),
            count: 0,
            vec: self.vec,
        };

        for i in 0..(newvec.vec.len()) {
            newvec.vec[i] -= other.vec[i];
        }

        newvec
    }
}

pub struct LanguageModel {
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
}

pub struct LanguageModelBuilder {
    window_width: usize,
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
}

pub struct WordAcceptor<'a> {
    window: VecDeque<(usize, String)>,
    builder: &'a mut LanguageModelBuilder,
}

impl LanguageModelBuilder {
    pub fn new(window_radius: usize, words: Vec<String>) -> LanguageModelBuilder {

        let word_vecs = words.iter()
                             .map(|s| WordVec::new(s.clone(), words.len()))
                             .collect();

        let words = HashMap::from_iter(
                        words.into_iter()
                             .enumerate()
                             .map(|(a, b)| (b, a)));

        LanguageModelBuilder {
            window_width: 2 * window_radius + 1,
            words: words,
            word_vecs: word_vecs,
        }
    }

    pub fn build(mut self) -> LanguageModel {
        let len = self.word_vecs[0].vec.len();
        let mut vec_scales: Vec<(f32, f32)> = repeat((0.0, f32::MAX)).take(len).collect();

        for vec in self.word_vecs.iter_mut() {
            vec.normalize();
        }

        for (i, vec) in self.word_vecs.iter().map(|w| &w.vec).enumerate() {
            for j in (0..len).filter(|j| i != *j) {
                let (min, max) = vec_scales[j];
                vec_scales[j] = (min.min(vec[j]), max.max(vec[j]))
            }
        }

        for vec in self.word_vecs.iter_mut() {
            vec.rescale(&vec_scales);
        }

        LanguageModel {
            words: self.words,
            word_vecs: self.word_vecs,
        }
    }

    pub fn new_file<'a>(&'a mut self) -> WordAcceptor<'a> {
        WordAcceptor {
            window: VecDeque::new(),
            builder: self,
        }
    }

    fn get_vec(&mut self, word: &str) -> &mut WordVec {
        let i = self.words[word];
        &mut self.word_vecs[i]
    }

    fn add_word(&mut self, from: usize, to: usize) {
        self.word_vecs[from].inc(to);
    }

    fn word_seen(&mut self, word: &str) {
        self.get_vec(word).count += 1;
    }
}

impl<'a> WordAcceptor<'a> {
    pub fn add_word(&mut self, word: String) {
        let ww = self.builder.window_width;
        let idx_opt = self.builder.words.get(&word).map(|w| *w);

        if let Some(next_idx) = idx_opt {
            self.window.push_back((next_idx, word));
            if self.window.len() > ww {
                self.window.pop_front();
            }

            if self.window.len() == ww {
                let (center_idx, ref center_word) = self.window[ww / 2];
                self.builder.word_seen(center_word);
                for i in (0..ww).filter(|a| *a != ww / 2) {
                    self.builder.add_word(center_idx, self.window[i].0);
                }
            }
        }
    }
}

impl LanguageModel {
    pub fn get(&self, word: &str) -> Option<&WordVec> {
        self.words.get(word).map(|i| &self.word_vecs[*i])
    }

    pub fn nearest_words(&self, word: &WordVec) -> Vec<&WordVec> {
        let mut vec_refs = self.word_vecs.iter().filter_map(|w| {
            let dist = w.distance(word);
            if w.word != word.word && !dist.is_nan() {
                Some((dist, w))
            } else {
                None
            }
        }).collect::<Vec<_>>();
        vec_refs.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or_else(|| {
            println!("bad vector: {:?}, {:?}", a, b);
            Equal
        }));
        vec_refs.into_iter().map(|x| x.1).collect()
    }
}<commit_msg>switch back to euclidean distance<commit_after>use std::ops::{Add, Sub, Div};
use std::collections::HashMap;
use std::iter::FromIterator;
use std::collections::VecDeque;
use std::iter::repeat;
use std::fmt::{Debug, Formatter, Error};
use std::cmp::Ordering::Equal;
use std::f32;

#[derive(Clone,)]
pub struct WordVec {
    pub word: String,
    pub count: u64,
    vec: Vec<f32>,
}

impl PartialEq for WordVec {
    fn eq(&self, other: &WordVec) -> bool {
        self.vec == other.vec
    }
}

impl Debug for WordVec {
    fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
        try!(self.word.fmt(fmt));
        try!(fmt.write_str(": "));
        try!(self.count.fmt(fmt));
        try!(fmt.write_str(", "));
        self.vec.iter().take(5).collect::<Vec<_>>().fmt(fmt)
    }
}

impl WordVec {

    fn dot_prod(&self, other: &WordVec) -> f32 {
        self.vec.iter()
                .zip(other.vec.iter())
                .map(|(x, y)| x * y)
                .fold(0.0, |x, y| x + y)
    }

    fn magnitude(&self) -> f32 {
        self.vec.iter()
                .map(|x| x * x)
                .fold(0.0, |x, y| x + y)
                .sqrt()
    }

    pub fn distance(&self, other: &WordVec) -> f32 {
        self.vec.iter().zip(other.vec.iter())
                .map(|(x, y)| (x * x - y * y).abs().sqrt())
                .fold(0.0, |x, y| x + y)
    }

    fn new(word: String, num_words: usize) -> WordVec {
        WordVec {
            word: word,
            count: 0,
            vec: repeat(0.0).take(num_words).collect(),
        }
    }

    fn normalize(&mut self) {
        let count = self.count as f32;
        for f in &mut self.vec {
            *f /= count;
        }
    }

    fn rescale(&mut self, vec_scales: &Vec<(f32, f32)>) {
        for i in 0..self.vec.len() {
            let (min, max) = vec_scales[i];
            self.vec[i] = 2.0 * (self.vec[i] - min) / (max - min) - 1.0;
        }
    }

    fn inc(&mut self, i: usize) {
        self.vec[i] += 1.0;
    }

}

impl Div<i32> for WordVec {
    type Output = WordVec;

    fn div(mut self, i: i32) -> WordVec {
        for f in &mut self.vec {
            *f /= i as f32;
        }

        self
    }
}

impl<'a> Add<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn add(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} + {}", &self.word, &other.word),
            count: 0,
            vec: self.vec,
        };

        for i in 0..newvec.vec.len() {
            newvec.vec[i] += other.vec[i];
        }

        newvec
    }
}

impl<'a> Sub<&'a WordVec> for WordVec {
    type Output = WordVec;

    fn sub(self, other: &WordVec) -> WordVec {
        debug_assert!(self.vec.len() == other.vec.len());
        let mut newvec = WordVec {
            word: format!("{} - {}", &self.word, &other.word),
            count: 0,
            vec: self.vec,
        };

        for i in 0..(newvec.vec.len()) {
            newvec.vec[i] -= other.vec[i];
        }

        newvec
    }
}

pub struct LanguageModel {
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
}

pub struct LanguageModelBuilder {
    window_width: usize,
    words: HashMap<String, usize>,
    word_vecs: Vec<WordVec>,
}

pub struct WordAcceptor<'a> {
    window: VecDeque<(usize, String)>,
    builder: &'a mut LanguageModelBuilder,
}

impl LanguageModelBuilder {
    pub fn new(window_radius: usize, words: Vec<String>) -> LanguageModelBuilder {

        let word_vecs = words.iter()
                             .map(|s| WordVec::new(s.clone(), words.len()))
                             .collect();

        let words = HashMap::from_iter(
                        words.into_iter()
                             .enumerate()
                             .map(|(a, b)| (b, a)));

        LanguageModelBuilder {
            window_width: 2 * window_radius + 1,
            words: words,
            word_vecs: word_vecs,
        }
    }

    pub fn build(mut self) -> LanguageModel {
        let len = self.word_vecs[0].vec.len();
        let mut vec_scales: Vec<(f32, f32)> = repeat((0.0, f32::MAX)).take(len).collect();

        for vec in self.word_vecs.iter_mut() {
            vec.normalize();
        }

        for (i, vec) in self.word_vecs.iter().map(|w| &w.vec).enumerate() {
            for j in (0..len).filter(|j| i != *j) {
                let (min, max) = vec_scales[j];
                vec_scales[j] = (min.min(vec[j]), max.max(vec[j]))
            }
        }

        for vec in self.word_vecs.iter_mut() {
            vec.rescale(&vec_scales);
        }

        LanguageModel {
            words: self.words,
            word_vecs: self.word_vecs,
        }
    }

    pub fn new_file<'a>(&'a mut self) -> WordAcceptor<'a> {
        WordAcceptor {
            window: VecDeque::new(),
            builder: self,
        }
    }

    fn get_vec(&mut self, word: &str) -> &mut WordVec {
        let i = self.words[word];
        &mut self.word_vecs[i]
    }

    fn add_word(&mut self, from: usize, to: usize) {
        self.word_vecs[from].inc(to);
    }

    fn word_seen(&mut self, word: &str) {
        self.get_vec(word).count += 1;
    }
}

impl<'a> WordAcceptor<'a> {
    pub fn add_word(&mut self, word: String) {
        let ww = self.builder.window_width;
        let idx_opt = self.builder.words.get(&word).map(|w| *w);

        if let Some(next_idx) = idx_opt {
            self.window.push_back((next_idx, word));
            if self.window.len() > ww {
                self.window.pop_front();
            }

            if self.window.len() == ww {
                let (center_idx, ref center_word) = self.window[ww / 2];
                self.builder.word_seen(center_word);
                for i in (0..ww).filter(|a| *a != ww / 2) {
                    self.builder.add_word(center_idx, self.window[i].0);
                }
            }
        }
    }
}

impl LanguageModel {
    pub fn get(&self, word: &str) -> Option<&WordVec> {
        self.words.get(word).map(|i| &self.word_vecs[*i])
    }

    pub fn nearest_words(&self, word: &WordVec) -> Vec<&WordVec> {
        let mut vec_refs = self.word_vecs.iter().filter_map(|w| {
            let dist = w.distance(word);
            if w.word != word.word && !dist.is_nan() {
                Some((dist, w))
            } else {
                None
            }
        }).collect::<Vec<_>>();
        vec_refs.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or_else(|| {
            println!("bad vector: {:?}, {:?}", a, b);
            Equal
        }));
        vec_refs.into_iter().map(|x| x.1).collect()
    }
}<|endoftext|>


<commit_before>use parser::combinators::{Parser, ParseTo, Consumer, ErrConsumer, token, token_match};
use parser::lexer::{Token};
use parser::lexer::Token::{Begin, End, Identifier, Number, Text};

use ast::{FunctionTyp, Import, Memory, Module, Segment, Typ, Var};
use ast::Typ::{F32, F64, I32, I64};

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub enum ParseError {
    ExpectingTyp(String),
    ExpectingId(String),
    ExpectingString(String),
    ExpectingNumber(String),
}

pub trait ParserConsumer<D> where D: Consumer<Module>+ErrConsumer<ParseError> {
    fn accept<P>(self, parser: P) where P: for<'a> ParseTo<&'a[Token<'a>],D>;
}

fn is_identifier<'a>(tok: Token<'a>) -> bool {
    match tok {
        Identifier(_) => true,
        _             => false,
    }
}

fn is_number<'a>(tok: Token<'a>) -> bool {
    match tok {
        Number(_) => true,
        _         => false,
    }
}

fn is_text<'a>(tok: Token<'a>) -> bool {
    match tok {
        Text(_) => true,
        _         => false,
    }
}

fn is_begin_import<'a>(tok: Token<'a>) -> bool { tok == Begin("import") }
fn is_begin_memory<'a>(tok: Token<'a>) -> bool { tok == Begin("memory") }
fn is_begin_module<'a>(tok: Token<'a>) -> bool { tok == Begin("module") }
fn is_begin_param<'a>(tok: Token<'a>) -> bool { tok == Begin("param") }
fn is_begin_result<'a>(tok: Token<'a>) -> bool { tok == Begin("result") }
fn is_begin_segment<'a>(tok: Token<'a>) -> bool { tok == Begin("segment") }
fn is_end<'a>(tok: Token<'a>) -> bool { tok == End }

fn mk_usize<'a>(tok: Token<'a>) -> Result<usize,ParseError> {
    match tok {
        Number(n) => Ok(n),
        _         => Err(ParseError::ExpectingNumber(String::from(tok))),
    }
}

fn mk_string<'a>(tok: Token<'a>) -> Result<String,ParseError> {
    match tok {
        Text(s) => Ok(String::from(s)), // TODO: escape sequences
        _       => Err(ParseError::ExpectingString(String::from(tok))),
    }
}

fn mk_typ<'a>(tok: Token<'a>) -> Result<Typ,ParseError> {
    match tok {
        Identifier("f32") => Ok(F32),
        Identifier("f64") => Ok(F64),
        Identifier("i32") => Ok(I32),
        Identifier("i64") => Ok(I64),
        _                 => Err(ParseError::ExpectingTyp(String::from(tok))),
    }
}

fn mk_id<'a>(tok: Token<'a>) -> Result<String,ParseError> {
    match tok {
        Identifier(x) => Ok(String::from(x)),
        _             => Err(ParseError::ExpectingId(String::from(tok))),
    }
}

fn mk_var(children: (String,Typ)) -> Var {
    Var{ name: children.0, typ: children.1 }
}

fn mk_function_typ(children: (Vec<Var>,Option<Typ>)) -> FunctionTyp {
    FunctionTyp{ params: children.0, result: children.1 }
}

fn mk_segment(children: (usize, String)) -> Segment {
    Segment{ addr: children.0, data: children.1 }
}

fn mk_memory(children: ((usize, Option<usize>), Vec<Segment>)) -> Memory {
    Memory{ init: (children.0).0, max: (children.0).1, segments: children.1 }
}

fn mk_import(children: (((String,String),String),FunctionTyp)) -> Import {
    Import{ func: ((children.0).0).0, module: ((children.0).0).1, name: (children.0).1, typ: children.1 }
}

fn mk_module(children: (Option<Memory>,Vec<Import>)) -> Module {
    Module{ memory: children.0, imports: children.1, exports: vec![], functions: vec![] }
}

pub fn parser<C,D>(consumer: C) where C: ParserConsumer<D>, D: Consumer<Module>+ErrConsumer<ParseError> {
    let typ = token_match(is_identifier)
        .map(mk_typ).results();
    let id = token_match(is_identifier)
        .map(mk_id).results();
    let param = token_match(is_begin_param).ignore()
        .and_then(id)
        .zip(typ)
        .and_then(token_match(is_end).ignore())
        .map(mk_var);
    let result_typ = token_match(is_begin_result).ignore()
        .and_then(typ)
        .and_then(token_match(is_end).ignore());
    let function_typ = param.star().collect(Vec::new())
        .zip(result_typ.map(Some).or_emit(None))
        .map(mk_function_typ);
    let number = token_match(is_number)
        .map(mk_usize).results();
    let text = token_match(is_text)
        .map(mk_string).results();
    let segment = token_match(is_begin_segment).ignore()
        .and_then(number)
        .zip(text)
        .and_then(token_match(is_end).ignore())
        .map(mk_segment);
    let memory = token_match(is_begin_memory).ignore()
        .and_then(number)
        .zip(number.map(Some).or_emit(None))
        .zip(segment.star().collect(Vec::new()))
        .and_then(token_match(is_end).ignore())
        .map(mk_memory);
    let import = token_match(is_begin_import).ignore()
        .and_then(id)
        .zip(text)
        .zip(text)
        .zip(function_typ)
        .and_then(token_match(is_end).ignore())
        .map(mk_import);
    let module = token_match(is_begin_module).ignore()
        .and_then(memory.map(Some).or_emit(None))
        .zip(import.star().collect(Vec::new()))
        .and_then(token_match(is_end).ignore())
        .map(mk_module);
    let top_level = module;
    consumer.accept(top_level);
}

#[test]
fn test_parser() {
    use parser::combinators::MatchResult::{Matched,Failed};
    struct TestConsumer(Vec<Module>,Vec<ParseError>);
    impl Consumer<Module> for TestConsumer {
        fn accept(&mut self, module: Module) {
            self.0.push(module);
        }
    }
    impl ErrConsumer<ParseError> for TestConsumer {
        fn error(&mut self, err: ParseError) {
            self.1.push(err);
        }
    }
    impl ParserConsumer<TestConsumer> for TestConsumer {
        fn accept<P>(mut self, mut parser: P) where P: for<'a> ParseTo<&'a[Token<'a>],TestConsumer> {
            let tokens = [
                Begin("module"),
                    Begin("memory"),
                        Number(1024),
                        Begin("segment"),
                            Number(0),
                            Text("abc"),
                        End,
                        Begin("segment"),
                            Number(1),
                            Text("def"),
                        End,
                    End,
                    Begin("import"),
                        Identifier("$foo"),
                        Text("ghi"),
                        Text("jkl"),
                    End,
                    Begin("import"),
                        Identifier("$bar"),
                        Text("ghi"),
                        Text("mno"),
                        Begin("param"),
                            Identifier("$x"),
                            Identifier("f32"),
                        End,
                        Begin("param"),
                            Identifier("$y"),
                            Identifier("f64"),
                        End,
                        Begin("result"),
                            Identifier("i32"),
                        End,
                    End,
                End,
            ];
            let ast = Module{
                memory: Some(Memory{
                    init: 1024,
                    max: None,
                    segments: vec![
                        Segment { addr: 0, data: String::from("abc") },
                        Segment { addr: 1, data: String::from("def") },
                    ],
                }),
                imports: vec![
                    Import {
                        func: String::from("$foo"),
                        module: String::from("ghi"),
                        name: String::from("jkl"),
                        typ: FunctionTyp{ params: vec![], result: None },
                    },
                    Import {
                        func: String::from("$bar"),
                        module: String::from("ghi"),
                        name: String::from("mno"),
                        typ: FunctionTyp{
                            params: vec![
                                Var{ name: String::from("$x"), typ: F32 },
                                Var{ name: String::from("$y"), typ: F64 },
                            ],
                            result: Some(I32),
                        },
                    },
                ],
                exports: vec![],
                functions: vec![]
            };
            assert_eq!(parser.done_to(&mut self), false);
            assert_eq!(self.0, []);
            assert_eq!(self.1, []);
            assert_eq!(parser.push_to(&tokens, &mut self), Matched(None));
            assert_eq!(parser.done_to(&mut self), true);
            assert_eq!(self.0, [ast]);
            assert_eq!(self.1, []);
        }
    }
    parser(TestConsumer(Vec::new(),Vec::new()));
}
<commit_msg>Added exports to modules.<commit_after>use parser::combinators::{Parser, ParseTo, Consumer, ErrConsumer, token, token_match};
use parser::lexer::{Token};
use parser::lexer::Token::{Begin, End, Identifier, Number, Text};

use ast::{Export, FunctionTyp, Import, Memory, Module, Segment, Typ, Var};
use ast::Typ::{F32, F64, I32, I64};

#[derive(Clone, Eq, PartialEq, Hash, Ord, PartialOrd, Debug)]
pub enum ParseError {
    ExpectingTyp(String),
    ExpectingId(String),
    ExpectingString(String),
    ExpectingNumber(String),
}

pub trait ParserConsumer<D> where D: Consumer<Module>+ErrConsumer<ParseError> {
    fn accept<P>(self, parser: P) where P: for<'a> ParseTo<&'a[Token<'a>],D>;
}

#[derive(Clone, Debug)]
struct ModuleContents {
    imports: Vec<Import>,
    exports: Vec<Export>,
}

impl ModuleContents {
    fn new() -> ModuleContents {
        ModuleContents { imports: Vec::new(), exports: Vec::new() }
    }
}

impl Consumer<Export> for ModuleContents {
    fn accept(&mut self, export: Export) {
        self.exports.push(export);
    }
}

impl Consumer<Import> for ModuleContents {
    fn accept(&mut self, import: Import) {
        self.imports.push(import);
    }
}

impl Module {
    pub fn new() -> Module {
        Module{ memory: None, exports: Vec::new(), imports: Vec::new(), functions: Vec::new() }
    }
}

fn is_identifier<'a>(tok: Token<'a>) -> bool {
    match tok {
        Identifier(_) => true,
        _             => false,
    }
}

fn is_number<'a>(tok: Token<'a>) -> bool {
    match tok {
        Number(_) => true,
        _         => false,
    }
}

fn is_text<'a>(tok: Token<'a>) -> bool {
    match tok {
        Text(_) => true,
        _         => false,
    }
}

fn is_begin_export<'a>(tok: Token<'a>) -> bool { tok == Begin("export") }
fn is_begin_import<'a>(tok: Token<'a>) -> bool { tok == Begin("import") }
fn is_begin_memory<'a>(tok: Token<'a>) -> bool { tok == Begin("memory") }
fn is_begin_module<'a>(tok: Token<'a>) -> bool { tok == Begin("module") }
fn is_begin_param<'a>(tok: Token<'a>) -> bool { tok == Begin("param") }
fn is_begin_result<'a>(tok: Token<'a>) -> bool { tok == Begin("result") }
fn is_begin_segment<'a>(tok: Token<'a>) -> bool { tok == Begin("segment") }
fn is_end<'a>(tok: Token<'a>) -> bool { tok == End }

fn mk_usize<'a>(tok: Token<'a>) -> Result<usize,ParseError> {
    match tok {
        Number(n) => Ok(n),
        _         => Err(ParseError::ExpectingNumber(String::from(tok))),
    }
}

fn mk_string<'a>(tok: Token<'a>) -> Result<String,ParseError> {
    match tok {
        Text(s) => Ok(String::from(s)), // TODO: escape sequences
        _       => Err(ParseError::ExpectingString(String::from(tok))),
    }
}

fn mk_typ<'a>(tok: Token<'a>) -> Result<Typ,ParseError> {
    match tok {
        Identifier("f32") => Ok(F32),
        Identifier("f64") => Ok(F64),
        Identifier("i32") => Ok(I32),
        Identifier("i64") => Ok(I64),
        _                 => Err(ParseError::ExpectingTyp(String::from(tok))),
    }
}

fn mk_id<'a>(tok: Token<'a>) -> Result<String,ParseError> {
    match tok {
        Identifier(x) => Ok(String::from(x)),
        _             => Err(ParseError::ExpectingId(String::from(tok))),
    }
}

fn mk_var(children: (String,Typ)) -> Var {
    Var{ name: children.0, typ: children.1 }
}

fn mk_function_typ(children: (Vec<Var>,Option<Typ>)) -> FunctionTyp {
    FunctionTyp{ params: children.0, result: children.1 }
}

fn mk_segment(children: (usize, String)) -> Segment {
    Segment{ addr: children.0, data: children.1 }
}

fn mk_memory(children: ((usize, Option<usize>), Vec<Segment>)) -> Memory {
    Memory{ init: (children.0).0, max: (children.0).1, segments: children.1 }
}

fn mk_import(children: (((String,String),String),FunctionTyp)) -> Import {
    Import{ func: ((children.0).0).0, module: ((children.0).0).1, name: (children.0).1, typ: children.1 }
}

fn mk_export(children: (String,String)) -> Export {
    Export{ name: children.0, func: children.1 }
}

fn mk_module(children: (Option<Memory>,ModuleContents)) -> Module {
    Module{ memory: children.0, imports: children.1.imports, exports: children.1.exports, functions: vec![] }
}

pub fn parser<C,D>(consumer: C) where C: ParserConsumer<D>, D: Consumer<Module>+ErrConsumer<ParseError> {
    let typ = token_match(is_identifier)
        .map(mk_typ).results();
    let id = token_match(is_identifier)
        .map(mk_id).results();
    let param = token_match(is_begin_param).ignore()
        .and_then(id)
        .zip(typ)
        .and_then(token_match(is_end).ignore())
        .map(mk_var);
    let result_typ = token_match(is_begin_result).ignore()
        .and_then(typ)
        .and_then(token_match(is_end).ignore());
    let function_typ = param.star().collect(Vec::new())
        .zip(result_typ.map(Some).or_emit(None))
        .map(mk_function_typ);
    let number = token_match(is_number)
        .map(mk_usize).results();
    let text = token_match(is_text)
        .map(mk_string).results();
    let segment = token_match(is_begin_segment).ignore()
        .and_then(number)
        .zip(text)
        .and_then(token_match(is_end).ignore())
        .map(mk_segment);
    let memory = token_match(is_begin_memory).ignore()
        .and_then(number)
        .zip(number.map(Some).or_emit(None))
        .zip(segment.star().collect(Vec::new()))
        .and_then(token_match(is_end).ignore())
        .map(mk_memory);
    let import = token_match(is_begin_import).ignore()
        .and_then(id)
        .zip(text)
        .zip(text)
        .zip(function_typ)
        .and_then(token_match(is_end).ignore())
        .map(mk_import);
    let export = token_match(is_begin_export).ignore()
        .and_then(text)
        .zip(id)
        .and_then(token_match(is_end).ignore())
        .map(mk_export);
    let module = token_match(is_begin_module).ignore()
        .and_then(memory.map(Some).or_emit(None))
        .zip(import.or_else(export).star().collect(ModuleContents::new()))
        .and_then(token_match(is_end).ignore())
        .map(mk_module);
    let top_level = module;
    consumer.accept(top_level);
}

#[test]
fn test_parser() {
    use parser::combinators::MatchResult::{Matched,Failed};
    struct TestConsumer(Vec<Module>,Vec<ParseError>);
    impl Consumer<Module> for TestConsumer {
        fn accept(&mut self, module: Module) {
            self.0.push(module);
        }
    }
    impl ErrConsumer<ParseError> for TestConsumer {
        fn error(&mut self, err: ParseError) {
            self.1.push(err);
        }
    }
    impl ParserConsumer<TestConsumer> for TestConsumer {
        fn accept<P>(mut self, mut parser: P) where P: for<'a> ParseTo<&'a[Token<'a>],TestConsumer> {
            let tokens = [
                Begin("module"),
                    Begin("memory"),
                        Number(1024),
                        Begin("segment"),
                            Number(0),
                            Text("abc"),
                        End,
                        Begin("segment"),
                            Number(1),
                            Text("def"),
                        End,
                    End,
                    Begin("import"),
                        Identifier("$foo"),
                        Text("ghi"),
                        Text("jkl"),
                    End,
                    Begin("export"),
                        Text("fish"),
                        Identifier("$fish"),
                    End,
                    Begin("import"),
                        Identifier("$bar"),
                        Text("ghi"),
                        Text("mno"),
                        Begin("param"),
                            Identifier("$x"),
                            Identifier("f32"),
                        End,
                        Begin("param"),
                            Identifier("$y"),
                            Identifier("f64"),
                        End,
                        Begin("result"),
                            Identifier("i32"),
                        End,
                    End,
                End,
            ];
            let ast = Module{
                memory: Some(Memory{
                    init: 1024,
                    max: None,
                    segments: vec![
                        Segment { addr: 0, data: String::from("abc") },
                        Segment { addr: 1, data: String::from("def") },
                    ],
                }),
                imports: vec![
                    Import {
                        func: String::from("$foo"),
                        module: String::from("ghi"),
                        name: String::from("jkl"),
                        typ: FunctionTyp{ params: vec![], result: None },
                    },
                    Import {
                        func: String::from("$bar"),
                        module: String::from("ghi"),
                        name: String::from("mno"),
                        typ: FunctionTyp{
                            params: vec![
                                Var{ name: String::from("$x"), typ: F32 },
                                Var{ name: String::from("$y"), typ: F64 },
                            ],
                            result: Some(I32),
                        },
                    },
                ],
                exports: vec![
                    Export { name: String::from("fish"), func: String::from("$fish") },
                ],
                functions: vec![]
            };
            assert_eq!(parser.done_to(&mut self), false);
            assert_eq!(self.0, []);
            assert_eq!(self.1, []);
            assert_eq!(parser.push_to(&tokens, &mut self), Matched(None));
            assert_eq!(parser.done_to(&mut self), true);
            assert_eq!(self.0, [ast]);
            assert_eq!(self.1, []);
        }
    }
    parser(TestConsumer(Vec::new(),Vec::new()));
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Anatoly Ikorsky
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use errors::*;
use io::futures::new_connecting_stream;
use io::futures::new_write_packet;
use io::futures::ConnectingStream;
use io::futures::WritePacket;
use lib_futures::stream;
use lib_futures::Async::NotReady;
use lib_futures::Async::Ready;
use lib_futures::Poll;
#[cfg(feature = "ssl")]
use lib_futures::{Future, IntoFuture};
use myc::packets::{PacketParser, ParseResult, RawPacket};
#[cfg(feature = "ssl")]
use native_tls::{Certificate, Identity, TlsConnector};
use opts::SslOpts;
use std::fmt;
#[cfg(feature = "ssl")]
use std::fs::File;
use std::io;
#[cfg(feature = "ssl")]
use std::io::Read;
use std::net::ToSocketAddrs;
use std::time::Duration;
use tokio::net::TcpStream;
use tokio::reactor::Handle;
use tokio_io::AsyncRead;
use tokio_io::AsyncWrite;
use BoxFuture;

#[cfg(feature = "ssl")]
mod async_tls;
pub mod futures;

#[derive(Debug)]
enum Endpoint {
    Plain(TcpStream),
    #[cfg(feature = "ssl")]
    Secure(self::async_tls::TlsStream<TcpStream>),
}

impl Endpoint {
    #[cfg(feature = "ssl")]
    pub fn is_secure(&self) -> bool {
        if let Endpoint::Secure(_) = self {
            true
        } else {
            false
        }
    }

    #[cfg(not(feature = "ssl"))]
    pub fn is_secure(&self) -> bool {
        false
    }

    pub fn set_keepalive_ms(&self, ms: Option<u32>) -> Result<()> {
        let ms = ms.map(|val| Duration::from_millis(val as u64));
        match *self {
            Endpoint::Plain(ref stream) => stream.set_keepalive(ms)?,
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref stream) => stream.get_ref().get_ref().set_keepalive(ms)?,
        }
        Ok(())
    }

    pub fn set_tcp_nodelay(&self, val: bool) -> Result<()> {
        match *self {
            Endpoint::Plain(ref stream) => stream.set_nodelay(val)?,
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref stream) => stream.get_ref().get_ref().set_nodelay(val)?,
        }
        Ok(())
    }

    #[cfg(feature = "ssl")]
    pub fn make_secure(self, domain: String, ssl_opts: SslOpts) -> BoxFuture<Self> {
        let fut = ::std::fs::File::open(ssl_opts.pkcs12_path())
            .map_err(Error::from)
            .and_then(|mut file| {
                let mut der = vec![];
                file.read_to_end(&mut der)?;
                let identity = Identity::from_pkcs12(&*der, ssl_opts.password().unwrap_or(""))
                    .chain_err(|| "Can't parse der")?;
                let mut builder = TlsConnector::builder();
                match ssl_opts.root_cert_path() {
                    Some(root_cert_path) => {
                        let mut root_cert_der = vec![];
                        let mut root_cert_file = File::open(root_cert_path)?;
                        root_cert_file.read_to_end(&mut root_cert_der)?;
                        let root_cert = Certificate::from_der(&*root_cert_der)
                            .chain_err(|| "Can't parse root certificate")?;
                        builder.add_root_certificate(root_cert);
                    }
                    None => (),
                }
                builder.identity(identity);
                builder.danger_accept_invalid_hostnames(ssl_opts.skip_domain_validation());
                builder
                    .build()
                    .chain_err(|| "Can't build TlsConnectorBuilder")
            })
            .into_future()
            .and_then(move |tls_connector| match self {
                Endpoint::Plain(stream) => {
                    let fut = self::async_tls::connect_async(&tls_connector, &*domain, stream);
                    fut.then(|result| result.chain_err(|| "Can't connect TlsConnector"))
                }
                Endpoint::Secure(_) => unreachable!(),
            })
            .map(|tls_stream| Endpoint::Secure(tls_stream));
        Box::new(fut)
    }
}

impl From<TcpStream> for Endpoint {
    fn from(stream: TcpStream) -> Self {
        Endpoint::Plain(stream)
    }
}

#[cfg(feature = "ssl")]
impl From<self::async_tls::TlsStream<TcpStream>> for Endpoint {
    fn from(stream: self::async_tls::TlsStream<TcpStream>) -> Self {
        Endpoint::Secure(stream)
    }
}

impl io::Read for Endpoint {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            Endpoint::Plain(ref mut stream) => stream.read(buf),
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref mut stream) => stream.read(buf),
        }
    }
}

impl io::Write for Endpoint {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match *self {
            Endpoint::Plain(ref mut stream) => stream.write(buf),
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref mut stream) => stream.write(buf),
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        match *self {
            Endpoint::Plain(ref mut stream) => stream.flush(),
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref mut stream) => stream.flush(),
        }
    }
}

impl AsyncRead for Endpoint {
    unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool {
        match *self {
            Endpoint::Plain(ref stream) => stream.prepare_uninitialized_buffer(_buf),
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref stream) => stream.prepare_uninitialized_buffer(_buf),
        }
    }
}

impl AsyncWrite for Endpoint {
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        match *self {
            Endpoint::Plain(ref mut stream) => stream.shutdown(),
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref mut stream) => stream.shutdown(),
        }
    }
}

/// Stream connected to MySql server.
pub struct Stream {
    endpoint: Option<Endpoint>,
    closed: bool,
    parser: Option<PacketParser>,
    packets: ::std::collections::VecDeque<(RawPacket, u8)>,
    buf: Vec<u8>,
}

impl fmt::Debug for Stream {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Stream (endpoint={:?})", self.endpoint)
    }
}

impl Stream {
    pub fn connect<S>(addr: S, handle: &Handle) -> ConnectingStream
    where
        S: ToSocketAddrs,
    {
        new_connecting_stream(addr, handle)
    }

    pub fn write_packet(self, data: Vec<u8>, seq_id: u8) -> WritePacket {
        new_write_packet(self, data, seq_id)
    }

    pub fn set_keepalive_ms(&self, ms: Option<u32>) -> Result<()> {
        match self.endpoint {
            Some(ref endpoint) => endpoint.set_keepalive_ms(ms),
            None => unreachable!(),
        }
    }

    pub fn set_tcp_nodelay(&self, val: bool) -> Result<()> {
        match self.endpoint {
            Some(ref endpoint) => endpoint.set_tcp_nodelay(val),
            None => unreachable!(),
        }
    }

    #[cfg(not(feature = "ssl"))]
    #[allow(unused)]
    pub fn make_secure(self, domain: String, ssl_opts: SslOpts) -> BoxFuture<Self> {
        panic!("Ssl connection requires `ssl` feature");
    }

    #[cfg(feature = "ssl")]
    pub fn make_secure(mut self, domain: String, ssl_opts: SslOpts) -> BoxFuture<Self> {
        match self.endpoint.take() {
            Some(endpoint) => {
                let fut = endpoint.make_secure(domain, ssl_opts).map(|endpoint| {
                    self.endpoint = Some(endpoint);
                    self
                });
                Box::new(fut)
            }
            None => unreachable!(),
        }
    }

    pub fn is_secure(&self) -> bool {
        match self.endpoint.as_ref() {
            Some(endpoint) => endpoint.is_secure(),
            _ => false,
        }
    }
}

impl io::Read for Stream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match self.endpoint {
            Some(ref mut endpoint) => endpoint.read(buf),
            None => unreachable!(),
        }
    }
}

impl io::Write for Stream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match self.endpoint {
            Some(ref mut endpoint) => endpoint.write(buf),
            None => unreachable!(),
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        match self.endpoint {
            Some(ref mut endpoint) => endpoint.flush(),
            None => unreachable!(),
        }
    }
}

impl AsyncRead for Stream {
    unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool {
        match self.endpoint {
            Some(ref endpoint) => endpoint.prepare_uninitialized_buffer(_buf),
            None => unreachable!(),
        }
    }
}

impl AsyncWrite for Stream {
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        match self.endpoint {
            Some(ref mut endpoint) => endpoint.shutdown(),
            None => unreachable!(),
        }
    }
}

impl stream::Stream for Stream {
    type Item = (RawPacket, u8);
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<(RawPacket, u8)>, Error> {
        // emit pending packets
        if let Some(packet) = self.packets.pop_front() {
            return Ok(Ready(Some(packet)));
        }

        // should read everything from self.endpoint
        let mut buf = [0u8; 4096];
        while !self.closed {
            match self.poll_read(&mut buf[..]) {
                Err(error) => {
                    self.closed = true;
                    bail!(error)
                }
                Ok(Ready(0)) => {
                    self.closed = true;
                }
                Ok(Ready(size)) => {
                    self.buf.extend_from_slice(&buf[..size]);
                }
                Ok(NotReady) => break,
            };
        }

        // parse buffer into packets
        let (packets, parser, buf) = parse_packet(self.parser.take().unwrap(), &self.buf);
        self.packets = packets.into();
        self.parser = Some(parser);
        self.buf = buf;

        if let Some(packet) = self.packets.pop_front() {
            return Ok(Ready(Some(packet)));
        }

        if self.closed {
            bail!(ErrorKind::ConnectionClosed);
        }
        return Ok(NotReady);
    }
}

fn parse_packet(
    mut parser: PacketParser,
    mut buf: &[u8],
) -> (Vec<(RawPacket, u8)>, PacketParser, Vec<u8>) {
    let mut packets = Vec::new();

    loop {
        parser = match parser.parse() {
            ParseResult::Done(packet, seq_id) => {
                packets.push((packet, seq_id));
                PacketParser::empty()
            }
            ParseResult::Incomplete(mut parser, needed) => {
                if buf.len() < needed {
                    return (packets, parser, Vec::from(buf));
                }

                parser.extend_from_slice(&buf[..needed]);
                buf = &buf[needed..];
                parser
            }
        };
    }
}
<commit_msg>Remove BoxFuture from src/io/mod.rs<commit_after>// Copyright (c) 2016 Anatoly Ikorsky
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.

use errors::*;
use io::futures::new_connecting_stream;
use io::futures::new_write_packet;
use io::futures::ConnectingStream;
use io::futures::WritePacket;
use lib_futures::{
    future::ok, stream, Async::{NotReady, Ready}, Poll,
};
#[cfg(feature = "ssl")]
use lib_futures::{Future, IntoFuture};
use myc::packets::{PacketParser, ParseResult, RawPacket};
#[cfg(feature = "ssl")]
use native_tls::{Certificate, Identity, TlsConnector};
use opts::SslOpts;
use std::fmt;
#[cfg(feature = "ssl")]
use std::fs::File;
use std::io;
#[cfg(feature = "ssl")]
use std::io::Read;
use std::net::ToSocketAddrs;
use std::time::Duration;
use tokio::net::TcpStream;
use tokio::reactor::Handle;
use tokio_io::AsyncRead;
use tokio_io::AsyncWrite;
use MyFuture;

#[cfg(feature = "ssl")]
mod async_tls;
pub mod futures;

#[derive(Debug)]
enum Endpoint {
    Plain(TcpStream),
    #[cfg(feature = "ssl")]
    Secure(self::async_tls::TlsStream<TcpStream>),
}

impl Endpoint {
    #[cfg(feature = "ssl")]
    pub fn is_secure(&self) -> bool {
        if let Endpoint::Secure(_) = self {
            true
        } else {
            false
        }
    }

    #[cfg(not(feature = "ssl"))]
    pub fn is_secure(&self) -> bool {
        false
    }

    pub fn set_keepalive_ms(&self, ms: Option<u32>) -> Result<()> {
        let ms = ms.map(|val| Duration::from_millis(val as u64));
        match *self {
            Endpoint::Plain(ref stream) => stream.set_keepalive(ms)?,
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref stream) => stream.get_ref().get_ref().set_keepalive(ms)?,
        }
        Ok(())
    }

    pub fn set_tcp_nodelay(&self, val: bool) -> Result<()> {
        match *self {
            Endpoint::Plain(ref stream) => stream.set_nodelay(val)?,
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref stream) => stream.get_ref().get_ref().set_nodelay(val)?,
        }
        Ok(())
    }

    #[cfg(feature = "ssl")]
    pub fn make_secure(self, domain: String, ssl_opts: SslOpts) -> impl MyFuture<Self> {
        ::std::fs::File::open(ssl_opts.pkcs12_path())
            .map_err(Error::from)
            .and_then(|mut file| {
                let mut der = vec![];
                file.read_to_end(&mut der)?;
                let identity = Identity::from_pkcs12(&*der, ssl_opts.password().unwrap_or(""))
                    .chain_err(|| "Can't parse der")?;
                let mut builder = TlsConnector::builder();
                match ssl_opts.root_cert_path() {
                    Some(root_cert_path) => {
                        let mut root_cert_der = vec![];
                        let mut root_cert_file = File::open(root_cert_path)?;
                        root_cert_file.read_to_end(&mut root_cert_der)?;
                        let root_cert = Certificate::from_der(&*root_cert_der)
                            .chain_err(|| "Can't parse root certificate")?;
                        builder.add_root_certificate(root_cert);
                    }
                    None => (),
                }
                builder.identity(identity);
                builder.danger_accept_invalid_hostnames(ssl_opts.skip_domain_validation());
                builder
                    .build()
                    .chain_err(|| "Can't build TlsConnectorBuilder")
            })
            .into_future()
            .and_then(move |tls_connector| match self {
                Endpoint::Plain(stream) => {
                    let fut = self::async_tls::connect_async(&tls_connector, &*domain, stream);
                    fut.then(|result| result.chain_err(|| "Can't connect TlsConnector"))
                }
                Endpoint::Secure(_) => unreachable!(),
            })
            .map(|tls_stream| Endpoint::Secure(tls_stream))
    }
}

impl From<TcpStream> for Endpoint {
    fn from(stream: TcpStream) -> Self {
        Endpoint::Plain(stream)
    }
}

#[cfg(feature = "ssl")]
impl From<self::async_tls::TlsStream<TcpStream>> for Endpoint {
    fn from(stream: self::async_tls::TlsStream<TcpStream>) -> Self {
        Endpoint::Secure(stream)
    }
}

impl io::Read for Endpoint {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match *self {
            Endpoint::Plain(ref mut stream) => stream.read(buf),
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref mut stream) => stream.read(buf),
        }
    }
}

impl io::Write for Endpoint {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match *self {
            Endpoint::Plain(ref mut stream) => stream.write(buf),
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref mut stream) => stream.write(buf),
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        match *self {
            Endpoint::Plain(ref mut stream) => stream.flush(),
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref mut stream) => stream.flush(),
        }
    }
}

impl AsyncRead for Endpoint {
    unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool {
        match *self {
            Endpoint::Plain(ref stream) => stream.prepare_uninitialized_buffer(_buf),
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref stream) => stream.prepare_uninitialized_buffer(_buf),
        }
    }
}

impl AsyncWrite for Endpoint {
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        match *self {
            Endpoint::Plain(ref mut stream) => stream.shutdown(),
            #[cfg(feature = "ssl")]
            Endpoint::Secure(ref mut stream) => stream.shutdown(),
        }
    }
}

/// Stream connected to MySql server.
pub struct Stream {
    endpoint: Option<Endpoint>,
    closed: bool,
    parser: Option<PacketParser>,
    packets: ::std::collections::VecDeque<(RawPacket, u8)>,
    buf: Vec<u8>,
}

impl fmt::Debug for Stream {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Stream (endpoint={:?})", self.endpoint)
    }
}

impl Stream {
    pub fn connect<S>(addr: S, handle: &Handle) -> ConnectingStream
    where
        S: ToSocketAddrs,
    {
        new_connecting_stream(addr, handle)
    }

    pub fn write_packet(self, data: Vec<u8>, seq_id: u8) -> WritePacket {
        new_write_packet(self, data, seq_id)
    }

    pub fn set_keepalive_ms(&self, ms: Option<u32>) -> Result<()> {
        match self.endpoint {
            Some(ref endpoint) => endpoint.set_keepalive_ms(ms),
            None => unreachable!(),
        }
    }

    pub fn set_tcp_nodelay(&self, val: bool) -> Result<()> {
        match self.endpoint {
            Some(ref endpoint) => endpoint.set_tcp_nodelay(val),
            None => unreachable!(),
        }
    }

    #[cfg(not(feature = "ssl"))]
    #[allow(unused)]
    pub fn make_secure(self, domain: String, ssl_opts: SslOpts) -> impl MyFuture<Self> {
        ok(panic!("Ssl connection requires `ssl` feature"))
    }

    #[cfg(feature = "ssl")]
    pub fn make_secure(mut self, domain: String, ssl_opts: SslOpts) -> impl MyFuture<Self> {
        match self.endpoint.take() {
            Some(endpoint) => endpoint.make_secure(domain, ssl_opts).map(|endpoint| {
                self.endpoint = Some(endpoint);
                self
            }),
            None => unreachable!(),
        }
    }

    pub fn is_secure(&self) -> bool {
        match self.endpoint.as_ref() {
            Some(endpoint) => endpoint.is_secure(),
            _ => false,
        }
    }
}

impl io::Read for Stream {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        match self.endpoint {
            Some(ref mut endpoint) => endpoint.read(buf),
            None => unreachable!(),
        }
    }
}

impl io::Write for Stream {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match self.endpoint {
            Some(ref mut endpoint) => endpoint.write(buf),
            None => unreachable!(),
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        match self.endpoint {
            Some(ref mut endpoint) => endpoint.flush(),
            None => unreachable!(),
        }
    }
}

impl AsyncRead for Stream {
    unsafe fn prepare_uninitialized_buffer(&self, _buf: &mut [u8]) -> bool {
        match self.endpoint {
            Some(ref endpoint) => endpoint.prepare_uninitialized_buffer(_buf),
            None => unreachable!(),
        }
    }
}

impl AsyncWrite for Stream {
    fn shutdown(&mut self) -> Poll<(), io::Error> {
        match self.endpoint {
            Some(ref mut endpoint) => endpoint.shutdown(),
            None => unreachable!(),
        }
    }
}

impl stream::Stream for Stream {
    type Item = (RawPacket, u8);
    type Error = Error;

    fn poll(&mut self) -> Poll<Option<(RawPacket, u8)>, Error> {
        // emit pending packets
        if let Some(packet) = self.packets.pop_front() {
            return Ok(Ready(Some(packet)));
        }

        // should read everything from self.endpoint
        let mut buf = [0u8; 4096];
        while !self.closed {
            match self.poll_read(&mut buf[..]) {
                Err(error) => {
                    self.closed = true;
                    bail!(error)
                }
                Ok(Ready(0)) => {
                    self.closed = true;
                }
                Ok(Ready(size)) => {
                    self.buf.extend_from_slice(&buf[..size]);
                }
                Ok(NotReady) => break,
            };
        }

        // parse buffer into packets
        let (packets, parser, buf) = parse_packet(self.parser.take().unwrap(), &self.buf);
        self.packets = packets.into();
        self.parser = Some(parser);
        self.buf = buf;

        if let Some(packet) = self.packets.pop_front() {
            return Ok(Ready(Some(packet)));
        }

        if self.closed {
            bail!(ErrorKind::ConnectionClosed);
        }
        return Ok(NotReady);
    }
}

fn parse_packet(
    mut parser: PacketParser,
    mut buf: &[u8],
) -> (Vec<(RawPacket, u8)>, PacketParser, Vec<u8>) {
    let mut packets = Vec::new();

    loop {
        parser = match parser.parse() {
            ParseResult::Done(packet, seq_id) => {
                packets.push((packet, seq_id));
                PacketParser::empty()
            }
            ParseResult::Incomplete(mut parser, needed) => {
                if buf.len() < needed {
                    return (packets, parser, Vec::from(buf));
                }

                parser.extend_from_slice(&buf[..needed]);
                buf = &buf[needed..];
                parser
            }
        };
    }
}
<|endoftext|>


<commit_before>use net2::{TcpBuilder, TcpStreamExt};
#[cfg(unix)]
use nix::{
    errno::Errno,
    sys::select,
    sys::socket,
    sys::time::{TimeVal, TimeValLike},
};
use std::io;
use std::mem;
use std::net::{TcpStream, SocketAddr, ToSocketAddrs};
#[cfg(target_os = "windows")]
use std::{
    os::raw::*,
    os::windows::prelude::*,
    ptr,
};
#[cfg(unix)]
use std::os::unix::prelude::*;
use std::time::Duration;
#[cfg(target_os = "windows")]
use winapi::um::winsock2::*;

pub struct MyTcpBuilder<T> {
    address: T,
    bind_address: Option<SocketAddr>,
    connect_timeout: Option<Duration>,
    read_timeout: Option<Duration>,
    write_timeout: Option<Duration>,
    keepalive_time_ms: Option<u32>,
    nodelay: bool,
}

impl<T: ToSocketAddrs> MyTcpBuilder<T> {
    pub fn keepalive_time_ms(&mut self, keepalive_time_ms: Option<u32>) -> &mut Self {
        self.keepalive_time_ms = keepalive_time_ms;
        self
    }

    pub fn nodelay(&mut self, nodelay: bool) -> &mut Self {
        self.nodelay = nodelay;
        self
    }

    pub fn write_timeout(&mut self, write_timeout: Option<Duration>) -> &mut Self {
        self.write_timeout = write_timeout;
        self
    }

    pub fn read_timeout(&mut self, read_timeout: Option<Duration>) -> &mut Self {
        self.read_timeout = read_timeout;
        self
    }

    pub fn bind_address<U>(&mut self, bind_address: Option<U>) -> &mut Self
        where U: Into<SocketAddr>
    {
        self.bind_address = bind_address.map(Into::into);
        self
    }

    pub fn connect_timeout(&mut self, timeout: Option<Duration>) -> &mut Self {
        self.connect_timeout = timeout;
        self
    }

    pub fn new(address: T) -> MyTcpBuilder<T> {
        MyTcpBuilder {
            address,
            bind_address: None,
            connect_timeout: None,
            read_timeout: None,
            write_timeout: None,
            keepalive_time_ms: None,
            nodelay: true,
        }
    }

    pub fn connect(self) -> io::Result<TcpStream> {
        let MyTcpBuilder {
            address,
            bind_address,
            connect_timeout,
            read_timeout,
            write_timeout,
            keepalive_time_ms,
            nodelay,
        } = self;
        let err_msg = if bind_address.is_none() {
            "could not connect to any address"
        } else {
            "could not connect to any address with specified bind address"
        };
        let err = io::Error::new(io::ErrorKind::Other, err_msg);
        address.to_socket_addrs()?
            .fold(Err(err), |prev, sock_addr| {
                prev.or_else(|_| {
                    let builder = if sock_addr.is_ipv4() {
                        TcpBuilder::new_v4()?
                    } else {
                        TcpBuilder::new_v6()?
                    };
                    if let Some(bind_address) = bind_address {
                        if bind_address.is_ipv4() == sock_addr.is_ipv4() {
                            builder.bind(bind_address)?;
                        }
                    }
                    if let Some(connect_timeout) = connect_timeout {
                        #[cfg(unix)]
                        connect_fd_timeout(builder.as_raw_fd(), &sock_addr, connect_timeout)?;
                        #[cfg(target_os = "windows")]
                        connect_fd_timeout(builder.as_raw_socket(), &sock_addr, connect_timeout)?;
                        builder.to_tcp_stream()
                    } else {
                        builder.connect(sock_addr)
                    }
                })
            })
            .and_then(|stream| {
                stream.set_read_timeout(read_timeout)?;
                stream.set_write_timeout(write_timeout)?;
                stream.set_keepalive_ms(keepalive_time_ms)?;
                stream.set_nodelay(nodelay)?;
                Ok(stream)
            })
    }
}

#[cfg(unix)]
fn set_non_blocking(fd: RawFd, non_blocking: bool) -> io::Result<()> {
    let stream = unsafe { TcpStream::from_raw_fd(fd) };
    let result = stream.set_nonblocking(non_blocking);
    mem::forget(stream);
    result
}

#[cfg(target_os = "windows")]
fn set_non_blocking(socket: RawSocket, non_blocking: bool) -> io::Result<()> {
    let stream = unsafe { TcpStream::from_raw_socket(socket) };
    let result = stream.set_nonblocking(non_blocking);
    mem::forget(stream);
    result
}

#[cfg(unix)]
fn connect_fd_timeout(fd: RawFd, sock_addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
    set_non_blocking(fd, true)?;

    let inet_addr = socket::InetAddr::from_std(sock_addr);
    let sock_addr = socket::SockAddr::Inet(inet_addr);
    match socket::connect(fd, &sock_addr) {
        Ok(_) => (),
        Err(err) => {
            match err {
                ::nix::Error::Sys(Errno::EALREADY) |
                ::nix::Error::Sys(Errno::EINPROGRESS) => (),
                ::nix::Error::Sys(errno) => {
                    return Err(io::Error::from_raw_os_error(errno as i32))
                },
                _ => return Err(io::Error::new(io::ErrorKind::Other, err)),
            }
        }
    }

    let mut fd_set = select::FdSet::new();
    let socket_fd = fd;
    fd_set.insert(socket_fd);
    let mut timeout_timeval = TimeVal::microseconds(timeout.as_secs() as i64 * 1000 * 1000);

    let select_res = select::select(
        socket_fd + 1,
        None,
        Some(&mut fd_set),
        None,
        Some(&mut timeout_timeval),
    );

    let select_res = select_res.map_err(|err| {
        match err {
            ::nix::Error::Sys(errno) => io::Error::from_raw_os_error(errno as i32),
            _ => io::Error::new(io::ErrorKind::Other, err),
        }
    })?;

    if select_res == -1 {
        return Err(io::Error::last_os_error());
    }

    if select_res != 1 {
        return Err(io::ErrorKind::TimedOut.into());
    }

    let socket_error_code = socket::getsockopt(
        socket_fd,
        socket::sockopt::SocketError,
    );

    let socket_error_code = socket_error_code.map_err(|err| {
        match err {
            ::nix::Error::Sys(errno) => io::Error::from_raw_os_error(errno as i32),
            _ => io::Error::new(io::ErrorKind::Other, err),
        }
    })?;

    if socket_error_code != 0 {
        return Err(io::Error::from_raw_os_error(socket_error_code));
    }

    set_non_blocking(fd, false)
}

#[cfg(target_os = "windows")]
fn connect_fd_timeout(socket: RawSocket,
                      sock_addr: &SocketAddr,
                      timeout: Duration) -> io::Result<()> {
    set_non_blocking(socket, true)?;
    let (name, name_len) = match *sock_addr {
        SocketAddr::V4(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as c_int)
        },
        SocketAddr::V6(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as c_int)
        }
    };
    let result = unsafe { connect(socket, name, name_len) };
    if result == SOCKET_ERROR {
        let err = io::Error::last_os_error();
        match err.raw_os_error() {
            Some(WSAEWOULDBLOCK) => {
                let mut write_fds = fd_set {
                    fd_count: 1,
                    fd_array: [0; FD_SETSIZE]
                };
                write_fds.fd_array[0] = socket as usize;
                let mut err_fds = write_fds.clone();
                let timeout = timeval {
                    tv_sec: timeout.as_secs() as c_long,
                    tv_usec: 0,
                };

                let result = unsafe {
                    select(0, ptr::null_mut(), &mut write_fds, &mut err_fds, &timeout)
                };

                if result == 0 {
                    return Err(io::ErrorKind::TimedOut.into());
                } else if result == SOCKET_ERROR {
                    return Err(io::Error::last_os_error());
                } else {
                    let mut error = None;
                    for i in 0..(err_fds.fd_count as usize) {
                        if err_fds.fd_array[i] as u64 == socket {
                            error = Some(true);
                        }
                    }
                    for i in 0..(write_fds.fd_count as usize) {
                        if write_fds.fd_array[i] as u64 == socket {
                            error = Some(false);
                        }
                    }
                    match error {
                        Some(false) => (),
                        Some(true) => {
                            let mut opt_val = 0i32;
                            let mut opt_len = mem::size_of::<i32>() as c_int;
                            let result = unsafe {
                                getsockopt(socket,
                                           SOL_SOCKET,
                                           SO_ERROR,
                                           &mut opt_val as *mut _ as *mut _,
                                           &mut opt_len)
                            };
                            return Err(io::Error::from_raw_os_error(result));
                        },
                        None => unreachable!(),
                    }
                }
            },
            _ => return Err(err),
        }
    }
    set_non_blocking(socket, false)
}
<commit_msg>Fix connect and getsockopt calls on windows<commit_after>use net2::{TcpBuilder, TcpStreamExt};
#[cfg(unix)]
use nix::{
    errno::Errno,
    sys::select,
    sys::socket,
    sys::time::{TimeVal, TimeValLike},
};
use std::io;
use std::mem;
use std::net::{TcpStream, SocketAddr, ToSocketAddrs};
#[cfg(target_os = "windows")]
use std::{
    os::raw::*,
    os::windows::prelude::*,
    ptr,
};
#[cfg(unix)]
use std::os::unix::prelude::*;
use std::time::Duration;
#[cfg(target_os = "windows")]
use winapi::um::winsock2::*;

pub struct MyTcpBuilder<T> {
    address: T,
    bind_address: Option<SocketAddr>,
    connect_timeout: Option<Duration>,
    read_timeout: Option<Duration>,
    write_timeout: Option<Duration>,
    keepalive_time_ms: Option<u32>,
    nodelay: bool,
}

impl<T: ToSocketAddrs> MyTcpBuilder<T> {
    pub fn keepalive_time_ms(&mut self, keepalive_time_ms: Option<u32>) -> &mut Self {
        self.keepalive_time_ms = keepalive_time_ms;
        self
    }

    pub fn nodelay(&mut self, nodelay: bool) -> &mut Self {
        self.nodelay = nodelay;
        self
    }

    pub fn write_timeout(&mut self, write_timeout: Option<Duration>) -> &mut Self {
        self.write_timeout = write_timeout;
        self
    }

    pub fn read_timeout(&mut self, read_timeout: Option<Duration>) -> &mut Self {
        self.read_timeout = read_timeout;
        self
    }

    pub fn bind_address<U>(&mut self, bind_address: Option<U>) -> &mut Self
        where U: Into<SocketAddr>
    {
        self.bind_address = bind_address.map(Into::into);
        self
    }

    pub fn connect_timeout(&mut self, timeout: Option<Duration>) -> &mut Self {
        self.connect_timeout = timeout;
        self
    }

    pub fn new(address: T) -> MyTcpBuilder<T> {
        MyTcpBuilder {
            address,
            bind_address: None,
            connect_timeout: None,
            read_timeout: None,
            write_timeout: None,
            keepalive_time_ms: None,
            nodelay: true,
        }
    }

    pub fn connect(self) -> io::Result<TcpStream> {
        let MyTcpBuilder {
            address,
            bind_address,
            connect_timeout,
            read_timeout,
            write_timeout,
            keepalive_time_ms,
            nodelay,
        } = self;
        let err_msg = if bind_address.is_none() {
            "could not connect to any address"
        } else {
            "could not connect to any address with specified bind address"
        };
        let err = io::Error::new(io::ErrorKind::Other, err_msg);
        address.to_socket_addrs()?
            .fold(Err(err), |prev, sock_addr| {
                prev.or_else(|_| {
                    let builder = if sock_addr.is_ipv4() {
                        TcpBuilder::new_v4()?
                    } else {
                        TcpBuilder::new_v6()?
                    };
                    if let Some(bind_address) = bind_address {
                        if bind_address.is_ipv4() == sock_addr.is_ipv4() {
                            builder.bind(bind_address)?;
                        }
                    }
                    if let Some(connect_timeout) = connect_timeout {
                        #[cfg(unix)]
                        connect_fd_timeout(builder.as_raw_fd(), &sock_addr, connect_timeout)?;
                        #[cfg(target_os = "windows")]
                        connect_fd_timeout(builder.as_raw_socket(), &sock_addr, connect_timeout)?;
                        builder.to_tcp_stream()
                    } else {
                        builder.connect(sock_addr)
                    }
                })
            })
            .and_then(|stream| {
                stream.set_read_timeout(read_timeout)?;
                stream.set_write_timeout(write_timeout)?;
                stream.set_keepalive_ms(keepalive_time_ms)?;
                stream.set_nodelay(nodelay)?;
                Ok(stream)
            })
    }
}

#[cfg(unix)]
fn set_non_blocking(fd: RawFd, non_blocking: bool) -> io::Result<()> {
    let stream = unsafe { TcpStream::from_raw_fd(fd) };
    let result = stream.set_nonblocking(non_blocking);
    mem::forget(stream);
    result
}

#[cfg(target_os = "windows")]
fn set_non_blocking(socket: RawSocket, non_blocking: bool) -> io::Result<()> {
    let stream = unsafe { TcpStream::from_raw_socket(socket) };
    let result = stream.set_nonblocking(non_blocking);
    mem::forget(stream);
    result
}

#[cfg(unix)]
fn connect_fd_timeout(fd: RawFd, sock_addr: &SocketAddr, timeout: Duration) -> io::Result<()> {
    set_non_blocking(fd, true)?;

    let inet_addr = socket::InetAddr::from_std(sock_addr);
    let sock_addr = socket::SockAddr::Inet(inet_addr);
    match socket::connect(fd, &sock_addr) {
        Ok(_) => (),
        Err(err) => {
            match err {
                ::nix::Error::Sys(Errno::EALREADY) |
                ::nix::Error::Sys(Errno::EINPROGRESS) => (),
                ::nix::Error::Sys(errno) => {
                    return Err(io::Error::from_raw_os_error(errno as i32))
                },
                _ => return Err(io::Error::new(io::ErrorKind::Other, err)),
            }
        }
    }

    let mut fd_set = select::FdSet::new();
    let socket_fd = fd;
    fd_set.insert(socket_fd);
    let mut timeout_timeval = TimeVal::microseconds(timeout.as_secs() as i64 * 1000 * 1000);

    let select_res = select::select(
        socket_fd + 1,
        None,
        Some(&mut fd_set),
        None,
        Some(&mut timeout_timeval),
    );

    let select_res = select_res.map_err(|err| {
        match err {
            ::nix::Error::Sys(errno) => io::Error::from_raw_os_error(errno as i32),
            _ => io::Error::new(io::ErrorKind::Other, err),
        }
    })?;

    if select_res == -1 {
        return Err(io::Error::last_os_error());
    }

    if select_res != 1 {
        return Err(io::ErrorKind::TimedOut.into());
    }

    let socket_error_code = socket::getsockopt(
        socket_fd,
        socket::sockopt::SocketError,
    );

    let socket_error_code = socket_error_code.map_err(|err| {
        match err {
            ::nix::Error::Sys(errno) => io::Error::from_raw_os_error(errno as i32),
            _ => io::Error::new(io::ErrorKind::Other, err),
        }
    })?;

    if socket_error_code != 0 {
        return Err(io::Error::from_raw_os_error(socket_error_code));
    }

    set_non_blocking(fd, false)
}

#[cfg(target_os = "windows")]
fn connect_fd_timeout(socket: RawSocket,
                      sock_addr: &SocketAddr,
                      timeout: Duration) -> io::Result<()> {
    set_non_blocking(socket, true)?;
    let (name, name_len) = match *sock_addr {
        SocketAddr::V4(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as c_int)
        },
        SocketAddr::V6(ref a) => {
            (a as *const _ as *const _, mem::size_of_val(a) as c_int)
        }
    };
    let result = unsafe { connect(socket as usize, name, name_len) };
    if result == SOCKET_ERROR {
        let err = io::Error::last_os_error();
        match err.raw_os_error() {
            Some(WSAEWOULDBLOCK) => {
                let mut write_fds = fd_set {
                    fd_count: 1,
                    fd_array: [0; FD_SETSIZE]
                };
                write_fds.fd_array[0] = socket as usize;
                let mut err_fds = write_fds.clone();
                let timeout = timeval {
                    tv_sec: timeout.as_secs() as c_long,
                    tv_usec: 0,
                };

                let result = unsafe {
                    select(0, ptr::null_mut(), &mut write_fds, &mut err_fds, &timeout)
                };

                if result == 0 {
                    return Err(io::ErrorKind::TimedOut.into());
                } else if result == SOCKET_ERROR {
                    return Err(io::Error::last_os_error());
                } else {
                    let mut error = None;
                    for i in 0..(err_fds.fd_count as usize) {
                        if err_fds.fd_array[i] as u64 == socket {
                            error = Some(true);
                        }
                    }
                    for i in 0..(write_fds.fd_count as usize) {
                        if write_fds.fd_array[i] as u64 == socket {
                            error = Some(false);
                        }
                    }
                    match error {
                        Some(false) => (),
                        Some(true) => {
                            let mut opt_val = 0i32;
                            let mut opt_len = mem::size_of::<i32>() as c_int;
                            let result = unsafe {
                                getsockopt(socket as usize,
                                           SOL_SOCKET,
                                           SO_ERROR,
                                           &mut opt_val as *mut _ as *mut _,
                                           &mut opt_len)
                            };
                            return Err(io::Error::from_raw_os_error(result));
                        },
                        None => unreachable!(),
                    }
                }
            },
            _ => return Err(err),
        }
    }
    set_non_blocking(socket, false)
}
<|endoftext|>


<commit_before>#![crate_name = "websocket"]

#![comment = "WebSocket client"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![feature(default_type_params)]
#![feature(slicing_syntax)]
#![feature(associated_types)]

extern crate url;
extern crate openssl;
extern crate serialize;
extern crate crypto;

#[cfg(test)]
extern crate test;

pub mod nonce;
pub mod message;
pub mod stream;
pub mod socket;

<commit_msg>old_orphan_check<commit_after>#![crate_name = "websocket"]

#![comment = "WebSocket client"]
#![license = "MIT/ASL2"]
#![crate_type = "dylib"]
#![crate_type = "rlib"]

#![feature(default_type_params)]
#![feature(slicing_syntax)]
#![feature(associated_types)]
#![feature(old_orphan_check)]

extern crate url;
extern crate openssl;
extern crate serialize;
extern crate crypto;

#[cfg(test)]
extern crate test;

pub mod nonce;
pub mod message;
pub mod stream;
pub mod socket;

<|endoftext|>


<commit_before>use std::io::net::ip::{Port, IpAddr};

use router::Router;
use middleware::{ MiddlewareStack, Middleware, ErrorHandler, Action };
use into_middleware::IntoMiddleware;
use nickel_error::{ NickelError, ErrorWithStatusCode };
use server::Server;

use http::method::{ Method, Get, Post, Put, Delete };
use http::status::NotFound;
use request::Request;
use response::Response;

//pre defined middleware
use static_files_handler::StaticFilesHandler;
use json_body_parser::JsonBodyParser;
use query_string::QueryStringParser;
use default_error_handler::DefaultErrorHandler;

/// Nickel is the application object. It's the surface that
/// holds all public APIs.

pub struct Nickel{
    middleware_stack: MiddlewareStack,
    server: Option<Server>,
}

impl Nickel {

    /// In order to use Nickels API one first has to create an instance.
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut server = Nickel::new();
    /// ```
    pub fn new() -> Nickel {
        let mut middleware_stack = MiddlewareStack::new();

        // Hook up the default error handler by default. Users are
        // free to cancel it out from their custom error handler if
        // they don't like the default behaviour.
        middleware_stack.add_error_handler(DefaultErrorHandler);

        Nickel {
            middleware_stack: middleware_stack,
            server: None
        }
    }

    /// Registers a middleware handler which will be invoked among other middleware
    /// handlers before each request. Middleware can be stacked and is invoked in the
    /// same order it was registered.
    ///
    /// A middleware handler is nearly identical to a regular route handler with the only
    /// difference that it expects a return value of boolean. That is to indicate whether
    /// other middleware handler (if any) further down the stack should continue or if the
    /// middleware invocation should be stopped after the current handler.
    ///
    /// # Example
    ///
    /// ```{rust,ignore}
    /// fn logger (req: &Request, res: &mut Response) -> Result<Action, NickelError>{
    ///     println!("logging request: {}", req.origin.request_uri);
    ///     Ok(Continue)
    /// }
    /// ```
    pub fn utilize<T: Middleware>(&mut self, handler: T){
        self.middleware_stack.add_middleware(handler);
    }

    /// Registers a handler to be used for a specific GET request.
    /// Handlers are assigned to paths and paths are allowed to contain
    /// variables and wildcards. A handler added through this API will
    /// be attached to the default router. Consider creating the router
    /// middleware manually for advanced functionality.
    ///
    /// # Example without variables and wildcards
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user");
    /// };
    /// server.get("/user", handler);
    /// ```
    /// # Example with variables
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     let text = format!("This is user: {}", request.params.get(&"userid".to_string()));
    ///     response.send(text.as_slice());
    /// };
    /// server.get("/user/:userid", handler);
    /// ```
    /// # Example with simple wildcard
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user/list/4711 but not /user/extended/list/4711");
    /// };
    /// server.get("/user/*/:userid", handler);
    /// ```
    /// # Example with double wildcard
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user/list/4711 and also /user/extended/list/4711");
    /// };
    /// server.get("/user/**/:userid", handler);
    /// ```
    pub fn get(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.register_route_with_new_router(Get, uri, handler);
    }

    /// Registers a handler to be used for a specific POST request.
    /// A handler added through this API will be attached to the default router.
    /// Consider creating the router middleware manually for advanced functionality.
    ///
    /// # Example
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a POST request to /a/post/request");
    /// };
    /// server.post("/a/post/request", handler);
    /// ```
    /// Take a look at `get()` for a more detailed description.
    pub fn post(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.register_route_with_new_router(Post, uri, handler);
    }

    /// Registers a handler to be used for a specific PUT request.
    /// A handler added through this API will be attached to the default router.
    /// Consider creating the router middleware manually for advanced functionality.
    ///
    /// # Example
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a POST request to /a/put/request");
    /// };
    /// server.put("/a/put/request", handler);
    /// ```
    /// Take a look at `get(..)` for a more detailed description.
    pub fn put(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.register_route_with_new_router(Put, uri, handler);
    }

    /// Registers a handler to be used for a specific DELETE request.
    /// A handler added through this API will be attached to the default router.
    /// Consider creating the router middleware manually for advanced functionality.
    ///
    /// # Example
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a DELETE request to /a/delete/request");
    /// };
    /// server.delete("/a/delete/request", handler);
    /// ```
    /// Take a look at `get(...)` for a more detailed description.
    pub fn delete(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.register_route_with_new_router(Delete, uri, handler);
    }

    fn register_route_with_new_router(&mut self, method: Method, uri: &str, handler: fn(request: &Request, response: &mut Response)) {
        let mut router = Router::new();
        router.add_route(method, String::from_str(uri), handler);
        self.utilize(router);
    }

    /// Registers an error handler which will be invoked among other error handler
    /// as soon as any regular handler returned an error
    ///
    /// A error handler is nearly identical to a regular middleware handler with the only
    /// difference that it takes an additional error parameter or type `NickelError.
    ///
    /// # Example
    ///
    /// ```{rust,ignore}
    /// fn error_handler (err: &NickelError, req: &Request, res: &mut Response) -> Result<Action, NickelError>{
    ///    match err.kind {
    ///        ErrorWithStatusCode(NotFound) => {
    ///            response.origin.headers.content_type = get_media_type("html");
    ///            response.origin.status = NotFound;
    ///            response.send("<h1>Call the police!<h1>");
    ///            Ok(Halt)
    ///        },
    ///        _ => Ok(Continue)
    ///    }
    /// }
    /// ```
    pub fn handle_error<T: ErrorHandler>(&mut self, handler: T){
        self.middleware_stack.add_error_handler(handler);
    }

    /// Create a new middleware to serve files from within a given root directory.
    /// The file to serve will be determined by combining the requested Url with
    /// the provided root directory.
    ///
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut server = Nickel::new();
    /// server.utilize(Nickel::static_files("/path/to/serve/"));
    /// ```
    pub fn static_files(root_path: &str) -> StaticFilesHandler {
        StaticFilesHandler::new(root_path)
    }

    /// Create a new middleware to serve as a router.
    ///
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut server = Nickel::new();
    /// let mut router = Nickel::router();
    ///
    /// router.get("/foo", foo_handler);
    /// server.utilize(router);
    /// ```
    pub fn router() -> Router {
        Router::new()
    }

    /// Create a new middleware to parse JSON bodies.
    ///
    ///
    /// # Example
    /// ```{rust,ignore}
    ///
    /// #[deriving(Decodable, Encodable)]
    /// struct Person {
    ///     firstname: String,
    ///     lastname:  String,
    /// }
    ///
    /// let mut server = Nickel::new();
    /// server.utilize(Nickel::json_body_parser());
    ///
    /// fn post_handler (request: &Request, response: &mut Response) {
    ///
    ///     let person = request.json_as::<Person>().unwrap();
    ///     let text = format!("Hello {} {}", person.firstname, person.lastname);
    ///     response.send(text.as_slice());
    /// };
    ///
    /// server.post("/a/post/request", post_handler);
    /// ```
    pub fn json_body_parser() -> JsonBodyParser {
        JsonBodyParser
    }

    /// Create a new middleware to parse the query string.
    ///
    ///
    /// # Example
    /// ```{rust}
    /// # #![feature(phase)]
    /// # #[phase(plugin)] extern crate nickel_macros;
    /// # extern crate nickel;
    /// # use nickel::{Nickel, Request, Response};
    /// use nickel::QueryString;
    /// # fn main() {
    /// let router = router! {
    ///     get "/a/get/request" => |request, response| {
    ///         let foo = request.query("foo", "this is the default value, if foo is not present!");
    ///         response.send(foo[0].as_slice());
    ///     }
    /// };
    ///
    /// let mut server = Nickel::new();
    /// // It is currently a requirement that the query_string middleware
    /// // is added before any routes that require it.
    /// server.utilize(Nickel::query_string());
    /// server.utilize(router);
    /// # }
    /// ```
    pub fn query_string() -> QueryStringParser {
        QueryStringParser
    }

    /// Bind and listen for connections on the given host and port
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut server = Nickel::new();
    /// server.listen(Ipv4Addr(127, 0, 0, 1), 6767);
    /// ```
    pub fn listen(mut self, ip: IpAddr, port: Port) {
        fn not_found_handler(_request: &Request, _response: &mut Response) -> Result<Action, NickelError> {
            Err(NickelError::new("File Not Found", ErrorWithStatusCode(NotFound)))
        }

        self.middleware_stack.add_middleware(IntoMiddleware::from_fn(not_found_handler));
        self.server = Some(Server::new(self.middleware_stack, ip, port));
        self.server.unwrap().serve();
    }
}
<commit_msg>docs(nickel): fix documentation for json_body_parser<commit_after>use std::io::net::ip::{Port, IpAddr};

use router::Router;
use middleware::{ MiddlewareStack, Middleware, ErrorHandler, Action };
use into_middleware::IntoMiddleware;
use nickel_error::{ NickelError, ErrorWithStatusCode };
use server::Server;

use http::method::{ Method, Get, Post, Put, Delete };
use http::status::NotFound;
use request::Request;
use response::Response;

//pre defined middleware
use static_files_handler::StaticFilesHandler;
use json_body_parser::JsonBodyParser;
use query_string::QueryStringParser;
use default_error_handler::DefaultErrorHandler;

/// Nickel is the application object. It's the surface that
/// holds all public APIs.

pub struct Nickel{
    middleware_stack: MiddlewareStack,
    server: Option<Server>,
}

impl Nickel {

    /// In order to use Nickels API one first has to create an instance.
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut server = Nickel::new();
    /// ```
    pub fn new() -> Nickel {
        let mut middleware_stack = MiddlewareStack::new();

        // Hook up the default error handler by default. Users are
        // free to cancel it out from their custom error handler if
        // they don't like the default behaviour.
        middleware_stack.add_error_handler(DefaultErrorHandler);

        Nickel {
            middleware_stack: middleware_stack,
            server: None
        }
    }

    /// Registers a middleware handler which will be invoked among other middleware
    /// handlers before each request. Middleware can be stacked and is invoked in the
    /// same order it was registered.
    ///
    /// A middleware handler is nearly identical to a regular route handler with the only
    /// difference that it expects a return value of boolean. That is to indicate whether
    /// other middleware handler (if any) further down the stack should continue or if the
    /// middleware invocation should be stopped after the current handler.
    ///
    /// # Example
    ///
    /// ```{rust,ignore}
    /// fn logger (req: &Request, res: &mut Response) -> Result<Action, NickelError>{
    ///     println!("logging request: {}", req.origin.request_uri);
    ///     Ok(Continue)
    /// }
    /// ```
    pub fn utilize<T: Middleware>(&mut self, handler: T){
        self.middleware_stack.add_middleware(handler);
    }

    /// Registers a handler to be used for a specific GET request.
    /// Handlers are assigned to paths and paths are allowed to contain
    /// variables and wildcards. A handler added through this API will
    /// be attached to the default router. Consider creating the router
    /// middleware manually for advanced functionality.
    ///
    /// # Example without variables and wildcards
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user");
    /// };
    /// server.get("/user", handler);
    /// ```
    /// # Example with variables
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     let text = format!("This is user: {}", request.params.get(&"userid".to_string()));
    ///     response.send(text.as_slice());
    /// };
    /// server.get("/user/:userid", handler);
    /// ```
    /// # Example with simple wildcard
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user/list/4711 but not /user/extended/list/4711");
    /// };
    /// server.get("/user/*/:userid", handler);
    /// ```
    /// # Example with double wildcard
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches /user/list/4711 and also /user/extended/list/4711");
    /// };
    /// server.get("/user/**/:userid", handler);
    /// ```
    pub fn get(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.register_route_with_new_router(Get, uri, handler);
    }

    /// Registers a handler to be used for a specific POST request.
    /// A handler added through this API will be attached to the default router.
    /// Consider creating the router middleware manually for advanced functionality.
    ///
    /// # Example
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a POST request to /a/post/request");
    /// };
    /// server.post("/a/post/request", handler);
    /// ```
    /// Take a look at `get()` for a more detailed description.
    pub fn post(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.register_route_with_new_router(Post, uri, handler);
    }

    /// Registers a handler to be used for a specific PUT request.
    /// A handler added through this API will be attached to the default router.
    /// Consider creating the router middleware manually for advanced functionality.
    ///
    /// # Example
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a POST request to /a/put/request");
    /// };
    /// server.put("/a/put/request", handler);
    /// ```
    /// Take a look at `get(..)` for a more detailed description.
    pub fn put(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.register_route_with_new_router(Put, uri, handler);
    }

    /// Registers a handler to be used for a specific DELETE request.
    /// A handler added through this API will be attached to the default router.
    /// Consider creating the router middleware manually for advanced functionality.
    ///
    /// # Example
    ///
    /// ```{rust,ignore}
    /// fn handler (request: Request, response: &mut Response) {
    ///     response.send("This matches a DELETE request to /a/delete/request");
    /// };
    /// server.delete("/a/delete/request", handler);
    /// ```
    /// Take a look at `get(...)` for a more detailed description.
    pub fn delete(&mut self, uri: &str, handler: fn(request: &Request, response: &mut Response)){
        self.register_route_with_new_router(Delete, uri, handler);
    }

    fn register_route_with_new_router(&mut self, method: Method, uri: &str, handler: fn(request: &Request, response: &mut Response)) {
        let mut router = Router::new();
        router.add_route(method, String::from_str(uri), handler);
        self.utilize(router);
    }

    /// Registers an error handler which will be invoked among other error handler
    /// as soon as any regular handler returned an error
    ///
    /// A error handler is nearly identical to a regular middleware handler with the only
    /// difference that it takes an additional error parameter or type `NickelError.
    ///
    /// # Example
    ///
    /// ```{rust,ignore}
    /// fn error_handler (err: &NickelError, req: &Request, res: &mut Response) -> Result<Action, NickelError>{
    ///    match err.kind {
    ///        ErrorWithStatusCode(NotFound) => {
    ///            response.origin.headers.content_type = get_media_type("html");
    ///            response.origin.status = NotFound;
    ///            response.send("<h1>Call the police!<h1>");
    ///            Ok(Halt)
    ///        },
    ///        _ => Ok(Continue)
    ///    }
    /// }
    /// ```
    pub fn handle_error<T: ErrorHandler>(&mut self, handler: T){
        self.middleware_stack.add_error_handler(handler);
    }

    /// Create a new middleware to serve files from within a given root directory.
    /// The file to serve will be determined by combining the requested Url with
    /// the provided root directory.
    ///
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut server = Nickel::new();
    /// server.utilize(Nickel::static_files("/path/to/serve/"));
    /// ```
    pub fn static_files(root_path: &str) -> StaticFilesHandler {
        StaticFilesHandler::new(root_path)
    }

    /// Create a new middleware to serve as a router.
    ///
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut server = Nickel::new();
    /// let mut router = Nickel::router();
    ///
    /// router.get("/foo", foo_handler);
    /// server.utilize(router);
    /// ```
    pub fn router() -> Router {
        Router::new()
    }

    /// Create a new middleware to parse JSON bodies.
    ///
    ///
    /// # Example
    /// ```{rust}
    /// # #![feature(phase)]
    /// # #[phase(plugin)] extern crate nickel_macros;
    /// # extern crate nickel;
    /// # extern crate serialize;
    /// # use nickel::{Nickel, Request, Response};
    /// use nickel::JsonBody;
    ///
    /// # fn main() {
    /// #[deriving(Decodable, Encodable)]
    /// struct Person {
    ///     first_name: String,
    ///     last_name:  String,
    /// }
    ///
    /// let router = router! {
    ///     post "/a/post/request" => |request, response| {
    ///         let person = request.json_as::<Person>().unwrap();
    ///         let text = format!("Hello {} {}", person.first_name, person.last_name);
    ///         response.send(text);
    ///     }
    /// };
    ///
    /// let mut server = Nickel::new();
    /// // It is currently a requirement that the json_body_parser middleware
    /// // is added before any routes that require it.
    /// server.utilize(Nickel::json_body_parser());
    /// server.utilize(router);
    /// # }
    /// ```
    pub fn json_body_parser() -> JsonBodyParser {
        JsonBodyParser
    }

    /// Create a new middleware to parse the query string.
    ///
    ///
    /// # Example
    /// ```{rust}
    /// # #![feature(phase)]
    /// # #[phase(plugin)] extern crate nickel_macros;
    /// # extern crate nickel;
    /// # use nickel::{Nickel, Request, Response};
    /// use nickel::QueryString;
    /// # fn main() {
    /// let router = router! {
    ///     get "/a/get/request" => |request, response| {
    ///         let foo = request.query("foo", "this is the default value, if foo is not present!");
    ///         response.send(foo[0].as_slice());
    ///     }
    /// };
    ///
    /// let mut server = Nickel::new();
    /// // It is currently a requirement that the query_string middleware
    /// // is added before any routes that require it.
    /// server.utilize(Nickel::query_string());
    /// server.utilize(router);
    /// # }
    /// ```
    pub fn query_string() -> QueryStringParser {
        QueryStringParser
    }

    /// Bind and listen for connections on the given host and port
    ///
    /// # Example
    /// ```{rust,ignore}
    /// let mut server = Nickel::new();
    /// server.listen(Ipv4Addr(127, 0, 0, 1), 6767);
    /// ```
    pub fn listen(mut self, ip: IpAddr, port: Port) {
        fn not_found_handler(_request: &Request, _response: &mut Response) -> Result<Action, NickelError> {
            Err(NickelError::new("File Not Found", ErrorWithStatusCode(NotFound)))
        }

        self.middleware_stack.add_middleware(IntoMiddleware::from_fn(not_found_handler));
        self.server = Some(Server::new(self.middleware_stack, ip, port));
        self.server.unwrap().serve();
    }
}
<|endoftext|>