<commit_before>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # Command Parser
//!
//! The `commands::parser` module provides:
//!
//! * Functionality for building a tree of commands based on their names.
//! * Parsing tokenized input to select a command. Input tokenization can
//!   be performed by the `commands::tokenizer` module.
//! * Validating parameters.
//! * Performing completion on commands and parameters.
//!
//! The command parser consists of two important things:
//!
//! * A tree that represents the available commands and their arguments.
//!   This tree consists of instances of `Nodes` from the
//!   `commands::parser::nodes` module. Construction of this tree
//!   is done with the help of the `commands::parser::builder` module.
//! * A `Parser` that handles input and matches it against the command
//!   tree. This parser is intended to be short-lived and to just live
//!   for the duration of parsing and evaluating a single command line
//!   input.

pub mod nodes;
pub mod completion;
pub mod builder;

use std::collections::HashMap;
use std::error::Error;
use std::fmt;
use std::rc::Rc;
use parser::nodes::*;
use tokenizer::{Token, TokenType};
use parser::completion::{Complete, Completion};

/// Command parser
///
/// The lifetime parameter `'text` refers to the lifetime of the
/// tokens passed into the parser. This is the same as the lifetime
/// of the text used to create the tokens.
///
/// When creating a `Parser`, you must give it an `Rc<RootNode>`.
/// The easiest and best way to get a root node is to use the
/// `commands::parser::builder` module.
///
/// ```
/// use commands::parser::builder::{Command, CommandTree};
/// use commands::parser::Parser;
///
/// let mut tree = CommandTree::new();
/// tree.command(Command::new("show").finalize());
/// tree.command(Command::new("set").finalize());
/// tree.command(Command::new("help").finalize());
///
/// let mut parser = Parser::new(tree.finalize());
/// ```
///
/// The parser is constructed as a `mut`able object as most of
/// the methods on it will modify its state.
pub struct Parser<'text> {
    current_node: Rc<Node>,
    /// The nodes which have been accepted during `parse` or `advance`.
    pub nodes: Vec<Rc<Node>>,
    /// The tokens which have been accepted during `parse` or `advance`.
    pub tokens: Vec<Token<'text>>,
    commands: Vec<Rc<CommandNode>>,
    parameters: HashMap<String, String>,
}

impl<'text> Parser<'text> {
    /// Construct a parser with a root node.
    pub fn new(initial_node: Rc<RootNode>) -> Parser<'text> {
        Parser {
            current_node: initial_node,
            nodes: vec![],
            tokens: vec![],
            commands: vec![],
            parameters: HashMap::new(),
        }
    }

    /// Given an optional token, get the possible valid completions
    /// for the current parser state.
    ///
    /// Possible completions are successors of the current node which
    /// are not `hidden`, are `acceptable`, and which match the token,
    /// if one has been provided.
    ///
    /// Nodes may customize the `Complete` trait to customize the
    /// `Completion` and `CompletionOption`s which are generated
    /// for that node.
    ///
    /// Each valid successor node will have one `Completion` in the
    /// result vector. Each `Completion` will have one or more
    /// `CompletionOption` for each valid way that the value may be
    /// entered.
    ///
    /// ```
    /// use commands::parser::builder::{Command, CommandTree};
    /// use commands::parser::Parser;
    /// use commands::tokenizer::{Token, tokenize};
    ///
    /// let mut tree = CommandTree::new();
    /// tree.command(Command::new("show").finalize());
    /// tree.command(Command::new("set").finalize());
    /// tree.command(Command::new("help").finalize());
    ///
    /// let mut parser = Parser::new(tree.finalize());
    ///
    /// // Completing now should have 3 options, 1 for each command.
    /// let comps = parser.complete(None);
    /// assert_eq!(comps.len(), 3);
    ///
    /// // But completing with a token for 'h' should have 1 option.
    /// if let Ok(tokens) = tokenize("h") {
    ///   let comps = parser.complete(Some(tokens[0]));
    ///   assert_eq!(comps.len(), 1);
    ///   assert_eq!(comps[0].options.len(), 1);
    ///   assert_eq!(comps[0].options[0].option_string, "help");
    /// } else {
    ///   panic!("Tokenize failed.");
    /// }
    ///
    /// // And completing for 's' should have 2 options.
    /// if let Ok(tokens) = tokenize("s") {
    ///   let comps = parser.complete(Some(tokens[0]));
    ///   assert_eq!(comps.len(), 2);
    /// } else {
    ///   panic!("Tokenize failed.");
    /// }
    /// ```
    pub fn complete(&self, token: Option<Token<'text>>) -> Vec<Completion> {
        self.current_node
            .successors()
            .into_iter()
            .filter(|n| {
                // To be a possible completion, the node should not be
                // hidden, it should be acceptable, and if there's a token,
                // it should be a valid match for the node.
                !n.hidden() && n.acceptable(self) &&
                if let Some(t) = token {
                    n.matches(self, t)
                } else {
                    true
                }
            })
            .map(|n| n.complete(token))
            .collect::<Vec<_>>()
    }

    /// Parse a vector of tokens, advancing through the
    /// node hierarchy.
    ///
    /// ```
    /// use commands::parser::builder::{Command, CommandTree};
    /// use commands::parser::Parser;
    /// use commands::tokenizer::tokenize;
    ///
    /// let mut tree = CommandTree::new();
    /// tree.command(Command::new("show interface").finalize());
    ///
    /// let mut parser = Parser::new(tree.finalize());
    ///
    /// if let Ok(tokens) = tokenize("show interface") {
    ///     parser.parse(tokens);
    /// }
    /// ```
    pub fn parse(&mut self, tokens: Vec<Token<'text>>) -> Result<(), ParseError<'text>> {
        for token in tokens {
            match token.token_type {
                TokenType::Invalid => unreachable!(),
                TokenType::Whitespace => {}
                TokenType::Word => try!(self.advance(token)),
            }
        }
        Ok(())
    }

    /// Parse a single token, advancing through the node hierarchy.
    pub fn advance(&mut self, token: Token<'text>) -> Result<(), ParseError<'text>> {
        // We clone the current node so that it doesn't stay borrowed
        // and break things when we try to modify it below.
        let cn = self.current_node.clone();
        let matches = cn.successors()
                        .into_iter()
                        .filter(|n| n.acceptable(self) && n.matches(self, token))
                        .collect::<Vec<_>>();
        match matches.len() {
            1 => {
                let matching_node = matches[0];
                matching_node.accept(self, token);
                self.current_node = matching_node.clone();
                self.nodes.push(matching_node.clone());
                self.tokens.push(token);
                Ok(())
            }
            0 => Err(ParseError::NoMatches(token)),
            _ => Err(ParseError::AmbiguousMatch(token)),
        }
    }

    /// Execute the command that has been accepted by the parser.
    ///
    /// * XXX: This should be returning a Result probably.
    pub fn execute(&self) {
        if !self.commands.is_empty() {
            unimplemented!();
            // self.commands[0].execute(self)
        }
    }

    /// Verify that the parser is in a valid state with
    /// respect to having accepted a command and all
    /// required parameters.
    pub fn verify(&self) -> Result<(), VerifyError> {
        if self.commands.is_empty() {
            return Err(VerifyError::NoCommandAccepted);
        } else {
            for expected in self.commands[0].parameters() {
                if expected.required() && !self.parameters.contains_key(expected.name()) {
                    return Err(VerifyError::MissingParameter(expected.name().clone()));
                }
            }
        }
        Ok(())
    }
}

/// Errors that calling `parse` on the `Parser` can raise.
#[derive(Clone,Debug)]
pub enum ParseError<'text> {
    /// The parser is in an invalid state.
    InvalidState,
    /// There were no matches for the token.
    NoMatches(Token<'text>),
    /// There was more than 1 possible match for the token.
    AmbiguousMatch(Token<'text>), // XXX: One day, add: Vec<&'text Rc<Node>>),
}

impl<'text> Error for ParseError<'text> {
    fn description(&self) -> &str {
        match *self {
            ParseError::InvalidState => "Invalid state.",
            ParseError::NoMatches(_) => "No match.",
            ParseError::AmbiguousMatch(_) => "Ambiguous match.",
        }
    }
}

impl<'text> fmt::Display for ParseError<'text> {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.description().fmt(f)
    }
}

/// Errors that calling `verify` on the `Parser` can raise.
#[derive(Clone,Debug)]
pub enum VerifyError {
    /// No command has been accepted by the parser.
    NoCommandAccepted,
    /// A required parameter is missing.
    MissingParameter(String),
}

impl Error for VerifyError {
    fn description(&self) -> &str {
        match *self {
            VerifyError::NoCommandAccepted => "No command has been accepted by the parser.",
            VerifyError::MissingParameter(_) => "A required parameter is missing.",
        }
    }
}

impl fmt::Display for VerifyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.description().fmt(f)
    }
}

/// Can this node be accepted in the current parser state?
pub trait Acceptable {
    /// Can this node be accepted in the current parser state?
    fn acceptable(&self, parser: &Parser) -> bool;
}

impl Acceptable for Rc<Node> {
    /// By default, a node can be accepted when it hasn't been seen yet.
    fn acceptable(&self, parser: &Parser) -> bool {
        !parser.nodes.contains(self)
    }
}

impl Acceptable for RepeatableNode {
    /// A repeatable node can be accepted.
    fn acceptable(&self, _parser: &Parser) -> bool {
        if self.repeatable() {
            return true;
        }
        unimplemented!()
        // This should check nodes.contains, but then go on to check
        // for a repeat marker and whether or not that's been seen.
    }
}

/// Define whether or not a node matches a token.
pub trait Matches {
    /// Does this node match the specified `token`?
    fn matches(&self, parser: &Parser, token: Token) -> bool;
}

impl Matches for Node {
    /// By default, a node matches a `token` when the name of the
    /// node starts with the `token`.
    fn matches(&self, _parser: &Parser, token: Token) -> bool {
        self.name().starts_with(token.text)
    }
}

impl Matches for ParameterNode {
    /// Parameters can match any token by default.
    fn matches(&self, _parser: &Parser, _token: Token) -> bool {
        true
    }
}

impl Matches for FlagParameterNode {
    /// A flag parameter is just looking for the token matching
    /// its name.
    fn matches(&self, _parser: &Parser, token: Token) -> bool {
        self.name().starts_with(token.text)
    }
}

/// Define the behavior of a node when it is accepted by the parser.
pub trait Accept {
    /// Accept this node with the given `token` as data.
    ///
    /// This is where parameters are stored, commands added.
    fn accept<'text>(&self, parser: &mut Parser<'text>, token: Token);
}

impl Accept for Node {
    /// By default, nothing needs to happen for `accept`.
    fn accept<'text>(&self, _parser: &mut Parser<'text>, _token: Token) {}
}

impl Accept for Rc<CommandNode> {
    /// Record this command.
    fn accept<'text>(&self, parser: &mut Parser<'text>, _token: Token) {
        if let Some(_) = self.handler() {
            parser.commands.push(self.clone())
        }
    }
}

impl Accept for ParameterNode {
    /// Record this parameter value.
    fn accept<'text>(&self, parser: &mut Parser<'text>, token: Token) {
        if self.repeatable() {
            unimplemented!();
        } else {
            parser.parameters.insert(self.name().clone(), token.text.to_string());
        }
    }
}

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

    #[test]
    #[should_panic]
    fn verify_signals_no_command() {
        let root = RootNode::new(vec![]);
        let parser = Parser::new(root);
        match parser.verify() {
            Err(VerifyError::NoCommandAccepted) => panic!(),
            _ => {}
        }
    }
}
<commit_msg>ParseError::AmbiguousMatch now carries possible matches.<commit_after>// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # Command Parser
//!
//! The `commands::parser` module provides:
//!
//! * Functionality for building a tree of commands based on their names.
//! * Parsing tokenized input to select a command. Input tokenization can
//!   be performed by the `commands::tokenizer` module.
//! * Validating parameters.
//! * Performing completion on commands and parameters.
//!
//! The command parser consists of two important things:
//!
//! * A tree that represents the available commands and their arguments.
//!   This tree consists of instances of `Nodes` from the
//!   `commands::parser::nodes` module. Construction of this tree
//!   is done with the help of the `commands::parser::builder` module.
//! * A `Parser` that handles input and matches it against the command
//!   tree. This parser is intended to be short-lived and to just live
//!   for the duration of parsing and evaluating a single command line
//!   input.

pub mod nodes;
pub mod completion;
pub mod builder;

use std::collections::HashMap;
use std::error::Error;
use std::fmt;
use std::rc::Rc;
use parser::nodes::*;
use tokenizer::{Token, TokenType};
use parser::completion::{Complete, Completion};

/// Command parser
///
/// The lifetime parameter `'text` refers to the lifetime of the
/// tokens passed into the parser. This is the same as the lifetime
/// of the text used to create the tokens.
///
/// When creating a `Parser`, you must give it an `Rc<RootNode>`.
/// The easiest and best way to get a root node is to use the
/// `commands::parser::builder` module.
///
/// ```
/// use commands::parser::builder::{Command, CommandTree};
/// use commands::parser::Parser;
///
/// let mut tree = CommandTree::new();
/// tree.command(Command::new("show").finalize());
/// tree.command(Command::new("set").finalize());
/// tree.command(Command::new("help").finalize());
///
/// let mut parser = Parser::new(tree.finalize());
/// ```
///
/// The parser is constructed as a `mut`able object as most of
/// the methods on it will modify its state.
pub struct Parser<'text> {
    current_node: Rc<Node>,
    /// The nodes which have been accepted during `parse` or `advance`.
    pub nodes: Vec<Rc<Node>>,
    /// The tokens which have been accepted during `parse` or `advance`.
    pub tokens: Vec<Token<'text>>,
    commands: Vec<Rc<CommandNode>>,
    parameters: HashMap<String, String>,
}

impl<'text> Parser<'text> {
    /// Construct a parser with a root node.
    pub fn new(initial_node: Rc<RootNode>) -> Parser<'text> {
        Parser {
            current_node: initial_node,
            nodes: vec![],
            tokens: vec![],
            commands: vec![],
            parameters: HashMap::new(),
        }
    }

    /// Given an optional token, get the possible valid completions
    /// for the current parser state.
    ///
    /// Possible completions are successors of the current node which
    /// are not `hidden`, are `acceptable`, and which match the token,
    /// if one has been provided.
    ///
    /// Nodes may customize the `Complete` trait to customize the
    /// `Completion` and `CompletionOption`s which are generated
    /// for that node.
    ///
    /// Each valid successor node will have one `Completion` in the
    /// result vector. Each `Completion` will have one or more
    /// `CompletionOption` for each valid way that the value may be
    /// entered.
    ///
    /// ```
    /// use commands::parser::builder::{Command, CommandTree};
    /// use commands::parser::Parser;
    /// use commands::tokenizer::{Token, tokenize};
    ///
    /// let mut tree = CommandTree::new();
    /// tree.command(Command::new("show").finalize());
    /// tree.command(Command::new("set").finalize());
    /// tree.command(Command::new("help").finalize());
    ///
    /// let mut parser = Parser::new(tree.finalize());
    ///
    /// // Completing now should have 3 options, 1 for each command.
    /// let comps = parser.complete(None);
    /// assert_eq!(comps.len(), 3);
    ///
    /// // But completing with a token for 'h' should have 1 option.
    /// if let Ok(tokens) = tokenize("h") {
    ///   let comps = parser.complete(Some(tokens[0]));
    ///   assert_eq!(comps.len(), 1);
    ///   assert_eq!(comps[0].options.len(), 1);
    ///   assert_eq!(comps[0].options[0].option_string, "help");
    /// } else {
    ///   panic!("Tokenize failed.");
    /// }
    ///
    /// // And completing for 's' should have 2 options.
    /// if let Ok(tokens) = tokenize("s") {
    ///   let comps = parser.complete(Some(tokens[0]));
    ///   assert_eq!(comps.len(), 2);
    /// } else {
    ///   panic!("Tokenize failed.");
    /// }
    /// ```
    pub fn complete(&self, token: Option<Token<'text>>) -> Vec<Completion> {
        self.current_node
            .successors()
            .into_iter()
            .filter(|n| {
                // To be a possible completion, the node should not be
                // hidden, it should be acceptable, and if there's a token,
                // it should be a valid match for the node.
                !n.hidden() && n.acceptable(self) &&
                if let Some(t) = token {
                    n.matches(self, t)
                } else {
                    true
                }
            })
            .map(|n| n.complete(token))
            .collect::<Vec<_>>()
    }

    /// Parse a vector of tokens, advancing through the
    /// node hierarchy.
    ///
    /// ```
    /// use commands::parser::builder::{Command, CommandTree};
    /// use commands::parser::Parser;
    /// use commands::tokenizer::tokenize;
    ///
    /// let mut tree = CommandTree::new();
    /// tree.command(Command::new("show interface").finalize());
    ///
    /// let mut parser = Parser::new(tree.finalize());
    ///
    /// if let Ok(tokens) = tokenize("show interface") {
    ///     parser.parse(tokens);
    /// }
    /// ```
    pub fn parse(&mut self, tokens: Vec<Token<'text>>) -> Result<(), ParseError<'text>> {
        for token in tokens {
            match token.token_type {
                TokenType::Invalid => unreachable!(),
                TokenType::Whitespace => {}
                TokenType::Word => try!(self.advance(token)),
            }
        }
        Ok(())
    }

    /// Parse a single token, advancing through the node hierarchy.
    pub fn advance(&mut self, token: Token<'text>) -> Result<(), ParseError<'text>> {
        // We clone the current node so that it doesn't stay borrowed
        // and break things when we try to modify it below.
        let cn = self.current_node.clone();
        let matches = cn.successors()
                        .into_iter()
                        .filter(|n| n.acceptable(self) && n.matches(self, token))
                        .map(|n| n.clone())
                        .collect::<Vec<_>>();
        match matches.len() {
            1 => {
                let ref matching_node = matches[0];
                matching_node.accept(self, token);
                self.current_node = matching_node.clone();
                self.nodes.push(matching_node.clone());
                self.tokens.push(token);
                Ok(())
            }
            0 => Err(ParseError::NoMatches(token)),
            _ => Err(ParseError::AmbiguousMatch(token, matches)),
        }
    }

    /// Execute the command that has been accepted by the parser.
    ///
    /// * XXX: This should be returning a Result probably.
    pub fn execute(&self) {
        if !self.commands.is_empty() {
            unimplemented!();
            // self.commands[0].execute(self)
        }
    }

    /// Verify that the parser is in a valid state with
    /// respect to having accepted a command and all
    /// required parameters.
    pub fn verify(&self) -> Result<(), VerifyError> {
        if self.commands.is_empty() {
            return Err(VerifyError::NoCommandAccepted);
        } else {
            for expected in self.commands[0].parameters() {
                if expected.required() && !self.parameters.contains_key(expected.name()) {
                    return Err(VerifyError::MissingParameter(expected.name().clone()));
                }
            }
        }
        Ok(())
    }
}

/// Errors that calling `parse` on the `Parser` can raise.
#[derive(Clone)]
pub enum ParseError<'text> {
    /// The parser is in an invalid state.
    InvalidState,
    /// There were no matches for the token.
    NoMatches(Token<'text>),
    /// There was more than 1 possible match for the token.
    AmbiguousMatch(Token<'text>, Vec<Rc<Node>>),
}

impl<'text> fmt::Debug for ParseError<'text> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            ParseError::InvalidState => write!(f, "InvalidState"),
            ParseError::NoMatches(token) => write!(f, "NoMatches({:?})", token),
            ParseError::AmbiguousMatch(token, _) => write!(f, "AmbiguousMatch({:?}, ...)", token),
        }
    }
}

impl<'text> Error for ParseError<'text> {
    fn description(&self) -> &str {
        match *self {
            ParseError::InvalidState => "Invalid state.",
            ParseError::NoMatches(_) => "No match.",
            ParseError::AmbiguousMatch(_, _) => "Ambiguous match.",
        }
    }
}

impl<'text> fmt::Display for ParseError<'text> {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.description().fmt(f)
    }
}

/// Errors that calling `verify` on the `Parser` can raise.
#[derive(Clone,Debug)]
pub enum VerifyError {
    /// No command has been accepted by the parser.
    NoCommandAccepted,
    /// A required parameter is missing.
    MissingParameter(String),
}

impl Error for VerifyError {
    fn description(&self) -> &str {
        match *self {
            VerifyError::NoCommandAccepted => "No command has been accepted by the parser.",
            VerifyError::MissingParameter(_) => "A required parameter is missing.",
        }
    }
}

impl fmt::Display for VerifyError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        self.description().fmt(f)
    }
}

/// Can this node be accepted in the current parser state?
pub trait Acceptable {
    /// Can this node be accepted in the current parser state?
    fn acceptable(&self, parser: &Parser) -> bool;
}

impl Acceptable for Rc<Node> {
    /// By default, a node can be accepted when it hasn't been seen yet.
    fn acceptable(&self, parser: &Parser) -> bool {
        !parser.nodes.contains(self)
    }
}

impl Acceptable for RepeatableNode {
    /// A repeatable node can be accepted.
    fn acceptable(&self, _parser: &Parser) -> bool {
        if self.repeatable() {
            return true;
        }
        unimplemented!()
        // This should check nodes.contains, but then go on to check
        // for a repeat marker and whether or not that's been seen.
    }
}

/// Define whether or not a node matches a token.
pub trait Matches {
    /// Does this node match the specified `token`?
    fn matches(&self, parser: &Parser, token: Token) -> bool;
}

impl Matches for Node {
    /// By default, a node matches a `token` when the name of the
    /// node starts with the `token`.
    fn matches(&self, _parser: &Parser, token: Token) -> bool {
        self.name().starts_with(token.text)
    }
}

impl Matches for ParameterNode {
    /// Parameters can match any token by default.
    fn matches(&self, _parser: &Parser, _token: Token) -> bool {
        true
    }
}

impl Matches for FlagParameterNode {
    /// A flag parameter is just looking for the token matching
    /// its name.
    fn matches(&self, _parser: &Parser, token: Token) -> bool {
        self.name().starts_with(token.text)
    }
}

/// Define the behavior of a node when it is accepted by the parser.
pub trait Accept {
    /// Accept this node with the given `token` as data.
    ///
    /// This is where parameters are stored, commands added.
    fn accept<'text>(&self, parser: &mut Parser<'text>, token: Token);
}

impl Accept for Node {
    /// By default, nothing needs to happen for `accept`.
    fn accept<'text>(&self, _parser: &mut Parser<'text>, _token: Token) {}
}

impl Accept for Rc<CommandNode> {
    /// Record this command.
    fn accept<'text>(&self, parser: &mut Parser<'text>, _token: Token) {
        if let Some(_) = self.handler() {
            parser.commands.push(self.clone())
        }
    }
}

impl Accept for ParameterNode {
    /// Record this parameter value.
    fn accept<'text>(&self, parser: &mut Parser<'text>, token: Token) {
        if self.repeatable() {
            unimplemented!();
        } else {
            parser.parameters.insert(self.name().clone(), token.text.to_string());
        }
    }
}

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

    #[test]
    #[should_panic]
    fn verify_signals_no_command() {
        let root = RootNode::new(vec![]);
        let parser = Parser::new(root);
        match parser.verify() {
            Err(VerifyError::NoCommandAccepted) => panic!(),
            _ => {}
        }
    }
}
<|endoftext|>


<commit_before>use ::*;

#[get("/pvp")]
fn pvpindex<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt = conn.prepare("SELECT id, name FROM players order by name").unwrap();
    let names: Vec<_> = stmt.query_map(&[], |row| {
            Named {
                id: row.get(0),
                name: row.get(1)
            }
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    let mut context = create_context("analysis");
    context.add("names", &names);

    respond_page("pvpindex", context)
}

#[get("/pvp/<p1>/<p2>")]
fn pvp<'a>(p1: i32, p2: i32) -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("SELECT (SELECT name FROM players p WHERE p.id = g.home_id) AS home, \
                      (SELECT name FROM players p WHERE p.id = g.away_id) AS away, home_score, \
                      away_score, ball_id, (SELECT img FROM balls b WHERE ball_id = b.id), \
                      (SELECT name FROM balls b WHERE ball_id = b.id), dato, home_id FROM games g \
                      WHERE (home_id = ?1 and away_id = ?2) or (home_id = ?2 and away_id = ?1) \
                      and dato > date('now','start of month') ORDER BY dato DESC")
            .unwrap();

    let mut map = ((0, 0, "".to_owned()), (0, 0, "".to_owned()));

    let pvp: Vec<_> = stmt.query_map(&[&p1, &p2], |row| {
            let game = PlayedGame {
                home: row.get(0),
                away: row.get(1),
                home_score: row.get(2),
                away_score: row.get(3),
                ball: row.get(5),
                ball_name: row.get(6),
                dato: row.get(7),
            };
            let home_id: i32 = row.get(8);

            let home_win = game.home_score > game.away_score;
            {
                let home = if home_id == p1 {&mut map.0} else {&mut map.1};
                if home.2.is_empty() {
                    home.2 = game.home.clone();
                }
                home.0 += game.home_score;
                if home_win { home.1 += 1 }
            }
            {
                let away = if home_id == p1 {&mut map.1} else {&mut map.0};
                if away.2.is_empty() {
                    away.2 = game.away.clone();
                }
                away.0 += game.away_score;
                if !home_win { away.1 += 1 }
            }

            game
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    print!("{:?}", map);

//      p1  mål     p1 vundne   p1 navn     p1 antal kampe
//      p2  mål     p2 vundne   p2 navn     p2 antal kampe

    let mut context = create_context("analysis");

    context.add("pvp", &pvp);
    context.add("map", &map);
    respond_page("pvp", context)
}
<commit_msg>Fix highlight of PvP context<commit_after>use ::*;

#[get("/pvp")]
fn pvpindex<'a>() -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt = conn.prepare("SELECT id, name FROM players order by name").unwrap();
    let names: Vec<_> = stmt.query_map(&[], |row| {
            Named {
                id: row.get(0),
                name: row.get(1)
            }
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    let mut context = create_context("pvp");
    context.add("names", &names);

    respond_page("pvpindex", context)
}

#[get("/pvp/<p1>/<p2>")]
fn pvp<'a>(p1: i32, p2: i32) -> ContRes<'a> {
    let conn = lock_database();
    let mut stmt =
        conn.prepare("SELECT (SELECT name FROM players p WHERE p.id = g.home_id) AS home, \
                      (SELECT name FROM players p WHERE p.id = g.away_id) AS away, home_score, \
                      away_score, ball_id, (SELECT img FROM balls b WHERE ball_id = b.id), \
                      (SELECT name FROM balls b WHERE ball_id = b.id), dato, home_id FROM games g \
                      WHERE (home_id = ?1 and away_id = ?2) or (home_id = ?2 and away_id = ?1) \
                      and dato > date('now','start of month') ORDER BY dato DESC")
            .unwrap();

    let mut map = ((0, 0, "".to_owned()), (0, 0, "".to_owned()));

    let pvp: Vec<_> = stmt.query_map(&[&p1, &p2], |row| {
            let game = PlayedGame {
                home: row.get(0),
                away: row.get(1),
                home_score: row.get(2),
                away_score: row.get(3),
                ball: row.get(5),
                ball_name: row.get(6),
                dato: row.get(7),
            };
            let home_id: i32 = row.get(8);

            let home_win = game.home_score > game.away_score;
            {
                let home = if home_id == p1 {&mut map.0} else {&mut map.1};
                if home.2.is_empty() {
                    home.2 = game.home.clone();
                }
                home.0 += game.home_score;
                if home_win { home.1 += 1 }
            }
            {
                let away = if home_id == p1 {&mut map.1} else {&mut map.0};
                if away.2.is_empty() {
                    away.2 = game.away.clone();
                }
                away.0 += game.away_score;
                if !home_win { away.1 += 1 }
            }

            game
        })
        .unwrap()
        .map(Result::unwrap)
        .collect();

    print!("{:?}", map);

//      p1  mål     p1 vundne   p1 navn     p1 antal kampe
//      p2  mål     p2 vundne   p2 navn     p2 antal kampe

    let mut context = create_context("pvp");

    context.add("pvp", &pvp);
    context.add("map", &map);
    respond_page("pvp", context)
}
<|endoftext|>


<commit_before>//! Managing raw mode.
//!
//! Raw mode is a particular state a TTY can have. It signifies that:
//!
//! 1. No line buffering (the input is given byte-by-byte).
//! 2. The input is not written out, instead it has to be done manually by the programmer.
//! 3. The output is not canonicalized (for example, `\n` means "go one line down", not "line
//!    break").
//!
//! It is essential to design terminal programs.
//!
//! # Example
//!
//! ```rust,no_run
//! use termion::raw::IntoRawMode;
//! use std::io::{Write, stdout};
//!
//! fn main() {
//!     let mut stdout = stdout().into_raw_mode().unwrap();
//!
//!     write!(stdout, "Hey there.").unwrap();
//! }
//! ```

use std::io::{self, Write};
use std::ops;

/// The timeout of an escape code control sequence, in milliseconds.
pub const CONTROL_SEQUENCE_TIMEOUT: u64 = 100;

/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
///
/// Restoring will entirely bring back the old TTY state.
#[cfg(target_os = "redox")]
pub struct RawTerminal<W: Write> {
    output: W,
}

#[cfg(target_os = "redox")]
impl<W: Write> Drop for RawTerminal<W> {
    fn drop(&mut self) {
        write!(self, csi!("?82l")).unwrap();
    }
}

#[cfg(not(target_os = "redox"))]
use termios::Termios;
/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
#[cfg(not(target_os = "redox"))]
pub struct RawTerminal<W: Write> {
    prev_ios: Termios,
    output: W,
}

#[cfg(not(target_os = "redox"))]
impl<W: Write> Drop for RawTerminal<W> {
    fn drop(&mut self) {
        use termios::set_terminal_attr;
        set_terminal_attr(&mut self.prev_ios as *mut _);
    }
}

impl<W: Write> ops::Deref for RawTerminal<W> {
    type Target = W;

    fn deref(&self) -> &W {
        &self.output
    }
}

impl<W: Write> ops::DerefMut for RawTerminal<W> {
    fn deref_mut(&mut self) -> &mut W {
        &mut self.output
    }
}

impl<W: Write> Write for RawTerminal<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.output.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.output.flush()
    }
}

/// Types which can be converted into "raw mode".
///
/// # Why is this type defined on writers and not readers?
///
/// TTYs has their state controlled by the writer, not the reader. You use the writer to clear the
/// screen, move the cursor and so on, so naturally you use the writer to change the mode as well.
pub trait IntoRawMode: Write + Sized {
    /// Switch to raw mode.
    ///
    /// Raw mode means that stdin won't be printed (it will instead have to be written manually by
    /// the program). Furthermore, the input isn't canonicalised or buffered (that is, you can
    /// read from stdin one byte of a time). The output is neither modified in any way.
    fn into_raw_mode(self) -> io::Result<RawTerminal<Self>>;
}

impl<W: Write> IntoRawMode for W {
    #[cfg(not(target_os = "redox"))]
    fn into_raw_mode(self) -> io::Result<RawTerminal<W>> {
        use termios::{cfmakeraw, get_terminal_attr, set_terminal_attr};

        let (mut ios, exit) = get_terminal_attr();
        let prev_ios = ios;
        if exit != 0 {
            return Err(io::Error::new(io::ErrorKind::Other, "Unable to get Termios attribute."));
        }

        unsafe {
            cfmakeraw(&mut ios);
        }

        if set_terminal_attr(&mut ios as *mut _) != 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Unable to set Termios attribute."))
        } else {
            let res = RawTerminal {
                prev_ios: prev_ios,
                output: self,
            };
            Ok(res)
        }
    }

    #[cfg(target_os = "redox")]
    fn into_raw_mode(mut self) -> io::Result<RawTerminal<W>> {
        write!(self, csi!("?82h")).map(|_| RawTerminal { output: self })
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::io::{Write, stdout};

    #[test]
    fn test_into_raw_mode() {
        let mut out = stdout().into_raw_mode().unwrap();

        out.write_all(b"this is a test, muahhahahah").unwrap();
    }
}
<commit_msg>Fix raw mode on Redox<commit_after>//! Managing raw mode.
//!
//! Raw mode is a particular state a TTY can have. It signifies that:
//!
//! 1. No line buffering (the input is given byte-by-byte).
//! 2. The input is not written out, instead it has to be done manually by the programmer.
//! 3. The output is not canonicalized (for example, `\n` means "go one line down", not "line
//!    break").
//!
//! It is essential to design terminal programs.
//!
//! # Example
//!
//! ```rust,no_run
//! use termion::raw::IntoRawMode;
//! use std::io::{Write, stdout};
//!
//! fn main() {
//!     let mut stdout = stdout().into_raw_mode().unwrap();
//!
//!     write!(stdout, "Hey there.").unwrap();
//! }
//! ```

use std::io::{self, Write};
use std::ops;

/// The timeout of an escape code control sequence, in milliseconds.
pub const CONTROL_SEQUENCE_TIMEOUT: u64 = 100;

/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
///
/// Restoring will entirely bring back the old TTY state.
#[cfg(target_os = "redox")]
pub struct RawTerminal<W: Write> {
    output: W,
}

#[cfg(target_os = "redox")]
impl<W: Write> Drop for RawTerminal<W> {
    fn drop(&mut self) {
        let _ = write!(self, csi!("?82l"));
        let _ = self.flush();
    }
}

#[cfg(not(target_os = "redox"))]
use termios::Termios;
/// A terminal restorer, which keeps the previous state of the terminal, and restores it, when
/// dropped.
#[cfg(not(target_os = "redox"))]
pub struct RawTerminal<W: Write> {
    prev_ios: Termios,
    output: W,
}

#[cfg(not(target_os = "redox"))]
impl<W: Write> Drop for RawTerminal<W> {
    fn drop(&mut self) {
        use termios::set_terminal_attr;
        set_terminal_attr(&mut self.prev_ios as *mut _);
    }
}

impl<W: Write> ops::Deref for RawTerminal<W> {
    type Target = W;

    fn deref(&self) -> &W {
        &self.output
    }
}

impl<W: Write> ops::DerefMut for RawTerminal<W> {
    fn deref_mut(&mut self) -> &mut W {
        &mut self.output
    }
}

impl<W: Write> Write for RawTerminal<W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.output.write(buf)
    }

    fn flush(&mut self) -> io::Result<()> {
        self.output.flush()
    }
}

/// Types which can be converted into "raw mode".
///
/// # Why is this type defined on writers and not readers?
///
/// TTYs has their state controlled by the writer, not the reader. You use the writer to clear the
/// screen, move the cursor and so on, so naturally you use the writer to change the mode as well.
pub trait IntoRawMode: Write + Sized {
    /// Switch to raw mode.
    ///
    /// Raw mode means that stdin won't be printed (it will instead have to be written manually by
    /// the program). Furthermore, the input isn't canonicalised or buffered (that is, you can
    /// read from stdin one byte of a time). The output is neither modified in any way.
    fn into_raw_mode(self) -> io::Result<RawTerminal<Self>>;
}

impl<W: Write> IntoRawMode for W {
    #[cfg(not(target_os = "redox"))]
    fn into_raw_mode(self) -> io::Result<RawTerminal<W>> {
        use termios::{cfmakeraw, get_terminal_attr, set_terminal_attr};

        let (mut ios, exit) = get_terminal_attr();
        let prev_ios = ios;
        if exit != 0 {
            return Err(io::Error::new(io::ErrorKind::Other, "Unable to get Termios attribute."));
        }

        unsafe {
            cfmakeraw(&mut ios);
        }

        if set_terminal_attr(&mut ios as *mut _) != 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Unable to set Termios attribute."))
        } else {
            let res = RawTerminal {
                prev_ios: prev_ios,
                output: self,
            };
            Ok(res)
        }
    }

    #[cfg(target_os = "redox")]
    fn into_raw_mode(mut self) -> io::Result<RawTerminal<W>> {
        write!(self, csi!("?82h"))?;
        self.flush()?;
        Ok(RawTerminal { output: self })
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::io::{Write, stdout};

    #[test]
    fn test_into_raw_mode() {
        let mut out = stdout().into_raw_mode().unwrap();

        out.write_all(b"this is a test, muahhahahah").unwrap();
    }
}
<|endoftext|>


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

#[link(name = "sax",
       vers = "0.1",
       author = "Brendan Zabarauskas",
       url = "https://github.com/bjz/sax-rs")];

#[comment = "Wrapper for libxml2's SAX parser."];
#[crate_type = "lib"];

extern mod extra;

use std::cast;
use std::comm::{Port, stream};
use std::hashmap::HashMap;
use std::libc::{c_char, c_int};
use std::str;
use std::task;

use error::ErrorData;

pub mod error;
pub mod ffi;
mod extfn;

/// Events to be sent by the parser.
#[deriving(Eq, Clone)]
pub enum ParseEvent {
    /// The document has begun to be processed.
    StartDocument,
    /// The document processing has finished.
    EndDocument,
    /// An opening tag has was parsed.
    StartElement(~str, Attributes),
    /// A closing tag was parsed.
    EndElement(~str),
    /// Some characters between tags have been recived.
    Characters(~str),
    /// Ignorable whitespace.
    IgnorableWhitespace(~str),
    /// A comment tag was parsed.
    Comment(~str),
    /// A `CDATA` block was parsed.
    CdataBlock(~str),
}

impl ToStr for ParseEvent {
    fn to_str(&self) -> ~str {
        match *self {
            StartDocument => ~"START DOCUMENT",
            EndDocument => ~"END DOCUMENT",
            StartElement(ref name, ref atts) => fmt!("<%s%s>", *name, atts.to_str()),
            EndElement(ref name) => fmt!("</%s>", *name),
            Characters(ref ch) => ch.clone(),
            IgnorableWhitespace(_) => ~"",
            Comment(ref value) => fmt!("", *value),
            CdataBlock(ref value) => fmt!("<![CDATA[%s]]>", *value),
        }
    }
}

/// A list of attributes stored in a hashmap.
#[deriving(Eq, Clone)]
pub struct Attributes(HashMap<~str, ~str>);

impl Attributes {
    unsafe fn from_buf(atts: **ffi::xmlChar) -> Attributes {
        let mut map = Attributes(HashMap::new());
        let mut ptr = atts as **c_char;
        while !ptr.is_null() && !(*ptr).is_null() {
            map.insert(str::raw::from_c_str(*ptr),
                       str::raw::from_c_str(*(ptr + 1)));
            ptr = ptr + 2;
        }
        map
    }
}

impl ToStr for Attributes {
    fn to_str(&self) -> ~str {
        do self.iter().map |(k, v)| {
            fmt!(" %s=\"%s\"", *k, *v)
        }.to_owned_vec().concat()
    }
}

/// Either a parse event wrapped in `Ok` or some Error data wrapped in `Err`.
pub type ParseResult = Result<ParseEvent, ErrorData>;

/// A port to recieve `ParseResult`s from the parser.
pub struct SaxPort {
    priv port: Port<ParseResult>,
}

impl GenericPort<ParseResult> for SaxPort {
    /// Recives a new parse message.
    ///
    /// # Failure
    ///
    /// Fails if the method is called again after the final `Ok(EndDocument)`
    /// parse result has been recived.
    pub fn recv(&self) -> ParseResult {
        self.port.try_recv().expect(
            "Could not get a new parse result, the parser has already finished!"
        )
    }

    /// Receives a parse result wrapped in `Some`, or `None` if the parser has
    /// finished.
    pub fn try_recv(&self) -> Option<ParseResult> {
        self.port.try_recv()
    }
}

/// Parses the entire XML string.
///
/// # Returns
///
/// A port that recieves parse results.
///
/// # Example
///
/// ~~~rust
/// let port = parse_xml("<hullo><world /></hullo>");
/// loop {
///     if port.recv() == Ok(EndDocument) { break }
/// }
/// ~~~
pub fn parse_xml(src: &str) -> SaxPort {
    let len = src.len() as c_int;
    do src.to_c_str().with_ref |c_str| {
        let (port, chan) = stream();
        do task::spawn {
            unsafe {
                ffi::xmlSAXUserParseMemory(&extfn::new_handler(),
                                           cast::transmute(&chan),
                                           c_str, len);
                ffi::xmlCleanupParser();
            }
        }
        SaxPort { port: port }
    }
}

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

    #[test]
    fn test() {
        let sax = parse_xml(
            "<hello><this />test</hello>"
        );
        loop {
            match sax.recv() {
                Ok(StartDocument) => (),
                Ok(EndDocument) => break,
                Ok(event) => println(event.to_str()),
                Err(err) => println(err.to_str()),
            }
        }
    }
}
<commit_msg>Comment out task spawning for now<commit_after>// Copyright 2013 The SAX-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#[link(name = "sax",
       vers = "0.1",
       author = "Brendan Zabarauskas",
       url = "https://github.com/bjz/sax-rs")];

#[comment = "Wrapper for libxml2's SAX parser."];
#[crate_type = "lib"];

extern mod extra;

use std::cast;
use std::comm::{Port, stream};
use std::hashmap::HashMap;
use std::libc::{c_char, c_int};
use std::str;
// use std::task;

use error::ErrorData;

pub mod error;
pub mod ffi;
mod extfn;

/// Events to be sent by the parser.
#[deriving(Eq, Clone)]
pub enum ParseEvent {
    /// The document has begun to be processed.
    StartDocument,
    /// The document processing has finished.
    EndDocument,
    /// An opening tag has was parsed.
    StartElement(~str, Attributes),
    /// A closing tag was parsed.
    EndElement(~str),
    /// Some characters between tags have been recived.
    Characters(~str),
    /// Ignorable whitespace.
    IgnorableWhitespace(~str),
    /// A comment tag was parsed.
    Comment(~str),
    /// A `CDATA` block was parsed.
    CdataBlock(~str),
}

impl ToStr for ParseEvent {
    fn to_str(&self) -> ~str {
        match *self {
            StartDocument => ~"START DOCUMENT",
            EndDocument => ~"END DOCUMENT",
            StartElement(ref name, ref atts) => fmt!("<%s%s>", *name, atts.to_str()),
            EndElement(ref name) => fmt!("</%s>", *name),
            Characters(ref ch) => ch.clone(),
            IgnorableWhitespace(_) => ~"",
            Comment(ref value) => fmt!("", *value),
            CdataBlock(ref value) => fmt!("<![CDATA[%s]]>", *value),
        }
    }
}

/// A list of attributes stored in a hashmap.
#[deriving(Eq, Clone)]
pub struct Attributes(HashMap<~str, ~str>);

impl Attributes {
    unsafe fn from_buf(atts: **ffi::xmlChar) -> Attributes {
        let mut map = Attributes(HashMap::new());
        let mut ptr = atts as **c_char;
        while !ptr.is_null() && !(*ptr).is_null() {
            map.insert(str::raw::from_c_str(*ptr),
                       str::raw::from_c_str(*(ptr + 1)));
            ptr = ptr + 2;
        }
        map
    }
}

impl ToStr for Attributes {
    fn to_str(&self) -> ~str {
        do self.iter().map |(k, v)| {
            fmt!(" %s=\"%s\"", *k, *v)
        }.to_owned_vec().concat()
    }
}

/// Either a parse event wrapped in `Ok` or some Error data wrapped in `Err`.
pub type ParseResult = Result<ParseEvent, ErrorData>;

/// A port to recieve `ParseResult`s from the parser.
pub struct SaxPort {
    priv port: Port<ParseResult>,
}

impl GenericPort<ParseResult> for SaxPort {
    /// Recives a new parse message.
    ///
    /// # Failure
    ///
    /// Fails if the method is called again after the final `Ok(EndDocument)`
    /// parse result has been recived.
    pub fn recv(&self) -> ParseResult {
        self.port.try_recv().expect(
            "Could not get a new parse result, the parser has already finished!"
        )
    }

    /// Receives a parse result wrapped in `Some`, or `None` if the parser has
    /// finished.
    pub fn try_recv(&self) -> Option<ParseResult> {
        self.port.try_recv()
    }
}

/// Parses the entire XML string.
///
/// # Returns
///
/// A port that recieves parse results.
///
/// # Example
///
/// ~~~rust
/// let port = parse_xml("<hullo><world /></hullo>");
/// loop {
///     if port.recv() == Ok(EndDocument) { break }
/// }
/// ~~~
pub fn parse_xml(src: &str) -> SaxPort {
    let len = src.len() as c_int;
    do src.to_c_str().with_ref |c_str| {
        let (port, chan) = stream();
        // do task::spawn {
            unsafe {
                ffi::xmlSAXUserParseMemory(&extfn::new_handler(),
                                           cast::transmute(&chan),
                                           c_str, len);
                ffi::xmlCleanupParser();
            }
        // }
        SaxPort { port: port }
    }
}

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

    #[test]
    fn test() {
        let sax = parse_xml(
            "<hello><this />test</hello>"
        );
        loop {
            match sax.recv() {
                Ok(StartDocument) => (),
                Ok(EndDocument) => break,
                Ok(event) => println(event.to_str()),
                Err(err) => println(err.to_str()),
            }
        }
    }
}
<|endoftext|>


<commit_before>//! Definitions of integer that is known not to equal zero.

use crate::fmt;
use crate::ops::{BitOr, BitOrAssign};
use crate::str::FromStr;

use super::from_str_radix;
use super::{IntErrorKind, ParseIntError};

macro_rules! doc_comment {
    ($x:expr, $($tt:tt)*) => {
        #[doc = $x]
        $($tt)*
    };
}

macro_rules! impl_nonzero_fmt {
    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
        $(
            #[$stability]
            impl fmt::$Trait for $Ty {
                #[inline]
                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                    self.get().fmt(f)
                }
            }
        )+
    }
}

macro_rules! nonzero_integers {
    ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
        $(
            doc_comment! {
                concat!("An integer that is known not to equal zero.

This enables some memory layout optimization.
For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:

```rust
use std::mem::size_of;
assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
">());
```"),
                #[$stability]
                #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
                #[repr(transparent)]
                #[rustc_layout_scalar_valid_range_start(1)]
                #[rustc_nonnull_optimization_guaranteed]
                pub struct $Ty($Int);
            }

            impl $Ty {
                /// Creates a non-zero without checking the value.
                ///
                /// # Safety
                ///
                /// The value must not be zero.
                #[$stability]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                #[inline]
                pub const unsafe fn new_unchecked(n: $Int) -> Self {
                    // SAFETY: this is guaranteed to be safe by the caller.
                    unsafe { Self(n) }
                }

                /// Creates a non-zero if the given value is not zero.
                #[$stability]
                #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
                #[inline]
                pub const fn new(n: $Int) -> Option<Self> {
                    if n != 0 {
                        // SAFETY: we just checked that there's no `0`
                        Some(unsafe { Self(n) })
                    } else {
                        None
                    }
                }

                /// Returns the value as a primitive type.
                #[$stability]
                #[inline]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                pub const fn get(self) -> $Int {
                    self.0
                }

            }

            #[stable(feature = "from_nonzero", since = "1.31.0")]
            impl From<$Ty> for $Int {
                doc_comment! {
                    concat!(
"Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`"),
                    fn from(nonzero: $Ty) -> Self {
                        nonzero.0
                    }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: Self) -> Self::Output {
                    // SAFETY: since `self` and `rhs` are both nonzero, the
                    // result of the bitwise-or will be nonzero.
                    unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Int> for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: $Int) -> Self::Output {
                    // SAFETY: since `self` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `rhs`.
                    unsafe { $Ty::new_unchecked(self.get() | rhs) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Ty> for $Int {
                type Output = $Ty;
                #[inline]
                fn bitor(self, rhs: $Ty) -> Self::Output {
                    // SAFETY: since `rhs` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `self`.
                    unsafe { $Ty::new_unchecked(self | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: Self) {
                    *self = *self | rhs;
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign<$Int> for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: $Int) {
                    *self = *self | rhs;
                }
            }

            impl_nonzero_fmt! {
                #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
            }
        )+
    }
}

nonzero_integers! {
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
}

macro_rules! from_str_radix_nzint_impl {
    ($($t:ty)*) => {$(
        #[stable(feature = "nonzero_parse", since = "1.35.0")]
        impl FromStr for $t {
            type Err = ParseIntError;
            fn from_str(src: &str) -> Result<Self, Self::Err> {
                Self::new(from_str_radix(src, 10)?)
                    .ok_or(ParseIntError {
                        kind: IntErrorKind::Zero
                    })
            }
        }
    )*}
}

from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
<commit_msg>Inline NonZeroN::from(n)<commit_after>//! Definitions of integer that is known not to equal zero.

use crate::fmt;
use crate::ops::{BitOr, BitOrAssign};
use crate::str::FromStr;

use super::from_str_radix;
use super::{IntErrorKind, ParseIntError};

macro_rules! doc_comment {
    ($x:expr, $($tt:tt)*) => {
        #[doc = $x]
        $($tt)*
    };
}

macro_rules! impl_nonzero_fmt {
    ( #[$stability: meta] ( $( $Trait: ident ),+ ) for $Ty: ident ) => {
        $(
            #[$stability]
            impl fmt::$Trait for $Ty {
                #[inline]
                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                    self.get().fmt(f)
                }
            }
        )+
    }
}

macro_rules! nonzero_integers {
    ( $( #[$stability: meta] $Ty: ident($Int: ty); )+ ) => {
        $(
            doc_comment! {
                concat!("An integer that is known not to equal zero.

This enables some memory layout optimization.
For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:

```rust
use std::mem::size_of;
assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int),
">());
```"),
                #[$stability]
                #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
                #[repr(transparent)]
                #[rustc_layout_scalar_valid_range_start(1)]
                #[rustc_nonnull_optimization_guaranteed]
                pub struct $Ty($Int);
            }

            impl $Ty {
                /// Creates a non-zero without checking the value.
                ///
                /// # Safety
                ///
                /// The value must not be zero.
                #[$stability]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                #[inline]
                pub const unsafe fn new_unchecked(n: $Int) -> Self {
                    // SAFETY: this is guaranteed to be safe by the caller.
                    unsafe { Self(n) }
                }

                /// Creates a non-zero if the given value is not zero.
                #[$stability]
                #[rustc_const_stable(feature = "const_nonzero_int_methods", since = "1.47.0")]
                #[inline]
                pub const fn new(n: $Int) -> Option<Self> {
                    if n != 0 {
                        // SAFETY: we just checked that there's no `0`
                        Some(unsafe { Self(n) })
                    } else {
                        None
                    }
                }

                /// Returns the value as a primitive type.
                #[$stability]
                #[inline]
                #[rustc_const_stable(feature = "nonzero", since = "1.34.0")]
                pub const fn get(self) -> $Int {
                    self.0
                }

            }

            #[stable(feature = "from_nonzero", since = "1.31.0")]
            impl From<$Ty> for $Int {
                doc_comment! {
                    concat!(
"Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`"),
                    #[inline]
                    fn from(nonzero: $Ty) -> Self {
                        nonzero.0
                    }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: Self) -> Self::Output {
                    // SAFETY: since `self` and `rhs` are both nonzero, the
                    // result of the bitwise-or will be nonzero.
                    unsafe { $Ty::new_unchecked(self.get() | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Int> for $Ty {
                type Output = Self;
                #[inline]
                fn bitor(self, rhs: $Int) -> Self::Output {
                    // SAFETY: since `self` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `rhs`.
                    unsafe { $Ty::new_unchecked(self.get() | rhs) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOr<$Ty> for $Int {
                type Output = $Ty;
                #[inline]
                fn bitor(self, rhs: $Ty) -> Self::Output {
                    // SAFETY: since `rhs` is nonzero, the result of the
                    // bitwise-or will be nonzero regardless of the value of
                    // `self`.
                    unsafe { $Ty::new_unchecked(self | rhs.get()) }
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: Self) {
                    *self = *self | rhs;
                }
            }

            #[stable(feature = "nonzero_bitor", since = "1.45.0")]
            impl BitOrAssign<$Int> for $Ty {
                #[inline]
                fn bitor_assign(&mut self, rhs: $Int) {
                    *self = *self | rhs;
                }
            }

            impl_nonzero_fmt! {
                #[$stability] (Debug, Display, Binary, Octal, LowerHex, UpperHex) for $Ty
            }
        )+
    }
}

nonzero_integers! {
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU8(u8);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU16(u16);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU32(u32);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU64(u64);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroU128(u128);
    #[stable(feature = "nonzero", since = "1.28.0")] NonZeroUsize(usize);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI8(i8);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI16(i16);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI32(i32);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI64(i64);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroI128(i128);
    #[stable(feature = "signed_nonzero", since = "1.34.0")] NonZeroIsize(isize);
}

macro_rules! from_str_radix_nzint_impl {
    ($($t:ty)*) => {$(
        #[stable(feature = "nonzero_parse", since = "1.35.0")]
        impl FromStr for $t {
            type Err = ParseIntError;
            fn from_str(src: &str) -> Result<Self, Self::Err> {
                Self::new(from_str_radix(src, 10)?)
                    .ok_or(ParseIntError {
                        kind: IntErrorKind::Zero
                    })
            }
        }
    )*}
}

from_str_radix_nzint_impl! { NonZeroU8 NonZeroU16 NonZeroU32 NonZeroU64 NonZeroU128 NonZeroUsize
NonZeroI8 NonZeroI16 NonZeroI32 NonZeroI64 NonZeroI128 NonZeroIsize }
<|endoftext|>


<commit_before>use crate::codec::*;
use crate::endpoint::Endpoint;
use crate::error::ZmqResult;
use crate::message::*;
use crate::transport::AcceptStopHandle;
use crate::util::PeerIdentity;
use crate::{
    MultiPeerBackend, Socket, SocketBackend, SocketEvent, SocketOptions, SocketRecv, SocketType,
};

use crate::backend::Peer;
use crate::fair_queue::FairQueue;
use crate::fair_queue::QueueInner;
use async_trait::async_trait;
use bytes::{BufMut, BytesMut};
use crossbeam::queue::SegQueue;
use dashmap::DashMap;
use futures::channel::mpsc;
use futures::{SinkExt, StreamExt};
use parking_lot::Mutex;
use std::collections::{HashMap, HashSet};
use std::sync::Arc;

pub enum SubBackendMsgType {
    UNSUBSCRIBE = 0,
    SUBSCRIBE = 1,
}

pub(crate) struct SubSocketBackend {
    pub(crate) peers: DashMap<PeerIdentity, Peer>,
    fair_queue_inner: Option<Arc<Mutex<QueueInner<ZmqFramedRead, PeerIdentity>>>>,
    pub(crate) round_robin: SegQueue<PeerIdentity>,
    socket_type: SocketType,
    socket_options: SocketOptions,
    pub(crate) socket_monitor: Mutex<Option<mpsc::Sender<SocketEvent>>>,
    subs: Mutex<HashSet<String>>,
}

impl SubSocketBackend {
    pub(crate) fn with_options(
        fair_queue_inner: Option<Arc<Mutex<QueueInner<ZmqFramedRead, PeerIdentity>>>>,
        socket_type: SocketType,
        options: SocketOptions,
    ) -> Self {
        Self {
            peers: DashMap::new(),
            fair_queue_inner,
            round_robin: SegQueue::new(),
            socket_type,
            socket_options: options,
            socket_monitor: Mutex::new(None),
            subs: Mutex::new(HashSet::new()),
        }
    }

    pub fn create_subs_message(subscription: &str, msg_type: SubBackendMsgType) -> ZmqMessage {
        let mut buf = BytesMut::with_capacity(subscription.len() + 1);
        buf.put_u8(msg_type as u8);
        buf.extend_from_slice(subscription.as_bytes());

        buf.freeze().into()
    }
}

impl SocketBackend for SubSocketBackend {
    fn socket_type(&self) -> SocketType {
        self.socket_type
    }

    fn socket_options(&self) -> &SocketOptions {
        &self.socket_options
    }

    fn shutdown(&self) {
        self.peers.clear();
    }

    fn monitor(&self) -> &Mutex<Option<mpsc::Sender<SocketEvent>>> {
        &self.socket_monitor
    }
}

#[async_trait]
impl MultiPeerBackend for SubSocketBackend {
    async fn peer_connected(self: Arc<Self>, peer_id: &PeerIdentity, io: FramedIo) {
        let (recv_queue, mut send_queue) = io.into_parts();

        let subs_msgs: Vec<ZmqMessage> = self
            .subs
            .lock()
            .iter()
            .map(|x| SubSocketBackend::create_subs_message(x, SubBackendMsgType::SUBSCRIBE))
            .collect();

        for message in subs_msgs.iter() {
            send_queue
                .send(Message::Message(message.clone()))
                .await
                .unwrap();
        }

        self.peers.insert(peer_id.clone(), Peer { send_queue });
        self.round_robin.push(peer_id.clone());
        match &self.fair_queue_inner {
            None => {}
            Some(inner) => {
                inner.lock().insert(peer_id.clone(), recv_queue);
            }
        };
    }

    fn peer_disconnected(&self, peer_id: &PeerIdentity) {
        self.peers.remove(peer_id);
    }
}

pub struct SubSocket {
    backend: Arc<SubSocketBackend>,
    fair_queue: FairQueue<ZmqFramedRead, PeerIdentity>,
    binds: HashMap<Endpoint, AcceptStopHandle>,
}

impl Drop for SubSocket {
    fn drop(&mut self) {
        self.backend.shutdown()
    }
}

impl SubSocket {
    pub async fn subscribe(&mut self, subscription: &str) -> ZmqResult<()> {
        self.backend.subs.lock().insert(subscription.to_string());
        self.process_subs(subscription, SubBackendMsgType::SUBSCRIBE)
            .await
    }

    pub async fn unsubscribe(&mut self, subscription: &str) -> ZmqResult<()> {
        self.backend.subs.lock().remove(subscription);
        self.process_subs(subscription, SubBackendMsgType::UNSUBSCRIBE)
            .await
    }

    async fn process_subs(
        &mut self,
        subscription: &str,
        msg_type: SubBackendMsgType,
    ) -> ZmqResult<()> {
        let message: ZmqMessage = SubSocketBackend::create_subs_message(subscription, msg_type);

        for mut peer in self.backend.peers.iter_mut() {
            peer.send_queue
                .send(Message::Message(message.clone()))
                .await?;
        }
        Ok(())
    }
}

#[async_trait]
impl Socket for SubSocket {
    fn with_options(options: SocketOptions) -> Self {
        let fair_queue = FairQueue::new(true);
        Self {
            backend: Arc::new(SubSocketBackend::with_options(
                Some(fair_queue.inner()),
                SocketType::SUB,
                options,
            )),
            fair_queue,
            binds: HashMap::new(),
        }
    }

    fn backend(&self) -> Arc<dyn MultiPeerBackend> {
        self.backend.clone()
    }

    fn binds(&mut self) -> &mut HashMap<Endpoint, AcceptStopHandle> {
        &mut self.binds
    }

    fn monitor(&mut self) -> mpsc::Receiver<SocketEvent> {
        let (sender, receiver) = mpsc::channel(1024);
        self.backend.socket_monitor.lock().replace(sender);
        receiver
    }
}

#[async_trait]
impl SocketRecv for SubSocket {
    async fn recv(&mut self) -> ZmqResult<ZmqMessage> {
        loop {
            match self.fair_queue.next().await {
                Some((_peer_id, Ok(Message::Message(message)))) => {
                    return Ok(message);
                }
                Some((_peer_id, _)) => todo!(),
                None => todo!(),
            }
        }
    }
}
<commit_msg>Removed extra message clone<commit_after>use crate::codec::*;
use crate::endpoint::Endpoint;
use crate::error::ZmqResult;
use crate::message::*;
use crate::transport::AcceptStopHandle;
use crate::util::PeerIdentity;
use crate::{
    MultiPeerBackend, Socket, SocketBackend, SocketEvent, SocketOptions, SocketRecv, SocketType,
};

use crate::backend::Peer;
use crate::fair_queue::FairQueue;
use crate::fair_queue::QueueInner;
use async_trait::async_trait;
use bytes::{BufMut, BytesMut};
use crossbeam::queue::SegQueue;
use dashmap::DashMap;
use futures::channel::mpsc;
use futures::{SinkExt, StreamExt};
use parking_lot::Mutex;
use std::collections::{HashMap, HashSet};
use std::sync::Arc;

pub enum SubBackendMsgType {
    UNSUBSCRIBE = 0,
    SUBSCRIBE = 1,
}

pub(crate) struct SubSocketBackend {
    pub(crate) peers: DashMap<PeerIdentity, Peer>,
    fair_queue_inner: Option<Arc<Mutex<QueueInner<ZmqFramedRead, PeerIdentity>>>>,
    pub(crate) round_robin: SegQueue<PeerIdentity>,
    socket_type: SocketType,
    socket_options: SocketOptions,
    pub(crate) socket_monitor: Mutex<Option<mpsc::Sender<SocketEvent>>>,
    subs: Mutex<HashSet<String>>,
}

impl SubSocketBackend {
    pub(crate) fn with_options(
        fair_queue_inner: Option<Arc<Mutex<QueueInner<ZmqFramedRead, PeerIdentity>>>>,
        socket_type: SocketType,
        options: SocketOptions,
    ) -> Self {
        Self {
            peers: DashMap::new(),
            fair_queue_inner,
            round_robin: SegQueue::new(),
            socket_type,
            socket_options: options,
            socket_monitor: Mutex::new(None),
            subs: Mutex::new(HashSet::new()),
        }
    }

    pub fn create_subs_message(subscription: &str, msg_type: SubBackendMsgType) -> ZmqMessage {
        let mut buf = BytesMut::with_capacity(subscription.len() + 1);
        buf.put_u8(msg_type as u8);
        buf.extend_from_slice(subscription.as_bytes());

        buf.freeze().into()
    }
}

impl SocketBackend for SubSocketBackend {
    fn socket_type(&self) -> SocketType {
        self.socket_type
    }

    fn socket_options(&self) -> &SocketOptions {
        &self.socket_options
    }

    fn shutdown(&self) {
        self.peers.clear();
    }

    fn monitor(&self) -> &Mutex<Option<mpsc::Sender<SocketEvent>>> {
        &self.socket_monitor
    }
}

#[async_trait]
impl MultiPeerBackend for SubSocketBackend {
    async fn peer_connected(self: Arc<Self>, peer_id: &PeerIdentity, io: FramedIo) {
        let (recv_queue, mut send_queue) = io.into_parts();

        let subs_msgs: Vec<ZmqMessage> = self
            .subs
            .lock()
            .iter()
            .map(|x| SubSocketBackend::create_subs_message(x, SubBackendMsgType::SUBSCRIBE))
            .collect();

        for message in subs_msgs {
            send_queue
                .send(Message::Message(message))
                .await
                .unwrap();
        }

        self.peers.insert(peer_id.clone(), Peer { send_queue });
        self.round_robin.push(peer_id.clone());
        match &self.fair_queue_inner {
            None => {}
            Some(inner) => {
                inner.lock().insert(peer_id.clone(), recv_queue);
            }
        };
    }

    fn peer_disconnected(&self, peer_id: &PeerIdentity) {
        self.peers.remove(peer_id);
    }
}

pub struct SubSocket {
    backend: Arc<SubSocketBackend>,
    fair_queue: FairQueue<ZmqFramedRead, PeerIdentity>,
    binds: HashMap<Endpoint, AcceptStopHandle>,
}

impl Drop for SubSocket {
    fn drop(&mut self) {
        self.backend.shutdown()
    }
}

impl SubSocket {
    pub async fn subscribe(&mut self, subscription: &str) -> ZmqResult<()> {
        self.backend.subs.lock().insert(subscription.to_string());
        self.process_subs(subscription, SubBackendMsgType::SUBSCRIBE)
            .await
    }

    pub async fn unsubscribe(&mut self, subscription: &str) -> ZmqResult<()> {
        self.backend.subs.lock().remove(subscription);
        self.process_subs(subscription, SubBackendMsgType::UNSUBSCRIBE)
            .await
    }

    async fn process_subs(
        &mut self,
        subscription: &str,
        msg_type: SubBackendMsgType,
    ) -> ZmqResult<()> {
        let message: ZmqMessage = SubSocketBackend::create_subs_message(subscription, msg_type);

        for mut peer in self.backend.peers.iter_mut() {
            peer.send_queue
                .send(Message::Message(message.clone()))
                .await?;
        }
        Ok(())
    }
}

#[async_trait]
impl Socket for SubSocket {
    fn with_options(options: SocketOptions) -> Self {
        let fair_queue = FairQueue::new(true);
        Self {
            backend: Arc::new(SubSocketBackend::with_options(
                Some(fair_queue.inner()),
                SocketType::SUB,
                options,
            )),
            fair_queue,
            binds: HashMap::new(),
        }
    }

    fn backend(&self) -> Arc<dyn MultiPeerBackend> {
        self.backend.clone()
    }

    fn binds(&mut self) -> &mut HashMap<Endpoint, AcceptStopHandle> {
        &mut self.binds
    }

    fn monitor(&mut self) -> mpsc::Receiver<SocketEvent> {
        let (sender, receiver) = mpsc::channel(1024);
        self.backend.socket_monitor.lock().replace(sender);
        receiver
    }
}

#[async_trait]
impl SocketRecv for SubSocket {
    async fn recv(&mut self) -> ZmqResult<ZmqMessage> {
        loop {
            match self.fair_queue.next().await {
                Some((_peer_id, Ok(Message::Message(message)))) => {
                    return Ok(message);
                }
                Some((_peer_id, _)) => todo!(),
                None => todo!(),
            }
        }
    }
}
<|endoftext|>


<commit_before>use crate::hir::map::definitions::*;
use crate::hir::def_id::DefIndex;

use syntax::ast::*;
use syntax::ext::hygiene::Mark;
use syntax::visit;
use syntax::symbol::{kw, sym};
use syntax::parse::token::{self, Token};
use syntax_pos::Span;

/// Creates `DefId`s for nodes in the AST.
pub struct DefCollector<'a> {
    definitions: &'a mut Definitions,
    parent_def: Option<DefIndex>,
    expansion: Mark,
}

impl<'a> DefCollector<'a> {
    pub fn new(definitions: &'a mut Definitions, expansion: Mark) -> Self {
        let parent_def = Some(definitions.invocation_parent(expansion));
        DefCollector { definitions, parent_def, expansion }
    }

    fn create_def(&mut self,
                  node_id: NodeId,
                  data: DefPathData,
                  span: Span)
                  -> DefIndex {
        let parent_def = self.parent_def.unwrap();
        debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
        self.definitions
            .create_def_with_parent(parent_def, node_id, data, self.expansion, span)
    }

    pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
        let parent = self.parent_def;
        self.parent_def = Some(parent_def);
        f(self);
        self.parent_def = parent;
    }

    fn visit_async_fn(
        &mut self,
        id: NodeId,
        name: Name,
        span: Span,
        header: &FnHeader,
        generics: &'a Generics,
        decl: &'a FnDecl,
        body: &'a Block,
    ) {
        let (closure_id, return_impl_trait_id) = match header.asyncness.node {
            IsAsync::Async {
                closure_id,
                return_impl_trait_id,
            } => (closure_id, return_impl_trait_id),
            _ => unreachable!(),
        };

        // For async functions, we need to create their inner defs inside of a
        // closure to match their desugared representation.
        let fn_def_data = DefPathData::ValueNs(name.as_interned_str());
        let fn_def = self.create_def(id, fn_def_data, span);
        return self.with_parent(fn_def, |this| {
            this.create_def(return_impl_trait_id, DefPathData::ImplTrait, span);

            visit::walk_generics(this, generics);
            visit::walk_fn_decl(this, decl);

            let closure_def = this.create_def(
                closure_id, DefPathData::ClosureExpr, span,
            );
            this.with_parent(closure_def, |this| {
                visit::walk_block(this, body);
            })
        })
    }

    fn visit_macro_invoc(&mut self, id: NodeId) {
        self.definitions.set_invocation_parent(id.placeholder_to_mark(), self.parent_def.unwrap());
    }
}

impl<'a> visit::Visitor<'a> for DefCollector<'a> {
    fn visit_item(&mut self, i: &'a Item) {
        debug!("visit_item: {:?}", i);

        // Pick the def data. This need not be unique, but the more
        // information we encapsulate into, the better
        let def_data = match i.node {
            ItemKind::Impl(..) => DefPathData::Impl,
            ItemKind::Mod(..) if i.ident.name == kw::Invalid => {
                return visit::walk_item(self, i);
            }
            ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
            ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
            ItemKind::Existential(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
            ItemKind::Ty(..) => DefPathData::TypeNs(i.ident.as_interned_str()),
            ItemKind::Fn(
                ref decl,
                ref header,
                ref generics,
                ref body,
            ) if header.asyncness.node.is_async() => {
                return self.visit_async_fn(
                    i.id,
                    i.ident.name,
                    i.span,
                    header,
                    generics,
                    decl,
                    body,
                )
            }
            ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
                DefPathData::ValueNs(i.ident.as_interned_str()),
            ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.as_interned_str()),
            ItemKind::Mac(..) => return self.visit_macro_invoc(i.id),
            ItemKind::GlobalAsm(..) => DefPathData::Misc,
            ItemKind::Use(..) => {
                return visit::walk_item(self, i);
            }
        };
        let def = self.create_def(i.id, def_data, i.span);

        self.with_parent(def, |this| {
            match i.node {
                ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => {
                    // If this is a unit or tuple-like struct, register the constructor.
                    if let Some(ctor_hir_id) = struct_def.ctor_id() {
                        this.create_def(ctor_hir_id, DefPathData::Ctor, i.span);
                    }
                }
                _ => {}
            }
            visit::walk_item(this, i);
        });
    }

    fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
        self.create_def(id, DefPathData::Misc, use_tree.span);
        visit::walk_use_tree(self, use_tree, id);
    }

    fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
        if let ForeignItemKind::Macro(_) = foreign_item.node {
            return self.visit_macro_invoc(foreign_item.id);
        }

        let def = self.create_def(foreign_item.id,
                                  DefPathData::ValueNs(foreign_item.ident.as_interned_str()),
                                  foreign_item.span);

        self.with_parent(def, |this| {
            visit::walk_foreign_item(this, foreign_item);
        });
    }

    fn visit_variant(&mut self, v: &'a Variant, g: &'a Generics, item_id: NodeId) {
        let def = self.create_def(v.node.id,
                                  DefPathData::TypeNs(v.node.ident.as_interned_str()),
                                  v.span);
        self.with_parent(def, |this| {
            if let Some(ctor_hir_id) = v.node.data.ctor_id() {
                this.create_def(ctor_hir_id, DefPathData::Ctor, v.span);
            }
            visit::walk_variant(this, v, g, item_id)
        });
    }

    fn visit_variant_data(&mut self, data: &'a VariantData, _: Ident,
                          _: &'a Generics, _: NodeId, _: Span) {
        for (index, field) in data.fields().iter().enumerate() {
            let name = field.ident.map(|ident| ident.name)
                .unwrap_or_else(|| sym::integer(index));
            let def = self.create_def(field.id,
                                      DefPathData::ValueNs(name.as_interned_str()),
                                      field.span);
            self.with_parent(def, |this| this.visit_struct_field(field));
        }
    }

    fn visit_generic_param(&mut self, param: &'a GenericParam) {
        let name = param.ident.as_interned_str();
        let def_path_data = match param.kind {
            GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(name),
            GenericParamKind::Type { .. } => DefPathData::TypeNs(name),
            GenericParamKind::Const { .. } => DefPathData::ValueNs(name),
        };
        self.create_def(param.id, def_path_data, param.ident.span);

        visit::walk_generic_param(self, param);
    }

    fn visit_trait_item(&mut self, ti: &'a TraitItem) {
        let def_data = match ti.node {
            TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
                DefPathData::ValueNs(ti.ident.as_interned_str()),
            TraitItemKind::Type(..) => {
                DefPathData::TypeNs(ti.ident.as_interned_str())
            },
            TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id),
        };

        let def = self.create_def(ti.id, def_data, ti.span);
        self.with_parent(def, |this| visit::walk_trait_item(this, ti));
    }

    fn visit_impl_item(&mut self, ii: &'a ImplItem) {
        let def_data = match ii.node {
            ImplItemKind::Method(MethodSig {
                ref header,
                ref decl,
            }, ref body) if header.asyncness.node.is_async() => {
                return self.visit_async_fn(
                    ii.id,
                    ii.ident.name,
                    ii.span,
                    header,
                    &ii.generics,
                    decl,
                    body,
                )
            }
            ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
                DefPathData::ValueNs(ii.ident.as_interned_str()),
            ImplItemKind::Type(..) |
            ImplItemKind::Existential(..) => {
                DefPathData::TypeNs(ii.ident.as_interned_str())
            },
            ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id),
        };

        let def = self.create_def(ii.id, def_data, ii.span);
        self.with_parent(def, |this| visit::walk_impl_item(this, ii));
    }

    fn visit_pat(&mut self, pat: &'a Pat) {
        match pat.node {
            PatKind::Mac(..) => return self.visit_macro_invoc(pat.id),
            _ => visit::walk_pat(self, pat),
        }
    }

    fn visit_anon_const(&mut self, constant: &'a AnonConst) {
        let def = self.create_def(constant.id,
                                  DefPathData::AnonConst,
                                  constant.value.span);
        self.with_parent(def, |this| visit::walk_anon_const(this, constant));
    }

    fn visit_expr(&mut self, expr: &'a Expr) {
        let parent_def = self.parent_def;

        match expr.node {
            ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id),
            ExprKind::Closure(_, asyncness, ..) => {
                let closure_def = self.create_def(expr.id,
                                          DefPathData::ClosureExpr,
                                          expr.span);
                self.parent_def = Some(closure_def);

                // Async closures desugar to closures inside of closures, so
                // we must create two defs.
                if let IsAsync::Async { closure_id, .. } = asyncness {
                    let async_def = self.create_def(closure_id,
                                                    DefPathData::ClosureExpr,
                                                    expr.span);
                    self.parent_def = Some(async_def);
                }
            }
            ExprKind::Async(_, async_id, _) => {
                let async_def = self.create_def(async_id,
                                                DefPathData::ClosureExpr,
                                                expr.span);
                self.parent_def = Some(async_def);
            }
            _ => {}
        };

        visit::walk_expr(self, expr);
        self.parent_def = parent_def;
    }

    fn visit_ty(&mut self, ty: &'a Ty) {
        match ty.node {
            TyKind::Mac(..) => return self.visit_macro_invoc(ty.id),
            TyKind::ImplTrait(node_id, _) => {
                self.create_def(node_id, DefPathData::ImplTrait, ty.span);
            }
            _ => {}
        }
        visit::walk_ty(self, ty);
    }

    fn visit_stmt(&mut self, stmt: &'a Stmt) {
        match stmt.node {
            StmtKind::Mac(..) => self.visit_macro_invoc(stmt.id),
            _ => visit::walk_stmt(self, stmt),
        }
    }

    fn visit_token(&mut self, t: Token) {
        if let token::Interpolated(nt) = t.kind {
            if let token::NtExpr(ref expr) = *nt {
                if let ExprKind::Mac(..) = expr.node {
                    self.visit_macro_invoc(expr.id);
                }
            }
        }
    }
}
<commit_msg>def_collector: `parent_def` is no longer optional<commit_after>use crate::hir::map::definitions::*;
use crate::hir::def_id::DefIndex;

use syntax::ast::*;
use syntax::ext::hygiene::Mark;
use syntax::visit;
use syntax::symbol::{kw, sym};
use syntax::parse::token::{self, Token};
use syntax_pos::Span;

/// Creates `DefId`s for nodes in the AST.
pub struct DefCollector<'a> {
    definitions: &'a mut Definitions,
    parent_def: DefIndex,
    expansion: Mark,
}

impl<'a> DefCollector<'a> {
    pub fn new(definitions: &'a mut Definitions, expansion: Mark) -> Self {
        let parent_def = definitions.invocation_parent(expansion);
        DefCollector { definitions, parent_def, expansion }
    }

    fn create_def(&mut self,
                  node_id: NodeId,
                  data: DefPathData,
                  span: Span)
                  -> DefIndex {
        let parent_def = self.parent_def;
        debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def);
        self.definitions.create_def_with_parent(parent_def, node_id, data, self.expansion, span)
    }

    pub fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_def: DefIndex, f: F) {
        let orig_parent_def = std::mem::replace(&mut self.parent_def, parent_def);
        f(self);
        self.parent_def = orig_parent_def;
    }

    fn visit_async_fn(
        &mut self,
        id: NodeId,
        name: Name,
        span: Span,
        header: &FnHeader,
        generics: &'a Generics,
        decl: &'a FnDecl,
        body: &'a Block,
    ) {
        let (closure_id, return_impl_trait_id) = match header.asyncness.node {
            IsAsync::Async {
                closure_id,
                return_impl_trait_id,
            } => (closure_id, return_impl_trait_id),
            _ => unreachable!(),
        };

        // For async functions, we need to create their inner defs inside of a
        // closure to match their desugared representation.
        let fn_def_data = DefPathData::ValueNs(name.as_interned_str());
        let fn_def = self.create_def(id, fn_def_data, span);
        return self.with_parent(fn_def, |this| {
            this.create_def(return_impl_trait_id, DefPathData::ImplTrait, span);

            visit::walk_generics(this, generics);
            visit::walk_fn_decl(this, decl);

            let closure_def = this.create_def(
                closure_id, DefPathData::ClosureExpr, span,
            );
            this.with_parent(closure_def, |this| {
                visit::walk_block(this, body);
            })
        })
    }

    fn visit_macro_invoc(&mut self, id: NodeId) {
        self.definitions.set_invocation_parent(id.placeholder_to_mark(), self.parent_def);
    }
}

impl<'a> visit::Visitor<'a> for DefCollector<'a> {
    fn visit_item(&mut self, i: &'a Item) {
        debug!("visit_item: {:?}", i);

        // Pick the def data. This need not be unique, but the more
        // information we encapsulate into, the better
        let def_data = match i.node {
            ItemKind::Impl(..) => DefPathData::Impl,
            ItemKind::Mod(..) if i.ident.name == kw::Invalid => {
                return visit::walk_item(self, i);
            }
            ItemKind::Mod(..) | ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
            ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
            ItemKind::Existential(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
            ItemKind::Ty(..) => DefPathData::TypeNs(i.ident.as_interned_str()),
            ItemKind::Fn(
                ref decl,
                ref header,
                ref generics,
                ref body,
            ) if header.asyncness.node.is_async() => {
                return self.visit_async_fn(
                    i.id,
                    i.ident.name,
                    i.span,
                    header,
                    generics,
                    decl,
                    body,
                )
            }
            ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) =>
                DefPathData::ValueNs(i.ident.as_interned_str()),
            ItemKind::MacroDef(..) => DefPathData::MacroNs(i.ident.as_interned_str()),
            ItemKind::Mac(..) => return self.visit_macro_invoc(i.id),
            ItemKind::GlobalAsm(..) => DefPathData::Misc,
            ItemKind::Use(..) => {
                return visit::walk_item(self, i);
            }
        };
        let def = self.create_def(i.id, def_data, i.span);

        self.with_parent(def, |this| {
            match i.node {
                ItemKind::Struct(ref struct_def, _) | ItemKind::Union(ref struct_def, _) => {
                    // If this is a unit or tuple-like struct, register the constructor.
                    if let Some(ctor_hir_id) = struct_def.ctor_id() {
                        this.create_def(ctor_hir_id, DefPathData::Ctor, i.span);
                    }
                }
                _ => {}
            }
            visit::walk_item(this, i);
        });
    }

    fn visit_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId, _nested: bool) {
        self.create_def(id, DefPathData::Misc, use_tree.span);
        visit::walk_use_tree(self, use_tree, id);
    }

    fn visit_foreign_item(&mut self, foreign_item: &'a ForeignItem) {
        if let ForeignItemKind::Macro(_) = foreign_item.node {
            return self.visit_macro_invoc(foreign_item.id);
        }

        let def = self.create_def(foreign_item.id,
                                  DefPathData::ValueNs(foreign_item.ident.as_interned_str()),
                                  foreign_item.span);

        self.with_parent(def, |this| {
            visit::walk_foreign_item(this, foreign_item);
        });
    }

    fn visit_variant(&mut self, v: &'a Variant, g: &'a Generics, item_id: NodeId) {
        let def = self.create_def(v.node.id,
                                  DefPathData::TypeNs(v.node.ident.as_interned_str()),
                                  v.span);
        self.with_parent(def, |this| {
            if let Some(ctor_hir_id) = v.node.data.ctor_id() {
                this.create_def(ctor_hir_id, DefPathData::Ctor, v.span);
            }
            visit::walk_variant(this, v, g, item_id)
        });
    }

    fn visit_variant_data(&mut self, data: &'a VariantData, _: Ident,
                          _: &'a Generics, _: NodeId, _: Span) {
        for (index, field) in data.fields().iter().enumerate() {
            let name = field.ident.map(|ident| ident.name)
                .unwrap_or_else(|| sym::integer(index));
            let def = self.create_def(field.id,
                                      DefPathData::ValueNs(name.as_interned_str()),
                                      field.span);
            self.with_parent(def, |this| this.visit_struct_field(field));
        }
    }

    fn visit_generic_param(&mut self, param: &'a GenericParam) {
        let name = param.ident.as_interned_str();
        let def_path_data = match param.kind {
            GenericParamKind::Lifetime { .. } => DefPathData::LifetimeNs(name),
            GenericParamKind::Type { .. } => DefPathData::TypeNs(name),
            GenericParamKind::Const { .. } => DefPathData::ValueNs(name),
        };
        self.create_def(param.id, def_path_data, param.ident.span);

        visit::walk_generic_param(self, param);
    }

    fn visit_trait_item(&mut self, ti: &'a TraitItem) {
        let def_data = match ti.node {
            TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
                DefPathData::ValueNs(ti.ident.as_interned_str()),
            TraitItemKind::Type(..) => {
                DefPathData::TypeNs(ti.ident.as_interned_str())
            },
            TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id),
        };

        let def = self.create_def(ti.id, def_data, ti.span);
        self.with_parent(def, |this| visit::walk_trait_item(this, ti));
    }

    fn visit_impl_item(&mut self, ii: &'a ImplItem) {
        let def_data = match ii.node {
            ImplItemKind::Method(MethodSig {
                ref header,
                ref decl,
            }, ref body) if header.asyncness.node.is_async() => {
                return self.visit_async_fn(
                    ii.id,
                    ii.ident.name,
                    ii.span,
                    header,
                    &ii.generics,
                    decl,
                    body,
                )
            }
            ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
                DefPathData::ValueNs(ii.ident.as_interned_str()),
            ImplItemKind::Type(..) |
            ImplItemKind::Existential(..) => {
                DefPathData::TypeNs(ii.ident.as_interned_str())
            },
            ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id),
        };

        let def = self.create_def(ii.id, def_data, ii.span);
        self.with_parent(def, |this| visit::walk_impl_item(this, ii));
    }

    fn visit_pat(&mut self, pat: &'a Pat) {
        match pat.node {
            PatKind::Mac(..) => return self.visit_macro_invoc(pat.id),
            _ => visit::walk_pat(self, pat),
        }
    }

    fn visit_anon_const(&mut self, constant: &'a AnonConst) {
        let def = self.create_def(constant.id,
                                  DefPathData::AnonConst,
                                  constant.value.span);
        self.with_parent(def, |this| visit::walk_anon_const(this, constant));
    }

    fn visit_expr(&mut self, expr: &'a Expr) {
        let parent_def = match expr.node {
            ExprKind::Mac(..) => return self.visit_macro_invoc(expr.id),
            ExprKind::Closure(_, asyncness, ..) => {
                // Async closures desugar to closures inside of closures, so
                // we must create two defs.
                let closure_def = self.create_def(expr.id, DefPathData::ClosureExpr, expr.span);
                match asyncness {
                    IsAsync::Async { closure_id, .. } =>
                        self.create_def(closure_id, DefPathData::ClosureExpr, expr.span),
                    IsAsync::NotAsync => closure_def,
                }
            }
            ExprKind::Async(_, async_id, _) =>
                self.create_def(async_id, DefPathData::ClosureExpr, expr.span),
            _ => self.parent_def,
        };

        self.with_parent(parent_def, |this| visit::walk_expr(this, expr));
    }

    fn visit_ty(&mut self, ty: &'a Ty) {
        match ty.node {
            TyKind::Mac(..) => return self.visit_macro_invoc(ty.id),
            TyKind::ImplTrait(node_id, _) => {
                self.create_def(node_id, DefPathData::ImplTrait, ty.span);
            }
            _ => {}
        }
        visit::walk_ty(self, ty);
    }

    fn visit_stmt(&mut self, stmt: &'a Stmt) {
        match stmt.node {
            StmtKind::Mac(..) => self.visit_macro_invoc(stmt.id),
            _ => visit::walk_stmt(self, stmt),
        }
    }

    fn visit_token(&mut self, t: Token) {
        if let token::Interpolated(nt) = t.kind {
            if let token::NtExpr(ref expr) = *nt {
                if let ExprKind::Mac(..) = expr.node {
                    self.visit_macro_invoc(expr.id);
                }
            }
        }
    }
}
<|endoftext|>