<commit_before>use std::fmt;

#[derive(Debug, PartialEq, Clone)]
pub struct Lexeme {
    pub token: Token,
    pub offset: Option<usize>,
}

impl Lexeme {
    pub fn new() -> Lexeme {
        Lexeme {
            token: Token::String("".into()),
            offset: None,
        }
    }

    pub fn combine(&self, other: &Lexeme) -> Lexeme {
        let offset = match self.offset {
            Some(o) => Some(o),
            None => other.offset,
        };
        Lexeme {
            token: self.token.combine(&other.token),
            offset: offset,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum Token {
    Plus,
    Minus,
    Star,
    Slash,
    Percent,
    LeftParen,
    RightParen,
    Comma,
    Colon,
    Semicolon,
    LeftCurlyBrace,
    RightCurlyBrace,

    String(String),
    // StringLiteral(String),

    Number(f32, Option<String>),

    // Comment(String),
}

impl Token {
    pub fn combine(&self, other: &Token) -> Token {
        match (self, other) {
            (&Token::String(ref my_str), &Token::String(ref other_str)) => {
                if my_str.len() > 0 {
                    Token::String(format!("{} {}", my_str, other_str))
                } else {
                    Token::String(other_str.clone())
                }
            },
            (_, _) => unimplemented!(),
        }
    }
}

impl fmt::Display for Token {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Token::Plus => write!(f, "+"),
            Token::Minus => write!(f, "-"),
            Token::Star => write!(f, "*"),
            Token::Slash => write!(f, "/"),
            Token::Percent => write!(f, "%"),
            Token::LeftParen => write!(f, "("),
            Token::RightParen => write!(f, ")"),
            Token::Comma => write!(f, ","),
            Token::Colon => write!(f, ":"),
            Token::Semicolon => write!(f, ";"),
            Token::LeftCurlyBrace => write!(f, "{{"),
            Token::RightCurlyBrace => write!(f, "}}"),

            Token::String(ref i) => write!(f, "{}", i),
            Token::Number(i, Some(ref u)) => write!(f, "{}{}", i, u),
            Token::Number(i, None) => write!(f, "{}", i),
            // Token::Variable(ref i) => write!(f, "{}", i),
            // Token::Literal(ref i) => write!(f, "{}", i),
            // Token::Comment(ref i) => write!(f, "{}", i),
            // Token::Color(ref i) => write!(f, "{}", i),
        }
    }
}

impl Token {
    pub fn from_char(c: char) -> Option<Token> {
        let r = match c {
            '+' => Token::Plus,
            '-' => Token::Minus,
            '*' => Token::Star,
            '/' => Token::Slash,
            '%' => Token::Percent,
            '(' => Token::LeftParen,
            ')' => Token::RightParen,
            ',' => Token::Comma,
            ':' => Token::Colon,
            ';' => Token::Semicolon,
            '{' => Token::LeftCurlyBrace,
            '}' => Token::RightCurlyBrace,
            _   => return None,
        };
        Some(r)
    }
}
<commit_msg>Make a better error message so I know what my problem is<commit_after>use std::fmt;

#[derive(Debug, PartialEq, Clone)]
pub struct Lexeme {
    pub token: Token,
    pub offset: Option<usize>,
}

impl Lexeme {
    pub fn new() -> Lexeme {
        Lexeme {
            token: Token::String("".into()),
            offset: None,
        }
    }

    pub fn combine(&self, other: &Lexeme) -> Lexeme {
        let offset = match self.offset {
            Some(o) => Some(o),
            None => other.offset,
        };
        Lexeme {
            token: self.token.combine(&other.token),
            offset: offset,
        }
    }
}

#[derive(Debug, PartialEq, Clone)]
pub enum Token {
    Plus,
    Minus,
    Star,
    Slash,
    Percent,
    LeftParen,
    RightParen,
    Comma,
    Colon,
    Semicolon,
    LeftCurlyBrace,
    RightCurlyBrace,

    String(String),
    // StringLiteral(String),

    Number(f32, Option<String>),

    // Comment(String),
}

impl Token {
    pub fn combine(&self, other: &Token) -> Token {
        match (self, other) {
            (&Token::String(ref my_str), &Token::String(ref other_str)) => {
                if my_str.len() > 0 {
                    Token::String(format!("{} {}", my_str, other_str))
                } else {
                    Token::String(other_str.clone())
                }
            },
            (s, o) => panic!("Don't know how to combine {:?} and {:?}", s, o),
        }
    }
}

impl fmt::Display for Token {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Token::Plus => write!(f, "+"),
            Token::Minus => write!(f, "-"),
            Token::Star => write!(f, "*"),
            Token::Slash => write!(f, "/"),
            Token::Percent => write!(f, "%"),
            Token::LeftParen => write!(f, "("),
            Token::RightParen => write!(f, ")"),
            Token::Comma => write!(f, ","),
            Token::Colon => write!(f, ":"),
            Token::Semicolon => write!(f, ";"),
            Token::LeftCurlyBrace => write!(f, "{{"),
            Token::RightCurlyBrace => write!(f, "}}"),

            Token::String(ref i) => write!(f, "{}", i),
            Token::Number(i, Some(ref u)) => write!(f, "{}{}", i, u),
            Token::Number(i, None) => write!(f, "{}", i),
            // Token::Variable(ref i) => write!(f, "{}", i),
            // Token::Literal(ref i) => write!(f, "{}", i),
            // Token::Comment(ref i) => write!(f, "{}", i),
            // Token::Color(ref i) => write!(f, "{}", i),
        }
    }
}

impl Token {
    pub fn from_char(c: char) -> Option<Token> {
        let r = match c {
            '+' => Token::Plus,
            '-' => Token::Minus,
            '*' => Token::Star,
            '/' => Token::Slash,
            '%' => Token::Percent,
            '(' => Token::LeftParen,
            ')' => Token::RightParen,
            ',' => Token::Comma,
            ':' => Token::Colon,
            ';' => Token::Semicolon,
            '{' => Token::LeftCurlyBrace,
            '}' => Token::RightCurlyBrace,
            _   => return None,
        };
        Some(r)
    }
}
<|endoftext|>


<commit_before>use std::fmt;

use features::Features;

/// This data type is a small wrapper around `Vec<Token>` that implements
/// the `Display` trait. The sentence will formatted in CoNLL-X format.
pub struct DisplaySentence<'a>(pub &'a [Token]);

impl<'a> fmt::Display for DisplaySentence<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let last_id = self.0.len() - 1;

        for (id, token) in self.0.iter().enumerate() {
            if id == last_id {
                write!(f, "{}\t{}", id + 1, token)?
            } else {
                write!(f, "{}\t{}\n", id + 1, token)?
            }
        }

        Ok(())
    }
}

/// A builder for `Token`s.
///
/// The `Token` type stores a CoNLL-X token. However, since this format
/// permits a large number of fields, construction of a token can get
/// tedious. This builder provides a fluent interface for creating `Token`s.
pub struct TokenBuilder {
    token: Token,
}

impl TokenBuilder {
    /// Create a `Token` builder with all non-form fields set to absent.
    pub fn new<S>(form: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        TokenBuilder {
            token: Token::new(form),
        }
    }

    /// Set the word form or punctuation symbol.
    pub fn form<S>(mut self, form: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_form(form);
        self
    }

    /// Set the lemma or stem of the word form.
    pub fn lemma<S>(mut self, lemma: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_lemma(Some(lemma));
        self
    }

    /// Set the coarse-grained part-of-speech tag.
    pub fn cpos<S>(mut self, cpos: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_cpos(Some(cpos));
        self
    }

    /// Set the fine-grained part-of-speech tag.
    pub fn pos<S>(mut self, pos: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_pos(Some(pos));
        self
    }

    /// Set the syntactic and/or morphological features of the token.
    pub fn features(mut self, features: Features) -> TokenBuilder {
        self.token.set_features(Some(features));
        self
    }

    /// Set the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    pub fn head(mut self, head: usize) -> TokenBuilder {
        self.token.set_head(Some(head));
        self
    }

    /// Set the dependency relation to the head of this token.
    pub fn head_rel<S>(mut self, head_rel: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_head_rel(Some(head_rel));
        self
    }

    /// Set the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    pub fn p_head(mut self, p_head: usize) -> TokenBuilder {
        self.token.set_p_head(Some(p_head));
        self
    }

    /// Set the dependency relation to the projective head of this token.
    pub fn p_head_rel<S>(mut self, p_head_rel: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_p_head_rel(Some(p_head_rel));
        self
    }

    pub fn token(self) -> Token {
        self.token
    }
}

impl From<Token> for TokenBuilder {
    fn from(token: Token) -> Self {
        TokenBuilder { token }
    }
}

/// A token with the CoNLL-X annotation layers.
///
/// The fields of CoNLLX tokens are described at:
///
/// <http://ilk.uvt.nl/conll/>
///
/// This type provides exactly the same fields, except for the ID field
/// (since it can be derived from the sentence position of the token).
/// If a particular field is absent (*_* in the CoNLL-X format), its
/// value is `None`.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Token {
    form: String,
    lemma: Option<String>,
    cpos: Option<String>,
    pos: Option<String>,
    features: Option<Features>,
    head: Option<usize>,
    head_rel: Option<String>,
    p_head: Option<usize>,
    p_head_rel: Option<String>,
}

impl Token {
    /// Create a new token where all the non-form fields are absent.
    pub fn new<S>(form: S) -> Token
    where
        S: Into<String>,
    {
        Token {
            form: form.into(),
            lemma: None,
            cpos: None,
            pos: None,
            features: None,
            head: None,
            head_rel: None,
            p_head: None,
            p_head_rel: None,
        }
    }

    /// Get the word form or punctuation symbol.
    pub fn form(&self) -> &str {
        self.form.as_ref()
    }

    /// Get the lemma or stem of the word form.
    pub fn lemma(&self) -> Option<&str> {
        self.lemma.as_ref().map(String::as_ref)
    }

    /// Get the coarse-grained part-of-speech tag.
    pub fn cpos(&self) -> Option<&str> {
        self.cpos.as_ref().map(String::as_ref)
    }

    /// Get the fine-grained part-of-speech tag.
    pub fn pos(&self) -> Option<&str> {
        self.pos.as_ref().map(String::as_ref)
    }

    /// Get the syntactic and/or morphological features of the token.
    pub fn features(&self) -> Option<&Features> {
        self.features.as_ref()
    }

    /// Get the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    pub fn head(&self) -> Option<usize> {
        self.head
    }

    /// Get the dependency relation to the head of this token.
    pub fn head_rel(&self) -> Option<&str> {
        self.head_rel.as_ref().map(String::as_ref)
    }

    /// Get the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    pub fn p_head(&self) -> Option<usize> {
        self.p_head
    }

    /// Get the dependency relation to the projective head of this token.
    pub fn p_head_rel(&self) -> Option<&str> {
        self.p_head_rel.as_ref().map(String::as_ref)
    }

    /// Set the word form or punctuation symbol.
    pub fn set_form<S>(&mut self, form: S)
    where
        S: Into<String>,
    {
        self.form = form.into()
    }

    /// Set the lemma or stem of the word form.
    pub fn set_lemma<S>(&mut self, lemma: Option<S>)
    where
        S: Into<String>,
    {
        self.lemma = lemma.map(|i| i.into())
    }

    /// Set the coarse-grained part-of-speech tag.
    pub fn set_cpos<S>(&mut self, cpos: Option<S>)
    where
        S: Into<String>,
    {
        self.cpos = cpos.map(|i| i.into())
    }

    /// Set the fine-grained part-of-speech tag.
    pub fn set_pos<S>(&mut self, pos: Option<S>)
    where
        S: Into<String>,
    {
        self.pos = pos.map(|i| i.into())
    }

    /// Set the syntactic and/or morphological features of the token.
    pub fn set_features(&mut self, features: Option<Features>) {
        self.features = features
    }

    /// Set the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    pub fn set_head(&mut self, head: Option<usize>) {
        self.head = head
    }

    /// Set the dependency relation to the head of this token.
    pub fn set_head_rel<S>(&mut self, head_rel: Option<S>)
    where
        S: Into<String>,
    {
        self.head_rel = head_rel.map(|i| i.into())
    }

    /// Set the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    pub fn set_p_head(&mut self, p_head: Option<usize>) {
        self.p_head = p_head
    }

    /// Set the dependency relation to the projective head of this token.
    pub fn set_p_head_rel<S>(&mut self, p_head_rel: Option<S>)
    where
        S: Into<String>,
    {
        self.p_head_rel = p_head_rel.map(|i| i.into())
    }
}

pub const EMPTY_TOKEN: &'static str = "_";

impl fmt::Display for Token {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let head_str = self.head.as_ref().map(|n| n.to_string());
        let p_head_str = self.p_head.as_ref().map(|n| n.to_string());

        write!(
            f,
            "{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}",
            self.form.as_str(),
            self.lemma
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.cpos
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.pos.as_ref().map(|s| s.as_ref()).unwrap_or(EMPTY_TOKEN),
            self.features
                .as_ref()
                .map(|s| s.as_str())
                .unwrap_or(EMPTY_TOKEN),
            head_str.as_ref().map(|s| s.as_ref()).unwrap_or(EMPTY_TOKEN),
            self.head_rel
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            p_head_str
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.p_head_rel
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
        )
    }
}

impl From<TokenBuilder> for Token {
    fn from(builder: TokenBuilder) -> Self {
        builder.token
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeMap;

    use super::{Features, Token, TokenBuilder};

    fn token_with_features() -> Vec<Token> {
        vec![
            TokenBuilder::new("Gilles")
                .lemma("Gilles")
                .cpos("N")
                .pos("NE")
                .features(Features::from_string(
                    "case:nominative|number:singular|gender:masculine",
                ))
                .head(0)
                .head_rel("ROOT")
                .token(),
            TokenBuilder::new("Deleuze")
                .lemma("Deleuze")
                .cpos("N")
                .pos("NE")
                .features(Features::from_string("nominative|singular|masculine"))
                .head(1)
                .head_rel("APP")
                .token(),
        ]
    }

    fn features_correct() -> Vec<BTreeMap<String, Option<String>>> {
        let mut correct1 = BTreeMap::new();
        correct1.insert("case".to_owned(), Some("nominative".to_owned()));
        correct1.insert("number".to_owned(), Some("singular".to_owned()));
        correct1.insert("gender".to_owned(), Some("masculine".to_owned()));

        let mut correct2 = BTreeMap::new();
        correct2.insert("nominative".to_owned(), None);
        correct2.insert("singular".to_owned(), None);
        correct2.insert("masculine".to_owned(), None);

        vec![correct1, correct2]
    }

    #[test]
    fn features() {
        let tokens = token_with_features();
        let features = features_correct();

        for (token, correct) in tokens.iter().zip(features) {
            let kv = token.features().as_ref().unwrap().as_map();
            assert_eq!(&correct, kv);
        }
    }
}
<commit_msg>Let the Token::set_* methods return the replaced value.<commit_after>use std::fmt;
use std::mem;

use features::Features;

/// This data type is a small wrapper around `Vec<Token>` that implements
/// the `Display` trait. The sentence will formatted in CoNLL-X format.
pub struct DisplaySentence<'a>(pub &'a [Token]);

impl<'a> fmt::Display for DisplaySentence<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let last_id = self.0.len() - 1;

        for (id, token) in self.0.iter().enumerate() {
            if id == last_id {
                write!(f, "{}\t{}", id + 1, token)?
            } else {
                write!(f, "{}\t{}\n", id + 1, token)?
            }
        }

        Ok(())
    }
}

/// A builder for `Token`s.
///
/// The `Token` type stores a CoNLL-X token. However, since this format
/// permits a large number of fields, construction of a token can get
/// tedious. This builder provides a fluent interface for creating `Token`s.
pub struct TokenBuilder {
    token: Token,
}

impl TokenBuilder {
    /// Create a `Token` builder with all non-form fields set to absent.
    pub fn new<S>(form: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        TokenBuilder {
            token: Token::new(form),
        }
    }

    /// Set the word form or punctuation symbol.
    pub fn form<S>(mut self, form: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_form(form);
        self
    }

    /// Set the lemma or stem of the word form.
    pub fn lemma<S>(mut self, lemma: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_lemma(Some(lemma));
        self
    }

    /// Set the coarse-grained part-of-speech tag.
    pub fn cpos<S>(mut self, cpos: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_cpos(Some(cpos));
        self
    }

    /// Set the fine-grained part-of-speech tag.
    pub fn pos<S>(mut self, pos: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_pos(Some(pos));
        self
    }

    /// Set the syntactic and/or morphological features of the token.
    pub fn features(mut self, features: Features) -> TokenBuilder {
        self.token.set_features(Some(features));
        self
    }

    /// Set the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    pub fn head(mut self, head: usize) -> TokenBuilder {
        self.token.set_head(Some(head));
        self
    }

    /// Set the dependency relation to the head of this token.
    pub fn head_rel<S>(mut self, head_rel: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_head_rel(Some(head_rel));
        self
    }

    /// Set the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    pub fn p_head(mut self, p_head: usize) -> TokenBuilder {
        self.token.set_p_head(Some(p_head));
        self
    }

    /// Set the dependency relation to the projective head of this token.
    pub fn p_head_rel<S>(mut self, p_head_rel: S) -> TokenBuilder
    where
        S: Into<String>,
    {
        self.token.set_p_head_rel(Some(p_head_rel));
        self
    }

    pub fn token(self) -> Token {
        self.token
    }
}

impl From<Token> for TokenBuilder {
    fn from(token: Token) -> Self {
        TokenBuilder { token }
    }
}

/// A token with the CoNLL-X annotation layers.
///
/// The fields of CoNLLX tokens are described at:
///
/// <http://ilk.uvt.nl/conll/>
///
/// This type provides exactly the same fields, except for the ID field
/// (since it can be derived from the sentence position of the token).
/// If a particular field is absent (*_* in the CoNLL-X format), its
/// value is `None`.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Token {
    form: String,
    lemma: Option<String>,
    cpos: Option<String>,
    pos: Option<String>,
    features: Option<Features>,
    head: Option<usize>,
    head_rel: Option<String>,
    p_head: Option<usize>,
    p_head_rel: Option<String>,
}

impl Token {
    /// Create a new token where all the non-form fields are absent.
    pub fn new<S>(form: S) -> Token
    where
        S: Into<String>,
    {
        Token {
            form: form.into(),
            lemma: None,
            cpos: None,
            pos: None,
            features: None,
            head: None,
            head_rel: None,
            p_head: None,
            p_head_rel: None,
        }
    }

    /// Get the word form or punctuation symbol.
    pub fn form(&self) -> &str {
        self.form.as_ref()
    }

    /// Get the lemma or stem of the word form.
    pub fn lemma(&self) -> Option<&str> {
        self.lemma.as_ref().map(String::as_ref)
    }

    /// Get the coarse-grained part-of-speech tag.
    pub fn cpos(&self) -> Option<&str> {
        self.cpos.as_ref().map(String::as_ref)
    }

    /// Get the fine-grained part-of-speech tag.
    pub fn pos(&self) -> Option<&str> {
        self.pos.as_ref().map(String::as_ref)
    }

    /// Get the syntactic and/or morphological features of the token.
    pub fn features(&self) -> Option<&Features> {
        self.features.as_ref()
    }

    /// Get the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    pub fn head(&self) -> Option<usize> {
        self.head
    }

    /// Get the dependency relation to the head of this token.
    pub fn head_rel(&self) -> Option<&str> {
        self.head_rel.as_ref().map(String::as_ref)
    }

    /// Get the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    pub fn p_head(&self) -> Option<usize> {
        self.p_head
    }

    /// Get the dependency relation to the projective head of this token.
    pub fn p_head_rel(&self) -> Option<&str> {
        self.p_head_rel.as_ref().map(String::as_ref)
    }

    /// Set the word form or punctuation symbol.
    ///
    /// Returns the form that is replaced.
    pub fn set_form<S>(&mut self, form: S) -> String
    where
        S: Into<String>,
    {
        mem::replace(&mut self.form, form.into())
    }

    /// Set the lemma or stem of the word form.
    ///
    /// Returns the lemma that is replaced.
    pub fn set_lemma<S>(&mut self, lemma: Option<S>) -> Option<String>
    where
        S: Into<String>,
    {
        mem::replace(&mut self.lemma, lemma.map(|i| i.into()))
    }

    /// Set the coarse-grained part-of-speech tag.
    ///
    /// Returns the coarse-grained part-of-speech tag that is replaced.
    pub fn set_cpos<S>(&mut self, cpos: Option<S>) -> Option<String>
    where
        S: Into<String>,
    {
        mem::replace(&mut self.cpos, cpos.map(|i| i.into()))
    }

    /// Set the fine-grained part-of-speech tag.
    ///
    /// Returns the fine-grained part-of-speech tag that is replaced.
    pub fn set_pos<S>(&mut self, pos: Option<S>) -> Option<String>
    where
        S: Into<String>,
    {
        mem::replace(&mut self.pos, pos.map(|i| i.into()))
    }

    /// Set the syntactic and/or morphological features of the token.
    ///
    /// Returns the features that are replaced.
    pub fn set_features(&mut self, features: Option<Features>) -> Option<Features> {
        mem::replace(&mut self.features, features)
    }

    /// Set the head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree.
    ///
    /// Returns the head that is replaced.
    pub fn set_head(&mut self, head: Option<usize>) -> Option<usize> {
        mem::replace(&mut self.head, head)
    }

    /// Set the dependency relation to the head of this token.
    ///
    /// Returns the dependency relation that is replaced.
    pub fn set_head_rel<S>(&mut self, head_rel: Option<S>) -> Option<String>
    where
        S: Into<String>,
    {
        mem::replace(&mut self.head_rel, head_rel.map(|i| i.into()))
    }

    /// Set the projective head of the token. This is the sentence position
    /// of the head **plus one**. If the head is 0, the token the root
    /// of the dependency tree. The dependency structure resulting from the
    /// projective heads must be projective.
    ///
    /// Returns the projective head that is replaced.
    pub fn set_p_head(&mut self, p_head: Option<usize>) -> Option<usize> {
        mem::replace(&mut self.p_head, p_head)
    }

    /// Set the dependency relation to the projective head of this token.
    ///
    /// Returns the projective dependency relation that is replaced.
    pub fn set_p_head_rel<S>(&mut self, p_head_rel: Option<S>) -> Option<String>
    where
        S: Into<String>,
    {
        mem::replace(&mut self.p_head_rel, p_head_rel.map(|i| i.into()))
    }
}

pub const EMPTY_TOKEN: &'static str = "_";

impl fmt::Display for Token {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let head_str = self.head.as_ref().map(|n| n.to_string());
        let p_head_str = self.p_head.as_ref().map(|n| n.to_string());

        write!(
            f,
            "{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}\t{}",
            self.form.as_str(),
            self.lemma
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.cpos
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.pos.as_ref().map(|s| s.as_ref()).unwrap_or(EMPTY_TOKEN),
            self.features
                .as_ref()
                .map(|s| s.as_str())
                .unwrap_or(EMPTY_TOKEN),
            head_str.as_ref().map(|s| s.as_ref()).unwrap_or(EMPTY_TOKEN),
            self.head_rel
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            p_head_str
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
            self.p_head_rel
                .as_ref()
                .map(|s| s.as_ref())
                .unwrap_or(EMPTY_TOKEN),
        )
    }
}

impl From<TokenBuilder> for Token {
    fn from(builder: TokenBuilder) -> Self {
        builder.token
    }
}

#[cfg(test)]
mod tests {
    use std::collections::BTreeMap;

    use super::{Features, Token, TokenBuilder};

    fn token_with_features() -> Vec<Token> {
        vec![
            TokenBuilder::new("Gilles")
                .lemma("Gilles")
                .cpos("N")
                .pos("NE")
                .features(Features::from_string(
                    "case:nominative|number:singular|gender:masculine",
                ))
                .head(0)
                .head_rel("ROOT")
                .token(),
            TokenBuilder::new("Deleuze")
                .lemma("Deleuze")
                .cpos("N")
                .pos("NE")
                .features(Features::from_string("nominative|singular|masculine"))
                .head(1)
                .head_rel("APP")
                .token(),
        ]
    }

    fn features_correct() -> Vec<BTreeMap<String, Option<String>>> {
        let mut correct1 = BTreeMap::new();
        correct1.insert("case".to_owned(), Some("nominative".to_owned()));
        correct1.insert("number".to_owned(), Some("singular".to_owned()));
        correct1.insert("gender".to_owned(), Some("masculine".to_owned()));

        let mut correct2 = BTreeMap::new();
        correct2.insert("nominative".to_owned(), None);
        correct2.insert("singular".to_owned(), None);
        correct2.insert("masculine".to_owned(), None);

        vec![correct1, correct2]
    }

    #[test]
    fn features() {
        let tokens = token_with_features();
        let features = features_correct();

        for (token, correct) in tokens.iter().zip(features) {
            let kv = token.features().as_ref().unwrap().as_map();
            assert_eq!(&correct, kv);
        }
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::path::Path;

use structopt::StructOpt;

use nmk::home::NmkHome;
use nmk::platform::is_mac;

mod backup;
mod build;
mod cmdline;
mod dotfiles;
mod entrypoint;
mod logging;
mod os_release;
mod settings;
mod updater;
mod vendor;

async fn main_task(opt: cmdline::Opt, _settings: settings::Settings) -> nmk::Result<()> {
    // Installation should be done in order
    let nmk_home = NmkHome::find_for_install().expect("Unable to locate NMK_HOME");
    assert!(!nmk_home.is_git(), "NMK_HOME is managed by git. Abort.");
    if opt.backup {
        backup::backup_files(&nmk_home)?;
    }
    dotfiles::install_or_update(&opt, &nmk_home).await?;
    if !is_mac() {
        let entrypoint_updated = entrypoint::install_or_update(&opt, &nmk_home).await?;
        updater::self_setup(&nmk_home, is_nmkup_init(), entrypoint_updated).await?;
        if opt.vendor {
            vendor::install(&opt, &nmk_home).await?;
        }
    }
    Ok(())
}

fn main() -> nmk::Result<()> {
    let opt = cmdline::Opt::from_args();
    let settings = settings::Settings::new(&opt);
    logging::setup(opt.verbosity);
    let mut rt = tokio::runtime::Builder::new()
        .basic_scheduler()
        .enable_all()
        .build()?;
    rt.block_on(main_task(opt, settings))
}

fn is_nmkup_init() -> bool {
    current_exec_stem().as_str().starts_with("nmkup-init")
}

fn current_exec_stem() -> String {
    env::args()
        .next()
        .map(std::path::PathBuf::from)
        .as_deref()
        .and_then(Path::file_stem)
        .and_then(std::ffi::OsStr::to_str)
        .map(String::from)
        .expect("Unable to parse argv[0] as String")
}
<commit_msg>nmk: check init doesn't need file stem<commit_after>use std::path::Path;

use structopt::StructOpt;

use nmk::home::NmkHome;
use nmk::platform::is_mac;

mod backup;
mod build;
mod cmdline;
mod dotfiles;
mod entrypoint;
mod logging;
mod os_release;
mod settings;
mod updater;
mod vendor;

async fn main_task(opt: cmdline::Opt, _settings: settings::Settings) -> nmk::Result<()> {
    // Installation should be done in order
    let nmk_home = NmkHome::find_for_install().expect("Unable to locate NMK_HOME");
    assert!(!nmk_home.is_git(), "NMK_HOME is managed by git. Abort.");
    if opt.backup {
        backup::backup_files(&nmk_home)?;
    }
    dotfiles::install_or_update(&opt, &nmk_home).await?;
    if !is_mac() {
        let entrypoint_updated = entrypoint::install_or_update(&opt, &nmk_home).await?;
        updater::self_setup(&nmk_home, is_nmkup_init(), entrypoint_updated).await?;
        if opt.vendor {
            vendor::install(&opt, &nmk_home).await?;
        }
    }
    Ok(())
}

fn main() -> nmk::Result<()> {
    let opt = cmdline::Opt::from_args();
    let settings = settings::Settings::new(&opt);
    logging::setup(opt.verbosity);
    let mut rt = tokio::runtime::Builder::new()
        .basic_scheduler()
        .enable_all()
        .build()?;
    rt.block_on(main_task(opt, settings))
}

fn is_nmkup_init() -> bool {
    current_exec_name().starts_with("nmkup-init")
}

fn current_exec_name() -> String {
    std::env::current_exe()
        .ok()
        .as_deref()
        .and_then(Path::file_name)
        .and_then(std::ffi::OsStr::to_str)
        .map(String::from)
        .expect("Unable to parse argv[0] as String")
}
<|endoftext|>


<commit_before>use libc::c_ulonglong;

#[doc(hidden)]
pub fn marshal<T, F>(buf: &[u8],
                     padbefore: usize,
                     bytestodrop: usize,
                     f: F
                     ) -> (Vec<u8>, T)
    where F: Fn(*mut u8, *const u8, c_ulonglong) -> T {
    let mut dst = Vec::with_capacity(buf.len() + padbefore);
    for _ in (0..padbefore) {
        dst.push(0);
    }
    dst.push_all(buf);
    let pdst = dst.as_mut_ptr();
    let psrc = dst.as_ptr();
    let res = f(pdst, psrc, dst.len() as c_ulonglong);
    (dst.into_iter().skip(bytestodrop).collect(), res)
}

macro_rules! newtype_clone (($newtype:ident) => (
        impl Clone for $newtype {
            fn clone(&self) -> $newtype {
                let &$newtype(v) = self;
                $newtype(v)
            }
        }

        ));

macro_rules! newtype_drop (($newtype:ident) => (
        impl Drop for $newtype {
            fn drop(&mut self) {
                let &mut $newtype(ref mut v) = self;
                unsafe {
                    volatile_set_memory(v.as_mut_ptr(), 0, v.len());
                }
            }
        }
        ));

macro_rules! newtype_impl (($newtype:ident, $len:expr) => (
    impl $newtype {
        /**
         * `from_slice()` creates an object from a byte slice
         *
         * This function will fail and return None if the length of
         * the byte-slice isn't equal to the length of the object
         */
        pub fn from_slice(bs: &[u8]) -> Option<$newtype> {
            if bs.len() != $len {
                return None
            }
            let mut n = $newtype([0; $len]);
            {
                let $newtype(ref mut b) = n;
                for (bi, &bsi) in b.iter_mut().zip(bs.iter()) {
                    *bi = bsi
                }
            }
            Some(n)
        }
    }
    /**
     * Allows a user to access the byte contents of an object as a slice.
     *
     * WARNING: it might be tempting to do comparisons on objects
     * by using `x[a..b] == y[a..b]`. This will open up for timing attacks
     * when comparing for example authenticator tags. Because of this only
     * use the comparison functions exposed by the sodiumoxide API.
     */
    impl Index<Range<usize>> for $newtype {
        type Output = [u8];
        fn index(&self, _index: &Range<usize>) -> &[u8] {
            let &$newtype(ref b) = self;
            b.index(_index)
        }
    }
    /**
     * Allows a user to access the byte contents of an object as a slice.
     *
     * WARNING: it might be tempting to do comparisons on objects
     * by using `x[..b] == y[..b]`. This will open up for timing attacks
     * when comparing for example authenticator tags. Because of this only
     * use the comparison functions exposed by the sodiumoxide API.
     */
    impl Index<RangeTo<usize>> for $newtype {
        type Output = [u8];
        fn index(&self, _index: &RangeTo<usize>) -> &[u8] {
            let &$newtype(ref b) = self;
            b.index(_index)
        }
    }
    /**
     * Allows a user to access the byte contents of an object as a slice.
     *
     * WARNING: it might be tempting to do comparisons on objects
     * by using `x[a..] == y[a..]`. This will open up for timing attacks
     * when comparing for example authenticator tags. Because of this only
     * use the comparison functions exposed by the sodiumoxide API.
     */
    impl Index<RangeFrom<usize>> for $newtype {
        type Output = [u8];
        fn index(&self, _index: &RangeFrom<usize>) -> &[u8] {
            let &$newtype(ref b) = self;
            b.index(_index)
        }
    }
    /**
     * Allows a user to access the byte contents of an object as a slice.
     *
     * WARNING: it might be tempting to do comparisons on objects
     * by using `x[] == y[]`. This will open up for timing attacks
     * when comparing for example authenticator tags. Because of this only
     * use the comparison functions exposed by the sodiumoxide API.
     */
    impl Index<RangeFull> for $newtype {
        type Output = [u8];
        fn index(&self, _index: &RangeFull) -> &[u8] {
            let &$newtype(ref b) = self;
            b.index(_index)
        }
    }
    ));
<commit_msg>Update for changed Index-traits<commit_after>use libc::c_ulonglong;

#[doc(hidden)]
pub fn marshal<T, F>(buf: &[u8],
                     padbefore: usize,
                     bytestodrop: usize,
                     f: F
                     ) -> (Vec<u8>, T)
    where F: Fn(*mut u8, *const u8, c_ulonglong) -> T {
    let mut dst = Vec::with_capacity(buf.len() + padbefore);
    for _ in (0..padbefore) {
        dst.push(0);
    }
    dst.push_all(buf);
    let pdst = dst.as_mut_ptr();
    let psrc = dst.as_ptr();
    let res = f(pdst, psrc, dst.len() as c_ulonglong);
    (dst.into_iter().skip(bytestodrop).collect(), res)
}

macro_rules! newtype_clone (($newtype:ident) => (
        impl Clone for $newtype {
            fn clone(&self) -> $newtype {
                let &$newtype(v) = self;
                $newtype(v)
            }
        }

        ));

macro_rules! newtype_drop (($newtype:ident) => (
        impl Drop for $newtype {
            fn drop(&mut self) {
                let &mut $newtype(ref mut v) = self;
                unsafe {
                    volatile_set_memory(v.as_mut_ptr(), 0, v.len());
                }
            }
        }
        ));

macro_rules! newtype_impl (($newtype:ident, $len:expr) => (
    impl $newtype {
        /**
         * `from_slice()` creates an object from a byte slice
         *
         * This function will fail and return None if the length of
         * the byte-slice isn't equal to the length of the object
         */
        pub fn from_slice(bs: &[u8]) -> Option<$newtype> {
            if bs.len() != $len {
                return None
            }
            let mut n = $newtype([0; $len]);
            {
                let $newtype(ref mut b) = n;
                for (bi, &bsi) in b.iter_mut().zip(bs.iter()) {
                    *bi = bsi
                }
            }
            Some(n)
        }
    }
    /**
     * Allows a user to access the byte contents of an object as a slice.
     *
     * WARNING: it might be tempting to do comparisons on objects
     * by using `x[a..b] == y[a..b]`. This will open up for timing attacks
     * when comparing for example authenticator tags. Because of this only
     * use the comparison functions exposed by the sodiumoxide API.
     */
    impl Index<Range<usize>> for $newtype {
        type Output = [u8];
        fn index(&self, _index: Range<usize>) -> &[u8] {
            let &$newtype(ref b) = self;
            b.index(_index)
        }
    }
    /**
     * Allows a user to access the byte contents of an object as a slice.
     *
     * WARNING: it might be tempting to do comparisons on objects
     * by using `x[..b] == y[..b]`. This will open up for timing attacks
     * when comparing for example authenticator tags. Because of this only
     * use the comparison functions exposed by the sodiumoxide API.
     */
    impl Index<RangeTo<usize>> for $newtype {
        type Output = [u8];
        fn index(&self, _index: RangeTo<usize>) -> &[u8] {
            let &$newtype(ref b) = self;
            b.index(_index)
        }
    }
    /**
     * Allows a user to access the byte contents of an object as a slice.
     *
     * WARNING: it might be tempting to do comparisons on objects
     * by using `x[a..] == y[a..]`. This will open up for timing attacks
     * when comparing for example authenticator tags. Because of this only
     * use the comparison functions exposed by the sodiumoxide API.
     */
    impl Index<RangeFrom<usize>> for $newtype {
        type Output = [u8];
        fn index(&self, _index: RangeFrom<usize>) -> &[u8] {
            let &$newtype(ref b) = self;
            b.index(_index)
        }
    }
    /**
     * Allows a user to access the byte contents of an object as a slice.
     *
     * WARNING: it might be tempting to do comparisons on objects
     * by using `x[] == y[]`. This will open up for timing attacks
     * when comparing for example authenticator tags. Because of this only
     * use the comparison functions exposed by the sodiumoxide API.
     */
    impl Index<RangeFull> for $newtype {
        type Output = [u8];
        fn index(&self, _index: RangeFull) -> &[u8] {
            let &$newtype(ref b) = self;
            b.index(_index)
        }
    }
    ));
<|endoftext|>


<commit_before>use serde::Serialize;
use serde_json::value::{to_value, Value as Json};

/// A JSON wrapper designed for handlebars internal use case
///
/// * Constant: the JSON value hardcoded into template
/// * Context:  the JSON value referenced in your provided data context
/// * Derived:  the owned JSON value computed during rendering process
///
#[derive(Debug)]
pub enum ScopedJson<'reg: 'rc, 'rc> {
    Constant(&'reg Json),
    Derived(Json),
    Context(&'rc Json),
}

impl<'reg: 'rc, 'rc> ScopedJson<'reg, 'rc> {
    /// get the JSON reference
    pub fn as_json(&self) -> &Json {
        match self {
            &ScopedJson::Constant(j) => j,
            &ScopedJson::Derived(ref j) => j,
            &ScopedJson::Context(j) => j,
        }
    }

    pub fn render(&self) -> String {
        self.as_json().render()
    }
}

impl<'reg: 'rc, 'rc> From<Json> for ScopedJson<'reg, 'rc> {
    fn from(v: Json) -> ScopedJson<'reg, 'rc> {
        ScopedJson::Derived(v)
    }
}

/// Json wrapper that holds the Json value and reference path information
///
#[derive(Debug)]
pub struct PathAndJson<'reg: 'rc, 'rc> {
    path: Option<String>,
    value: ScopedJson<'reg, 'rc>,
}

impl<'reg: 'rc, 'rc> PathAndJson<'reg, 'rc> {
    pub fn new(path: Option<String>, value: ScopedJson<'reg, 'rc>) -> PathAndJson<'reg, 'rc> {
        PathAndJson { path, value }
    }

    /// Returns relative path when the value is referenced
    /// If the value is from a literal, the path is `None`
    pub fn path(&self) -> Option<&String> {
        self.path.as_ref()
    }

    /// Return root level of this path if any
    pub fn path_root(&self) -> Option<&str> {
        self.path
            .as_ref()
            .and_then(|p| p.split(|c| c == '.' || c == '/').nth(0))
    }

    /// Returns the value
    pub fn value(&self) -> &Json {
        self.value.as_json()
    }
}

/// Render Json data with default format
pub trait JsonRender {
    fn render(&self) -> String;
}

pub trait JsonTruthy {
    fn is_truthy(&self, include_zero: bool) -> bool;
}

impl JsonRender for Json {
    fn render(&self) -> String {
        match *self {
            Json::String(ref s) => s.to_string(),
            Json::Bool(i) => i.to_string(),
            Json::Number(ref n) => n.to_string(),
            Json::Null => "".to_owned(),
            Json::Array(ref a) => {
                let mut buf = String::new();
                buf.push('[');
                for i in a.iter() {
                    buf.push_str(i.render().as_ref());
                    buf.push_str(", ");
                }
                buf.push(']');
                buf
            }
            Json::Object(_) => "[object]".to_owned(),
        }
    }
}

pub fn to_json<T>(src: T) -> Json
where
    T: Serialize,
{
    to_value(src).unwrap_or_default()
}

pub fn as_string(src: &Json) -> Option<&str> {
    src.as_str()
}

impl JsonTruthy for Json {
    fn is_truthy(&self, include_zero: bool) -> bool {
        match *self {
            Json::Bool(ref i) => *i,
            Json::Number(ref n) => {
                if include_zero {
                    n.as_f64().map(|f| !f.is_nan()).unwrap_or(false)
                } else {
                    // there is no inifity in json/serde_json
                    n.as_f64().map(|f| f.is_normal()).unwrap_or(false)
                }
            }
            Json::Null => false,
            Json::String(ref i) => !i.is_empty(),
            Json::Array(ref i) => !i.is_empty(),
            Json::Object(ref i) => !i.is_empty(),
        }
    }
}

#[test]
fn test_json_render() {
    let raw = "
Hello world
\n<p thing=\"hello\"
";
    let thing = Json::String(raw.to_string());

    assert_eq!(raw, thing.render());
}

#[test]
fn test_json_number_truthy() {
    assert!(json!(16i16).is_truthy(false));
    assert!(json!(16i16).is_truthy(true));

    assert!(json!(0i16).is_truthy(true));
    assert!(!json!(0i16).is_truthy(false));

    assert!(json!(1.0f64).is_truthy(false));
    assert!(json!(1.0f64).is_truthy(true));

    assert!(json!(Some(16i16)).is_truthy(false));
    assert!(json!(Some(16i16)).is_truthy(true));

    assert!(!json!(None as Option<i16>).is_truthy(false));
    assert!(!json!(None as Option<i16>).is_truthy(true));

    assert!(!json!(std::f64::NAN).is_truthy(false));
    assert!(!json!(std::f64::NAN).is_truthy(true));

    // there is no infinity in json/serde_json
    // assert!(json!(std::f64::INFINITY).is_truthy(false));
    // assert!(json!(std::f64::INFINITY).is_truthy(true));

    // assert!(json!(std::f64::NEG_INFINITY).is_truthy(false));
    // assert!(json!(std::f64::NEG_INFINITY).is_truthy(true));
}
<commit_msg>(test)  fix build on stable channel<commit_after>use serde::Serialize;
use serde_json::value::{to_value, Value as Json};

/// A JSON wrapper designed for handlebars internal use case
///
/// * Constant: the JSON value hardcoded into template
/// * Context:  the JSON value referenced in your provided data context
/// * Derived:  the owned JSON value computed during rendering process
///
#[derive(Debug)]
pub enum ScopedJson<'reg: 'rc, 'rc> {
    Constant(&'reg Json),
    Derived(Json),
    Context(&'rc Json),
}

impl<'reg: 'rc, 'rc> ScopedJson<'reg, 'rc> {
    /// get the JSON reference
    pub fn as_json(&self) -> &Json {
        match self {
            &ScopedJson::Constant(j) => j,
            &ScopedJson::Derived(ref j) => j,
            &ScopedJson::Context(j) => j,
        }
    }

    pub fn render(&self) -> String {
        self.as_json().render()
    }
}

impl<'reg: 'rc, 'rc> From<Json> for ScopedJson<'reg, 'rc> {
    fn from(v: Json) -> ScopedJson<'reg, 'rc> {
        ScopedJson::Derived(v)
    }
}

/// Json wrapper that holds the Json value and reference path information
///
#[derive(Debug)]
pub struct PathAndJson<'reg: 'rc, 'rc> {
    path: Option<String>,
    value: ScopedJson<'reg, 'rc>,
}

impl<'reg: 'rc, 'rc> PathAndJson<'reg, 'rc> {
    pub fn new(path: Option<String>, value: ScopedJson<'reg, 'rc>) -> PathAndJson<'reg, 'rc> {
        PathAndJson { path, value }
    }

    /// Returns relative path when the value is referenced
    /// If the value is from a literal, the path is `None`
    pub fn path(&self) -> Option<&String> {
        self.path.as_ref()
    }

    /// Return root level of this path if any
    pub fn path_root(&self) -> Option<&str> {
        self.path
            .as_ref()
            .and_then(|p| p.split(|c| c == '.' || c == '/').nth(0))
    }

    /// Returns the value
    pub fn value(&self) -> &Json {
        self.value.as_json()
    }
}

/// Render Json data with default format
pub trait JsonRender {
    fn render(&self) -> String;
}

pub trait JsonTruthy {
    fn is_truthy(&self, include_zero: bool) -> bool;
}

impl JsonRender for Json {
    fn render(&self) -> String {
        match *self {
            Json::String(ref s) => s.to_string(),
            Json::Bool(i) => i.to_string(),
            Json::Number(ref n) => n.to_string(),
            Json::Null => "".to_owned(),
            Json::Array(ref a) => {
                let mut buf = String::new();
                buf.push('[');
                for i in a.iter() {
                    buf.push_str(i.render().as_ref());
                    buf.push_str(", ");
                }
                buf.push(']');
                buf
            }
            Json::Object(_) => "[object]".to_owned(),
        }
    }
}

pub fn to_json<T>(src: T) -> Json
where
    T: Serialize,
{
    to_value(src).unwrap_or_default()
}

pub fn as_string(src: &Json) -> Option<&str> {
    src.as_str()
}

impl JsonTruthy for Json {
    fn is_truthy(&self, include_zero: bool) -> bool {
        match *self {
            Json::Bool(ref i) => *i,
            Json::Number(ref n) => {
                if include_zero {
                    n.as_f64().map(|f| !f.is_nan()).unwrap_or(false)
                } else {
                    // there is no inifity in json/serde_json
                    n.as_f64().map(|f| f.is_normal()).unwrap_or(false)
                }
            }
            Json::Null => false,
            Json::String(ref i) => !i.is_empty(),
            Json::Array(ref i) => !i.is_empty(),
            Json::Object(ref i) => !i.is_empty(),
        }
    }
}

#[test]
fn test_json_render() {
    let raw = "
Hello world
\n<p thing=\"hello\"
";
    let thing = Json::String(raw.to_string());

    assert_eq!(raw, thing.render());
}

#[test]
fn test_json_number_truthy() {
    use std::f64;
    assert!(json!(16i16).is_truthy(false));
    assert!(json!(16i16).is_truthy(true));

    assert!(json!(0i16).is_truthy(true));
    assert!(!json!(0i16).is_truthy(false));

    assert!(json!(1.0f64).is_truthy(false));
    assert!(json!(1.0f64).is_truthy(true));

    assert!(json!(Some(16i16)).is_truthy(false));
    assert!(json!(Some(16i16)).is_truthy(true));

    assert!(!json!(None as Option<i16>).is_truthy(false));
    assert!(!json!(None as Option<i16>).is_truthy(true));

    assert!(!json!(f64::NAN).is_truthy(false));
    assert!(!json!(f64::NAN).is_truthy(true));

    // there is no infinity in json/serde_json
    // assert!(json!(f64::INFINITY).is_truthy(false));
    // assert!(json!(f64::INFINITY).is_truthy(true));

    // assert!(json!(f64::NEG_INFINITY).is_truthy(false));
    // assert!(json!(f64::NEG_INFINITY).is_truthy(true));
}
<|endoftext|>


<commit_before>use std::collections::{
    HashSet,
    BitvSet,
    RingBuf,
};
use std::collections::hash_map::Hasher;
use std::hash::Hash;

use super::{
    graph,
    digraph,
    ograph,
    EdgeDirection,
    OGraph,
    Graph,
    DiGraph,
};

pub trait Graphlike {
    type NodeId: Clone;
}

/// A graph trait for accessing the neighbors iterator **I**.
pub trait IntoNeighbors<N> : Copy {
    type Iter: Iterator<Item=N>;
    fn neighbors(self, n: N) -> Self::Iter;
}

impl<'a, N: 'a, E> IntoNeighbors<N> for &'a Graph<N, E>
where N: Copy + Clone + PartialOrd + Hash<Hasher> + Eq
{
    type Iter = graph::Neighbors<'a, N>;
    fn neighbors(self, n: N) -> graph::Neighbors<'a, N>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N: 'a, E: 'a> IntoNeighbors<N> for &'a DiGraph<N, E>
where N: Copy + Clone + Hash<Hasher> + Eq
{
    type Iter = digraph::Neighbors<'a, N, E>;
    fn neighbors(self, n: N) -> digraph::Neighbors<'a, N, E>
    {
        DiGraph::neighbors(self, n)
    }
}

impl<'a, N, E, Ty: ograph::EdgeType> IntoNeighbors< ograph::NodeIndex> for &'a OGraph<N, E, Ty>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct AsUndirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E> IntoNeighbors< ograph::NodeIndex> for &'a AsUndirected<&'b OGraph<N, E>>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors_undirected(self.0, n)
    }
}

impl<'a, 'b, N, E, Ty: ograph::EdgeType> IntoNeighbors< ograph::NodeIndex> for &'a Reversed<&'b OGraph<N, E, Ty>>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

pub trait VisitMap<N> {
    fn visit(&mut self, N) -> bool;
    fn contains(&self, &N) -> bool;
}

impl VisitMap<ograph::NodeIndex> for BitvSet {
    fn visit(&mut self, x: ograph::NodeIndex) -> bool {
        self.insert(x.0)
    }
    fn contains(&self, x: &ograph::NodeIndex) -> bool {
        self.contains(&x.0)
    }
}

impl<N: Eq + Hash<Hasher>> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn contains(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for Graph that knows which datastructure is the best for its visitor map
pub trait Visitable : Graphlike {
    type Map: VisitMap<<Self as Graphlike>::Item>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, Ty> Graphlike for OGraph<N, E, Ty> {
    type NodeId = ograph::NodeIndex;
}

impl<N, E, Ty> Visitable for OGraph<N, E, Ty> where
    Ty: ograph::EdgeType,
{
    type Map = BitvSet;
    fn visit_map(&self) -> BitvSet { BitvSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for DiGraph<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for DiGraph<N, E>
    where N: Copy + Clone + Eq + Hash<Hasher>
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for Graph<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for Graph<N, E>
    where N: Copy + Clone + Ord + Eq + Hash<Hasher>
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, V: Graphlike> Graphlike for AsUndirected<&'a V>
{
    type NodeId = <V as Graphlike>::NodeId;
}

impl<'a, V: Graphlike> Graphlike for Reversed<&'a V>
{
    type NodeId = <V as Graphlike>::NodeId;
}

impl<'a, V: Visitable> Visitable for AsUndirected<&'a V>
{
    type Map = <V as Visitable>::Map;
    fn visit_map(&self) -> <V as Visitable>::Map {
        self.0.visit_map()
    }
}

impl<'a, V: Visitable> Visitable for Reversed<&'a V>
{
    type Map = <V as Visitable>::Map;
    fn visit_map(&self) -> <V as Visitable>::Map {
        self.0.visit_map()
    }
}

/// “Color” of nodes used in a regular depth-first search
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum Color {
    /// Unvisited
    White = 0,
    /// Discovered
    Gray = 1,
    /// Visited
    Black = 2,
}

/// Trait for Graph that knows which datastructure is the best for its visitor map
pub trait ColorVisitable : Graphlike {
    type Map;
    fn color_visit_map(&self) -> Self::Map;
}

/// A breadth first traversal of a graph.
#[derive(Clone)]
pub struct BreadthFirst<'a, G, N> where
    G: 'a,
    N: Eq + Hash<Hasher>,
{
    pub graph: &'a G,
    pub stack: RingBuf<N>,
    pub visited: HashSet<N>,
}

impl<'a, G, N> BreadthFirst<'a, G, N> where
    G: 'a,
    &'a G: IntoNeighbors< N>,
    N: Copy + Eq + Hash<Hasher>,
{
    pub fn new(graph: &'a G, start: N) -> BreadthFirst<'a, G, N>
    {
        let mut rb = RingBuf::new();
        rb.push_back(start);
        BreadthFirst{
            graph: graph,
            stack: rb,
            visited: HashSet::new(),
        }
    }
}

impl<'a, G: 'a, N> Iterator for BreadthFirst<'a, G, N> where
    &'a G: IntoNeighbors<N>,
    N: Copy + Eq + Hash<Hasher>,
    <&'a G as IntoNeighbors< N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop_front() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// A depth first search (DFS) of a graph.
///
/// Using a **Dfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{OGraph, Dfs};
///
/// let mut graph = OGraph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut dfs = Dfs::new(&graph, a);
/// while let Some(nx) = dfs.next(&graph) {
///     // we can access parts of `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph.node_weight(a), Some(&1));
/// ```
///
/// **Note:** The algorithm will not behave correctly if nodes are removed
/// during iteration. It will also not necessarily visit added nodes or edges.
#[derive(Clone)]
pub struct Dfs<N, VM> {
    pub stack: Vec<N>,
    pub visited: VM,
}

impl<N> Dfs<N, HashSet<N>> where N: Hash<Hasher> + Eq
{
    /// Create a new **Dfs**.
    fn new_with_hashset(start: N) -> Self
    {
        Dfs {
            stack: vec![start],
            visited: HashSet::new(),
        }
    }
}

impl<G> Dfs<<G as Graphlike>::NodeId, <G as Visitable>::Map> where
    G: Visitable,
{
    /// Create a new **Dfs**, using the graph's visitor map.
    ///
    /// **Note:** Does not borrow the graph.
    pub fn new(graph: &G, start: <G as Graphlike>::NodeId) -> Self
    {
        Dfs {
            stack: vec![start],
            visited: graph.visit_map(),
        }
    }
}

impl<N, G> Dfs<N, <G as Visitable>::Map> where
    G: Visitable<NodeId=N>,
{
    /// Run a DFS over a graph.
    pub fn search<'a, F>(graph: &'a G, start: N, mut f: F) -> bool where
        N: Clone,
        &'a G: IntoNeighbors<N>,
        <&'a G as IntoNeighbors<N>>::Iter: Iterator<Item=N>,
        <G as Visitable>::Map: VisitMap<N>,
        F: FnMut(N) -> bool,
    {
        let mut dfs = Dfs::new(graph, start);
        while let Some(node) = dfs.next(graph) {
            if !f(node) {
                return false
            }
        }
        true
    }
}

impl<N, VM> Dfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<'a, G>(&mut self, graph: &'a G) -> Option<N> where
        &'a G: IntoNeighbors< N>,
        <&'a G as IntoNeighbors< N>>::Iter: Iterator<Item=N>,
    {
        while let Some(node) = self.stack.pop() {
            if !self.visited.visit(node.clone()) {
                continue;
            }

            for succ in graph.neighbors(node.clone()) {
                if !self.visited.contains(&succ) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }

}

/// An iterator for a depth first traversal of a graph.
#[derive(Clone)]
pub struct DfsIter<'a, G, N, VM> where
    G: 'a,
    //N: Clone,
    //VM: VisitMap<N>,
{
    graph: &'a G,
    dfs: Dfs<N, VM>,
}

impl<'a, G, N> DfsIter<'a, G, N, <G as Visitable>::Map> where
    N: Clone,
    G: Visitable<NodeId=N>,
    <G as Visitable>::Map: VisitMap<N>,
{
    pub fn new(graph: &'a G, start: N) -> DfsIter<'a, G, N, <G as Visitable>::Map>
    {
        DfsIter {
            graph: graph,
            dfs: Dfs::new(graph, start)
        }
    }
}

impl<'a, G, N, VM> Iterator for DfsIter<'a, G, N, VM> where
    G: 'a,
    N: Clone,
    VM: VisitMap<N>,
    &'a G: IntoNeighbors< N>,
    <&'a G as IntoNeighbors< N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        self.dfs.next(self.graph)
    }
}
<commit_msg>Draft ColorVisitable trait<commit_after>use std::collections::{
    HashSet,
    HashMap,
    Bitv,
    BitvSet,
    RingBuf,
};
use std::collections::hash_map::Hasher;
use std::hash::Hash;

use super::{
    graph,
    digraph,
    ograph,
    EdgeDirection,
    OGraph,
    Graph,
    DiGraph,
};

pub trait Graphlike {
    type NodeId: Clone;
}

/// A graph trait for accessing the neighbors iterator **I**.
pub trait IntoNeighbors<N> : Copy {
    type Iter: Iterator<Item=N>;
    fn neighbors(self, n: N) -> Self::Iter;
}

impl<'a, N: 'a, E> IntoNeighbors<N> for &'a Graph<N, E>
where N: Copy + Clone + PartialOrd + Hash<Hasher> + Eq
{
    type Iter = graph::Neighbors<'a, N>;
    fn neighbors(self, n: N) -> graph::Neighbors<'a, N>
    {
        Graph::neighbors(self, n)
    }
}

impl<'a, N: 'a, E: 'a> IntoNeighbors<N> for &'a DiGraph<N, E>
where N: Copy + Clone + Hash<Hasher> + Eq
{
    type Iter = digraph::Neighbors<'a, N, E>;
    fn neighbors(self, n: N) -> digraph::Neighbors<'a, N, E>
    {
        DiGraph::neighbors(self, n)
    }
}

impl<'a, N, E, Ty: ograph::EdgeType> IntoNeighbors< ograph::NodeIndex> for &'a OGraph<N, E, Ty>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors(self, n)
    }
}

/// Wrapper type for walking the graph as if it is undirected
pub struct AsUndirected<G>(pub G);
/// Wrapper type for walking edges the other way
pub struct Reversed<G>(pub G);

impl<'a, 'b, N, E> IntoNeighbors< ograph::NodeIndex> for &'a AsUndirected<&'b OGraph<N, E>>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors_undirected(self.0, n)
    }
}

impl<'a, 'b, N, E, Ty: ograph::EdgeType> IntoNeighbors< ograph::NodeIndex> for &'a Reversed<&'b OGraph<N, E, Ty>>
{
    type Iter = ograph::Neighbors<'a, E>;
    fn neighbors(self, n: ograph::NodeIndex) -> ograph::Neighbors<'a, E>
    {
        OGraph::neighbors_directed(self.0, n, EdgeDirection::Incoming)
    }
}

pub trait VisitMap<N> {
    fn visit(&mut self, N) -> bool;
    fn contains(&self, &N) -> bool;
}

impl VisitMap<ograph::NodeIndex> for BitvSet {
    fn visit(&mut self, x: ograph::NodeIndex) -> bool {
        self.insert(x.0)
    }
    fn contains(&self, x: &ograph::NodeIndex) -> bool {
        self.contains(&x.0)
    }
}

impl<N: Eq + Hash<Hasher>> VisitMap<N> for HashSet<N> {
    fn visit(&mut self, x: N) -> bool {
        self.insert(x)
    }
    fn contains(&self, x: &N) -> bool {
        self.contains(x)
    }
}

/// Trait for Graph that knows which datastructure is the best for its visitor map
pub trait Visitable : Graphlike {
    type Map: VisitMap<<Self as Graphlike>::Item>;
    fn visit_map(&self) -> Self::Map;
}

impl<N, E, Ty> Graphlike for OGraph<N, E, Ty> {
    type NodeId = ograph::NodeIndex;
}

impl<N, E, Ty> Visitable for OGraph<N, E, Ty> where
    Ty: ograph::EdgeType,
{
    type Map = BitvSet;
    fn visit_map(&self) -> BitvSet { BitvSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for DiGraph<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for DiGraph<N, E>
    where N: Copy + Clone + Eq + Hash<Hasher>
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<N: Clone, E> Graphlike for Graph<N, E>
{
    type NodeId = N;
}

impl<N, E> Visitable for Graph<N, E>
    where N: Copy + Clone + Ord + Eq + Hash<Hasher>
{
    type Map = HashSet<N>;
    fn visit_map(&self) -> HashSet<N> { HashSet::with_capacity(self.node_count()) }
}

impl<'a, V: Graphlike> Graphlike for AsUndirected<&'a V>
{
    type NodeId = <V as Graphlike>::NodeId;
}

impl<'a, V: Graphlike> Graphlike for Reversed<&'a V>
{
    type NodeId = <V as Graphlike>::NodeId;
}

impl<'a, V: Visitable> Visitable for AsUndirected<&'a V>
{
    type Map = <V as Visitable>::Map;
    fn visit_map(&self) -> <V as Visitable>::Map {
        self.0.visit_map()
    }
}

impl<'a, V: Visitable> Visitable for Reversed<&'a V>
{
    type Map = <V as Visitable>::Map;
    fn visit_map(&self) -> <V as Visitable>::Map {
        self.0.visit_map()
    }
}

/// “Color” of nodes used in a regular depth-first search
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum Color {
    /// Unvisited
    White = 0,
    /// Discovered
    Gray = 1,
    /// Visited
    Black = 2,
}

/// Trait for Graph that knows which datastructure is the best for its visitor map
pub trait ColorVisitable : Graphlike {
    type Map;
    fn color_visit_map(&self) -> Self::Map;
}

impl<N, E> ColorVisitable for Graph<N, E> where
    N: Clone + Eq + Hash<Hasher>,
{
    type Map = HashMap<N, Color>;
    fn color_visit_map(&self) -> HashMap<N, Color>
    {
        HashMap::new()
    }
}

impl<N, E, Ty> ColorVisitable for OGraph<N, E, Ty> where
    Ty: ograph::EdgeType,
{
    type Map = Bitv;
    fn color_visit_map(&self) -> Bitv
    {
        Bitv::from_elem(self.node_count() * 2, false)
    }
}

pub trait ColorMap<K> {
    fn color(&self, &K) -> Color;
    fn visit(&mut self, K, Color);
    fn is_white(&self, k: &K) -> bool {
        self.color(k) == Color::White
    }
}

// Use two bits per node.
// 00 => White
// 10 => Gray
// 11 => Black
impl ColorMap<ograph::NodeIndex> for Bitv
{
    fn is_white(&self, k: &ograph::NodeIndex) -> bool {
        let ix = k.0;
        self[2*ix]
    }

    fn color(&self, k: &ograph::NodeIndex) -> Color {
        let ix = k.0;
        let white_bit = self[2*ix];
        let gray_bit = self[2*ix+1];
        if white_bit {
            Color::White
        } else if gray_bit {
            Color::Gray
        } else {
            Color::Black
        }
    }

    fn visit(&mut self, k: ograph::NodeIndex, c: Color) {
        let ix = k.0;
        match c {
            Color::White => {
                self.set(2*ix, false);
                self.set(2*ix + 1, false);
            }
            Color::Gray => {
                self.set(2*ix, true);
                self.set(2*ix + 1, false);
            }
            Color::Black => {
                self.set(2*ix, true);
                self.set(2*ix + 1, true);
            }
        }
    }
}

impl<K: Eq + Hash<Hasher>> ColorMap<K> for HashMap<K, Color>
{
    fn color(&self, k: &K) -> Color {
        *self.get(k).unwrap_or(&Color::White)
    }

    fn visit(&mut self, k: K, c: Color) {
        self.insert(k, c);
    }
}

/// A breadth first traversal of a graph.
#[derive(Clone)]
pub struct BreadthFirst<'a, G, N> where
    G: 'a,
    N: Eq + Hash<Hasher>,
{
    pub graph: &'a G,
    pub stack: RingBuf<N>,
    pub visited: HashSet<N>,
}

impl<'a, G, N> BreadthFirst<'a, G, N> where
    G: 'a,
    &'a G: IntoNeighbors< N>,
    N: Copy + Eq + Hash<Hasher>,
{
    pub fn new(graph: &'a G, start: N) -> BreadthFirst<'a, G, N>
    {
        let mut rb = RingBuf::new();
        rb.push_back(start);
        BreadthFirst{
            graph: graph,
            stack: rb,
            visited: HashSet::new(),
        }
    }
}

impl<'a, G: 'a, N> Iterator for BreadthFirst<'a, G, N> where
    &'a G: IntoNeighbors<N>,
    N: Copy + Eq + Hash<Hasher>,
    <&'a G as IntoNeighbors< N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        while let Some(node) = self.stack.pop_front() {
            if !self.visited.insert(node) {
                continue;
            }

            for succ in self.graph.neighbors(node) {
                if !self.visited.contains(&succ) {
                    self.stack.push_back(succ);
                }
            }

            return Some(node);
        }
        None
    }
}

/// A depth first search (DFS) of a graph.
///
/// Using a **Dfs** you can run a traversal over a graph while still retaining
/// mutable access to it, if you use it like the following example:
///
/// ```
/// use petgraph::{OGraph, Dfs};
///
/// let mut graph = OGraph::<_,()>::new();
/// let a = graph.add_node(0);
///
/// let mut dfs = Dfs::new(&graph, a);
/// while let Some(nx) = dfs.next(&graph) {
///     // we can access parts of `graph` mutably here still
///     graph[nx] += 1;
/// }
///
/// assert_eq!(graph.node_weight(a), Some(&1));
/// ```
///
/// **Note:** The algorithm will not behave correctly if nodes are removed
/// during iteration. It will also not necessarily visit added nodes or edges.
#[derive(Clone)]
pub struct Dfs<N, VM> {
    pub stack: Vec<N>,
    pub visited: VM,
}

impl<N> Dfs<N, HashSet<N>> where N: Hash<Hasher> + Eq
{
    /// Create a new **Dfs**.
    fn new_with_hashset(start: N) -> Self
    {
        Dfs {
            stack: vec![start],
            visited: HashSet::new(),
        }
    }
}

impl<G> Dfs<<G as Graphlike>::NodeId, <G as Visitable>::Map> where
    G: Visitable,
{
    /// Create a new **Dfs**, using the graph's visitor map.
    ///
    /// **Note:** Does not borrow the graph.
    pub fn new(graph: &G, start: <G as Graphlike>::NodeId) -> Self
    {
        Dfs {
            stack: vec![start],
            visited: graph.visit_map(),
        }
    }
}

impl<N, G> Dfs<N, <G as Visitable>::Map> where
    G: Visitable<NodeId=N>,
{
    /// Run a DFS over a graph.
    pub fn search<'a, F>(graph: &'a G, start: N, mut f: F) -> bool where
        N: Clone,
        &'a G: IntoNeighbors<N>,
        <&'a G as IntoNeighbors<N>>::Iter: Iterator<Item=N>,
        <G as Visitable>::Map: VisitMap<N>,
        F: FnMut(N) -> bool,
    {
        let mut dfs = Dfs::new(graph, start);
        while let Some(node) = dfs.next(graph) {
            if !f(node) {
                return false
            }
        }
        true
    }
}

impl<N, VM> Dfs<N, VM> where
    N: Clone,
    VM: VisitMap<N>
{
    /// Return the next node in the dfs, or **None** if the traversal is done.
    pub fn next<'a, G>(&mut self, graph: &'a G) -> Option<N> where
        &'a G: IntoNeighbors< N>,
        <&'a G as IntoNeighbors< N>>::Iter: Iterator<Item=N>,
    {
        while let Some(node) = self.stack.pop() {
            if !self.visited.visit(node.clone()) {
                continue;
            }

            for succ in graph.neighbors(node.clone()) {
                if !self.visited.contains(&succ) {
                    self.stack.push(succ);
                }
            }

            return Some(node);
        }
        None
    }

}

/// An iterator for a depth first traversal of a graph.
#[derive(Clone)]
pub struct DfsIter<'a, G, N, VM> where
    G: 'a,
    //N: Clone,
    //VM: VisitMap<N>,
{
    graph: &'a G,
    dfs: Dfs<N, VM>,
}

impl<'a, G, N> DfsIter<'a, G, N, <G as Visitable>::Map> where
    N: Clone,
    G: Visitable<NodeId=N>,
    <G as Visitable>::Map: VisitMap<N>,
{
    pub fn new(graph: &'a G, start: N) -> DfsIter<'a, G, N, <G as Visitable>::Map>
    {
        DfsIter {
            graph: graph,
            dfs: Dfs::new(graph, start)
        }
    }
}

impl<'a, G, N, VM> Iterator for DfsIter<'a, G, N, VM> where
    G: 'a,
    N: Clone,
    VM: VisitMap<N>,
    &'a G: IntoNeighbors< N>,
    <&'a G as IntoNeighbors< N>>::Iter: Iterator<Item=N>,
{
    type Item = N;
    fn next(&mut self) -> Option<N>
    {
        self.dfs.next(self.graph)
    }
}
<|endoftext|>


<commit_before>
#[cfg(feature="serialisation")] use cereal::{CerealData, CerealResult};
#[cfg(feature="serialisation")] use std::io::{Read, Write};

use std::ops::{Deref, DerefMut};

use {EntityData, ModifyData};
use {Entity, IndexedEntity, EntityIter};
use {EntityBuilder, EntityModifier};
use entity::EntityManager;

pub struct World<S> where S: SystemManager
{
    pub systems: S,
    pub data: DataHelper<S::Components, S::Services>,
}

pub struct DataHelper<C, M> where C: ComponentManager, M: ServiceManager
{
    pub components: C,
    pub services: M,
    entities: EntityManager<C>,
}

pub trait ComponentManager: 'static+Sized
{
    #[doc(hidden)]
    fn __new() -> Self;
    #[doc(hidden)]
    fn __remove_all(&mut self, &IndexedEntity<Self>);
}

pub trait ServiceManager: 'static {}

impl ServiceManager for () {}

pub trait SystemManager
{
    type Components: ComponentManager;
    type Services: ServiceManager;
    #[doc(hidden)]
    fn __new() -> Self;
    #[doc(hidden)]
    fn __activated(&mut self, EntityData<Self::Components>, &Self::Components, &mut Self::Services);
    #[doc(hidden)]
    fn __reactivated(&mut self, EntityData<Self::Components>, &Self::Components, &mut Self::Services);
    #[doc(hidden)]
    fn __deactivated(&mut self, EntityData<Self::Components>, &Self::Components, &mut Self::Services);
    #[doc(hidden)]
    fn __update(&mut self, &mut DataHelper<Self::Components, Self::Services>);
}

impl<S: SystemManager> Deref for World<S>
{
    type Target = DataHelper<S::Components, S::Services>;
    fn deref(&self) -> &DataHelper<S::Components, S::Services>
    {
        &self.data
    }
}

impl<S: SystemManager> DerefMut for World<S>
{
    fn deref_mut(&mut self) -> &mut DataHelper<S::Components, S::Services>
    {
        &mut self.data
    }
}

impl<C: ComponentManager, M: ServiceManager> Deref for DataHelper<C, M>
{
    type Target = C;
    fn deref(&self) -> &C
    {
        &self.components
    }
}

impl<C: ComponentManager, M: ServiceManager> DerefMut for DataHelper<C, M>
{
    fn deref_mut(&mut self) -> &mut C
    {
        &mut self.components
    }
}

impl<C: ComponentManager, M: ServiceManager> DataHelper<C, M>
{
    pub fn with_entity_data<F, R>(&mut self, entity: &Entity, mut call: F) -> Option<R>
        where F: FnMut(EntityData<C>, &mut C) -> R
    {
        if self.entities.is_valid(entity) {
            Some(call(EntityData(&self.entities.indexed(&entity).__clone()), self))
        } else {
            None
        }
    }

    pub fn create_entity<B>(&mut self, builder: B) -> Entity where B: EntityBuilder<C>
    {
        self.entities.create_entity(builder, &mut self.components)
    }

    pub fn remove_entity(&mut self, entity: Entity)
    {
        self.entities.remove_entity(entity);
    }
}

#[cfg(feature="serialisation")]
unsafe impl<C: ComponentManager, M: ServiceManager> CerealData for DataHelper<C, M> where C: CerealData, M: CerealData {
    fn write(&self, w: &mut Write) -> CerealResult<()> {
        try!(self.services.write(w));
        try!(self.entities.write(w));
        self.components.write(w)
    }

    fn read(r: &mut Read) -> CerealResult<Self> {
        let services = try!(CerealData::read(r));
        let entities = try!(CerealData::read(r));
        let components = try!(CerealData::read(r));
        Ok(DataHelper {
            components: components,
            services: services,
            entities: entities,
        })
    }
}

#[cfg(feature="serialisation")]
impl<S: SystemManager> World<S> where DataHelper<S::Components, S::Services>: CerealData {
    pub fn load(reader: &mut Read) -> CerealResult<World<S>> {
        let mut world = World {
            systems: S::__new(),
            data: try!(CerealData::read(reader)),
        };
        world.refresh();
        Ok(world)
    }

    pub fn save(&mut self, writer: &mut Write) -> CerealResult<()> {
        self.flush_queue();
        self.data.write(writer)
    }
}

impl<S: SystemManager> World<S>
{
    pub fn new() -> World<S> where S::Services: Default
    {
        World {
            systems: S::__new(),
            data: DataHelper {
                components: S::Components::__new(),
                services: S::Services::default(),
                entities: EntityManager::new(),
            },
        }
    }

    pub fn with_services(services: S::Services) -> World<S>
    {
        World {
            systems: S::__new(),
            data: DataHelper {
                components: S::Components::__new(),
                services: services,
                entities: EntityManager::new(),
            },
        }
    }

    pub fn entities(&self) -> EntityIter<S::Components>
    {
        self.data.entities.iter()
    }

    pub fn modify_entity<M>(&mut self, entity: Entity, modifier: M) where M: EntityModifier<S::Components>
    {
        let indexed = self.data.entities.indexed(&entity);
        modifier.modify(ModifyData(indexed), &mut self.data.components);
        self.systems.__reactivated(
            EntityData(indexed), &self.data.components, &mut self.data.services
        );
    }

    pub fn refresh(&mut self)
    {
        self.flush_queue();
        for entity in self.data.entities.iter() {
            self.systems.__reactivated(entity, &self.data.components, &mut self.data.services);
        }
    }

    pub fn flush_queue(&mut self)
    {
        self.data.entities.flush_queue(
            &mut self.data.components,
            &mut self.data.services,
            &mut self.systems
        );
    }

    pub fn update(&mut self)
    {
        self.flush_queue();
        self.systems.__update(&mut self.data);
        self.flush_queue();
    }
}
<commit_msg>remove unnecessary constraint on closure that is only called once<commit_after>
#[cfg(feature="serialisation")] use cereal::{CerealData, CerealResult};
#[cfg(feature="serialisation")] use std::io::{Read, Write};

use std::ops::{Deref, DerefMut};

use {EntityData, ModifyData};
use {Entity, IndexedEntity, EntityIter};
use {EntityBuilder, EntityModifier};
use entity::EntityManager;

pub struct World<S> where S: SystemManager
{
    pub systems: S,
    pub data: DataHelper<S::Components, S::Services>,
}

pub struct DataHelper<C, M> where C: ComponentManager, M: ServiceManager
{
    pub components: C,
    pub services: M,
    entities: EntityManager<C>,
}

pub trait ComponentManager: 'static+Sized
{
    #[doc(hidden)]
    fn __new() -> Self;
    #[doc(hidden)]
    fn __remove_all(&mut self, &IndexedEntity<Self>);
}

pub trait ServiceManager: 'static {}

impl ServiceManager for () {}

pub trait SystemManager
{
    type Components: ComponentManager;
    type Services: ServiceManager;
    #[doc(hidden)]
    fn __new() -> Self;
    #[doc(hidden)]
    fn __activated(&mut self, EntityData<Self::Components>, &Self::Components, &mut Self::Services);
    #[doc(hidden)]
    fn __reactivated(&mut self, EntityData<Self::Components>, &Self::Components, &mut Self::Services);
    #[doc(hidden)]
    fn __deactivated(&mut self, EntityData<Self::Components>, &Self::Components, &mut Self::Services);
    #[doc(hidden)]
    fn __update(&mut self, &mut DataHelper<Self::Components, Self::Services>);
}

impl<S: SystemManager> Deref for World<S>
{
    type Target = DataHelper<S::Components, S::Services>;
    fn deref(&self) -> &DataHelper<S::Components, S::Services>
    {
        &self.data
    }
}

impl<S: SystemManager> DerefMut for World<S>
{
    fn deref_mut(&mut self) -> &mut DataHelper<S::Components, S::Services>
    {
        &mut self.data
    }
}

impl<C: ComponentManager, M: ServiceManager> Deref for DataHelper<C, M>
{
    type Target = C;
    fn deref(&self) -> &C
    {
        &self.components
    }
}

impl<C: ComponentManager, M: ServiceManager> DerefMut for DataHelper<C, M>
{
    fn deref_mut(&mut self) -> &mut C
    {
        &mut self.components
    }
}

impl<C: ComponentManager, M: ServiceManager> DataHelper<C, M>
{
    pub fn with_entity_data<F, R>(&mut self, entity: &Entity, call: F) -> Option<R>
        where F: FnOnce(EntityData<C>, &mut C) -> R
    {
        if self.entities.is_valid(entity) {
            Some(call(EntityData(&self.entities.indexed(&entity).__clone()), self))
        } else {
            None
        }
    }

    pub fn create_entity<B>(&mut self, builder: B) -> Entity where B: EntityBuilder<C>
    {
        self.entities.create_entity(builder, &mut self.components)
    }

    pub fn remove_entity(&mut self, entity: Entity)
    {
        self.entities.remove_entity(entity);
    }
}

#[cfg(feature="serialisation")]
unsafe impl<C: ComponentManager, M: ServiceManager> CerealData for DataHelper<C, M> where C: CerealData, M: CerealData {
    fn write(&self, w: &mut Write) -> CerealResult<()> {
        try!(self.services.write(w));
        try!(self.entities.write(w));
        self.components.write(w)
    }

    fn read(r: &mut Read) -> CerealResult<Self> {
        let services = try!(CerealData::read(r));
        let entities = try!(CerealData::read(r));
        let components = try!(CerealData::read(r));
        Ok(DataHelper {
            components: components,
            services: services,
            entities: entities,
        })
    }
}

#[cfg(feature="serialisation")]
impl<S: SystemManager> World<S> where DataHelper<S::Components, S::Services>: CerealData {
    pub fn load(reader: &mut Read) -> CerealResult<World<S>> {
        let mut world = World {
            systems: S::__new(),
            data: try!(CerealData::read(reader)),
        };
        world.refresh();
        Ok(world)
    }

    pub fn save(&mut self, writer: &mut Write) -> CerealResult<()> {
        self.flush_queue();
        self.data.write(writer)
    }
}

impl<S: SystemManager> World<S>
{
    pub fn new() -> World<S> where S::Services: Default
    {
        World {
            systems: S::__new(),
            data: DataHelper {
                components: S::Components::__new(),
                services: S::Services::default(),
                entities: EntityManager::new(),
            },
        }
    }

    pub fn with_services(services: S::Services) -> World<S>
    {
        World {
            systems: S::__new(),
            data: DataHelper {
                components: S::Components::__new(),
                services: services,
                entities: EntityManager::new(),
            },
        }
    }

    pub fn entities(&self) -> EntityIter<S::Components>
    {
        self.data.entities.iter()
    }

    pub fn modify_entity<M>(&mut self, entity: Entity, modifier: M) where M: EntityModifier<S::Components>
    {
        let indexed = self.data.entities.indexed(&entity);
        modifier.modify(ModifyData(indexed), &mut self.data.components);
        self.systems.__reactivated(
            EntityData(indexed), &self.data.components, &mut self.data.services
        );
    }

    pub fn refresh(&mut self)
    {
        self.flush_queue();
        for entity in self.data.entities.iter() {
            self.systems.__reactivated(entity, &self.data.components, &mut self.data.services);
        }
    }

    pub fn flush_queue(&mut self)
    {
        self.data.entities.flush_queue(
            &mut self.data.components,
            &mut self.data.services,
            &mut self.systems
        );
    }

    pub fn update(&mut self)
    {
        self.flush_queue();
        self.systems.__update(&mut self.data);
        self.flush_queue();
    }
}
<|endoftext|>