<commit_before>#![feature(macro_rules)]
#![feature(slicing_syntax)]
#![feature(default_type_params)]
#![allow(unused_variables)]
#![allow(dead_code)]

//! # Rules
//! Rules uses regular expressions to do pattern matching using syntax
//! based upon the Perl 6 regex grammar. The Perl 6 grammar has been heavily
//! revised from Perl 5 and should not be equated with it. This may look
//! nothing like any regex you have seen before.
//!
//! # Syntax
//!
//! Currently, this is designed for ASCII and may not behave properly
//! with Unicode.
//!
//! Whitespace is generally ignored to so that a regex can be more readable
//! and less dense.
//!
//! ```rust
//! r"fred"    // Normal way
//! r"f r e d" // Completely equivalent
//! // Will match `apples_oranges` or any other deliminator
//! r"apples . oranges"
//! ```
//!
//! # Set operators
//!
//! These operators can be applied to groups which will be analyzed later:
//!
//! ```plain
//! +       Union                // [123] + [345] = [12345]
//! |       Union                // Same
//! &       Intersection         // [123] & [345] = [3]
//! -       Complement           // [123] - [345] = [1]
//! ^       Symmetric difference // [123] ^ [345] = [1245]
//! ```
//!
//! # Character classes
//!
//! ## Default character classes
//!
//! Character | Matches               | Inverse
//! ----------|-----------------------|--------
//! `.`       | Any character         | N/A
//! `\d`      | Digit                 | `\D`
//! `\h`      | Horizontal whitespace | `\H`
//! `\n`      | Newline               | `\N`
//! `\s`      | Any whitespace        | `\S`
//! `\t`      | Tab                   | `\T`
//! `\w`      | Alphanumeric or `_`   | `\W`
//!
//! ## Custom character classes
//!
//! Characters inside a set of `<[ ]>` form a custom character
//! class:
//!
//! ```plain
//! // Matches `a` or `b` or `c`
//! <[ a b c ]>
//!
//! // `..` expresses a range so this matches
//! // from `a` to `g` or a digit
//! <[ a .. g \d ]>
//!
//! // The `[]` bind the sets together into (non-capturing)
//! // groups so set operators can be used.
//! <[0-9] - [13579]> // Matches an even number
//! <\d - [13579]>    // Same
//! <[0-6] ^ [5-9]>   // Matches a `5` or `6`
//! ```
//!
//! # Comments
//!
//! Comments are allowed inside a regex.
//!
//! ```rust
//! // This matches `myregex`
//! r"my // This is a comment which goes to the end of the line
//! regex"
//! ```

use std::fmt;

#[macro_export]
macro_rules! matches(
    ($expression: expr, $($pattern:pat)|+) => (
        matches!($expression, $($pattern)|+ if true)
    );
    ($expression: expr, $($pattern:pat)|+ if $guard: expr) => (
        match $expression {
            $($pattern)|+ => $guard,
            _ => false
        }
    );
);

enum Mode {
    Match,
    Scan,
}

struct CharSet {
    chars: String,
    include: bool,
}

// Types
enum Ty {
    Group(Group),
    Meta(Meta),
    Op(Op),
}

impl fmt::Show for Ty {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Ty::Group(ref ty) => write!(f, "{}", ty),
            Ty::Meta(ref ty)  => write!(f, "{}", ty),
            Ty::Op(ref ty)    => write!(f, "{}", ty),
        }
    }
}

enum Op {
    Ellipsis,                  // ..
    SetDifference,             // -
    SetSymmetricDifference,    // ^
    SetIntersection,           // &
    SetUnion,                  // + or |
}

impl fmt::Show for Op {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Op::Ellipsis => write!(f, ".."),
            Op::SetDifference => write!(f, "-"),
            Op::SetSymmetricDifference => write!(f, "^"),
            Op::SetIntersection => write!(f, "&"),
            Op::SetUnion => write!(f, "+"),
        }
    }
}

enum Group {
//    Capture(Vec<char>),         // ()
    NonCapture(Vec<Ty>), // []
    CharClass(Vec<Ty>),  // <[]>
    Literal(Vec<char>),         // '' or ""
}

impl fmt::Show for Group {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Group::NonCapture(ref vec) => write!(f, "{}", vec),
            Group::CharClass(ref vec)  => write!(f, "<{}>", vec),
            Group::Literal(ref vec)    => write!(f, "{}", vec),
        }
    }
}

// Meta characters are characters which need to be escaped
// to match themselves. For example: `\.` matches a period.
// `.` matches anything.
enum Meta {
    Char(char),             // a b c etc.
    Digit(bool),            // \d
    Dot,                    // .
    Newline(bool),          // \n
    Tab(bool),              // \t
    Whitespace(bool),       // \s
    HWhitespace(bool),      // \h
    Word(bool),             // \w
}

impl fmt::Show for Meta {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Meta::Char(ty) => write!(f, "{}", ty),
            Meta::Digit(ty) => write!(f, "digit({})", ty),
            _ => write!(f, "unimplemented"),
        }
    }
}

/*impl PartialEq<char> for Meta {
    fn eq(&self, c: &char) -> bool {
        match *self {
            Meta::Char(s) => s == *c,
            Meta::Digit(digit) => {
                let res = matches!(*c, '0' ... '9');
                if digit { res } else { !res }
            },
            Meta::Dot => { true },
            Meta::Tab(tab) => {
                let res = matches!(*c, '\t');
                if tab { res } else { !res }
            },
            Meta::Whitespace(white) => {
                let res = matches!(*c, ' ' | '\t' | '\n');
                if white { res } else { !res }
            },
            Meta::HWhitespace(h_white) => {
                let res = matches!(*c, ' ' | '\t');
                if h_white { res } else { !res }
            },
            Meta::Newline(is) => {
                let res = matches!(*c, '\n');
                if is { res } else { !res }
            },
            Meta::Word(word) => {
                let res = matches!(*c, 'a' ... 'z' |
                                       'A' ... 'Z' |
                                       '0' ... '9' |
                                       '_' );
                if word { res } else { !res }
            },
        }
    }

    fn data(&self) -> CharSet {
        match *self {
            Meta::Char(c)     => CharSet { Chars: String::from_char(1, c), Include: true },
            Meta::Digit(test) => CharSet { Chars: "0123456789".to_string(), Include: test },
            Meta::Dot         => CharSet { Chars: "".to_string(), Include: false },

        }
    }
}*/

impl Meta {
    // Push characters between first 2 `'` or `"` sets into Literal.
    fn literal(open: char, chars: &mut Iterator<char>) -> Ty {
        let mut vec = vec![];

        while let Some(c) = chars.next() {
            match c {
                _ if c == open => return Ty::Group(Group::Literal(vec)),
                c => vec.push(c),
            }
        }

        // Characters ran out before literal was closed with ' or ".
		panic!(r"The sets of {} are unbalanced.", open);
    }

    fn char_class(chars: &mut Iterator<char>) -> Ty {
        let mut vec = vec![];

        while let Some(c) = chars.next() {
            match c {
                // Ignore whitespace
                ' ' | '\t' | '\n' => continue,

                // Set operators
                '-' => vec.push(Ty::Op(Op::SetDifference)),
                '^' => vec.push(Ty::Op(Op::SetSymmetricDifference)),
                '&' => vec.push(Ty::Op(Op::SetIntersection)),
                '+' => vec.push(Ty::Op(Op::SetUnion)),

                '[' => vec.push(Meta::non_capture(chars)),
                '>' => return Ty::Group(Group::CharClass(vec)),
                _   => panic!("`{}` is not valid inside a character class \
and outside a group.", c),
            }
        }

		panic!(r"Missing a `>` char.");
    }

    fn non_capture(chars: &mut Iterator<char>) -> Ty {
        let mut vec = vec![];

        while let Some(c) = chars.next() {
            match c {
                // Ignore whitespace
                ' ' | '\t' | '\n' => continue,

                'a' ... 'z' | 'A' ... 'Z' | '0' ... '9' | '_'
                            => vec.push(Ty::Meta(Meta::Char(c))),
                '.'  | '\\' => vec.push(Meta::single(c, chars)),
                ']'         => return Ty::Group(Group::NonCapture(vec)),
                c           => panic!("`{}` is an invalid in this position.", c),
            }
        }

		panic!(r"The sets of `]` are unbalanced.");
    }

    // Multiple characters which represent a single symbol.
    fn single(open: char, chars: &mut Iterator<char>) -> Ty {
        match (open, chars.next().expect("Another character is expected.")) {
            // Default character classes
            ('\\', 'd') => Ty::Meta(Meta::Digit(true)),
            ('\\', 'D') => Ty::Meta(Meta::Digit(false)),
            ('\\', 'n') => Ty::Meta(Meta::Newline(true)),
            ('\\', 'N') => Ty::Meta(Meta::Newline(false)),
            ('\\', 't') => Ty::Meta(Meta::Tab(true)),
            ('\\', 'T') => Ty::Meta(Meta::Tab(false)),
            ('\\', 's') => Ty::Meta(Meta::Whitespace(true)),
            ('\\', 'S') => Ty::Meta(Meta::Whitespace(false)),
            ('\\', 'h') => Ty::Meta(Meta::HWhitespace(true)),
            ('\\', 'H') => Ty::Meta(Meta::HWhitespace(false)),
            ('\\', 'w') => Ty::Meta(Meta::Word(true)),
            ('\\', 'W') => Ty::Meta(Meta::Word(false)),
            ('\\', c)   => Ty::Meta(Meta::Char(c)),

            ('.', '.')  => Ty::Op(Op::Ellipsis),
            (a, b)      => panic!(r"`{}{}` is not a valid sequence.", a, b),
        }
    }
    /*fn simplify(class: &mut Meta) -> Meta {
        let mut loc = None;
        for (i, element) in class.iter().enumerate() {
            match element {
                Meta::Union => {
                    loc = Some(i);
                    break;
                },
                _ => {},
            }
        }

    }*/
}

#[deriving(Show)]
pub struct Rule {
    regex: Vec<Ty>,
}

impl Rule {
    pub fn new(s: &str) -> Result<Rule, &'static str> {
        let mut chars = s.chars();
        let mut regex = vec![];

        while let Some(c) = chars.next() {
            match c {
                'a' ... 'z' | 'A' ... 'Z' | '0' ... '9' | '_'
                           => regex.push(Ty::Meta(Meta::Char(c))),
                '.'        => regex.push(Ty::Meta(Meta::Dot)),
                ' ' | '\t' | '\n' => continue,
                '\\'       => regex.push(Meta::single(c, &mut chars)),
                '\'' | '"' => regex.push(Meta::literal(c, &mut chars)),
                '<'        => regex.push(Meta::char_class(&mut chars)),
                '['        => regex.push(Meta::non_capture(&mut chars)),
                _          => continue,
            }
        }
        println!("regex: {}", regex[0]);
        //Meta::simplify(&mut vec[0]);
        Ok(Rule { regex: regex })
    }

    /*pub fn is_match(self, s: &str) -> bool {
        let mut chars = s.chars();
        let mut mode = Mode::Scan;

        loop {
            match mode {
                Mode::Match => {
                    let mut first = true;
                    for regex in self.regex.iter() {
                        // Scan already checked first character so skip iteration.
                        if first {
                            first = false;
                            continue;
                        }

                        if let Some(c) = chars.next() {
                            println!("c: {}, regex: {}", c, regex);
                            // Issue 19035: swapping cmp order breaks code
                            if *regex != c  {
                                mode = Mode::Scan;
                                break;
                            }
                        }
                    }

                    // If finished checking without needing further scanning,
                    // then it found a match.
                    if let Mode::Match = mode { return true; }
                },
                Mode::Scan => {
                    while let Some(c) = chars.next() {
                        // Issue 19035: swapping cmp order breaks code
                        if self.regex[0] == c {
                            mode = Mode::Match;
                            break;
                        }
                    }

                    // If finished scanning string but no match, there isn't a match.
                    if let Mode::Scan = mode { return false; }
                },
            };
        };
    }*/
}

<commit_msg>Default character classes now have characters specified. And tested! Not just matched against.<commit_after>#![feature(macro_rules)]
#![feature(slicing_syntax)]
#![feature(default_type_params)]
#![allow(unused_variables)]
#![allow(dead_code)]

//! # Rules
//! Rules uses regular expressions to do pattern matching using syntax
//! based upon the Perl 6 regex grammar. The Perl 6 grammar has been heavily
//! revised from Perl 5 and should not be equated with it. This may look
//! nothing like any regex you have seen before.
//!
//! # Syntax
//!
//! Currently, this is designed for ASCII and may not behave properly
//! with Unicode.
//!
//! Whitespace is generally ignored to so that a regex can be more readable
//! and less dense.
//!
//! ```rust
//! r"fred"    // Normal way
//! r"f r e d" // Completely equivalent
//! // Will match `apples_oranges` or any other deliminator
//! r"apples . oranges"
//! ```
//!
//! # Set operators
//!
//! These operators can be applied to groups which will be analyzed later:
//!
//! ```plain
//! +       Union                // [123] + [345] = [12345]
//! |       Union                // Same
//! &       Intersection         // [123] & [345] = [3]
//! -       Complement           // [123] - [345] = [1]
//! ^       Symmetric difference // [123] ^ [345] = [1245]
//! ```
//!
//! # Character classes
//!
//! ## Default character classes
//!
//! Character | Matches               | Inverse
//! ----------|-----------------------|--------
//! `.`       | Any character         | N/A
//! `\d`      | Digit                 | `\D`
//! `\h`      | Horizontal whitespace | `\H`
//! `\n`      | Newline               | `\N`
//! `\s`      | Any whitespace        | `\S`
//! `\t`      | Tab                   | `\T`
//! `\w`      | Alphanumeric or `_`   | `\W`
//!
//! ## Custom character classes
//!
//! Characters inside a set of `<[ ]>` form a custom character
//! class:
//!
//! ```plain
//! // Matches `a` or `b` or `c`
//! <[ a b c ]>
//!
//! // `..` expresses a range so this matches
//! // from `a` to `g` or a digit
//! <[ a .. g \d ]>
//!
//! // The `[]` bind the sets together into (non-capturing)
//! // groups so set operators can be used.
//! <[0-9] - [13579]> // Matches an even number
//! <\d - [13579]>    // Same
//! <[0-6] ^ [5-9]>   // Matches a `5` or `6`
//! ```
//!
//! # Comments
//!
//! Comments are allowed inside a regex.
//!
//! ```rust
//! // This matches `myregex`
//! r"my // This is a comment which goes to the end of the line
//! regex"
//! ```

use std::fmt;

#[macro_export]
macro_rules! matches(
    ($expression: expr, $($pattern:pat)|+) => (
        matches!($expression, $($pattern)|+ if true)
    );
    ($expression: expr, $($pattern:pat)|+ if $guard: expr) => (
        match $expression {
            $($pattern)|+ => $guard,
            _ => false
        }
    );
);

enum Mode {
    Match,
    Scan,
}

struct CharSet {
    chars: String,
    // If true include the exact contents. Otherwise, include
    // everything *not* inside `chars`.
    include: bool,
}

impl CharSet {
    fn new(meta: Meta) -> CharSet {
        match meta {
            Meta::Char(c)           => CharSet { chars: String::from_char(1, c), include: true },
            Meta::Digit(test)       => CharSet { chars: "0123456789".to_string(), include: test },
            Meta::Dot               => CharSet { chars: "".to_string(), include: false },
            Meta::Newline(test)     => CharSet { chars: "\n".to_string(), include: test },
            Meta::Tab(test)         => CharSet { chars: "\t".to_string(), include: test },
            Meta::Whitespace(test)  => CharSet { chars: " \t\n".to_string(), include: test },
            Meta::HWhitespace(test) => CharSet { chars: " \t".to_string(), include: test },
            Meta::Word(test)        => CharSet { chars:
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".to_string(),
                include: test },
        }
    }
}

// Types
enum Ty {
    Group(Group),
    Meta(Meta),
    Op(Op),
}

impl fmt::Show for Ty {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Ty::Group(ref ty) => write!(f, "{}", ty),
            Ty::Meta(ref ty)  => write!(f, "{}", ty),
            Ty::Op(ref ty)    => write!(f, "{}", ty),
        }
    }
}

enum Op {
    Ellipsis,                  // ..
    SetDifference,             // -
    SetSymmetricDifference,    // ^
    SetIntersection,           // &
    SetUnion,                  // + or |
}

impl fmt::Show for Op {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Op::Ellipsis => write!(f, ".."),
            Op::SetDifference => write!(f, "-"),
            Op::SetSymmetricDifference => write!(f, "^"),
            Op::SetIntersection => write!(f, "&"),
            Op::SetUnion => write!(f, "+"),
        }
    }
}

enum Group {
//    Capture(Vec<char>),         // ()
    NonCapture(Vec<Ty>), // []
    CharClass(Vec<Ty>),  // <[]>
    Literal(Vec<char>),         // '' or ""
}

impl fmt::Show for Group {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Group::NonCapture(ref vec) => write!(f, "{}", vec),
            Group::CharClass(ref vec)  => write!(f, "<{}>", vec),
            Group::Literal(ref vec)    => write!(f, "{}", vec),
        }
    }
}

// Meta characters are characters which need to be escaped
// to match themselves. For example: `\.` matches a period.
// `.` matches anything.
enum Meta {
    Char(char),             // a b c etc.
    Digit(bool),            // \d
    Dot,                    // .
    Newline(bool),          // \n
    Tab(bool),              // \t
    Whitespace(bool),       // \s
    HWhitespace(bool),      // \h
    Word(bool),             // \w
}

impl fmt::Show for Meta {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Meta::Char(ty) => write!(f, "{}", ty),
            Meta::Digit(ty) => write!(f, "digit({})", ty),
            _ => write!(f, "unimplemented"),
        }
    }
}

impl PartialEq<char> for Meta {
    fn eq(&self, c: &char) -> bool {
        match *self {
            Meta::Char(s) => s == *c,
            Meta::Digit(digit) => {
                let res = matches!(*c, '0' ... '9');
                if digit { res } else { !res }
            },
            Meta::Dot => { true },
            Meta::Tab(tab) => {
                let res = matches!(*c, '\t');
                if tab { res } else { !res }
            },
            Meta::Whitespace(white) => {
                let res = matches!(*c, ' ' | '\t' | '\n');
                if white { res } else { !res }
            },
            Meta::HWhitespace(h_white) => {
                let res = matches!(*c, ' ' | '\t');
                if h_white { res } else { !res }
            },
            Meta::Newline(is) => {
                let res = matches!(*c, '\n');
                if is { res } else { !res }
            },
            Meta::Word(word) => {
                let res = matches!(*c, 'a' ... 'z' |
                                       'A' ... 'Z' |
                                       '0' ... '9' |
                                       '_' );
                if word { res } else { !res }
            },
        }
    }

}

impl Meta {
    // Push characters between first 2 `'` or `"` sets into Literal.
    fn literal(open: char, chars: &mut Iterator<char>) -> Ty {
        let mut vec = vec![];

        while let Some(c) = chars.next() {
            match c {
                _ if c == open => return Ty::Group(Group::Literal(vec)),
                c => vec.push(c),
            }
        }

        // Characters ran out before literal was closed with ' or ".
		panic!(r"The sets of {} are unbalanced.", open);
    }

    fn char_class(chars: &mut Iterator<char>) -> Ty {
        let mut vec = vec![];

        while let Some(c) = chars.next() {
            match c {
                // Ignore whitespace
                ' ' | '\t' | '\n' => continue,

                // Set operators
                '-' => vec.push(Ty::Op(Op::SetDifference)),
                '^' => vec.push(Ty::Op(Op::SetSymmetricDifference)),
                '&' => vec.push(Ty::Op(Op::SetIntersection)),
                '+' => vec.push(Ty::Op(Op::SetUnion)),

                '[' => vec.push(Meta::non_capture(chars)),
                '>' => return Ty::Group(Group::CharClass(vec)),
                _   => panic!("`{}` is not valid inside a character class \
and outside a group.", c),
            }
        }

		panic!(r"Missing a `>` char.");
    }

    fn non_capture(chars: &mut Iterator<char>) -> Ty {
        let mut vec = vec![];

        while let Some(c) = chars.next() {
            match c {
                // Ignore whitespace
                ' ' | '\t' | '\n' => continue,

                'a' ... 'z' | 'A' ... 'Z' | '0' ... '9' | '_'
                            => vec.push(Ty::Meta(Meta::Char(c))),
                '.'  | '\\' => vec.push(Meta::single(c, chars)),
                ']'         => return Ty::Group(Group::NonCapture(vec)),
                c           => panic!("`{}` is an invalid in this position.", c),
            }
        }

		panic!(r"The sets of `]` are unbalanced.");
    }

    // Multiple characters which represent a single symbol.
    fn single(open: char, chars: &mut Iterator<char>) -> Ty {
        match (open, chars.next().expect("Another character is expected.")) {
            // Default character classes
            ('\\', 'd') => Ty::Meta(Meta::Digit(true)),
            ('\\', 'D') => Ty::Meta(Meta::Digit(false)),
            ('\\', 'n') => Ty::Meta(Meta::Newline(true)),
            ('\\', 'N') => Ty::Meta(Meta::Newline(false)),
            ('\\', 't') => Ty::Meta(Meta::Tab(true)),
            ('\\', 'T') => Ty::Meta(Meta::Tab(false)),
            ('\\', 's') => Ty::Meta(Meta::Whitespace(true)),
            ('\\', 'S') => Ty::Meta(Meta::Whitespace(false)),
            ('\\', 'h') => Ty::Meta(Meta::HWhitespace(true)),
            ('\\', 'H') => Ty::Meta(Meta::HWhitespace(false)),
            ('\\', 'w') => Ty::Meta(Meta::Word(true)),
            ('\\', 'W') => Ty::Meta(Meta::Word(false)),
            ('\\', c)   => Ty::Meta(Meta::Char(c)),

            ('.', '.')  => Ty::Op(Op::Ellipsis),
            (a, b)      => panic!(r"`{}{}` is not a valid sequence.", a, b),
        }
    }
    /*fn simplify(class: &mut Meta) -> Meta {
        let mut loc = None;
        for (i, element) in class.iter().enumerate() {
            match element {
                Meta::Union => {
                    loc = Some(i);
                    break;
                },
                _ => {},
            }
        }

    }*/
}

#[deriving(Show)]
pub struct Rule {
    regex: Vec<Ty>,
}

impl Rule {
    pub fn new(s: &str) -> Result<Rule, &'static str> {
        let mut chars = s.chars();
        let mut regex = vec![];

        while let Some(c) = chars.next() {
            match c {
                'a' ... 'z' | 'A' ... 'Z' | '0' ... '9' | '_'
                           => regex.push(Ty::Meta(Meta::Char(c))),
                '.'        => regex.push(Ty::Meta(Meta::Dot)),
                ' ' | '\t' | '\n' => continue,
                '\\'       => regex.push(Meta::single(c, &mut chars)),
                '\'' | '"' => regex.push(Meta::literal(c, &mut chars)),
                '<'        => regex.push(Meta::char_class(&mut chars)),
                '['        => regex.push(Meta::non_capture(&mut chars)),
                _          => continue,
            }
        }
        println!("regex: {}", regex[0]);
        //Meta::simplify(&mut vec[0]);
        Ok(Rule { regex: regex })
    }

    /*pub fn is_match(self, s: &str) -> bool {
        let mut chars = s.chars();
        let mut mode = Mode::Scan;

        loop {
            match mode {
                Mode::Match => {
                    let mut first = true;
                    for regex in self.regex.iter() {
                        // Scan already checked first character so skip iteration.
                        if first {
                            first = false;
                            continue;
                        }

                        if let Some(c) = chars.next() {
                            println!("c: {}, regex: {}", c, regex);
                            // Issue 19035: swapping cmp order breaks code
                            if *regex != c  {
                                mode = Mode::Scan;
                                break;
                            }
                        }
                    }

                    // If finished checking without needing further scanning,
                    // then it found a match.
                    if let Mode::Match = mode { return true; }
                },
                Mode::Scan => {
                    while let Some(c) = chars.next() {
                        // Issue 19035: swapping cmp order breaks code
                        if self.regex[0] == c {
                            mode = Mode::Match;
                            break;
                        }
                    }

                    // If finished scanning string but no match, there isn't a match.
                    if let Mode::Scan = mode { return false; }
                },
            };
        };
    }*/
}

#[cfg(test)]
mod test {
    use super::{CharSet, Meta};

    #[test]
    fn charset_alphanumerics_is_accurate() {

        let CharSet { chars: digits, .. }   = CharSet::new(Meta::Digit(true));
        let CharSet { chars: alphabet, .. } = CharSet::new(Meta::Word(true));

        let mut new_alphabet = vec![];
        let mut new_digits   = vec![];

        for i in range(97, 123u8) { // a-z
            new_alphabet.push(i as char);
        }
        for i in range(65, 91u8) {  // A-Z
            new_alphabet.push(i as char);
        }
        for i in range(48, 58u8) {  // 0-9
            new_alphabet.push(i as char);
            new_digits.push(i as char);
        }

        new_alphabet.push(95u8 as char);   // _

        // Check that typed alphabet is the same as computed
        for (a1, a2) in alphabet.chars().zip(new_alphabet.iter()) {
            assert_eq!(a1, *a2);
        }

        // Check that typed digits are the same as computed
        for (d1, d2) in digits.chars().zip(new_digits.iter()) {
            assert_eq!(d1, *d2);
        }
    }
}

<|endoftext|>


<commit_before>#![feature(vec_push_all)]

pub struct JsonEncoder {
    buffer: Vec<u8>
}

impl JsonEncoder {
    pub fn new() -> JsonEncoder {
        JsonEncoder{buffer: Vec::new()}
    }

    #[inline(always)]
    pub fn encode_raw(&mut self, raw: &[u8]) {
        self.buffer.push_all(raw);
    }

    pub fn into_vec(self) -> Vec<u8> {
        self.buffer
    }

    pub fn with_buf<F>(&mut self, f: F) where F: Fn(&mut Vec<u8>) {
        f(&mut self.buffer);
    }

    #[inline(always)]
    pub fn encode_str_noescape(&mut self, raw_str: &str) {
        self.buffer.push(b'"');
        self.buffer.push_all(raw_str.as_bytes());
        self.buffer.push(b'"');
    }

    fn escape_bytes(&mut self, bytes: &[u8]) {
        let mut start = 0;

        for (i, byte) in bytes.iter().enumerate() {
            let escaped = match *byte {
                b'"' => b"\\\"",
                b'\\' => b"\\\\",
                b'\x08' => b"\\b",
                b'\x0c' => b"\\f",
                b'\n' => b"\\n",
                b'\r' => b"\\r",
                b'\t' => b"\\t",
                _ => {
                    continue;
                }
            };

            if start < i {
                self.encode_raw(&bytes[start..i]);
            }

            self.encode_raw(escaped);

            start = i + 1;
        }

        if start != bytes.len() {
            self.encode_raw(&bytes[start..]);
        }
    }

    pub fn encode_decimal_str(&mut self, value: u64) {
        self.buffer.push(b'"');
        self.encode_u64_decimal(value);
        self.buffer.push(b'"');
    }

    // encodes as decimal string
    #[inline(always)]
    fn encode_u64_decimal(&mut self, value: u64) {
        const CHARS: &'static [u8] = b"0123456789";
        const MAX_DIGITS: usize = 20;

        if value == 0 {
            self.buffer.push(b'0');
            return;
        }

        let mut digits: [u8; MAX_DIGITS] = [b'0'; MAX_DIGITS];
        let mut i = MAX_DIGITS;
        let mut n = value;
        while n > 0 {
            i -= 1;
            digits[i] = CHARS[(n % 10) as usize];
            n = n / 10;
        }

        self.encode_raw(&digits[i..]);
    }

    #[inline(always)]
    pub fn encode_str(&mut self, s: &str) {
        self.buffer.push(b'"');
        self.escape_bytes(s.as_bytes());
        self.buffer.push(b'"');
    }

    #[inline(always)]
    pub fn encode_i32(&mut self, value: i32) {
        if value == 0 {
            self.buffer.push(b'0');
        } else if value > 0 {
            self.encode_u31(value as u32);
        } else {
            self.buffer.push(b'-');
            self.encode_u31((-value) as u32);
        }
    }

    // encodes a 31-bit unsigned integer != 0
    fn encode_u31(&mut self, value: u32) {
        const CHARS: &'static [u8] = b"0123456789";
        const MAX_DIGITS: usize = 10;
        debug_assert!(value != 0);

        let mut digits: [u8; MAX_DIGITS] = [b'0'; MAX_DIGITS];
        let mut i = MAX_DIGITS;
        let mut n = value;
        while n > 0 {
            i -= 1;
            digits[i] = CHARS[(n % 10) as usize];
            n = n / 10;
        }

        self.encode_raw(&digits[i..]);
    }

    pub fn encode_obj<F>(&mut self, f: F) where F: Fn(&mut JsonObjectEncoder) {
        self.buffer.push(b'{');
        {
            f(&mut JsonObjectEncoder {js: self, needs_sep: false});
        }
        self.buffer.push(b'}');
    }

    pub fn encode_array<F>(&mut self, f: F) where F: Fn(&mut JsonArrayEncoder) {
        self.buffer.push(b'[');
        {
            f(&mut JsonArrayEncoder {js: self, needs_sep: false});
        }
        self.buffer.push(b']');
    }

}

pub struct JsonObjectEncoder<'a> {
    js: &'a mut JsonEncoder,
    needs_sep: bool,
}

impl<'a> JsonObjectEncoder<'a> {
    // XXX: name MAY NOT include escapable characters
    #[inline(always)]
    pub fn encode_field<F:Fn(&mut JsonEncoder)>(&mut self, name: &str, f: F) {
        if self.needs_sep {
            self.js.buffer.push(b',');
        } else {
            self.needs_sep = true;
        }
        self.js.encode_str_noescape(name);
        self.js.buffer.push(b':');

        f(self.js);
    }

    #[inline(always)]
    pub fn encode_field_array<F:Fn(&mut JsonArrayEncoder)>(&mut self, name: &str, f: F) {
        self.encode_field(name, |js| js.encode_array(|jsa| f(jsa)));
    }

    #[inline(always)]
    pub fn encode_field_i32(&mut self, name: &str, val: i32) {
        self.encode_field(name, |js| js.encode_i32(val));
    }

    #[inline(always)]
    pub fn encode_field_str(&mut self, name: &str, s: &str) {
        self.encode_field(name, |js| js.encode_str(s));
    }

}

pub struct JsonArrayEncoder<'a> {
    js: &'a mut JsonEncoder,
    needs_sep: bool,
}

impl<'a> JsonArrayEncoder<'a> {
    #[inline(always)]
    pub fn encode_elm<F:Fn(&mut JsonEncoder)>(&mut self, f: F) {
        if self.needs_sep {
            self.js.buffer.push(b',');
        } else {
            self.needs_sep = true;
        }
        f(self.js);
    }

    #[inline(always)]
    pub fn encode_elm_i32(&mut self, val: i32) {
        self.encode_elm(|js| js.encode_i32(val));
    }

    #[inline(always)]
    pub fn encode_elm_str(&mut self, s: &str) {
        self.encode_elm(|js| js.encode_str(s));
    }

    #[inline(always)]
    pub fn encode_elm_obj<F:Fn(&mut JsonObjectEncoder)>(&mut self, f: F) {
        self.encode_elm(|js| js.encode_obj(|jso| f(jso)));
    }
}

#[test]
fn test_json_obj_encoder() {
    use std::str;

    let mut js = JsonEncoder::new();
    js.encode_obj(|_|{});
    assert_eq!(b"{}", &js.into_vec()[..]);

    let mut js = JsonEncoder::new();
    js.encode_obj(|jso| {
        jso.encode_field("total", |js| js.encode_i32(31));
    });
    assert_eq!(b"{\"total\":31}", &js.into_vec()[..]);

    let mut js = JsonEncoder::new();
    js.encode_obj(|jso| {
        jso.encode_field("total", |js| js.encode_i32(31));
        jso.encode_field("next", |js| js.encode_str("abc"));
    });
    assert_eq!(b"{\"total\":31,\"next\":\"abc\"}", &js.into_vec()[..]);

    let mut js = JsonEncoder::new();
    js.encode_obj(|jso| {
        jso.encode_field("total", |js| js.encode_i32(31));
        jso.encode_field("next", |js| js.encode_str("abc"));
        jso.encode_field("tags", |js| {
                js.encode_array(|jsa| {
                        jsa.encode_elm(|js| js.encode_i32(1));
                        jsa.encode_elm(|js| js.encode_i32(2));
                });
        });
    });
    assert_eq!("{\"total\":31,\"next\":\"abc\",\"tags\":[1,2]}", str::from_utf8(&js.into_vec()[..]).unwrap());
}
<commit_msg>Add JsonEncoder::with_capacity<commit_after>#![feature(vec_push_all)]

pub struct JsonEncoder {
    buffer: Vec<u8>
}

impl JsonEncoder {
    #[inline(always)]
    pub fn new() -> JsonEncoder {
        JsonEncoder{buffer: Vec::new()}
    }

    #[inline(always)]
    pub fn with_capacity(capa: usize) -> JsonEncoder {
        JsonEncoder{buffer: Vec::with_capacity(capa)}
    }

    #[inline(always)]
    pub fn encode_raw(&mut self, raw: &[u8]) {
        self.buffer.push_all(raw);
    }

    pub fn into_vec(self) -> Vec<u8> {
        self.buffer
    }

    pub fn with_buf<F>(&mut self, f: F) where F: Fn(&mut Vec<u8>) {
        f(&mut self.buffer);
    }

    #[inline(always)]
    pub fn encode_str_noescape(&mut self, raw_str: &str) {
        self.buffer.push(b'"');
        self.buffer.push_all(raw_str.as_bytes());
        self.buffer.push(b'"');
    }

    fn escape_bytes(&mut self, bytes: &[u8]) {
        let mut start = 0;

        for (i, byte) in bytes.iter().enumerate() {
            let escaped = match *byte {
                b'"' => b"\\\"",
                b'\\' => b"\\\\",
                b'\x08' => b"\\b",
                b'\x0c' => b"\\f",
                b'\n' => b"\\n",
                b'\r' => b"\\r",
                b'\t' => b"\\t",
                _ => {
                    continue;
                }
            };

            if start < i {
                self.encode_raw(&bytes[start..i]);
            }

            self.encode_raw(escaped);

            start = i + 1;
        }

        if start != bytes.len() {
            self.encode_raw(&bytes[start..]);
        }
    }

    pub fn encode_decimal_str(&mut self, value: u64) {
        self.buffer.push(b'"');
        self.encode_u64_decimal(value);
        self.buffer.push(b'"');
    }

    // encodes as decimal string
    #[inline(always)]
    fn encode_u64_decimal(&mut self, value: u64) {
        const CHARS: &'static [u8] = b"0123456789";
        const MAX_DIGITS: usize = 20;

        if value == 0 {
            self.buffer.push(b'0');
            return;
        }

        let mut digits: [u8; MAX_DIGITS] = [b'0'; MAX_DIGITS];
        let mut i = MAX_DIGITS;
        let mut n = value;
        while n > 0 {
            i -= 1;
            digits[i] = CHARS[(n % 10) as usize];
            n = n / 10;
        }

        self.encode_raw(&digits[i..]);
    }

    #[inline(always)]
    pub fn encode_str(&mut self, s: &str) {
        self.buffer.push(b'"');
        self.escape_bytes(s.as_bytes());
        self.buffer.push(b'"');
    }

    #[inline(always)]
    pub fn encode_i32(&mut self, value: i32) {
        if value == 0 {
            self.buffer.push(b'0');
        } else if value > 0 {
            self.encode_u31(value as u32);
        } else {
            self.buffer.push(b'-');
            self.encode_u31((-value) as u32);
        }
    }

    // encodes a 31-bit unsigned integer != 0
    fn encode_u31(&mut self, value: u32) {
        const CHARS: &'static [u8] = b"0123456789";
        const MAX_DIGITS: usize = 10;
        debug_assert!(value != 0);

        let mut digits: [u8; MAX_DIGITS] = [b'0'; MAX_DIGITS];
        let mut i = MAX_DIGITS;
        let mut n = value;
        while n > 0 {
            i -= 1;
            digits[i] = CHARS[(n % 10) as usize];
            n = n / 10;
        }

        self.encode_raw(&digits[i..]);
    }

    pub fn encode_obj<F>(&mut self, f: F) where F: Fn(&mut JsonObjectEncoder) {
        self.buffer.push(b'{');
        {
            f(&mut JsonObjectEncoder {js: self, needs_sep: false});
        }
        self.buffer.push(b'}');
    }

    pub fn encode_array<F>(&mut self, f: F) where F: Fn(&mut JsonArrayEncoder) {
        self.buffer.push(b'[');
        {
            f(&mut JsonArrayEncoder {js: self, needs_sep: false});
        }
        self.buffer.push(b']');
    }

}

pub struct JsonObjectEncoder<'a> {
    js: &'a mut JsonEncoder,
    needs_sep: bool,
}

impl<'a> JsonObjectEncoder<'a> {
    // XXX: name MAY NOT include escapable characters
    #[inline(always)]
    pub fn encode_field<F:Fn(&mut JsonEncoder)>(&mut self, name: &str, f: F) {
        if self.needs_sep {
            self.js.buffer.push(b',');
        } else {
            self.needs_sep = true;
        }
        self.js.encode_str_noescape(name);
        self.js.buffer.push(b':');

        f(self.js);
    }

    #[inline(always)]
    pub fn encode_field_array<F:Fn(&mut JsonArrayEncoder)>(&mut self, name: &str, f: F) {
        self.encode_field(name, |js| js.encode_array(|jsa| f(jsa)));
    }

    #[inline(always)]
    pub fn encode_field_i32(&mut self, name: &str, val: i32) {
        self.encode_field(name, |js| js.encode_i32(val));
    }

    #[inline(always)]
    pub fn encode_field_str(&mut self, name: &str, s: &str) {
        self.encode_field(name, |js| js.encode_str(s));
    }

}

pub struct JsonArrayEncoder<'a> {
    js: &'a mut JsonEncoder,
    needs_sep: bool,
}

impl<'a> JsonArrayEncoder<'a> {
    #[inline(always)]
    pub fn encode_elm<F:Fn(&mut JsonEncoder)>(&mut self, f: F) {
        if self.needs_sep {
            self.js.buffer.push(b',');
        } else {
            self.needs_sep = true;
        }
        f(self.js);
    }

    #[inline(always)]
    pub fn encode_elm_i32(&mut self, val: i32) {
        self.encode_elm(|js| js.encode_i32(val));
    }

    #[inline(always)]
    pub fn encode_elm_str(&mut self, s: &str) {
        self.encode_elm(|js| js.encode_str(s));
    }

    #[inline(always)]
    pub fn encode_elm_obj<F:Fn(&mut JsonObjectEncoder)>(&mut self, f: F) {
        self.encode_elm(|js| js.encode_obj(|jso| f(jso)));
    }
}

#[test]
fn test_json_obj_encoder() {
    use std::str;

    let mut js = JsonEncoder::new();
    js.encode_obj(|_|{});
    assert_eq!(b"{}", &js.into_vec()[..]);

    let mut js = JsonEncoder::new();
    js.encode_obj(|jso| {
        jso.encode_field("total", |js| js.encode_i32(31));
    });
    assert_eq!(b"{\"total\":31}", &js.into_vec()[..]);

    let mut js = JsonEncoder::new();
    js.encode_obj(|jso| {
        jso.encode_field("total", |js| js.encode_i32(31));
        jso.encode_field("next", |js| js.encode_str("abc"));
    });
    assert_eq!(b"{\"total\":31,\"next\":\"abc\"}", &js.into_vec()[..]);

    let mut js = JsonEncoder::new();
    js.encode_obj(|jso| {
        jso.encode_field("total", |js| js.encode_i32(31));
        jso.encode_field("next", |js| js.encode_str("abc"));
        jso.encode_field("tags", |js| {
                js.encode_array(|jsa| {
                        jsa.encode_elm(|js| js.encode_i32(1));
                        jsa.encode_elm(|js| js.encode_i32(2));
                });
        });
    });
    assert_eq!("{\"total\":31,\"next\":\"abc\",\"tags\":[1,2]}", str::from_utf8(&js.into_vec()[..]).unwrap());
}
<|endoftext|>


<commit_before>extern crate rand;
use std::str;
use std::fmt;
use std::collections::VecDeque;
use rand::Rng;

#[derive(Debug, Eq, PartialEq, PartialOrd, Clone)]
pub struct Card {
    pub suit:  String,
    pub value: String,
}

#[derive(Debug, Eq, PartialEq, PartialOrd, Clone)]
pub struct Deck {
    pub cards: VecDeque<Card>
}

impl Card {
    pub fn new(suit: String, value: String) -> Card {
        Card { suit: suit, value: value.to_string() }
    }

    pub fn new_from_str(suit: &str, value: &str) -> Card {
        Card::new(suit.to_string(), value.to_string())
    }
}

impl Ord for Card {
    fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
        self.value.cmp(&other.value)
    }
}

impl fmt::Display for Card {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Suit: {}, Value: {}", self.suit, self.value)
    }
}

impl Deck {
    pub fn new_from_vec_deque(input: VecDeque<Card>) -> Deck {
        Deck { cards: input }
    }

    pub fn make_standard() -> Deck {
        let mut result = VecDeque::new();
        let suits  = &["♣", "♦", "♥", "♠"];
        let values = &["2", "3", "4", "5", "6", "7", "8", "9", "10",
                       "Jack", "Queen", "King", "Ace"];

        for suit in suits {
            for value in values {
                result.push_back(Card::new_from_str(*suit, value));
            }
        }
        return Deck::new_from_vec_deque(result);
    }

    pub fn make_fifth_dimension() -> Deck {
        let mut result = VecDeque::new();
        let suits  = &["♣", "♦", "♥", "♠", "★"];
        let values = &["1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
                       "Jack", "Princess", "Queen", "King", "Joker"];

        for suit in suits {
            for value in values {
                result.push_back(Card::new_from_str(*suit, value));
            }
        }
        return Deck::new_from_vec_deque(result);
    }

    // destructively shuffles the internal vector
    pub fn shuffle(&mut self) {
        // shuffle isn't defined on VecDeques, so it's manually defined here.
        let mut i = self.len();
        while i > 2 {
            i -= 2;
            let j = rand::thread_rng().gen_range(0, i + 1);
            self.cards.swap(i, j)
        }
    }

    // returns a new shuffled deck
    pub fn shuffled(&self) -> Self {
        let mut res = self.clone();
        res.shuffle();
        res
    }

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

    pub fn push_front(&mut self, card: Card) {
        self.cards.push_front(card);
    }

    pub fn push_back(&mut self, card: Card) {
        self.cards.push_back(card);
    }

    pub fn pop_front(&mut self) -> Option<Card> {
        self.cards.pop_front()
    }

    pub fn pop_back(&mut self) -> Option<Card> {
        self.cards.pop_back()
    }
}

impl Ord for Deck {
    fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
        self.cards.cmp(&other.cards)
    }
}
<commit_msg>change new_from_vec_deque to from_vec_deque<commit_after>extern crate rand;
use std::str;
use std::fmt;
use std::collections::VecDeque;
use rand::Rng;

#[derive(Debug, Eq, PartialEq, PartialOrd, Clone)]
pub struct Card {
    pub suit:  String,
    pub value: String,
}

#[derive(Debug, Eq, PartialEq, PartialOrd, Clone)]
pub struct Deck {
    pub cards: VecDeque<Card>
}

impl Card {
    pub fn new(suit: String, value: String) -> Card {
        Card { suit: suit, value: value.to_string() }
    }

    pub fn new_from_str(suit: &str, value: &str) -> Card {
        Card::new(suit.to_string(), value.to_string())
    }
}

impl Ord for Card {
    fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
        self.value.cmp(&other.value)
    }
}

impl fmt::Display for Card {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Suit: {}, Value: {}", self.suit, self.value)
    }
}

impl Deck {
    pub fn from_vec_deque(input: VecDeque<Card>) -> Deck {
        Deck { cards: input }
    }

    pub fn make_standard() -> Deck {
        let mut result = VecDeque::new();
        let suits  = &["♣", "♦", "♥", "♠"];
        let values = &["2", "3", "4", "5", "6", "7", "8", "9", "10",
                       "Jack", "Queen", "King", "Ace"];

        for suit in suits {
            for value in values {
                result.push_back(Card::new_from_str(*suit, value));
            }
        }
        return Deck::from_vec_deque(result);
    }

    pub fn make_fifth_dimension() -> Deck {
        let mut result = VecDeque::new();
        let suits  = &["♣", "♦", "♥", "♠", "★"];
        let values = &["1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
                       "Jack", "Princess", "Queen", "King", "Joker"];

        for suit in suits {
            for value in values {
                result.push_back(Card::new_from_str(*suit, value));
            }
        }
        return Deck::from_vec_deque(result);
    }

    // destructively shuffles the internal vector
    pub fn shuffle(&mut self) {
        // shuffle isn't defined on VecDeques, so it's manually defined here.
        let mut i = self.len();
        while i > 2 {
            i -= 2;
            let j = rand::thread_rng().gen_range(0, i + 1);
            self.cards.swap(i, j)
        }
    }

    // returns a new shuffled deck
    pub fn shuffled(&self) -> Self {
        let mut res = self.clone();
        res.shuffle();
        res
    }

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

    pub fn push_front(&mut self, card: Card) {
        self.cards.push_front(card);
    }

    pub fn push_back(&mut self, card: Card) {
        self.cards.push_back(card);
    }

    pub fn pop_front(&mut self) -> Option<Card> {
        self.cards.pop_front()
    }

    pub fn pop_back(&mut self) -> Option<Card> {
        self.cards.pop_back()
    }
}

impl Ord for Deck {
    fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
        self.cards.cmp(&other.cards)
    }
}
<|endoftext|>


<commit_before>#![doc(html_root_url = "https://hyperium.github.io/hyper/")]
#![cfg_attr(test, deny(missing_docs))]
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(all(test, feature = "nightly"), feature(test))]
#![cfg_attr(feature = "timeouts", feature(duration, socket_timeout))]

//! # Hyper
//!
//! Hyper is a fast, modern HTTP implementation written in and for Rust. It
//! is a low-level typesafe abstraction over raw HTTP, providing an elegant
//! layer over "stringly-typed" HTTP.
//!
//! Hyper offers both a [Client](client/index.html) and a
//! [Server](server/index.html) which can be used to drive complex web
//! applications written entirely in Rust.
//!
//! ## Internal Design
//!
//! Hyper is designed as a relatively low-level wrapper over raw HTTP. It should
//! allow the implementation of higher-level abstractions with as little pain as
//! possible, and should not irrevocably hide any information from its users.
//!
//! ### Common Functionality
//!
//! Functionality and code shared between the Server and Client implementations
//! can be found in `src` directly - this includes `NetworkStream`s, `Method`s,
//! `StatusCode`, and so on.
//!
//! #### Methods
//!
//! Methods are represented as a single `enum` to remain as simple as possible.
//! Extension Methods are represented as raw `String`s. A method's safety and
//! idempotence can be accessed using the `safe` and `idempotent` methods.
//!
//! #### StatusCode
//!
//! Status codes are also represented as a single, exhaustive, `enum`. This
//! representation is efficient, typesafe, and ergonomic as it allows the use of
//! `match` to disambiguate known status codes.
//!
//! #### Headers
//!
//! Hyper's [header](header/index.html) representation is likely the most
//! complex API exposed by Hyper.
//!
//! Hyper's headers are an abstraction over an internal `HashMap` and provides a
//! typesafe API for interacting with headers that does not rely on the use of
//! "string-typing."
//!
//! Each HTTP header in Hyper has an associated type and implementation of the
//! `Header` trait, which defines an HTTP headers name as a string, how to parse
//! that header, and how to format that header.
//!
//! Headers are then parsed from the string representation lazily when the typed
//! representation of a header is requested and formatted back into their string
//! representation when headers are written back to the client.
//!
//! #### NetworkStream and NetworkAcceptor
//!
//! These are found in `src/net.rs` and define the interface that acceptors and
//! streams must fulfill for them to be used within Hyper. They are by and large
//! internal tools and you should only need to mess around with them if you want to
//! mock or replace `TcpStream` and `TcpAcceptor`.
//!
//! ### Server
//!
//! Server-specific functionality, such as `Request` and `Response`
//! representations, are found in in `src/server`.
//!
//! #### Handler + Server
//!
//! A `Handler` in Hyper accepts a `Request` and `Response`. This is where
//! user-code can handle each connection. The server accepts connections in a
//! task pool with a customizable number of threads, and passes the Request /
//! Response to the handler.
//!
//! #### Request
//!
//! An incoming HTTP Request is represented as a struct containing
//! a `Reader` over a `NetworkStream`, which represents the body, headers, a remote
//! address, an HTTP version, and a `Method` - relatively standard stuff.
//!
//! `Request` implements `Reader` itself, meaning that you can ergonomically get
//! the body out of a `Request` using standard `Reader` methods and helpers.
//!
//! #### Response
//!
//! An outgoing HTTP Response is also represented as a struct containing a `Writer`
//! over a `NetworkStream` which represents the Response body in addition to
//! standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer`
//! implementation provides a streaming interface for sending data over to the
//! client.
//!
//! One of the traditional problems with representing outgoing HTTP Responses is
//! tracking the write-status of the Response - have we written the status-line,
//! the headers, the body, etc.? Hyper tracks this information statically using the
//! type system and prevents you, using the type system, from writing headers after
//! you have started writing to the body or vice versa.
//!
//! Hyper does this through a phantom type parameter in the definition of Response,
//! which tracks whether you are allowed to write to the headers or the body. This
//! phantom type can have two values `Fresh` or `Streaming`, with `Fresh`
//! indicating that you can write the headers and `Streaming` indicating that you
//! may write to the body, but not the headers.
//!
//! ### Client
//!
//! Client-specific functionality, such as `Request` and `Response`
//! representations, are found in `src/client`.
//!
//! #### Request
//!
//! An outgoing HTTP Request is represented as a struct containing a `Writer` over
//! a `NetworkStream` which represents the Request body in addition to the standard
//! information such as headers and the request method.
//!
//! Outgoing Requests track their write-status in almost exactly the same way as
//! outgoing HTTP Responses do on the Server, so we will defer to the explanation
//! in the documentation for server Response.
//!
//! Requests expose an efficient streaming interface instead of a builder pattern,
//! but they also provide the needed interface for creating a builder pattern over
//! the API exposed by core Hyper.
//!
//! #### Response
//!
//! Incoming HTTP Responses are represented as a struct containing a `Reader` over
//! a `NetworkStream` and contain headers, a status, and an http version. They
//! implement `Reader` and can be read to get the data out of a `Response`.
//!

extern crate rustc_serialize as serialize;
extern crate time;
extern crate url;
#[cfg(feature = "openssl")]
extern crate openssl;
#[cfg(feature = "serde-serialization")]
extern crate serde;
extern crate cookie;
extern crate unicase;
extern crate httparse;
extern crate num_cpus;
extern crate traitobject;
extern crate typeable;
extern crate solicit;

#[macro_use]
extern crate language_tags;

#[macro_use]
extern crate mime as mime_crate;

#[macro_use]
extern crate log;

#[cfg(all(test, feature = "nightly"))]
extern crate test;

pub use url::Url;
pub use client::Client;
pub use error::{Result, Error};
pub use method::Method::{Get, Head, Post, Delete};
pub use status::StatusCode::{Ok, BadRequest, NotFound};
pub use server::Server;
pub use language_tags::LanguageTag;

macro_rules! todo(
    ($($arg:tt)*) => (if cfg!(not(ndebug)) {
        trace!("TODO: {:?}", format_args!($($arg)*))
    })
);

macro_rules! inspect(
    ($name:expr, $value:expr) => ({
        let v = $value;
        trace!("inspect: {:?} = {:?}", $name, v);
        v
    })
);

#[cfg(test)]
#[macro_use]
mod mock;
#[doc(hidden)]
pub mod buffer;
pub mod client;
pub mod error;
pub mod method;
pub mod header;
pub mod http;
pub mod net;
pub mod server;
pub mod status;
pub mod uri;
pub mod version;

/// Re-exporting the mime crate, for convenience.
pub mod mime {
    pub use mime_crate::*;
}

#[allow(unconditional_recursion)]
fn _assert_send<T: Send>() {
    _assert_send::<Client>();
    _assert_send::<client::Request<net::Fresh>>();
    _assert_send::<client::Response>();
    _assert_send::<error::Error>();
}

#[allow(unconditional_recursion)]
fn _assert_sync<T: Sync>() {
    _assert_sync::<Client>();
    _assert_sync::<error::Error>();
}
<commit_msg>fix(nightly): remove feature flag for duration<commit_after>#![doc(html_root_url = "https://hyperium.github.io/hyper/")]
#![cfg_attr(test, deny(missing_docs))]
#![cfg_attr(test, deny(warnings))]
#![cfg_attr(all(test, feature = "nightly"), feature(test))]
#![cfg_attr(feature = "timeouts", feature(socket_timeout))]

//! # Hyper
//!
//! Hyper is a fast, modern HTTP implementation written in and for Rust. It
//! is a low-level typesafe abstraction over raw HTTP, providing an elegant
//! layer over "stringly-typed" HTTP.
//!
//! Hyper offers both a [Client](client/index.html) and a
//! [Server](server/index.html) which can be used to drive complex web
//! applications written entirely in Rust.
//!
//! ## Internal Design
//!
//! Hyper is designed as a relatively low-level wrapper over raw HTTP. It should
//! allow the implementation of higher-level abstractions with as little pain as
//! possible, and should not irrevocably hide any information from its users.
//!
//! ### Common Functionality
//!
//! Functionality and code shared between the Server and Client implementations
//! can be found in `src` directly - this includes `NetworkStream`s, `Method`s,
//! `StatusCode`, and so on.
//!
//! #### Methods
//!
//! Methods are represented as a single `enum` to remain as simple as possible.
//! Extension Methods are represented as raw `String`s. A method's safety and
//! idempotence can be accessed using the `safe` and `idempotent` methods.
//!
//! #### StatusCode
//!
//! Status codes are also represented as a single, exhaustive, `enum`. This
//! representation is efficient, typesafe, and ergonomic as it allows the use of
//! `match` to disambiguate known status codes.
//!
//! #### Headers
//!
//! Hyper's [header](header/index.html) representation is likely the most
//! complex API exposed by Hyper.
//!
//! Hyper's headers are an abstraction over an internal `HashMap` and provides a
//! typesafe API for interacting with headers that does not rely on the use of
//! "string-typing."
//!
//! Each HTTP header in Hyper has an associated type and implementation of the
//! `Header` trait, which defines an HTTP headers name as a string, how to parse
//! that header, and how to format that header.
//!
//! Headers are then parsed from the string representation lazily when the typed
//! representation of a header is requested and formatted back into their string
//! representation when headers are written back to the client.
//!
//! #### NetworkStream and NetworkAcceptor
//!
//! These are found in `src/net.rs` and define the interface that acceptors and
//! streams must fulfill for them to be used within Hyper. They are by and large
//! internal tools and you should only need to mess around with them if you want to
//! mock or replace `TcpStream` and `TcpAcceptor`.
//!
//! ### Server
//!
//! Server-specific functionality, such as `Request` and `Response`
//! representations, are found in in `src/server`.
//!
//! #### Handler + Server
//!
//! A `Handler` in Hyper accepts a `Request` and `Response`. This is where
//! user-code can handle each connection. The server accepts connections in a
//! task pool with a customizable number of threads, and passes the Request /
//! Response to the handler.
//!
//! #### Request
//!
//! An incoming HTTP Request is represented as a struct containing
//! a `Reader` over a `NetworkStream`, which represents the body, headers, a remote
//! address, an HTTP version, and a `Method` - relatively standard stuff.
//!
//! `Request` implements `Reader` itself, meaning that you can ergonomically get
//! the body out of a `Request` using standard `Reader` methods and helpers.
//!
//! #### Response
//!
//! An outgoing HTTP Response is also represented as a struct containing a `Writer`
//! over a `NetworkStream` which represents the Response body in addition to
//! standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer`
//! implementation provides a streaming interface for sending data over to the
//! client.
//!
//! One of the traditional problems with representing outgoing HTTP Responses is
//! tracking the write-status of the Response - have we written the status-line,
//! the headers, the body, etc.? Hyper tracks this information statically using the
//! type system and prevents you, using the type system, from writing headers after
//! you have started writing to the body or vice versa.
//!
//! Hyper does this through a phantom type parameter in the definition of Response,
//! which tracks whether you are allowed to write to the headers or the body. This
//! phantom type can have two values `Fresh` or `Streaming`, with `Fresh`
//! indicating that you can write the headers and `Streaming` indicating that you
//! may write to the body, but not the headers.
//!
//! ### Client
//!
//! Client-specific functionality, such as `Request` and `Response`
//! representations, are found in `src/client`.
//!
//! #### Request
//!
//! An outgoing HTTP Request is represented as a struct containing a `Writer` over
//! a `NetworkStream` which represents the Request body in addition to the standard
//! information such as headers and the request method.
//!
//! Outgoing Requests track their write-status in almost exactly the same way as
//! outgoing HTTP Responses do on the Server, so we will defer to the explanation
//! in the documentation for server Response.
//!
//! Requests expose an efficient streaming interface instead of a builder pattern,
//! but they also provide the needed interface for creating a builder pattern over
//! the API exposed by core Hyper.
//!
//! #### Response
//!
//! Incoming HTTP Responses are represented as a struct containing a `Reader` over
//! a `NetworkStream` and contain headers, a status, and an http version. They
//! implement `Reader` and can be read to get the data out of a `Response`.
//!

extern crate rustc_serialize as serialize;
extern crate time;
extern crate url;
#[cfg(feature = "openssl")]
extern crate openssl;
#[cfg(feature = "serde-serialization")]
extern crate serde;
extern crate cookie;
extern crate unicase;
extern crate httparse;
extern crate num_cpus;
extern crate traitobject;
extern crate typeable;
extern crate solicit;

#[macro_use]
extern crate language_tags;

#[macro_use]
extern crate mime as mime_crate;

#[macro_use]
extern crate log;

#[cfg(all(test, feature = "nightly"))]
extern crate test;

pub use url::Url;
pub use client::Client;
pub use error::{Result, Error};
pub use method::Method::{Get, Head, Post, Delete};
pub use status::StatusCode::{Ok, BadRequest, NotFound};
pub use server::Server;
pub use language_tags::LanguageTag;

macro_rules! todo(
    ($($arg:tt)*) => (if cfg!(not(ndebug)) {
        trace!("TODO: {:?}", format_args!($($arg)*))
    })
);

macro_rules! inspect(
    ($name:expr, $value:expr) => ({
        let v = $value;
        trace!("inspect: {:?} = {:?}", $name, v);
        v
    })
);

#[cfg(test)]
#[macro_use]
mod mock;
#[doc(hidden)]
pub mod buffer;
pub mod client;
pub mod error;
pub mod method;
pub mod header;
pub mod http;
pub mod net;
pub mod server;
pub mod status;
pub mod uri;
pub mod version;

/// Re-exporting the mime crate, for convenience.
pub mod mime {
    pub use mime_crate::*;
}

#[allow(unconditional_recursion)]
fn _assert_send<T: Send>() {
    _assert_send::<Client>();
    _assert_send::<client::Request<net::Fresh>>();
    _assert_send::<client::Response>();
    _assert_send::<error::Error>();
}

#[allow(unconditional_recursion)]
fn _assert_sync<T: Sync>() {
    _assert_sync::<Client>();
    _assert_sync::<error::Error>();
}
<|endoftext|>


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

pub fn puzzle(input: &str) -> String {
    String::from("no")
}

struct Column {
    freqs: HashMap<char, u32>,
}

impl Column {
    fn add_char(&mut self, ch: char) {
        let count = self.freqs.entry(ch).or_insert(0);
        *count += 1;
    }

    fn most_common_char(&self) -> char {
        let mut f: Vec<char, u32> = self.freqs.iter().collect();
        f.sort_by(|a, b| b.1.cmp(&a.1));
        f[0]
    }
}

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

    #[test]
    fn most_common_char_seen_in_column() {
        let mut c = Column { freqs: HashMap::new() };
        c.add_char('a');
        c.add_char('b');
        c.add_char('a');
        assert_eq!(c.most_common_char(), 'a');
    }
}
<commit_msg>Fix my compiler errors<commit_after>use std::collections::HashMap;

pub fn puzzle(input: &str) -> String {
    String::from("no")
}

pub struct Column {
    freqs: HashMap<char, u32>,
}

impl Column {
    fn add_char(&mut self, ch: char) {
        let count = self.freqs.entry(ch).or_insert(0);
        *count += 1;
    }

    fn most_common_char(&self) -> char {
        let mut f: Vec<(&char, &u32)> = self.freqs.iter().collect();
        f.sort_by(|a, b| b.1.cmp(&a.1));
        *f[0].0
    }
}

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

    #[test]
    fn most_common_char_seen_in_column() {
        let mut c = Column { freqs: HashMap::new() };
        c.add_char('a');
        c.add_char('b');
        c.add_char('a');
        assert_eq!(c.most_common_char(), 'a');
    }
}
<|endoftext|>


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

//! The time oracle service for Exonum.

#![deny(missing_debug_implementations, missing_docs)]

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate exonum;
extern crate router;
extern crate bodyparser;
extern crate iron;

use iron::prelude::*;
use iron::Handler;
use router::Router;

use std::time::SystemTime;
use std::collections::HashMap;

use exonum::blockchain::{Blockchain, Service, ServiceContext, Schema, Transaction, ApiContext};
use exonum::messages::{RawTransaction, FromRaw, Message};
use exonum::encoding::serialize::json::reexport::Value;
use exonum::storage::{Fork, Snapshot, MapIndex, Entry};
use exonum::crypto::PublicKey;
use exonum::encoding;
use exonum::helpers::fabric::{ServiceFactory, Context};
use exonum::api::Api;

/// Time service id.
const SERVICE_ID: u16 = 4;
/// `TxTime` transaction id.
const TX_TIME_ID: u16 = 1;
/// Time service name.
const SERVICE_NAME: &str = "exonum_time";

encoding_struct! {
    /// Time information.
    struct Time {
        const SIZE = 12;

        /// Field that stores `SystemTime`.
        field time:     SystemTime  [00 => 12]
    }
}

/// `Exonum-time` service database schema.
#[derive(Debug)]
pub struct TimeSchema<T> {
    view: T,
}

impl<T: AsRef<Snapshot>> TimeSchema<T> {
    /// Constructs schema for the given `snapshot`.
    pub fn new(view: T) -> Self {
        TimeSchema { view }
    }

    /// Returns the table that stores `Time` struct for every validator.
    pub fn validators_time(&self) -> MapIndex<&Snapshot, PublicKey, Time> {
        MapIndex::new(
            format!("{}.validators_time", SERVICE_NAME),
            self.view.as_ref(),
        )
    }

    /// Returns stored `Time`.
    pub fn time(&self) -> Entry<&Snapshot, Time> {
        Entry::new(format!("{}.time", SERVICE_NAME), self.view.as_ref())
    }
}

impl<'a> TimeSchema<&'a mut Fork> {
    /// Mutable reference to the ['validators_time'][1] index.
    ///
    /// [1]: struct.TimeSchema.html#method.validators_time
    pub fn validators_time_mut(&mut self) -> MapIndex<&mut Fork, PublicKey, Time> {
        MapIndex::new(format!("{}.validators_time", SERVICE_NAME), self.view)
    }

    /// Mutable reference to the ['time'][1] index.
    ///
    /// [1]: struct.TimeSchema.html#method.time
    pub fn time_mut(&mut self) -> Entry<&mut Fork, Time> {
        Entry::new(format!("{}.time", SERVICE_NAME), self.view)
    }
}

message! {
    /// Transaction that is sent by the validator after the commit of the block.
    struct TxTime {
        const TYPE = SERVICE_ID;
        const ID = TX_TIME_ID;
        const SIZE = 44;
        /// Validator's time.
        field time:     SystemTime  [00 => 12]
        /// Validator's public key.
        field pub_key:  &PublicKey  [12 => 44]
    }
}

impl Transaction for TxTime {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let validator_keys = Schema::new(&view).actual_configuration().validator_keys;

        // The transaction must be signed by the validator.
        let signed = validator_keys.iter().any(|&validator| {
            validator.service_key == *self.pub_key()
        });
        if !signed {
            return;
        }

        let mut schema = TimeSchema::new(view);
        match schema.validators_time().get(self.pub_key()) {
            // The validator time in the storage should be less than in the transaction.
            Some(ref storage_time) if storage_time.time() >= self.time() => {
                return;
            }
            // Write the time for the validator.
            _ => {
                schema.validators_time_mut().put(
                    self.pub_key(),
                    Time::new(self.time()),
                )
            }
        }

        // Find all known times for the validators.
        let mut validators_time: Vec<SystemTime>;
        {
            let idx = schema.validators_time();
            validators_time = idx.iter()
                .filter_map(|pair| {
                    validator_keys
                        .iter()
                        .find(|validator| validator.service_key == pair.0)
                        .map(|_| pair.1.time())
                })
                .collect();
        }

        // The largest number of Byzantine nodes.
        let max_byzantine_nodes = validator_keys.len() / 3;
        if validators_time.len() <= 2 * max_byzantine_nodes {
            return;
        }
        // Ordering time from highest to lowest.
        validators_time.sort_by(|a, b| b.cmp(a));

        match schema.time().get() {
            // Selected time should be longer than the time in the storage.
            Some(ref current_time)
                if current_time.time() >= validators_time[max_byzantine_nodes] => {
                return;
            }
            _ => {
                // Change the time in the storage.
                schema.time_mut().set(Time::new(
                    validators_time[max_byzantine_nodes],
                ));
            }
        }
    }
}

/// Implements the node API.
#[derive(Clone)]
struct TimeApi {
    blockchain: Blockchain,
}

/// Shortcut to get data from storage.
impl TimeApi {
    /// Endpoint for getting value of the time that is saved in storage.
    fn get_current_time(&self, _: &mut Request) -> IronResult<Response> {
        let view = self.blockchain.snapshot();
        let schema = TimeSchema::new(&view);
        let current_time = schema.time().get();
        self.ok_response(&serde_json::to_value(current_time).unwrap())
    }

    /// Endpoint for getting time values for all validators.
    fn get_validators_time(&self, _: &mut Request) -> IronResult<Response> {
        let view = self.blockchain.snapshot();
        let schema = TimeSchema::new(&view);
        let idx = schema.validators_time();

        let validators_time: HashMap<_, _> = idx.iter().collect();

        if validators_time.is_empty() {
            self.not_found_response(&serde_json::to_value("Validators time database is empty")
                .unwrap())
        } else {
            self.ok_response(&serde_json::to_value(validators_time).unwrap())
        }
    }

    fn wire_private(&self, router: &mut Router) {
        let self_ = self.clone();
        let get_validators_time = move |req: &mut Request| self_.get_validators_time(req);
        router.get(
            "/validators_time",
            get_validators_time,
            "get_validators_time",
        );
    }
}

impl Api for TimeApi {
    fn wire(&self, router: &mut Router) {
        let self_ = self.clone();
        let get_current_time = move |req: &mut Request| self_.get_current_time(req);
        router.get("/current_time", get_current_time, "get_current_time");
    }
}

/// A helper trait that provides the node with a current time.
pub trait TimeProvider: Send + Sync + ::std::fmt::Debug {
    /// Returns the current time.
    fn current_time(&self) -> SystemTime;
}

#[derive(Debug)]
struct SystemTimeProvider;

impl TimeProvider for SystemTimeProvider {
    fn current_time(&self) -> SystemTime {
        SystemTime::now()
    }
}

/// Define the service.
#[derive(Debug)]
pub struct TimeService {
    /// Current time.
    time: Box<TimeProvider>,
}

impl Default for TimeService {
    fn default() -> TimeService {
        TimeService { time: Box::new(SystemTimeProvider) as Box<TimeProvider> }
    }
}

impl TimeService {
    /// Create a new `TimeService`.
    pub fn new() -> TimeService {
        TimeService::default()
    }

    /// Create a new `TimeService` with time provider `T`.
    pub fn with_provider<T: Into<Box<TimeProvider>>>(time_provider: T) -> TimeService {
        TimeService { time: time_provider.into() }
    }
}

impl Service for TimeService {
    fn service_name(&self) -> &'static str {
        SERVICE_NAME
    }

    fn service_id(&self) -> u16 {
        SERVICE_ID
    }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
        match raw.message_type() {
            TX_TIME_ID => Ok(Box::new(TxTime::from_raw(raw)?)),
            _ => {
                let error =
                    encoding::Error::IncorrectMessageType { message_type: raw.message_type() };
                Err(error)
            }
        }
    }

    fn initialize(&self, _fork: &mut Fork) -> Value {
        Value::Null
    }

    /// Creates transaction after commit of the block.
    fn handle_commit(&self, context: &ServiceContext) {
        // The transaction must be created by the validator.
        if context.validator_id().is_none() {
            return;
        }
        let (pub_key, sec_key) = (*context.public_key(), context.secret_key().clone());
        context
            .transaction_sender()
            .send(Box::new(
                TxTime::new(self.time.current_time(), &pub_key, &sec_key),
            ))
            .unwrap();
    }

    fn private_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = TimeApi { blockchain: ctx.blockchain().clone() };
        api.wire_private(&mut router);
        Some(Box::new(router))
    }

    fn public_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = TimeApi { blockchain: ctx.blockchain().clone() };
        api.wire(&mut router);
        Some(Box::new(router))
    }
}

/// A time service creator for the `NodeBuilder`.
#[derive(Debug)]
pub struct TimeServiceFactory;

impl ServiceFactory for TimeServiceFactory {
    fn make_service(&mut self, _: &Context) -> Box<Service> {
        Box::new(TimeService::new())
    }
}
<commit_msg>Fix formula for max_byzantine_nodes<commit_after>// Copyright 2017 The Exonum Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! The time oracle service for Exonum.

#![deny(missing_debug_implementations, missing_docs)]

extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate exonum;
extern crate router;
extern crate bodyparser;
extern crate iron;

use iron::prelude::*;
use iron::Handler;
use router::Router;

use std::time::SystemTime;
use std::collections::HashMap;

use exonum::blockchain::{Blockchain, Service, ServiceContext, Schema, Transaction, ApiContext};
use exonum::messages::{RawTransaction, FromRaw, Message};
use exonum::encoding::serialize::json::reexport::Value;
use exonum::storage::{Fork, Snapshot, MapIndex, Entry};
use exonum::crypto::PublicKey;
use exonum::encoding;
use exonum::helpers::fabric::{ServiceFactory, Context};
use exonum::api::Api;

/// Time service id.
const SERVICE_ID: u16 = 4;
/// `TxTime` transaction id.
const TX_TIME_ID: u16 = 1;
/// Time service name.
const SERVICE_NAME: &str = "exonum_time";

encoding_struct! {
    /// Time information.
    struct Time {
        const SIZE = 12;

        /// Field that stores `SystemTime`.
        field time:     SystemTime  [00 => 12]
    }
}

/// `Exonum-time` service database schema.
#[derive(Debug)]
pub struct TimeSchema<T> {
    view: T,
}

impl<T: AsRef<Snapshot>> TimeSchema<T> {
    /// Constructs schema for the given `snapshot`.
    pub fn new(view: T) -> Self {
        TimeSchema { view }
    }

    /// Returns the table that stores `Time` struct for every validator.
    pub fn validators_time(&self) -> MapIndex<&Snapshot, PublicKey, Time> {
        MapIndex::new(
            format!("{}.validators_time", SERVICE_NAME),
            self.view.as_ref(),
        )
    }

    /// Returns stored `Time`.
    pub fn time(&self) -> Entry<&Snapshot, Time> {
        Entry::new(format!("{}.time", SERVICE_NAME), self.view.as_ref())
    }
}

impl<'a> TimeSchema<&'a mut Fork> {
    /// Mutable reference to the ['validators_time'][1] index.
    ///
    /// [1]: struct.TimeSchema.html#method.validators_time
    pub fn validators_time_mut(&mut self) -> MapIndex<&mut Fork, PublicKey, Time> {
        MapIndex::new(format!("{}.validators_time", SERVICE_NAME), self.view)
    }

    /// Mutable reference to the ['time'][1] index.
    ///
    /// [1]: struct.TimeSchema.html#method.time
    pub fn time_mut(&mut self) -> Entry<&mut Fork, Time> {
        Entry::new(format!("{}.time", SERVICE_NAME), self.view)
    }
}

message! {
    /// Transaction that is sent by the validator after the commit of the block.
    struct TxTime {
        const TYPE = SERVICE_ID;
        const ID = TX_TIME_ID;
        const SIZE = 44;
        /// Validator's time.
        field time:     SystemTime  [00 => 12]
        /// Validator's public key.
        field pub_key:  &PublicKey  [12 => 44]
    }
}

impl Transaction for TxTime {
    fn verify(&self) -> bool {
        self.verify_signature(self.pub_key())
    }

    fn execute(&self, view: &mut Fork) {
        let validator_keys = Schema::new(&view).actual_configuration().validator_keys;

        // The transaction must be signed by the validator.
        let signed = validator_keys.iter().any(|&validator| {
            validator.service_key == *self.pub_key()
        });
        if !signed {
            return;
        }

        let mut schema = TimeSchema::new(view);
        match schema.validators_time().get(self.pub_key()) {
            // The validator time in the storage should be less than in the transaction.
            Some(ref storage_time) if storage_time.time() >= self.time() => {
                return;
            }
            // Write the time for the validator.
            _ => {
                schema.validators_time_mut().put(
                    self.pub_key(),
                    Time::new(self.time()),
                )
            }
        }

        // Find all known times for the validators.
        let mut validators_time: Vec<SystemTime>;
        {
            let idx = schema.validators_time();
            validators_time = idx.iter()
                .filter_map(|pair| {
                    validator_keys
                        .iter()
                        .find(|validator| validator.service_key == pair.0)
                        .map(|_| pair.1.time())
                })
                .collect();
        }

        // The largest number of Byzantine nodes.
        let max_byzantine_nodes = (validator_keys.len() - 1) / 3;
        if validators_time.len() <= 2 * max_byzantine_nodes {
            return;
        }
        // Ordering time from highest to lowest.
        validators_time.sort_by(|a, b| b.cmp(a));

        match schema.time().get() {
            // Selected time should be longer than the time in the storage.
            Some(ref current_time)
                if current_time.time() >= validators_time[max_byzantine_nodes] => {
                return;
            }
            _ => {
                // Change the time in the storage.
                schema.time_mut().set(Time::new(
                    validators_time[max_byzantine_nodes],
                ));
            }
        }
    }
}

/// Implements the node API.
#[derive(Clone)]
struct TimeApi {
    blockchain: Blockchain,
}

/// Shortcut to get data from storage.
impl TimeApi {
    /// Endpoint for getting value of the time that is saved in storage.
    fn get_current_time(&self, _: &mut Request) -> IronResult<Response> {
        let view = self.blockchain.snapshot();
        let schema = TimeSchema::new(&view);
        let current_time = schema.time().get();
        self.ok_response(&serde_json::to_value(current_time).unwrap())
    }

    /// Endpoint for getting time values for all validators.
    fn get_validators_time(&self, _: &mut Request) -> IronResult<Response> {
        let view = self.blockchain.snapshot();
        let schema = TimeSchema::new(&view);
        let idx = schema.validators_time();

        let validators_time: HashMap<_, _> = idx.iter().collect();

        if validators_time.is_empty() {
            self.not_found_response(&serde_json::to_value("Validators time database is empty")
                .unwrap())
        } else {
            self.ok_response(&serde_json::to_value(validators_time).unwrap())
        }
    }

    fn wire_private(&self, router: &mut Router) {
        let self_ = self.clone();
        let get_validators_time = move |req: &mut Request| self_.get_validators_time(req);
        router.get(
            "/validators_time",
            get_validators_time,
            "get_validators_time",
        );
    }
}

impl Api for TimeApi {
    fn wire(&self, router: &mut Router) {
        let self_ = self.clone();
        let get_current_time = move |req: &mut Request| self_.get_current_time(req);
        router.get("/current_time", get_current_time, "get_current_time");
    }
}

/// A helper trait that provides the node with a current time.
pub trait TimeProvider: Send + Sync + ::std::fmt::Debug {
    /// Returns the current time.
    fn current_time(&self) -> SystemTime;
}

#[derive(Debug)]
struct SystemTimeProvider;

impl TimeProvider for SystemTimeProvider {
    fn current_time(&self) -> SystemTime {
        SystemTime::now()
    }
}

/// Define the service.
#[derive(Debug)]
pub struct TimeService {
    /// Current time.
    time: Box<TimeProvider>,
}

impl Default for TimeService {
    fn default() -> TimeService {
        TimeService { time: Box::new(SystemTimeProvider) as Box<TimeProvider> }
    }
}

impl TimeService {
    /// Create a new `TimeService`.
    pub fn new() -> TimeService {
        TimeService::default()
    }

    /// Create a new `TimeService` with time provider `T`.
    pub fn with_provider<T: Into<Box<TimeProvider>>>(time_provider: T) -> TimeService {
        TimeService { time: time_provider.into() }
    }
}

impl Service for TimeService {
    fn service_name(&self) -> &'static str {
        SERVICE_NAME
    }

    fn service_id(&self) -> u16 {
        SERVICE_ID
    }

    fn tx_from_raw(&self, raw: RawTransaction) -> Result<Box<Transaction>, encoding::Error> {
        match raw.message_type() {
            TX_TIME_ID => Ok(Box::new(TxTime::from_raw(raw)?)),
            _ => {
                let error =
                    encoding::Error::IncorrectMessageType { message_type: raw.message_type() };
                Err(error)
            }
        }
    }

    fn initialize(&self, _fork: &mut Fork) -> Value {
        Value::Null
    }

    /// Creates transaction after commit of the block.
    fn handle_commit(&self, context: &ServiceContext) {
        // The transaction must be created by the validator.
        if context.validator_id().is_none() {
            return;
        }
        let (pub_key, sec_key) = (*context.public_key(), context.secret_key().clone());
        context
            .transaction_sender()
            .send(Box::new(
                TxTime::new(self.time.current_time(), &pub_key, &sec_key),
            ))
            .unwrap();
    }

    fn private_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = TimeApi { blockchain: ctx.blockchain().clone() };
        api.wire_private(&mut router);
        Some(Box::new(router))
    }

    fn public_api_handler(&self, ctx: &ApiContext) -> Option<Box<Handler>> {
        let mut router = Router::new();
        let api = TimeApi { blockchain: ctx.blockchain().clone() };
        api.wire(&mut router);
        Some(Box::new(router))
    }
}

/// A time service creator for the `NodeBuilder`.
#[derive(Debug)]
pub struct TimeServiceFactory;

impl ServiceFactory for TimeServiceFactory {
    fn make_service(&mut self, _: &Context) -> Box<Service> {
        Box::new(TimeService::new())
    }
}
<|endoftext|>


<commit_before>//! # What is this?
//!
//! ggez is a Rust library to create a Good Game Easily.
//!
//! More specifically, ggez is a lightweight game framework for making
//! 2D games with minimum friction.  It aims to implement an API based
//! on (a Rustified version of) the [LÖVE](https://love2d.org/) game
//! framework.  This means it contains basic and portable 2D
//! drawing, sound, resource loading and event handling.
//!
//! For a fuller outline, see the [README.md](https://github.com/ggez/ggez/)
//!
//! ## Usage
//!
//! ggez consists of three main parts: A [`Context`](struct.Context.html) object
//! which contains all the state required to interface with the computer's
//! hardware, an [`EventHandler`](event/trait.EventHandler.html) trait that the
//! user implements to register callbacks for events, and various sub-modules such as
//! [`graphics`](graphics/index.html) and [`audio`](audio/index.html) that provide
//! the functionality to actually get stuff done.
//!
//! The general pattern is to create a struct holding your game's data which implements
//! the `EventHandler` trait. Create a new `Context` object with default objects from a
//! [`ContextBuilder`](struct.ContextBuilder.html) or [`Conf`](conf/struct.Conf.html) object,
//! and then call [`event::run()`](event/fn.run.html) with the `Context` and an instance of
//! your `EventHandler` to run your game's main loop.
//!
//! ## Basic Project Template
//!
//! ```rust,no_run
//! use ggez::{Context, ContextBuilder, GameResult};
//! use ggez::event::{self, EventHandler};
//!
//! fn main() {
//!     // Make a Context and an EventLoop.
//!     let (mut ctx, mut event_loop) = /* ContextBuilder params */
//! #       ContextBuilder::new("doc_template", "ggez")
//! #           .build()
//! #           .unwrap();
//!
//!     // Create an instance of your event handler.
//!     // Usually, you should provide it with the Context object to
//!     // use when setting your game up.
//!     let mut my_game = MyGame::new(&mut ctx);
//!
//!     // Run!
//!     match event::run(&mut ctx, &mut event_loop, &mut my_game) {
//!         Ok(_) => println!("Exited cleanly."),
//!         Err(e) => println!("Error occured: {}", e)
//!     }
//! }
//!
//! struct MyGame {
//!     // Your state here...
//! }
//!
//! impl EventHandler for MyGame {
//!     fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
//!         // Update code here...
//! #       Ok(())
//!     }
//!
//!     fn draw(&mut self, _ctx: &mut Context) -> GameResult<()> {
//!         // Draw code here...
//! #       Ok(())
//!     }
//! }
//! #
//! # impl MyGame {
//! #   pub fn new(_ctx: &mut Context) -> MyGame {
//! #       MyGame { }
//! #   }
//! # }
//! ```

#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![deny(unused_results)]
// This is not as strong a constraint as `#![forbid(unsafe_code)]` but is good enough.
// It means the only place we use unsafe is then in the modules noted as allowing it.
#![deny(unsafe_code)]
#![warn(bare_trait_objects)]
#![warn(missing_copy_implementations)]

#[macro_use]
extern crate bitflags;
extern crate app_dirs2;
#[macro_use]
extern crate gfx;
extern crate gfx_device_gl;
extern crate gfx_window_glutin;
extern crate glutin;
extern crate glyph_brush;
extern crate image;
#[macro_use]
extern crate log;
extern crate lyon;
pub extern crate mint;
pub extern crate nalgebra;
extern crate rodio;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate smart_default;
extern crate gilrs;
extern crate toml;
extern crate zip;

pub mod audio;
pub mod conf;
mod context;
pub mod error;
pub mod event;
pub mod filesystem;
pub mod graphics;
pub mod input;
pub mod timer;
mod vfs;

#[cfg(test)]
pub mod tests;

pub use crate::context::{quit, Context, ContextBuilder};
pub use crate::error::*;
<commit_msg>Removed unneeded extern crates<commit_after>//! # What is this?
//!
//! ggez is a Rust library to create a Good Game Easily.
//!
//! More specifically, ggez is a lightweight game framework for making
//! 2D games with minimum friction.  It aims to implement an API based
//! on (a Rustified version of) the [LÖVE](https://love2d.org/) game
//! framework.  This means it contains basic and portable 2D
//! drawing, sound, resource loading and event handling.
//!
//! For a fuller outline, see the [README.md](https://github.com/ggez/ggez/)
//!
//! ## Usage
//!
//! ggez consists of three main parts: A [`Context`](struct.Context.html) object
//! which contains all the state required to interface with the computer's
//! hardware, an [`EventHandler`](event/trait.EventHandler.html) trait that the
//! user implements to register callbacks for events, and various sub-modules such as
//! [`graphics`](graphics/index.html) and [`audio`](audio/index.html) that provide
//! the functionality to actually get stuff done.
//!
//! The general pattern is to create a struct holding your game's data which implements
//! the `EventHandler` trait. Create a new `Context` object with default objects from a
//! [`ContextBuilder`](struct.ContextBuilder.html) or [`Conf`](conf/struct.Conf.html) object,
//! and then call [`event::run()`](event/fn.run.html) with the `Context` and an instance of
//! your `EventHandler` to run your game's main loop.
//!
//! ## Basic Project Template
//!
//! ```rust,no_run
//! use ggez::{Context, ContextBuilder, GameResult};
//! use ggez::event::{self, EventHandler};
//!
//! fn main() {
//!     // Make a Context and an EventLoop.
//!     let (mut ctx, mut event_loop) = /* ContextBuilder params */
//! #       ContextBuilder::new("doc_template", "ggez")
//! #           .build()
//! #           .unwrap();
//!
//!     // Create an instance of your event handler.
//!     // Usually, you should provide it with the Context object to
//!     // use when setting your game up.
//!     let mut my_game = MyGame::new(&mut ctx);
//!
//!     // Run!
//!     match event::run(&mut ctx, &mut event_loop, &mut my_game) {
//!         Ok(_) => println!("Exited cleanly."),
//!         Err(e) => println!("Error occured: {}", e)
//!     }
//! }
//!
//! struct MyGame {
//!     // Your state here...
//! }
//!
//! impl EventHandler for MyGame {
//!     fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
//!         // Update code here...
//! #       Ok(())
//!     }
//!
//!     fn draw(&mut self, _ctx: &mut Context) -> GameResult<()> {
//!         // Draw code here...
//! #       Ok(())
//!     }
//! }
//! #
//! # impl MyGame {
//! #   pub fn new(_ctx: &mut Context) -> MyGame {
//! #       MyGame { }
//! #   }
//! # }
//! ```

#![deny(missing_docs)]
#![deny(missing_debug_implementations)]
#![deny(unused_results)]
// This is not as strong a constraint as `#![forbid(unsafe_code)]` but is good enough.
// It means the only place we use unsafe is then in the modules noted as allowing it.
#![deny(unsafe_code)]
#![warn(bare_trait_objects)]
#![warn(missing_copy_implementations)]

#[macro_use] extern crate bitflags;
#[macro_use] extern crate gfx;
#[macro_use] extern crate log;
#[macro_use] extern crate serde_derive;
#[macro_use] extern crate smart_default;

pub extern crate mint;
pub extern crate nalgebra;

pub mod audio;
pub mod conf;
mod context;
pub mod error;
pub mod event;
pub mod filesystem;
pub mod graphics;
pub mod input;
pub mod timer;
mod vfs;

#[cfg(test)]
pub mod tests;

pub use crate::context::{quit, Context, ContextBuilder};
pub use crate::error::*;
<|endoftext|>