<commit_before>use futures::sync::mpsc::UnboundedSender;

use super::inputs::Input;
use super::token::Token;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum TokenDestination {
    Stream,
    Queue,
    Ignore
}

/// A `struct` which contains the complete state of a `Parser`.
pub struct ParserState<'a, Rule> {
    input:       &'a Input,
    pos:         usize,
    sender:      UnboundedSender<Token<Rule>>,
    queue:       Vec<Token<Rule>>,
    dest:        TokenDestination,
    is_atomic:   bool,
    attempts:    Vec<Rule>,
    attempt_pos: usize
}

impl<'a, Rule: Clone + Ord> ParserState<'a, Rule> {
    /// Creates a new `ParserState` from an `Input` and an `UnboundedSender`.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("a");
    ///
    /// let state = ParserState::new(&input, s);
    /// # }
    /// ```
    pub fn new(input: &'a Input, sender: UnboundedSender<Token<Rule>>) -> ParserState<'a, Rule> {
        ParserState {
            input:       input,
            pos:         0,
            sender:      sender,
            queue:       vec![],
            dest:        TokenDestination::Stream,
            is_atomic:   false,
            attempts:    vec![],
            attempt_pos: 0
        }
    }

    /// Sends `token` according to the state's destination. The `Token` will get sent to the
    /// `TokenStream`, queued up to be sent later, or ignored.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// state.send(Token::Start((), 0));
    /// # }
    /// ```
    #[inline]
    pub fn send(&mut self, token: Token<Rule>) {
        match self.dest {
            TokenDestination::Stream => self.sender.send(token).unwrap(),
            TokenDestination::Queue  => self.queue.push(token),
            TokenDestination::Ignore => ()
        };
    }

    /// Matches `string`, returns whether it matched, and advances the position with `string.len()`
    /// in case it did.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("abcd");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(state.match_string("ab"));
    /// assert!(state.match_string("cd"));
    /// # }
    /// ```
    #[inline]
    pub fn match_string(&mut self, string: &str) -> bool {
        let result = self.input.match_string(string, self.pos);

        if result {
            self.pos += string.len();
        }

        result
    }

    /// Matches `string` case insensitively, returns whether it matched, and advances the position
    /// with `string.len()` in case it did.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("AbcD");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(state.match_insensitive("ab"));
    /// assert!(state.match_insensitive("cd"));
    /// # }
    /// ```
    #[inline]
    pub fn match_insensitive(&mut self, string: &str) -> bool {
        let result = self.input.match_insensitive(string, self.pos);

        if result {
            self.pos += string.len();
        }

        result
    }

    /// Matches if the current `char` is between `left` and `right`, and advances the position with
    /// one `char` length in case it did.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("Cd");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(state.match_range('A', 'Z'));
    /// assert!(state.match_range('a', 'z'));
    /// # }
    /// ```
    #[inline]
    pub fn match_range(&mut self, left: char, right: char) -> bool {
        let result = self.input.match_range(left, right, self.pos);

        if result {
            self.pos += left.len_utf8();
        }

        result
    }

    /// Matches the current `rule`, queues up all generated `Token`s, and reverts the state if the
    /// `rule` fails.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("abacad");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(state.queued(|state| {
    ///     state.match_string("a") && state.match_string("b")
    /// }));
    /// assert!(state.queued(|state| {
    ///     state.match_string("a") && state.match_string("c")
    /// }));
    /// assert!(!state.queued(|state| {
    ///     state.match_string("a") && state.match_string("c")
    /// }));
    /// # }
    /// ```
    #[inline]
    pub fn queued<F>(&mut self, rule: F) -> bool
        where F: FnOnce(&mut ParserState<'a, Rule>) -> bool {

        let initial_pos = self.pos;
        let should_toggle = self.dest == TokenDestination::Stream;

        if should_toggle {
            self.dest = TokenDestination::Queue;
        }

        let result = rule(self);

        if should_toggle {
            self.dest = TokenDestination::Stream;

            if result {
                for token in self.queue.drain(..) {
                    self.sender.send(token).unwrap();
                }
            } else {
                self.queue.clear();
            }
        }

        if !result {
            self.pos = initial_pos;
        }

        result
    }

    /// Matches the current `rule`, ignores all `Token`s, and reverts the state.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("ab");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(state.ignored(|state| {
    ///     state.send(Token::Start((), 0));
    ///     state.match_string("a") && state.match_string("b")
    /// }));
    /// assert!(state.ignored(|state| {
    ///     state.send(Token::Start((), 0));
    ///     state.match_string("a") && state.match_string("b")
    /// }));
    /// assert!(!state.ignored(|state| {
    ///     state.send(Token::Start((), 0));
    ///     state.match_string("a") && state.match_string("c")
    /// }));
    /// # }
    /// ```
    #[inline]
    pub fn ignored<F>(&mut self, rule: F) -> bool
        where F: FnOnce(&mut ParserState<'a, Rule>) -> bool {

        let initial_pos = self.pos;
        let should_toggle = self.dest != TokenDestination::Ignore;
        let initial_dest = self.dest;

        if should_toggle {
            self.dest = TokenDestination::Ignore;
        }

        let result = rule(self);

        if should_toggle {
            self.dest = initial_dest;
        }

        self.pos = initial_pos;

        result
    }

    /// Matches the current `rule` while toggling atomicity.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(!state.is_atomic());
    /// state.atomic(true, |state| {
    ///     assert!(state.is_atomic());
    ///     true
    /// });
    /// assert!(!state.is_atomic());
    /// # }
    /// ```
    #[inline]
    pub fn atomic<F>(&mut self, is_atomic: bool, rule: F) -> bool
        where F: FnOnce(&mut ParserState<'a, Rule>) -> bool {

        let should_toggle = self.is_atomic != is_atomic;

        if should_toggle {
            self.is_atomic = is_atomic;
        }

        let result = rule(self);

        if should_toggle {
            self.is_atomic = !is_atomic;
        }

        result
    }

    /// Returns the state's current atomicity.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(!state.is_atomic());
    /// # }
    /// ```
    #[inline]
    pub fn is_atomic(&self) -> bool {
        self.is_atomic
    }

    /// Keeps track of failed rule attempts. It should be called when a `Rule` fails at current
    /// `pos`.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let (s, _) = unbounded::<Token<Rule>>();
    /// let input = StringInput::new("a");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// state.track(Rule::a);
    /// assert_eq!(state.attempts(), (vec![Rule::a], 0));
    ///
    /// state.match_string("a");
    ///
    /// state.track(Rule::b);
    /// assert_eq!(state.attempts(), (vec![Rule::b], 1));
    /// # }
    /// ```
    #[inline]
    pub fn track(&mut self, rule: Rule) {
        if self.is_atomic || self.dest == TokenDestination::Ignore {
            return
        }

        if self.attempts.is_empty() {
            self.attempts.push(rule);

            self.attempt_pos = self.pos;
        } else {
            if self.pos == self.attempt_pos {
                self.attempts.push(rule);
            } else if self.pos > self.attempt_pos {
                self.attempts.clear();
                self.attempts.push(rule);

                self.attempt_pos = self.pos;
            }
        }
    }

    /// Returns a `Vec` of all attempted `Rule`s at the deepest position where the parsing last
    /// stopped. It only returns leaves from the rule tree.
    ///
    /// It is commonly used for error reporting and debugging grammars.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// state.track(());
    /// assert_eq!(state.attempts(), (vec![()], 0));
    /// # }
    /// ```
    #[inline]
    pub fn attempts(&mut self) -> (Vec<Rule>, usize) {
        self.attempts.sort();
        self.attempts.dedup();

        (self.attempts.iter().cloned().collect(), self.attempt_pos)
    }
}
<commit_msg>Completed ParserState implementation.<commit_after>use futures::sync::mpsc::UnboundedSender;

use super::inputs::Input;
use super::token::Token;

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum TokenDestination {
    Stream,
    Queue,
    Ignore
}

/// A `struct` which contains the complete state of a `Parser`.
pub struct ParserState<'a, Rule> {
    input:           &'a Input,
    pos:             usize,
    sender:          UnboundedSender<Token<Rule>>,
    queue:           Vec<Token<Rule>>,
    dest:            TokenDestination,
    is_atomic:       bool,
    attempts:        Vec<Rule>,
    attempt_pos:     usize,
    /// Stack of captured strings
    pub stack:       Vec<&'a str>,
    /// End-of-input matched flag
    pub eoi_matched: bool
}

impl<'a, Rule: Clone + Ord> ParserState<'a, Rule> {
    /// Creates a new `ParserState` from an `Input` and an `UnboundedSender`.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("a");
    ///
    /// let state = ParserState::new(&input, s);
    /// # }
    /// ```
    pub fn new(input: &'a Input, sender: UnboundedSender<Token<Rule>>) -> ParserState<'a, Rule> {
        ParserState {
            input:       input,
            pos:         0,
            sender:      sender,
            queue:       vec![],
            dest:        TokenDestination::Stream,
            is_atomic:   false,
            attempts:    vec![],
            attempt_pos: 0,
            stack:       vec![],
            eoi_matched: false
        }
    }

    /// Sends `token` according to the state's destination. The `Token` will get sent to the
    /// `TokenStream`, queued up to be sent later, or ignored.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// state.send(Token::Start((), 0));
    /// # }
    /// ```
    #[inline]
    pub fn send(&mut self, token: Token<Rule>) {
        match self.dest {
            TokenDestination::Stream => self.sender.send(token).unwrap(),
            TokenDestination::Queue  => self.queue.push(token),
            TokenDestination::Ignore => ()
        };
    }

    /// Returns whether the position is at the start of the `Input`.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("ab");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(state.at_start());
    /// state.match_string("ab");
    /// assert!(!state.at_start());
    /// # }
    /// ```
    #[inline]
    pub fn at_start(&self) -> bool {
        self.pos == 0
    }

    /// Returns whether the position is at the end of the `Input`.
    ///
    /// # Examples
    ///
    /// ```no_run
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("ab");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(!state.at_end());
    /// state.match_string("ab");
    /// assert!(state.at_end());
    /// # }
    /// ```
    #[inline]
    pub fn at_end(&self) -> bool {
        self.pos == self.input.len()
    }

    /// Matches `string`, returns whether it matched, and advances the position with `string.len()`
    /// in case it did.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("abcd");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(state.match_string("ab"));
    /// assert!(state.match_string("cd"));
    /// # }
    /// ```
    #[inline]
    pub fn match_string(&mut self, string: &str) -> bool {
        let result = self.input.match_string(string, self.pos);

        if result {
            self.pos += string.len();
        }

        result
    }

    /// Matches `string` case insensitively, returns whether it matched, and advances the position
    /// with `string.len()` in case it did.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("AbcD");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(state.match_insensitive("ab"));
    /// assert!(state.match_insensitive("cd"));
    /// # }
    /// ```
    #[inline]
    pub fn match_insensitive(&mut self, string: &str) -> bool {
        let result = self.input.match_insensitive(string, self.pos);

        if result {
            self.pos += string.len();
        }

        result
    }

    /// Matches if the current `char` is between `left` and `right`, and advances the position with
    /// one `char` length in case it did.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("Cd");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(state.match_range('A', 'Z'));
    /// assert!(state.match_range('a', 'z'));
    /// # }
    /// ```
    #[inline]
    pub fn match_range(&mut self, left: char, right: char) -> bool {
        let result = self.input.match_range(left, right, self.pos);

        if result {
            self.pos += left.len_utf8();
        }

        result
    }

    /// Matches the current `rule`, queues up all generated `Token`s, and reverts the state if the
    /// `rule` fails.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("abacad");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(state.queued(|state| {
    ///     state.match_string("a") && state.match_string("b")
    /// }));
    /// assert!(state.queued(|state| {
    ///     state.match_string("a") && state.match_string("c")
    /// }));
    /// assert!(!state.queued(|state| {
    ///     state.match_string("a") && state.match_string("c")
    /// }));
    /// # }
    /// ```
    #[inline]
    pub fn queued<F>(&mut self, rule: F) -> bool
        where F: FnOnce(&mut ParserState<'a, Rule>) -> bool {

        let initial_pos = self.pos;
        let should_toggle = self.dest == TokenDestination::Stream;

        if should_toggle {
            self.dest = TokenDestination::Queue;
        }

        let result = rule(self);

        if should_toggle {
            self.dest = TokenDestination::Stream;

            if result {
                for token in self.queue.drain(..) {
                    self.sender.send(token).unwrap();
                }
            } else {
                self.queue.clear();
            }
        }

        if !result {
            self.pos = initial_pos;
        }

        result
    }

    /// Matches the current `rule`, ignores all `Token`s, and reverts the state.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("ab");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(state.ignored(|state| {
    ///     state.send(Token::Start((), 0));
    ///     state.match_string("a") && state.match_string("b")
    /// }));
    /// assert!(state.ignored(|state| {
    ///     state.send(Token::Start((), 0));
    ///     state.match_string("a") && state.match_string("b")
    /// }));
    /// assert!(!state.ignored(|state| {
    ///     state.send(Token::Start((), 0));
    ///     state.match_string("a") && state.match_string("c")
    /// }));
    /// # }
    /// ```
    #[inline]
    pub fn ignored<F>(&mut self, rule: F) -> bool
        where F: FnOnce(&mut ParserState<'a, Rule>) -> bool {

        let initial_pos = self.pos;
        let should_toggle = self.dest != TokenDestination::Ignore;
        let initial_dest = self.dest;

        if should_toggle {
            self.dest = TokenDestination::Ignore;
        }

        let result = rule(self);

        if should_toggle {
            self.dest = initial_dest;
        }

        self.pos = initial_pos;

        result
    }

    /// Matches the current `rule` while toggling atomicity.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(!state.is_atomic());
    /// state.atomic(true, |state| {
    ///     assert!(state.is_atomic());
    ///     true
    /// });
    /// assert!(!state.is_atomic());
    /// # }
    /// ```
    #[inline]
    pub fn atomic<F>(&mut self, is_atomic: bool, rule: F) -> bool
        where F: FnOnce(&mut ParserState<'a, Rule>) -> bool {

        let should_toggle = self.is_atomic != is_atomic;

        if should_toggle {
            self.is_atomic = is_atomic;
        }

        let result = rule(self);

        if should_toggle {
            self.is_atomic = !is_atomic;
        }

        result
    }

    /// Returns the state's current atomicity.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// assert!(!state.is_atomic());
    /// # }
    /// ```
    #[inline]
    pub fn is_atomic(&self) -> bool {
        self.is_atomic
    }

    /// Keeps track of failed rule attempts. It should be called when a `Rule` fails at current
    /// `pos`.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// #[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
    /// enum Rule {
    ///     a,
    ///     b
    /// }
    ///
    /// let (s, _) = unbounded::<Token<Rule>>();
    /// let input = StringInput::new("a");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// state.track(Rule::a);
    /// assert_eq!(state.attempts(), (vec![Rule::a], 0));
    ///
    /// state.match_string("a");
    ///
    /// state.track(Rule::b);
    /// assert_eq!(state.attempts(), (vec![Rule::b], 1));
    /// # }
    /// ```
    #[inline]
    pub fn track(&mut self, rule: Rule) {
        if self.is_atomic || self.dest == TokenDestination::Ignore {
            return
        }

        if self.attempts.is_empty() {
            self.attempts.push(rule);

            self.attempt_pos = self.pos;
        } else {
            if self.pos == self.attempt_pos {
                self.attempts.push(rule);
            } else if self.pos > self.attempt_pos {
                self.attempts.clear();
                self.attempts.push(rule);

                self.attempt_pos = self.pos;
            }
        }
    }

    /// Returns a `Vec` of all attempted `Rule`s at the deepest position where the parsing last
    /// stopped. It only returns leaves from the rule tree.
    ///
    /// It is commonly used for error reporting and debugging grammars.
    ///
    /// # Examples
    ///
    /// ```
    /// # extern crate futures;
    /// # extern crate pest;
    /// # use futures::sync::mpsc::unbounded;
    /// # use pest::{ParserState, StringInput, Token};
    /// # fn main() {
    /// let (s, _) = unbounded::<Token<()>>();
    /// let input = StringInput::new("");
    /// let mut state = ParserState::new(&input, s);
    ///
    /// state.track(());
    /// assert_eq!(state.attempts(), (vec![()], 0));
    /// # }
    /// ```
    #[inline]
    pub fn attempts(&mut self) -> (Vec<Rule>, usize) {
        self.attempts.sort();
        self.attempts.dedup();

        (self.attempts.iter().cloned().collect(), self.attempt_pos)
    }
}
<|endoftext|>


<commit_before>
use std::hash::{Hash, Hasher};
use std::cmp::Ordering;

use ring::digest::Algorithm;

use tree::{Tree, LeavesIterator, LeavesIntoIterator};
use hashutils::{Hashable, HashUtils};

use proof::{Proof, Lemma};

/// A Merkle tree is a binary tree, with values of type `T` at the leafs,
/// and where every internal node holds the hash of the concatenation of the hashes of its children nodes.
#[derive(Clone, Debug)]
pub struct MerkleTree<T> {
    /// The hashing algorithm used by this Merkle tree
    pub algorithm: &'static Algorithm,

    /// The root of the inner binary tree
    root: Tree<T>,

    /// The height of the tree
    height: usize,

    /// The number of leaf nodes in the tree
    count: usize,
}

impl<T: PartialEq> PartialEq for MerkleTree<T> {
    fn eq(&self, other: &MerkleTree<T>) -> bool {
        self.root == other.root && self.height == other.height && self.count == other.count
    }
}

impl<T: Eq> Eq for MerkleTree<T> {}

impl<T: Ord> PartialOrd for MerkleTree<T> {
    fn partial_cmp(&self, other: &MerkleTree<T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<T: Ord> Ord for MerkleTree<T> {
    fn cmp(&self, other: &MerkleTree<T>) -> Ordering {
        self.height
            .cmp(&other.height)
            .then(self.count.cmp(&other.count))
            .then_with(|| self.root.cmp(&other.root))
    }
}

impl<T: Hash> Hash for MerkleTree<T> {
    fn hash<H: Hasher>(&self, state: &mut H) {
        <Tree<T> as Hash>::hash(&self.root, state);
        self.height.hash(state);
        self.count.hash(state);
    }
}

impl<T> MerkleTree<T> {
    /// Constructs a Merkle Tree from a vector of data blocks.
    /// Returns `None` if `values` is empty.
    pub fn from_vec(algorithm: &'static Algorithm, values: Vec<T>) -> Self
    where
        T: Hashable,
    {

        if values.is_empty() {
            return MerkleTree {
                algorithm: algorithm,
                root: Tree::empty(algorithm.hash_empty()),
                height: 0,
                count: 0,
            };
        }

        let count = values.len();
        let mut height = 0;
        let mut cur = Vec::with_capacity(count);

        for v in values {
            let leaf = Tree::new_leaf(algorithm, v);
            cur.push(leaf);
        }

        while cur.len() > 1 {
            let mut next = Vec::new();
            while !cur.is_empty() {
                if cur.len() == 1 {
                    next.push(cur.remove(0));
                } else {
                    let left = cur.remove(0);
                    let right = cur.remove(0);

                    let combined_hash = algorithm.hash_nodes(left.hash(), right.hash());

                    let node = Tree::Node {
                        hash: combined_hash.as_ref().into(),
                        left: Box::new(left),
                        right: Box::new(right),
                    };

                    next.push(node);
                }
            }

            height += 1;

            cur = next;
        }

        debug_assert!(cur.len() == 1);

        let root = cur.remove(0);

        MerkleTree {
            algorithm: algorithm,
            root: root,
            height: height,
            count: count,
        }
    }

    /// Returns the root hash of Merkle tree
    pub fn root_hash(&self) -> &Vec<u8> {
        self.root.hash()
    }

    /// Returns the height of Merkle tree
    pub fn height(&self) -> usize {
        self.height
    }

    /// Returns the number of leaves in the Merkle tree
    pub fn count(&self) -> usize {
        self.count
    }

    /// Returns whether the Merkle tree is empty or not
    pub fn is_empty(&self) -> bool {
        self.count() == 0
    }

    /// Generate an inclusion proof for the given value.
    /// Returns `None` if the given value is not found in the tree.
    pub fn gen_proof(&self, value: T) -> Option<Proof<T>>
    where
        T: Hashable,
    {

        let root_hash = self.root_hash().clone();
        let leaf_hash = self.algorithm.hash_leaf(&value);

        Lemma::new(&self.root, leaf_hash.as_ref()).map(|lemma| {
            Proof::new(self.algorithm, root_hash, lemma, value)
        })
    }

    /// Creates an `Iterator` over the values contained in this Merkle tree.
    pub fn iter(&self) -> LeavesIterator<T> {
        self.root.iter()
    }
}

impl<T> IntoIterator for MerkleTree<T> {
    type Item = T;
    type IntoIter = LeavesIntoIterator<T>;

    /// Creates a consuming iterator, that is, one that moves each value out of the Merkle tree.
    /// The tree cannot be used after calling this.
    fn into_iter(self) -> Self::IntoIter {
        self.root.into_iter()
    }
}

impl<'a, T> IntoIterator for &'a MerkleTree<T> {
    type Item = &'a T;
    type IntoIter = LeavesIterator<'a, T>;

    /// Creates a borrowing `Iterator` over the values contained in this Merkle tree.
    fn into_iter(self) -> Self::IntoIter {
        self.root.iter()
    }
}
<commit_msg>Take hashing algorithm into account for Eq/Ord impls.<commit_after>
use std::hash::{Hash, Hasher};
use std::cmp::Ordering;

use ring::digest::Algorithm;

use tree::{Tree, LeavesIterator, LeavesIntoIterator};
use hashutils::{Hashable, HashUtils};

use proof::{Proof, Lemma};

/// A Merkle tree is a binary tree, with values of type `T` at the leafs,
/// and where every internal node holds the hash of the concatenation of the hashes of its children nodes.
#[derive(Clone, Debug)]
pub struct MerkleTree<T> {
    /// The hashing algorithm used by this Merkle tree
    pub algorithm: &'static Algorithm,

    /// The root of the inner binary tree
    root: Tree<T>,

    /// The height of the tree
    height: usize,

    /// The number of leaf nodes in the tree
    count: usize,
}

impl<T: PartialEq> PartialEq for MerkleTree<T> {
    #[allow(trivial_casts)]
    fn eq(&self, other: &MerkleTree<T>) -> bool {
        self.root == other.root && self.height == other.height && self.count == other.count &&
            (self.algorithm as *const Algorithm) == (other.algorithm as *const Algorithm)
    }
}

impl<T: Eq> Eq for MerkleTree<T> {}

impl<T: Ord> PartialOrd for MerkleTree<T> {
    fn partial_cmp(&self, other: &MerkleTree<T>) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}

impl<T: Ord> Ord for MerkleTree<T> {
    #[allow(trivial_casts)]
    fn cmp(&self, other: &MerkleTree<T>) -> Ordering {
        self.height
            .cmp(&other.height)
            .then(self.count.cmp(&other.count))
            .then((self.algorithm as *const Algorithm).cmp(
                &(other.algorithm as
                      *const Algorithm),
            ))
            .then_with(|| self.root.cmp(&other.root))
    }
}

impl<T: Hash> Hash for MerkleTree<T> {
    #[allow(trivial_casts)]
    fn hash<H: Hasher>(&self, state: &mut H) {
        <Tree<T> as Hash>::hash(&self.root, state);
        self.height.hash(state);
        self.count.hash(state);
        (self.algorithm as *const Algorithm).hash(state);
    }
}

impl<T> MerkleTree<T> {
    /// Constructs a Merkle Tree from a vector of data blocks.
    /// Returns `None` if `values` is empty.
    pub fn from_vec(algorithm: &'static Algorithm, values: Vec<T>) -> Self
    where
        T: Hashable,
    {

        if values.is_empty() {
            return MerkleTree {
                algorithm: algorithm,
                root: Tree::empty(algorithm.hash_empty()),
                height: 0,
                count: 0,
            };
        }

        let count = values.len();
        let mut height = 0;
        let mut cur = Vec::with_capacity(count);

        for v in values {
            let leaf = Tree::new_leaf(algorithm, v);
            cur.push(leaf);
        }

        while cur.len() > 1 {
            let mut next = Vec::new();
            while !cur.is_empty() {
                if cur.len() == 1 {
                    next.push(cur.remove(0));
                } else {
                    let left = cur.remove(0);
                    let right = cur.remove(0);

                    let combined_hash = algorithm.hash_nodes(left.hash(), right.hash());

                    let node = Tree::Node {
                        hash: combined_hash.as_ref().into(),
                        left: Box::new(left),
                        right: Box::new(right),
                    };

                    next.push(node);
                }
            }

            height += 1;

            cur = next;
        }

        debug_assert!(cur.len() == 1);

        let root = cur.remove(0);

        MerkleTree {
            algorithm: algorithm,
            root: root,
            height: height,
            count: count,
        }
    }

    /// Returns the root hash of Merkle tree
    pub fn root_hash(&self) -> &Vec<u8> {
        self.root.hash()
    }

    /// Returns the height of Merkle tree
    pub fn height(&self) -> usize {
        self.height
    }

    /// Returns the number of leaves in the Merkle tree
    pub fn count(&self) -> usize {
        self.count
    }

    /// Returns whether the Merkle tree is empty or not
    pub fn is_empty(&self) -> bool {
        self.count() == 0
    }

    /// Generate an inclusion proof for the given value.
    /// Returns `None` if the given value is not found in the tree.
    pub fn gen_proof(&self, value: T) -> Option<Proof<T>>
    where
        T: Hashable,
    {

        let root_hash = self.root_hash().clone();
        let leaf_hash = self.algorithm.hash_leaf(&value);

        Lemma::new(&self.root, leaf_hash.as_ref()).map(|lemma| {
            Proof::new(self.algorithm, root_hash, lemma, value)
        })
    }

    /// Creates an `Iterator` over the values contained in this Merkle tree.
    pub fn iter(&self) -> LeavesIterator<T> {
        self.root.iter()
    }
}

impl<T> IntoIterator for MerkleTree<T> {
    type Item = T;
    type IntoIter = LeavesIntoIterator<T>;

    /// Creates a consuming iterator, that is, one that moves each value out of the Merkle tree.
    /// The tree cannot be used after calling this.
    fn into_iter(self) -> Self::IntoIter {
        self.root.into_iter()
    }
}

impl<'a, T> IntoIterator for &'a MerkleTree<T> {
    type Item = &'a T;
    type IntoIter = LeavesIterator<'a, T>;

    /// Creates a borrowing `Iterator` over the values contained in this Merkle tree.
    fn into_iter(self) -> Self::IntoIter {
        self.root.iter()
    }
}
<|endoftext|>


<commit_before>use std::any::TypeId;
use std::collections::HashMap;
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use std::sync::atomic::{AtomicUsize, Ordering};
use mopa::Any;
use {Index, Generation, Entity, StorageBase, Storage};
use bitset::{AtomicBitSet, BitSet, BitSetLike, BitSetOr};
use join::{Open, Get};

/// Abstract component type. Doesn't have to be Copy or even Clone.
pub trait Component: Any + Sized {
    /// Associated storage type for this component.
    type Storage: Storage<Component=Self> + Any + Send + Sync;
}

/// A custom entity guard used to hide the the fact that Generations
/// is lazily created and updated. For this to be useful it _must_
/// be joined with a component. This is because the Generation table
/// includes every possible Generation of Entities even if they
/// have never been
pub struct Entities<'a> {
    guard: RwLockReadGuard<'a, Allocator>,
}

impl<'a> Open for &'a Entities<'a> {
    type Value = Self;
    type Mask = BitSetOr<&'a BitSet, &'a AtomicBitSet>;
    fn open(self) -> (Self::Mask, Self::Value) {
        (BitSetOr(&self.guard.alive, &self.guard.raised), self)
    }
}

impl<'a> Get for &'a Entities<'a> {
    type Value = Entity;
    unsafe fn get(&self, idx: Index) -> Self::Value {
        let gen = self.guard.generations.get(idx as usize)
            .map(|&gen| if gen.is_alive() { gen } else { gen.raised() })
            .unwrap_or(Generation(1));
        Entity(idx, gen)
    }
}

/// Helper builder for entities.
pub struct EntityBuilder<'a>(Entity, &'a World);

impl<'a> EntityBuilder<'a> {
    /// Adds a `Component` value to the new `Entity`.
    pub fn with<T: Component>(self, value: T) -> EntityBuilder<'a> {
        self.1.write::<T>().insert(self.0, value);
        self
    }
    /// Finishes entity construction.
    pub fn build(self) -> Entity {
        self.0
    }
}

struct Allocator {
    generations: Vec<Generation>,
    alive: BitSet,
    raised: AtomicBitSet,
    killed: AtomicBitSet,
    start_from: AtomicUsize
}

impl Allocator {
    fn new() -> Allocator {
        Allocator {
            generations: vec![],
            alive: BitSet::new(),
            raised: AtomicBitSet::with_capacity(1_000_000),
            killed: AtomicBitSet::with_capacity(1_000_000),
            start_from: AtomicUsize::new(0)
        }
    }

    fn kill(&self, idx: Index) {
        self.killed.add_atomic(idx);
    }

    /// Attempt to move the `start_from` value
    fn update_start_from(&self, start_from: usize) {
        loop {
            let current = self.start_from.load(Ordering::Relaxed);

            // if the current value is bigger then ours, we bail
            if current >= start_from {
                return;
            }

            if start_from == self.start_from.compare_and_swap(current, start_from, Ordering::Relaxed) {
                return;
            }
        }
    }

    /// Allocate a new entity
    fn allocate_atomic(&self) -> Entity {
        let idx = self.start_from.load(Ordering::Relaxed);
        for i in idx.. {
            if !self.alive.contains(i as Index) && !self.raised.add_atomic(i as Index) {
                self.update_start_from(i+1);

                let gen = self.generations.get(idx as usize)
                    .map(|&gen| if gen.is_alive() { gen } else { gen.raised() })
                    .unwrap_or(Generation(1));

                return Entity(i as Index, gen);
            }
        }
        panic!("No entities left to allocate")
    }

    /// Allocate a new entity
    fn allocate(&mut self) -> Entity {
        let idx = self.start_from.load(Ordering::Relaxed);
        for i in idx.. {
            if !self.raised.contains(i as Index) && !self.alive.add(i as Index) {
                self.update_start_from(i+1);

                while self.generations.len() <= i as usize {
                    self.generations.push(Generation(0));
                }
                self.generations[i as usize] = self.generations[i as usize].raised();

                return Entity(i as Index, self.generations[i as usize]);
            }
        }
        panic!("No entities left to allocate")
    }

    fn merge(&mut self) -> Vec<Entity> {
        let mut deleted = vec![];

        for i in (&self.raised).iter() {
            while self.generations.len() <= i as usize {
                self.generations.push(Generation(0));
            }
            self.generations[i as usize] = self.generations[i as usize].raised();
            self.alive.add(i);
        }
        self.raised.clear();

        if let Some(lowest) = (&self.killed).iter().next() {
            if lowest < self.start_from.load(Ordering::Relaxed) as Index {
                self.start_from.store(lowest as usize, Ordering::Relaxed);
            }
        }

        for i in (&self.killed).iter() {
            self.alive.remove(i);
            self.generations[i as usize].die();
            deleted.push(Entity(i, self.generations[i as usize]))
        }
        self.killed.clear();

        deleted
    }
}

/// Entity creation iterator. Will yield new empty entities infinitely.
/// Useful for bulk entity construction, since the locks are only happening once.
pub struct CreateEntities<'a> {
    allocate: RwLockWriteGuard<'a, Allocator>,
}

impl<'a> Iterator for CreateEntities<'a> {
    type Item = Entity;
    fn next(&mut self) -> Option<Entity> {
        Some(self.allocate.allocate())
    }
}

trait StorageLock: Any + Send + Sync {
    fn del_slice(&self, &[Entity]);
}

mopafy!(StorageLock);

impl<S: StorageBase + Any + Send + Sync> StorageLock for RwLock<S> {
    fn del_slice(&self, entities: &[Entity]) {
        let mut guard = self.write().unwrap();
        for &e in entities.iter() {
            guard.del(e);
        }
    }
}

/// The `World` struct contains all the data, which is entities and their components.
/// All methods are supposed to be valid for any context they are available in.
pub struct World {
    allocator: RwLock<Allocator>,
    components: HashMap<TypeId, Box<StorageLock>>,
}

impl World {
    /// Creates a new empty `World`.
    pub fn new() -> World {
        World {
            components: HashMap::new(),
            allocator: RwLock::new(Allocator::new())
        }
    }
    /// Registers a new component type.
    pub fn register<T: Component>(&mut self) {
        let any = RwLock::new(T::Storage::new());
        self.components.insert(TypeId::of::<T>(), Box::new(any));
    }
    /// Unregisters a component type.
    pub fn unregister<T: Component>(&mut self) -> Option<T::Storage> {
        self.components.remove(&TypeId::of::<T>()).map(|boxed|
            match boxed.downcast::<RwLock<T::Storage>>() {
                Ok(b) => (*b).into_inner().unwrap(),
                Err(_) => panic!("Unable to downcast the storage type"),
            }
        )
    }
    fn lock<T: Component>(&self) -> &RwLock<T::Storage> {
        let boxed = self.components.get(&TypeId::of::<T>())
            .expect("Tried to perform an operation on type that was not registered");
        boxed.downcast_ref().unwrap()
    }
    /// Locks a component's storage for reading.
    pub fn read<T: Component>(&self) -> RwLockReadGuard<T::Storage> {
        self.lock::<T>().read().unwrap()
    }
    /// Locks a component's storage for writing.
    pub fn write<T: Component>(&self) -> RwLockWriteGuard<T::Storage> {
        self.lock::<T>().write().unwrap()
    }
    /// Returns the entity iterator.
    pub fn entities(&self) -> Entities {
        Entities {
            guard: self.allocator.read().unwrap(),
        }
    }
    /// Returns the entity creation iterator. Can be used to create many
    /// empty entities at once without paying the locking overhead.
    pub fn create_iter(&self) -> CreateEntities {
        CreateEntities {
            allocate: self.allocator.write().unwrap(),
        }
    }
    /// Creates a new entity instantly, locking the generations data.
    pub fn create_now(&self) -> EntityBuilder {
        let id = self.allocator.write().unwrap().allocate();
        EntityBuilder(id, self)
    }
    /// Deletes a new entity instantly, locking the generations data.
    pub fn delete_now(&self, entity: Entity) {
        for comp in self.components.values() {
            comp.del_slice(&[entity]);
        }
        let mut gens = self.allocator.write().unwrap();
        gens.generations[entity.get_id()].die();
        gens.alive.remove(entity.get_id() as Index);
        gens.raised.remove(entity.get_id() as Index);
        if entity.get_id() < gens.start_from.load(Ordering::Relaxed) {
            gens.start_from.store(entity.get_id(), Ordering::Relaxed);
        }
    }
    /// Creates a new entity dynamically.
    pub fn create_later(&self) -> Entity {
        let allocator = self.allocator.read().unwrap();
        allocator.allocate_atomic()
    }
    /// Deletes an entity dynamically.
    pub fn delete_later(&self, entity: Entity) {
        let allocator = self.allocator.read().unwrap();
        allocator.kill(entity.get_id() as Index);
    }
    /// Returns `true` if the given `Entity` is alive.
    pub fn is_alive(&self, entity: Entity) -> bool {
        debug_assert!(entity.get_gen().is_alive());
        let gens = self.allocator.read().unwrap();
        gens.generations.get(entity.get_id()).map(|&x| x == entity.get_gen()).unwrap_or(false)
    }
    /// Merges in the appendix, recording all the dynamically created
    /// and deleted entities into the persistent generations vector.
    /// Also removes all the abandoned components.
    pub fn merge(&self) {
        let mut allocator = self.allocator.write().unwrap();

        let temp_list = allocator.merge();
        for comp in self.components.values() {
            comp.del_slice(&temp_list);
        }
    }
}

/// System fetch-time argument. The fetch is executed at the start of the run.
/// It contains a subset of `World` methods that make sense during initialization.
#[derive(Copy, Clone)]
pub struct FetchArg<'a>(&'a World);

impl<'a> FetchArg<'a> {
    /// Constructs a new `FetchArg`, not supposed to be used.
    #[doc(hidden)]
    pub fn new(w: &'a World) -> FetchArg<'a> {
        FetchArg(w)
    }
    /// Locks a `Component` for reading.
    pub fn read<T: Component>(self) -> RwLockReadGuard<'a, T::Storage> {
        self.0.read::<T>()
    }
    /// Locks a `Component` for writing.
    pub fn write<T: Component>(self) -> RwLockWriteGuard<'a, T::Storage> {
        self.0.write::<T>()
    }
    /// Returns the entity iterator.
    pub fn entities(self) -> Entities<'a> {
        self.0.entities()
    }
}
<commit_msg>use MAX_EID<commit_after>use std::any::TypeId;
use std::collections::HashMap;
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
use std::sync::atomic::{AtomicUsize, Ordering};
use mopa::Any;
use {Index, Generation, Entity, StorageBase, Storage};
use bitset::{AtomicBitSet, BitSet, BitSetLike, BitSetOr, MAX_EID};
use join::{Open, Get};

/// Abstract component type. Doesn't have to be Copy or even Clone.
pub trait Component: Any + Sized {
    /// Associated storage type for this component.
    type Storage: Storage<Component=Self> + Any + Send + Sync;
}

/// A custom entity guard used to hide the the fact that Generations
/// is lazily created and updated. For this to be useful it _must_
/// be joined with a component. This is because the Generation table
/// includes every possible Generation of Entities even if they
/// have never been
pub struct Entities<'a> {
    guard: RwLockReadGuard<'a, Allocator>,
}

impl<'a> Open for &'a Entities<'a> {
    type Value = Self;
    type Mask = BitSetOr<&'a BitSet, &'a AtomicBitSet>;
    fn open(self) -> (Self::Mask, Self::Value) {
        (BitSetOr(&self.guard.alive, &self.guard.raised), self)
    }
}

impl<'a> Get for &'a Entities<'a> {
    type Value = Entity;
    unsafe fn get(&self, idx: Index) -> Self::Value {
        let gen = self.guard.generations.get(idx as usize)
            .map(|&gen| if gen.is_alive() { gen } else { gen.raised() })
            .unwrap_or(Generation(1));
        Entity(idx, gen)
    }
}

/// Helper builder for entities.
pub struct EntityBuilder<'a>(Entity, &'a World);

impl<'a> EntityBuilder<'a> {
    /// Adds a `Component` value to the new `Entity`.
    pub fn with<T: Component>(self, value: T) -> EntityBuilder<'a> {
        self.1.write::<T>().insert(self.0, value);
        self
    }
    /// Finishes entity construction.
    pub fn build(self) -> Entity {
        self.0
    }
}

struct Allocator {
    generations: Vec<Generation>,
    alive: BitSet,
    raised: AtomicBitSet,
    killed: AtomicBitSet,
    start_from: AtomicUsize
}

impl Allocator {
    fn new() -> Allocator {
        Allocator {
            generations: vec![],
            alive: BitSet::new(),
            raised: AtomicBitSet::with_capacity(MAX_EID as u32),
            killed: AtomicBitSet::with_capacity(MAX_EID as u32),
            start_from: AtomicUsize::new(0)
        }
    }

    fn kill(&self, idx: Index) {
        self.killed.add_atomic(idx);
    }

    /// Attempt to move the `start_from` value
    fn update_start_from(&self, start_from: usize) {
        loop {
            let current = self.start_from.load(Ordering::Relaxed);

            // if the current value is bigger then ours, we bail
            if current >= start_from {
                return;
            }

            if start_from == self.start_from.compare_and_swap(current, start_from, Ordering::Relaxed) {
                return;
            }
        }
    }

    /// Allocate a new entity
    fn allocate_atomic(&self) -> Entity {
        let idx = self.start_from.load(Ordering::Relaxed);
        for i in idx.. {
            if !self.alive.contains(i as Index) && !self.raised.add_atomic(i as Index) {
                self.update_start_from(i+1);

                let gen = self.generations.get(idx as usize)
                    .map(|&gen| if gen.is_alive() { gen } else { gen.raised() })
                    .unwrap_or(Generation(1));

                return Entity(i as Index, gen);
            }
        }
        panic!("No entities left to allocate")
    }

    /// Allocate a new entity
    fn allocate(&mut self) -> Entity {
        let idx = self.start_from.load(Ordering::Relaxed);
        for i in idx.. {
            if !self.raised.contains(i as Index) && !self.alive.add(i as Index) {
                self.update_start_from(i+1);

                while self.generations.len() <= i as usize {
                    self.generations.push(Generation(0));
                }
                self.generations[i as usize] = self.generations[i as usize].raised();

                return Entity(i as Index, self.generations[i as usize]);
            }
        }
        panic!("No entities left to allocate")
    }

    fn merge(&mut self) -> Vec<Entity> {
        let mut deleted = vec![];

        for i in (&self.raised).iter() {
            while self.generations.len() <= i as usize {
                self.generations.push(Generation(0));
            }
            self.generations[i as usize] = self.generations[i as usize].raised();
            self.alive.add(i);
        }
        self.raised.clear();

        if let Some(lowest) = (&self.killed).iter().next() {
            if lowest < self.start_from.load(Ordering::Relaxed) as Index {
                self.start_from.store(lowest as usize, Ordering::Relaxed);
            }
        }

        for i in (&self.killed).iter() {
            self.alive.remove(i);
            self.generations[i as usize].die();
            deleted.push(Entity(i, self.generations[i as usize]))
        }
        self.killed.clear();

        deleted
    }
}

/// Entity creation iterator. Will yield new empty entities infinitely.
/// Useful for bulk entity construction, since the locks are only happening once.
pub struct CreateEntities<'a> {
    allocate: RwLockWriteGuard<'a, Allocator>,
}

impl<'a> Iterator for CreateEntities<'a> {
    type Item = Entity;
    fn next(&mut self) -> Option<Entity> {
        Some(self.allocate.allocate())
    }
}

trait StorageLock: Any + Send + Sync {
    fn del_slice(&self, &[Entity]);
}

mopafy!(StorageLock);

impl<S: StorageBase + Any + Send + Sync> StorageLock for RwLock<S> {
    fn del_slice(&self, entities: &[Entity]) {
        let mut guard = self.write().unwrap();
        for &e in entities.iter() {
            guard.del(e);
        }
    }
}

/// The `World` struct contains all the data, which is entities and their components.
/// All methods are supposed to be valid for any context they are available in.
pub struct World {
    allocator: RwLock<Allocator>,
    components: HashMap<TypeId, Box<StorageLock>>,
}

impl World {
    /// Creates a new empty `World`.
    pub fn new() -> World {
        World {
            components: HashMap::new(),
            allocator: RwLock::new(Allocator::new())
        }
    }
    /// Registers a new component type.
    pub fn register<T: Component>(&mut self) {
        let any = RwLock::new(T::Storage::new());
        self.components.insert(TypeId::of::<T>(), Box::new(any));
    }
    /// Unregisters a component type.
    pub fn unregister<T: Component>(&mut self) -> Option<T::Storage> {
        self.components.remove(&TypeId::of::<T>()).map(|boxed|
            match boxed.downcast::<RwLock<T::Storage>>() {
                Ok(b) => (*b).into_inner().unwrap(),
                Err(_) => panic!("Unable to downcast the storage type"),
            }
        )
    }
    fn lock<T: Component>(&self) -> &RwLock<T::Storage> {
        let boxed = self.components.get(&TypeId::of::<T>())
            .expect("Tried to perform an operation on type that was not registered");
        boxed.downcast_ref().unwrap()
    }
    /// Locks a component's storage for reading.
    pub fn read<T: Component>(&self) -> RwLockReadGuard<T::Storage> {
        self.lock::<T>().read().unwrap()
    }
    /// Locks a component's storage for writing.
    pub fn write<T: Component>(&self) -> RwLockWriteGuard<T::Storage> {
        self.lock::<T>().write().unwrap()
    }
    /// Returns the entity iterator.
    pub fn entities(&self) -> Entities {
        Entities {
            guard: self.allocator.read().unwrap(),
        }
    }
    /// Returns the entity creation iterator. Can be used to create many
    /// empty entities at once without paying the locking overhead.
    pub fn create_iter(&self) -> CreateEntities {
        CreateEntities {
            allocate: self.allocator.write().unwrap(),
        }
    }
    /// Creates a new entity instantly, locking the generations data.
    pub fn create_now(&self) -> EntityBuilder {
        let id = self.allocator.write().unwrap().allocate();
        EntityBuilder(id, self)
    }
    /// Deletes a new entity instantly, locking the generations data.
    pub fn delete_now(&self, entity: Entity) {
        for comp in self.components.values() {
            comp.del_slice(&[entity]);
        }
        let mut gens = self.allocator.write().unwrap();
        gens.generations[entity.get_id()].die();
        gens.alive.remove(entity.get_id() as Index);
        gens.raised.remove(entity.get_id() as Index);
        if entity.get_id() < gens.start_from.load(Ordering::Relaxed) {
            gens.start_from.store(entity.get_id(), Ordering::Relaxed);
        }
    }
    /// Creates a new entity dynamically.
    pub fn create_later(&self) -> Entity {
        let allocator = self.allocator.read().unwrap();
        allocator.allocate_atomic()
    }
    /// Deletes an entity dynamically.
    pub fn delete_later(&self, entity: Entity) {
        let allocator = self.allocator.read().unwrap();
        allocator.kill(entity.get_id() as Index);
    }
    /// Returns `true` if the given `Entity` is alive.
    pub fn is_alive(&self, entity: Entity) -> bool {
        debug_assert!(entity.get_gen().is_alive());
        let gens = self.allocator.read().unwrap();
        gens.generations.get(entity.get_id()).map(|&x| x == entity.get_gen()).unwrap_or(false)
    }
    /// Merges in the appendix, recording all the dynamically created
    /// and deleted entities into the persistent generations vector.
    /// Also removes all the abandoned components.
    pub fn merge(&self) {
        let mut allocator = self.allocator.write().unwrap();

        let temp_list = allocator.merge();
        for comp in self.components.values() {
            comp.del_slice(&temp_list);
        }
    }
}

/// System fetch-time argument. The fetch is executed at the start of the run.
/// It contains a subset of `World` methods that make sense during initialization.
#[derive(Copy, Clone)]
pub struct FetchArg<'a>(&'a World);

impl<'a> FetchArg<'a> {
    /// Constructs a new `FetchArg`, not supposed to be used.
    #[doc(hidden)]
    pub fn new(w: &'a World) -> FetchArg<'a> {
        FetchArg(w)
    }
    /// Locks a `Component` for reading.
    pub fn read<T: Component>(self) -> RwLockReadGuard<'a, T::Storage> {
        self.0.read::<T>()
    }
    /// Locks a `Component` for writing.
    pub fn write<T: Component>(self) -> RwLockWriteGuard<'a, T::Storage> {
        self.0.write::<T>()
    }
    /// Returns the entity iterator.
    pub fn entities(self) -> Entities<'a> {
        self.0.entities()
    }
}
<|endoftext|>


<commit_before>#![feature(unboxed_closures)]
#![feature(plugin)]
#![feature(box_syntax)]
#![feature(env)]
#![feature(os)]
#[macro_use]
extern crate log;
extern crate getopts;
extern crate "rustc-serialize" as rustc_serialize;
extern crate wtftw_core;
extern crate wtftw_xlib;

use std::env;
use getopts::Options;
use rustc_serialize::json;
use wtftw_core::config::Config;
use wtftw_core::window_manager::WindowManager;
use wtftw_core::window_system::*;
use wtftw_xlib::XlibWindowSystem;

pub fn parse_window_ids(ids: &str) -> Vec<(Window, u32)> {
    json::decode(ids).unwrap()
}

fn main() {
    // Parse command line arguments
    let args : Vec<String> = env::args().map(|x| x.into_string().unwrap()).collect();

    let mut options = Options::new();
    options.optopt("r", "resume", "list of window IDs to capture in resume", "WINDOW");
    let matches = match options.parse(args.into_iter().skip(1).collect::<Vec<_>>()) {
        Ok(m)  => m,
        Err(f) => panic!(f.to_string())
    };

    // Create a default config.generaluration
    let mut config = Config::initialize();
    // Initialize window system. Use xlib here for now
    debug!("initialize window system");
    let window_system = XlibWindowSystem::new();
    // Create the actual window manager
    debug!("create window manager");
    let mut window_manager = WindowManager::new(&window_system, &config.general);

    // If available, compile the config.general file at ~/.wtftw/config.general.rs
    // and call the config.generalure method
    config.compile_and_call(&mut window_manager, &window_system);
    window_manager = WindowManager::new(&window_system, &config.general);

    // Output some initial information
    info!("WTFTW - Window Tiling For The Win");
    info!("Starting wtftw on {} screen(s)", window_system.get_screen_infos().len());

    // Output information about displays
    for (i, &Rectangle(x, y, w, h)) in window_system.get_screen_infos().iter().enumerate() {
        debug!("Display {}: {}x{} ({}, {})", i, w, h, x, y);
    }

    debug!("Size of keyhandlers after config.generaluration: {}", config.internal.key_handlers.len());

    for (command, _) in config.internal.key_handlers.iter() {
        window_system.grab_keys(vec!(command.clone()));
    }

    for (&command, _) in config.internal.mouse_handlers.iter() {
        window_system.grab_button(command);
    }

    let window_ids = if matches.opt_present("r") {
        debug!("trying to manage pre-existing windows");
        debug!("found {}", matches.opt_str("r").unwrap());
        parse_window_ids(&matches.opt_str("r").unwrap())
    } else {
        Vec::new()
    };

    for (window, workspace) in window_ids {
        debug!("re-inserting window {}", window);
        window_manager = window_manager.view(&window_system, workspace, &config.general)
            .manage(&window_system, window, &config.general);
    }

    // Enter the event loop and just listen for events
    while window_manager.running {
        let event = window_system.get_event();
        debug!("Got event {:?}", event);
        match event {
            WindowSystemEvent::ClientMessageEvent(_) => {
            },
            // The X11/Wayland configuration changed, so we need to readjust the
            // screen configurations.
            WindowSystemEvent::ConfigurationNotification(window) => {
                if window_system.get_root() == window {
                    debug!("screen config.generaluration changed. Rescreen");
                    window_manager = window_manager.rescreen(&window_system);
                }
            },
            // A window asked to be reconfigured (i.e. resized, border change, etc.)
            WindowSystemEvent::ConfigurationRequest(window, window_changes, mask) => {
                let floating = window_manager.workspaces.floating.iter().any(|(&x, _)| x == window) ||
                    !window_manager.workspaces.contains(window);
                window_system.configure_window(window, window_changes, mask, floating);
                window_manager = window_manager.windows(&window_system, &config.general, |x| x.clone());
            },
            // A new window was created, so we need to manage
            // it unless it is already managed by us.
            WindowSystemEvent::WindowCreated(window) => {
                if window_manager.is_window_managed(window) || window_system.overrides_redirect(window) {
                    continue;
                }

                window_manager = window_manager.manage(&window_system, window, &config.general)
                                               .windows(&window_system, &config.general,
                                                        |x| (config.internal.manage_hook)(x.clone(),
                                                        &window_system, window));
            },
            WindowSystemEvent::WindowUnmapped(window, synthetic) => {
                if synthetic && window_manager.is_window_managed(window) {
                    window_manager = if synthetic || !window_manager.is_waiting_unmap(window) {
                        window_manager.unmanage(&window_system, window, &config.general)
                    } else {
                        window_manager.update_unmap(window)
                    }
                }
            },
            WindowSystemEvent::WindowDestroyed(window) => {
                if window_manager.is_window_managed(window) {
                    window_manager = window_manager.unmanage(&window_system, window, &config.general)
                        .remove_from_unmap(window);
                }
            },
            // The mouse pointer entered a window's region. If focus following
            // is enabled, we need to set focus to it.
            WindowSystemEvent::Enter(window) => {
                if config.general.focus_follows_mouse && window_manager.is_window_managed(window) {
                    debug!("enter event on {}", window_system.get_window_name(window));
                    window_manager = window_manager.focus(window, &window_system, &config.general);
                }
            },
            WindowSystemEvent::ButtonPressed(window, subwindow, button, _, _) => {
                let is_root = window_system.get_root() == window;
                let is_sub_root = window_system.get_root() == subwindow || subwindow == 0;
                let act = config.internal.mouse_handlers.get(&button);

                match act {
                    Some(ref action) => {
                        // If it's a root window, then it's an event we grabbed
                        if is_root && !is_sub_root {
                            let local_window_manager = window_manager.clone();
                            window_manager = action(local_window_manager, &window_system,
                                                          &config.general, subwindow);
                        }
                    }
                    None => {
                        // Otherwise just clock to focus
                        if !is_root {
                            window_manager = window_manager.focus(window, &window_system, &config.general);
                        }
                    }
                }
            },
            WindowSystemEvent::ButtonReleased => {
                // If we were dragging, release the pointer and
                // reset the dragging closure
                if let Some(_) = window_manager.dragging {
                    window_system.ungrab_pointer();
                    window_manager.dragging = None;
                }
            }
            WindowSystemEvent::KeyPressed(_, key) => {
                if config.internal.key_handlers.contains_key(&key) {
                    let local_window_manager = window_manager.clone();
                    window_manager = config.internal.key_handlers[key](local_window_manager,
                        &window_system, &config.general);
                }
            },
            WindowSystemEvent::MouseMotion(x, y) => {
                let local_window_manager = window_manager.clone();
                if let Some(drag) = window_manager.dragging {
                    debug!("dragging: {} {}", x, y);
                    window_manager = drag(x, y, local_window_manager, &window_system);
                    window_system.remove_motion_events();
                }
            },
            _ => ()
        };
        debug!("processed {:?}", event);

        if let Some(ref mut loghook) = config.internal.loghook {
            loghook(window_manager.clone(), &window_system);
        }
    }
}
<commit_msg>Replace `into_string` with `to_string`<commit_after>#![feature(unboxed_closures)]
#![feature(plugin)]
#![feature(box_syntax)]
#![feature(env)]
#![feature(os)]
#[macro_use]
extern crate log;
extern crate getopts;
extern crate "rustc-serialize" as rustc_serialize;
extern crate wtftw_core;
extern crate wtftw_xlib;

use std::env;
use getopts::Options;
use rustc_serialize::json;
use wtftw_core::config::Config;
use wtftw_core::window_manager::WindowManager;
use wtftw_core::window_system::*;
use wtftw_xlib::XlibWindowSystem;

pub fn parse_window_ids(ids: &str) -> Vec<(Window, u32)> {
    json::decode(ids).unwrap()
}

fn main() {
    // Parse command line arguments
    let args : Vec<String> = env::args().map(|x| x.to_string()).collect();

    let mut options = Options::new();
    options.optopt("r", "resume", "list of window IDs to capture in resume", "WINDOW");
    let matches = match options.parse(args.into_iter().skip(1).collect::<Vec<_>>()) {
        Ok(m)  => m,
        Err(f) => panic!(f.to_string())
    };

    // Create a default config.generaluration
    let mut config = Config::initialize();
    // Initialize window system. Use xlib here for now
    debug!("initialize window system");
    let window_system = XlibWindowSystem::new();
    // Create the actual window manager
    debug!("create window manager");
    let mut window_manager = WindowManager::new(&window_system, &config.general);

    // If available, compile the config.general file at ~/.wtftw/config.general.rs
    // and call the config.generalure method
    config.compile_and_call(&mut window_manager, &window_system);
    window_manager = WindowManager::new(&window_system, &config.general);

    // Output some initial information
    info!("WTFTW - Window Tiling For The Win");
    info!("Starting wtftw on {} screen(s)", window_system.get_screen_infos().len());

    // Output information about displays
    for (i, &Rectangle(x, y, w, h)) in window_system.get_screen_infos().iter().enumerate() {
        debug!("Display {}: {}x{} ({}, {})", i, w, h, x, y);
    }

    debug!("Size of keyhandlers after config.generaluration: {}", config.internal.key_handlers.len());

    for (command, _) in config.internal.key_handlers.iter() {
        window_system.grab_keys(vec!(command.clone()));
    }

    for (&command, _) in config.internal.mouse_handlers.iter() {
        window_system.grab_button(command);
    }

    let window_ids = if matches.opt_present("r") {
        debug!("trying to manage pre-existing windows");
        debug!("found {}", matches.opt_str("r").unwrap());
        parse_window_ids(&matches.opt_str("r").unwrap())
    } else {
        Vec::new()
    };

    for (window, workspace) in window_ids {
        debug!("re-inserting window {}", window);
        window_manager = window_manager.view(&window_system, workspace, &config.general)
            .manage(&window_system, window, &config.general);
    }

    // Enter the event loop and just listen for events
    while window_manager.running {
        let event = window_system.get_event();
        debug!("Got event {:?}", event);
        match event {
            WindowSystemEvent::ClientMessageEvent(_) => {
            },
            // The X11/Wayland configuration changed, so we need to readjust the
            // screen configurations.
            WindowSystemEvent::ConfigurationNotification(window) => {
                if window_system.get_root() == window {
                    debug!("screen config.generaluration changed. Rescreen");
                    window_manager = window_manager.rescreen(&window_system);
                }
            },
            // A window asked to be reconfigured (i.e. resized, border change, etc.)
            WindowSystemEvent::ConfigurationRequest(window, window_changes, mask) => {
                let floating = window_manager.workspaces.floating.iter().any(|(&x, _)| x == window) ||
                    !window_manager.workspaces.contains(window);
                window_system.configure_window(window, window_changes, mask, floating);
                window_manager = window_manager.windows(&window_system, &config.general, |x| x.clone());
            },
            // A new window was created, so we need to manage
            // it unless it is already managed by us.
            WindowSystemEvent::WindowCreated(window) => {
                if window_manager.is_window_managed(window) || window_system.overrides_redirect(window) {
                    continue;
                }

                window_manager = window_manager.manage(&window_system, window, &config.general)
                                               .windows(&window_system, &config.general,
                                                        |x| (config.internal.manage_hook)(x.clone(),
                                                        &window_system, window));
            },
            WindowSystemEvent::WindowUnmapped(window, synthetic) => {
                if synthetic && window_manager.is_window_managed(window) {
                    window_manager = if synthetic || !window_manager.is_waiting_unmap(window) {
                        window_manager.unmanage(&window_system, window, &config.general)
                    } else {
                        window_manager.update_unmap(window)
                    }
                }
            },
            WindowSystemEvent::WindowDestroyed(window) => {
                if window_manager.is_window_managed(window) {
                    window_manager = window_manager.unmanage(&window_system, window, &config.general)
                        .remove_from_unmap(window);
                }
            },
            // The mouse pointer entered a window's region. If focus following
            // is enabled, we need to set focus to it.
            WindowSystemEvent::Enter(window) => {
                if config.general.focus_follows_mouse && window_manager.is_window_managed(window) {
                    debug!("enter event on {}", window_system.get_window_name(window));
                    window_manager = window_manager.focus(window, &window_system, &config.general);
                }
            },
            WindowSystemEvent::ButtonPressed(window, subwindow, button, _, _) => {
                let is_root = window_system.get_root() == window;
                let is_sub_root = window_system.get_root() == subwindow || subwindow == 0;
                let act = config.internal.mouse_handlers.get(&button);

                match act {
                    Some(ref action) => {
                        // If it's a root window, then it's an event we grabbed
                        if is_root && !is_sub_root {
                            let local_window_manager = window_manager.clone();
                            window_manager = action(local_window_manager, &window_system,
                                                          &config.general, subwindow);
                        }
                    }
                    None => {
                        // Otherwise just clock to focus
                        if !is_root {
                            window_manager = window_manager.focus(window, &window_system, &config.general);
                        }
                    }
                }
            },
            WindowSystemEvent::ButtonReleased => {
                // If we were dragging, release the pointer and
                // reset the dragging closure
                if let Some(_) = window_manager.dragging {
                    window_system.ungrab_pointer();
                    window_manager.dragging = None;
                }
            }
            WindowSystemEvent::KeyPressed(_, key) => {
                if config.internal.key_handlers.contains_key(&key) {
                    let local_window_manager = window_manager.clone();
                    window_manager = config.internal.key_handlers[key](local_window_manager,
                        &window_system, &config.general);
                }
            },
            WindowSystemEvent::MouseMotion(x, y) => {
                let local_window_manager = window_manager.clone();
                if let Some(drag) = window_manager.dragging {
                    debug!("dragging: {} {}", x, y);
                    window_manager = drag(x, y, local_window_manager, &window_system);
                    window_system.remove_motion_events();
                }
            },
            _ => ()
        };
        debug!("processed {:?}", event);

        if let Some(ref mut loghook) = config.internal.loghook {
            loghook(window_manager.clone(), &window_system);
        }
    }
}
<|endoftext|>


<commit_before>use request::Request;
use response::Response;
use nickel_error::NickelError;

#[deriving(PartialEq)]
pub enum Action {
  Continue,
  Halt
}

// the usage of + Send is weird here because what we really want is + Static
// but that's not possible as of today. We have to use + Send for now.
pub trait Middleware: Clone + Send {
    fn invoke (&self, _req: &mut Request, _res: &mut Response) -> Result<Action, NickelError> {
        Ok(Continue)
    }

    // we need this because otherwise clone() would be ambiguous
    fn clone_box(&self) -> Box<Middleware + Send> {
        box self.clone() as Box<Middleware + Send>
    }
}

impl Clone for Box<Middleware + Send> {
    fn clone(&self) -> Box<Middleware + Send> {
        self.clone_box()
    }
}

pub trait ErrorHandler: Clone + Send {
    fn invoke (&self, _err: &NickelError, _req: &mut Request, _res: &mut Response) -> Result<Action, NickelError> {
        Ok(Continue)
    }

    // we need this because otherwise clone() would be ambiguous
    fn clone_box(&self) -> Box<ErrorHandler + Send> {
        box self.clone() as Box<ErrorHandler + Send>
    }
}

impl Clone for Box<ErrorHandler + Send> {
    fn clone(&self) -> Box<ErrorHandler + Send> {
        self.clone_box()
    }
}

// this is temporally not possible anymore
// Read https://github.com/iron/iron/issues/76 for more details

// impl Middleware for fn (req: &Request, res: &mut Response) -> Result<Action, NickelError> {
//     fn invoke(&self, req: &mut Request, res: &mut Response) -> Result<Action, NickelError> {
//         (*self)(req, res)
//     }
// }

#[deriving(Clone)]
pub struct MiddlewareStack {
    handlers: Vec<Box<Middleware + Send>>,
    error_handlers: Vec<Box<ErrorHandler + Send>>
}

impl MiddlewareStack {
    pub fn add_middleware<T: Middleware> (&mut self, handler: T) {
        self.handlers.push(box handler);
    }

    pub fn add_error_handler<T: ErrorHandler> (&mut self, handler: T) {
        // insert(0) is probably a bad choice. TODO: figure out how to run through the
        // vector in reverse order.
        self.error_handlers.insert(0, box handler);
    }

    pub fn invoke (&self, req: &mut Request, res: &mut Response) {
        self.handlers.iter().all(|handler| {
            match (*handler).invoke(req, res) {
                Ok(Continue) => true,
                Ok(Halt)     => false,
                Err(err)     => {
                    let mut err = err;
                    self.error_handlers.iter().all(|error_handler| {
                        match (*error_handler).invoke(&err, req, res) {
                            Ok(Continue) => true,
                            Ok(Halt)     => false,
                            Err(new_err)     => {
                                // change the error so that other ErrorHandler down the stack receive
                                // the new error.
                                err = new_err;
                                true
                            }
                        }
                    })
                }
            }
        });
    }

    pub fn new () -> MiddlewareStack {
        MiddlewareStack{
            handlers: Vec::new(),
            error_handlers: Vec::new()
        }
    }
}
<commit_msg>fix(middleware): use rev() rather than shifting handlers<commit_after>use request::Request;
use response::Response;
use nickel_error::NickelError;

#[deriving(PartialEq)]
pub enum Action {
  Continue,
  Halt
}

// the usage of + Send is weird here because what we really want is + Static
// but that's not possible as of today. We have to use + Send for now.
pub trait Middleware: Clone + Send {
    fn invoke (&self, _req: &mut Request, _res: &mut Response) -> Result<Action, NickelError> {
        Ok(Continue)
    }

    // we need this because otherwise clone() would be ambiguous
    fn clone_box(&self) -> Box<Middleware + Send> {
        box self.clone() as Box<Middleware + Send>
    }
}

impl Clone for Box<Middleware + Send> {
    fn clone(&self) -> Box<Middleware + Send> {
        self.clone_box()
    }
}

pub trait ErrorHandler: Clone + Send {
    fn invoke (&self, _err: &NickelError, _req: &mut Request, _res: &mut Response) -> Result<Action, NickelError> {
        Ok(Continue)
    }

    // we need this because otherwise clone() would be ambiguous
    fn clone_box(&self) -> Box<ErrorHandler + Send> {
        box self.clone() as Box<ErrorHandler + Send>
    }
}

impl Clone for Box<ErrorHandler + Send> {
    fn clone(&self) -> Box<ErrorHandler + Send> {
        self.clone_box()
    }
}

// this is temporally not possible anymore
// Read https://github.com/iron/iron/issues/76 for more details

// impl Middleware for fn (req: &Request, res: &mut Response) -> Result<Action, NickelError> {
//     fn invoke(&self, req: &mut Request, res: &mut Response) -> Result<Action, NickelError> {
//         (*self)(req, res)
//     }
// }

#[deriving(Clone)]
pub struct MiddlewareStack {
    handlers: Vec<Box<Middleware + Send>>,
    error_handlers: Vec<Box<ErrorHandler + Send>>
}

impl MiddlewareStack {
    pub fn add_middleware<T: Middleware> (&mut self, handler: T) {
        self.handlers.push(box handler);
    }

    pub fn add_error_handler<T: ErrorHandler> (&mut self, handler: T) {
        self.error_handlers.push(box handler);
    }

    pub fn invoke (&self, req: &mut Request, res: &mut Response) {
        self.handlers.iter().all(|handler| {
            match (*handler).invoke(req, res) {
                Ok(Continue) => true,
                Ok(Halt)     => false,
                Err(err)     => {
                    let mut err = err;
                    self.error_handlers.iter().rev().all(|error_handler| {
                        match (*error_handler).invoke(&err, req, res) {
                            Ok(Continue) => true,
                            Ok(Halt)     => false,
                            Err(new_err)     => {
                                // change the error so that other ErrorHandler down the stack receive
                                // the new error.
                                err = new_err;
                                true
                            }
                        }
                    })
                }
            }
        });
    }

    pub fn new () -> MiddlewareStack {
        MiddlewareStack{
            handlers: Vec::new(),
            error_handlers: Vec::new()
        }
    }
}
<|endoftext|>


<commit_before>use value::{Value};

#[derive(Clone, Debug, Copy)]
pub enum Primitive {
    Add,
    Subtract,
    Count,
    Contains,
    Sum,
    Mean,
    StandardDeviation,
    Empty,
}

pub fn resolve_as_scalar<'a>(mut ix: usize, constants: &'a [Value], outer: &'a [Value]) -> &'a Value {
    if ix < constants.len() {
        return &constants[ix];
    } else {
        ix = ix - constants.len()
    }
    return &outer[ix];
}

pub fn resolve_as_vector<'a>(mut ix: usize, constants: &'a [Value], outer: &'a [Value], inner: &'a [Vec<Value>]) -> Vec<&'a Value> {
    if ix < constants.len() {
        return vec![&constants[ix]; inner.len()];
    } else {
        ix = ix - constants.len()
    }
    if ix < outer.len() {
        return vec![&outer[ix]; inner.len()];
    } else {
        ix = ix - outer.len()
    }
    return inner.iter().map(|values| &values[ix]).collect();
}

impl Primitive {
    pub fn eval_from_join<'a>(&self, arguments: &[usize], inputs: &[&Value]) -> Vec<Vec<Value>> {
        use primitive::Primitive::*;
        use value::Value::*;
        let values = arguments.iter().map(|ix| inputs[*ix]).collect::<Vec<_>>();
        match (*self, &values[..]) {
            // NOTE be aware that arguments will be in alphabetical order by field id
            (Add, [&Float(a), &Float(b)]) => vec![vec![Float(a+b)]],
            (Subtract, [&Float(a), &Float(b)]) => vec![vec![Float(a-b)]],
            (Contains, [&String(ref inner), &String(ref outer)]) => vec![vec![Bool(outer.contains(inner))]],
            (Count, _) => panic!("Cannot use {:?} in a join", self),
            (Sum, _) => panic!("Cannot use {:?} in a join", self),
            (Mean, _) => panic!("Cannot use {:?} in a join", self),
            (StandardDeviation, _) => panic!("Cannot use {:?} in a join", self),
            (Empty, _) => panic!("Cannot use {:?} in a join", self),
            _ => panic!("Type error while calling: {:?} {:?}", self, &arguments)
        }
    }

    pub fn eval_from_aggregate<'a>(&self, arguments: &[usize], constants: &[Value], outer: &[Value], inner: &[Vec<Value>]) -> Vec<Vec<Value>> {
        use primitive::Primitive::*;
        use value::Value::*;
        match (*self, arguments) {
            // NOTE be aware that arguments will be in alphabetical order by field id
            (Add, _) => panic!("Cannot use {:?} in an aggregate", self),
            (Subtract, _) => panic!("Cannot use {:?} in an aggregate", self),
            (Contains, _) => panic!("Cannot use {:?} in an aggregate", self),
            (Count, [_]) => {
                vec![vec![Float(inner.len() as f64)]]
            }
            (Sum, [in_ix]) => {
                let in_values = resolve_as_vector(in_ix, constants, outer, inner);
                let sum = in_values.iter().fold(0f64, |sum, value|
                    match **value {
                        Float(float) => sum + float,
                        _ => panic!("Type error while calling: {:?} {:?}", self, in_values),
                    });
                vec![vec![Float(sum)]]
            },
            (Mean, [in_ix]) => {
                let in_values = resolve_as_vector(in_ix, constants, outer, inner);
                let sum = in_values.iter().fold(0f64, |sum, value|
                    match **value {
                        Float(float) => sum + float,
                        _ => panic!("Type error while calling: {:?} {:?}", self, in_values),
                    });
                let mean = sum / (in_values.len() as f64);
                vec![vec![Float(mean)]]
            },
            (StandardDeviation, [in_ix]) => {
                let in_values = resolve_as_vector(in_ix, constants, outer, inner);
                let sum = in_values.iter().fold(0f64, |sum, value|
                    match **value {
                        Float(float) => sum + float,
                        _ => panic!("Type error while calling: {:?} {:?}", self, in_values),
                    });
                let sum_squares = in_values.iter().fold(0f64, |sum, value|
                    match **value {
                        Float(float) => sum + float.powi(2),
                        _ => panic!("Type error while calling: {:?} {:?}", self, in_values),
                    });
                let standard_deviation = ((sum_squares - sum.powi(2)) / (in_values.len() as f64)).sqrt();
                vec![vec![Float(standard_deviation)]]
            },
            (Empty, [in_ix]) => {
                let in_values = resolve_as_vector(in_ix, constants, outer, inner);
                vec![vec![Bool(in_values.len() == 0)]]
            }
            _ => panic!("Wrong number of arguments while calling: {:?} {:?}", self, arguments),
        }
    }

    pub fn from_str(string: &str) -> Self {
        match string {
            "add" => Primitive::Add,
            "subtract" => Primitive::Subtract,
            "contains" => Primitive::Contains,
            "count" => Primitive::Count,
            "sum" => Primitive::Sum,
            "mean" => Primitive::Mean,
            "standard deviation" => Primitive::StandardDeviation,
            "empty" => Primitive::Empty,
            _ => panic!("Unknown primitive: {:?}", string),
        }
    }
}

pub fn primitives() -> Vec<(&'static str, Vec<&'static str>, Vec<&'static str>, Vec<&'static str>)> {
    vec![
        ("add", vec!["in A", "in B"], vec![], vec!["out"]),
        ("subtract", vec!["in A", "in B"], vec![], vec!["out"]),
        ("contains", vec!["inner", "outer"], vec![], vec!["out"]),
        ("count", vec![], vec!["in"], vec!["out"]),
        ("sum", vec![], vec!["in"], vec!["out"]),
        ("mean", vec![], vec!["in"], vec!["out"]),
        ("standard deviation", vec![], vec!["in"], vec!["out"]),
        ("empty", vec![], vec!["in"], vec!["out"]),
    ]
}<commit_msg>add Split primitive for splitting strings<commit_after>use value::{Value};

#[derive(Clone, Debug, Copy)]
pub enum Primitive {
    Add,
    Subtract,
    Split,
    Count,
    Contains,
    Sum,
    Mean,
    StandardDeviation,
    Empty,
}

pub fn resolve_as_scalar<'a>(mut ix: usize, constants: &'a [Value], outer: &'a [Value]) -> &'a Value {
    if ix < constants.len() {
        return &constants[ix];
    } else {
        ix = ix - constants.len()
    }
    return &outer[ix];
}

pub fn resolve_as_vector<'a>(mut ix: usize, constants: &'a [Value], outer: &'a [Value], inner: &'a [Vec<Value>]) -> Vec<&'a Value> {
    if ix < constants.len() {
        return vec![&constants[ix]; inner.len()];
    } else {
        ix = ix - constants.len()
    }
    if ix < outer.len() {
        return vec![&outer[ix]; inner.len()];
    } else {
        ix = ix - outer.len()
    }
    return inner.iter().map(|values| &values[ix]).collect();
}

impl Primitive {
    pub fn eval_from_join<'a>(&self, arguments: &[usize], inputs: &[&Value]) -> Vec<Vec<Value>> {
        use primitive::Primitive::*;
        use value::Value::*;
        let values = arguments.iter().map(|ix| inputs[*ix]).collect::<Vec<_>>();
        match (*self, &values[..]) {
            // NOTE be aware that arguments will be in alphabetical order by field id
            (Add, [&Float(a), &Float(b)]) => vec![vec![Float(a+b)]],
            (Subtract, [&Float(a), &Float(b)]) => vec![vec![Float(a-b)]],
            (Contains, [&String(ref inner), &String(ref outer)]) => vec![vec![Bool(outer.contains(inner))]],
            (Split, [&String(ref split), &String(ref string)]) => {
                string.split(split).enumerate().map(|(ix, segment)| vec![Float(ix as f64), String(segment.to_owned())]).collect()
            },
            (Count, _) => panic!("Cannot use {:?} in a join", self),
            (Sum, _) => panic!("Cannot use {:?} in a join", self),
            (Mean, _) => panic!("Cannot use {:?} in a join", self),
            (StandardDeviation, _) => panic!("Cannot use {:?} in a join", self),
            (Empty, _) => panic!("Cannot use {:?} in a join", self),
            _ => panic!("Type error while calling: {:?} {:?}", self, &arguments)
        }
    }

    pub fn eval_from_aggregate<'a>(&self, arguments: &[usize], constants: &[Value], outer: &[Value], inner: &[Vec<Value>]) -> Vec<Vec<Value>> {
        use primitive::Primitive::*;
        use value::Value::*;
        match (*self, arguments) {
            // NOTE be aware that arguments will be in alphabetical order by field id
            (Add, _) => panic!("Cannot use {:?} in an aggregate", self),
            (Subtract, _) => panic!("Cannot use {:?} in an aggregate", self),
            (Contains, _) => panic!("Cannot use {:?} in an aggregate", self),
            (Split, _) => panic!("Cannot use {:?} in an aggregate", self),
            (Count, [_]) => {
                vec![vec![Float(inner.len() as f64)]]
            },
            (Sum, [in_ix]) => {
                let in_values = resolve_as_vector(in_ix, constants, outer, inner);
                let sum = in_values.iter().fold(0f64, |sum, value|
                    match **value {
                        Float(float) => sum + float,
                        _ => panic!("Type error while calling: {:?} {:?}", self, in_values),
                    });
                vec![vec![Float(sum)]]
            },
            (Mean, [in_ix]) => {
                let in_values = resolve_as_vector(in_ix, constants, outer, inner);
                let sum = in_values.iter().fold(0f64, |sum, value|
                    match **value {
                        Float(float) => sum + float,
                        _ => panic!("Type error while calling: {:?} {:?}", self, in_values),
                    });
                let mean = sum / (in_values.len() as f64);
                vec![vec![Float(mean)]]
            },
            (StandardDeviation, [in_ix]) => {
                let in_values = resolve_as_vector(in_ix, constants, outer, inner);
                let sum = in_values.iter().fold(0f64, |sum, value|
                    match **value {
                        Float(float) => sum + float,
                        _ => panic!("Type error while calling: {:?} {:?}", self, in_values),
                    });
                let sum_squares = in_values.iter().fold(0f64, |sum, value|
                    match **value {
                        Float(float) => sum + float.powi(2),
                        _ => panic!("Type error while calling: {:?} {:?}", self, in_values),
                    });
                let standard_deviation = ((sum_squares - sum.powi(2)) / (in_values.len() as f64)).sqrt();
                vec![vec![Float(standard_deviation)]]
            },
            (Empty, [in_ix]) => {
                let in_values = resolve_as_vector(in_ix, constants, outer, inner);
                vec![vec![Bool(in_values.len() == 0)]]
            },
            _ => panic!("Wrong number of arguments while calling: {:?} {:?}", self, arguments),
        }
    }

    pub fn from_str(string: &str) -> Self {
        match string {
            "add" => Primitive::Add,
            "subtract" => Primitive::Subtract,
            "contains" => Primitive::Contains,
            "split" => Primitive::Split,
            "count" => Primitive::Count,
            "sum" => Primitive::Sum,
            "mean" => Primitive::Mean,
            "standard deviation" => Primitive::StandardDeviation,
            "empty" => Primitive::Empty,
            _ => panic!("Unknown primitive: {:?}", string),
        }
    }
}

pub fn primitives() -> Vec<(&'static str, Vec<&'static str>, Vec<&'static str>, Vec<&'static str>)> {
    vec![
        ("add", vec!["in A", "in B"], vec![], vec!["out"]),
        ("subtract", vec!["in A", "in B"], vec![], vec!["out"]),
        ("contains", vec!["inner", "outer"], vec![], vec!["out"]),
        ("split", vec!["split", "string"], vec![], vec!["ix", "segment"]),
        ("count", vec![], vec!["in"], vec!["out"]),
        ("sum", vec![], vec!["in"], vec!["out"]),
        ("mean", vec![], vec!["in"], vec!["out"]),
        ("standard deviation", vec![], vec!["in"], vec!["out"]),
        ("empty", vec![], vec!["in"], vec!["out"]),
    ]
}
<|endoftext|>