<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.

//! # Parser Nodes
//!
//! Parser nodes represent the grammar that is defined
//! by the currently permissible set of commands and their
//! parameters.

use std::rc::Rc;

/// Minimum priority.
pub const PRIORITY_MINIMUM: i32 = -10000;
/// The default priority for a parameter.
pub const PRIORITY_PARAMETER: i32 = -10;
/// The default priority.
pub const PRIORITY_DEFAULT: i32 = 0;

/// A node in the tree of commands and their parameters
/// used by the `Parser`.
pub trait Node {
    /// The data describing this node.
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields;

    /// The text used to identify this node in help text.
    /// This is typically the node name, either in plain
    /// form or decorated for parameters.
    fn help_symbol(&self) -> &String {
        &self.node_data().help_symbol
    }

    /// Help text describing this node.
    fn help_text(&self) -> &Option<String> {
        &self.node_data().help_text
    }

    /// Hidden nodes are still found for matching, but are
    /// hidden from completion.
    fn hidden(&self) -> bool {
        self.node_data().hidden
    }

    /// The name of this node.
    fn name(&self) -> &String {
        &self.node_data().name
    }

    /// This priority of this node during matching and completion.
    fn priority(&self) -> i32 {
        self.node_data().priority
    }

    /// Nodes that are children of this node. Used to
    /// by the `Parser` during `advance`, `complete`, etc.
    fn successors(&self) -> &Vec<Rc<Node>> {
        &self.node_data().successors
    }
}

impl PartialEq for Node {
    /// Nodes are equal based on pointer equality.
    fn eq(&self, other: &Self) -> bool {
        self as *const _ == other as *const _
    }
}

/// A parse tree node.
#[doc(hidden)]
pub struct NodeFields {
    /// The name of this node.
    name: String,
    /// The text used to identify this node in help text.
    /// This is typically the node name, either in plain
    /// form or decorated for parameters.
    help_symbol: String,
    /// Help text describing this node.
    help_text: Option<String>,
    /// Hidden nodes are not completed. This doesn't modify matching.
    hidden: bool,
    /// Match and complete priority.
    priority: i32,
    /// Possible successor nodes. Collected while building.
    successors: Vec<Rc<Node>>,
}

/// The root of a command tree.
///
/// ```
/// use commands::parser::nodes::RootNode;
///
/// let root = RootNode::new(vec![]);
/// ```
pub struct RootNode {
    node_fields: NodeFields,
}

impl RootNode {
    /// Create a new `RootNode`
    pub fn new(successors: Vec<Rc<Node>>) -> Rc<Self> {
        Rc::new(RootNode {
            node_fields: NodeFields {
                name: "__root__".to_string(),
                help_symbol: "".to_string(),
                help_text: None,
                hidden: false,
                priority: PRIORITY_DEFAULT,
                successors: successors,
            },
        })
    }
}

impl Node for RootNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

/// A node representing a command.
pub struct CommandNode {
    node_fields: NodeFields,
    command_fields: CommandNodeFields,
}

struct CommandNodeFields {
    handler: Option<fn(&node: Node) -> ()>,
    parameters: Vec<Rc<ParameterNode>>,
}

impl CommandNode {
    /// Construct a new `CommandNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               handler: Option<fn(&node: Node) -> ()>,
               parameters: Vec<Rc<ParameterNode>>)
               -> Self {
        CommandNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: name.to_string(),
                help_text: help_text.or(Some("Command".to_string())),
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            command_fields: CommandNodeFields {
                handler: handler,
                parameters: parameters,
            },
        }
    }

    /// The handler which is executed once this node has been accepted.
    pub fn handler(&self) -> Option<fn(&node: Node) -> ()> {
        self.command_fields.handler
    }

    /// Get the parameter nodes for this command.
    pub fn parameters(&self) -> &Vec<Rc<ParameterNode>> {
        &self.command_fields.parameters
    }
}

impl Node for CommandNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

/// A wrapper node wraps another command.
///
/// This is used for the help command so that it can complete
/// normal commands.
///
/// The `successors` will be those of the wrapped node.
pub struct WrapperNode {
    node_fields: NodeFields,
    #[allow(dead_code)]
    command_fields: CommandNodeFields,
    root: Rc<Node>,
}

impl Node for WrapperNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }

    fn successors(&self) -> &Vec<Rc<Node>> {
        self.root.successors()
    }
}

/// A repeatable node is an internal helper for representing
/// nodes that can be repeated, like some parameters.
pub trait RepeatableNode: Node {
    /// Internal data for a repeatable node.
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields;

    /// Whether or not this node can be repeated. A repeated
    /// node can be `accept`ed multiple times.
    fn repeatable(&self) -> bool {
        self.repeatable_data().repeatable
    }

    /// If present, this node will no longer be `acceptable`.
    fn repeat_marker(&self) -> &Option<Rc<Node>> {
        &self.repeatable_data().repeat_marker
    }
}

/// The data for a repeatable node.
#[doc(hidden)]
pub struct RepeatableNodeFields {
    repeatable: bool,
    repeat_marker: Option<Rc<Node>>,
}

/// A node that represented the name portion of a named
/// parameter.
pub struct ParameterNameNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    /// The `parameter` named by this node.
    pub parameter: Rc<ParameterNode>,
}

impl ParameterNameNode {
    /// Construct a new `ParameterNameNode`.
    pub fn new(name: &str,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               parameter: Rc<ParameterNode>)
               -> Self {
        let help_text = parameter.help_text().clone();
        let help_symbol = name.to_string() + " " + parameter.help_symbol().as_str();
        ParameterNameNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: help_symbol,
                help_text: help_text,
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter: parameter,
        }
    }
}

impl Node for ParameterNameNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for ParameterNameNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

/// Parameter nodes.
pub trait ParameterNode: Node + RepeatableNode {
    /// Internal data for a parameter node.
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields;

    /// A `required` parameter must be supplied for the
    /// command line being parsed to be valid.
    fn required(&self) -> bool {
        self.parameter_data().required
    }
}

/// Data for parameter nodes.
#[doc(hidden)]
pub struct ParameterNodeFields {
    required: bool,
}

/// A flag parameter node.
///
/// When implemented, this will only have a value of
/// true when it is present.
pub struct FlagParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for FlagParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for FlagParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for FlagParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl FlagParameterNode {
    /// Construct a new `FlagParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        let help_symbol = String::from("<") + name +
                          if repeatable {
            ">..."
        } else {
            ">"
        };
        FlagParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: help_symbol,
                help_text: help_text.or(Some("Flag".to_string())),
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}

/// A named parameter node.
pub struct NamedParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for NamedParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for NamedParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for NamedParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl NamedParameterNode {
    /// Construct a new `NamedParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        NamedParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: name.to_string(),
                help_text: help_text.or(Some("Parameter".to_string())),
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}

/// A simple parameter node. This is only present in a command
/// line as a value.
pub struct SimpleParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for SimpleParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for SimpleParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for SimpleParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl SimpleParameterNode {
    /// Construct a new `SimpleParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        SimpleParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: name.to_string(),
                help_text: help_text.or(Some("Parameter".to_string())),
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}
<commit_msg>Use Option.or_else instead of Option.or.<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.

//! # Parser Nodes
//!
//! Parser nodes represent the grammar that is defined
//! by the currently permissible set of commands and their
//! parameters.

use std::rc::Rc;

/// Minimum priority.
pub const PRIORITY_MINIMUM: i32 = -10000;
/// The default priority for a parameter.
pub const PRIORITY_PARAMETER: i32 = -10;
/// The default priority.
pub const PRIORITY_DEFAULT: i32 = 0;

/// A node in the tree of commands and their parameters
/// used by the `Parser`.
pub trait Node {
    /// The data describing this node.
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields;

    /// The text used to identify this node in help text.
    /// This is typically the node name, either in plain
    /// form or decorated for parameters.
    fn help_symbol(&self) -> &String {
        &self.node_data().help_symbol
    }

    /// Help text describing this node.
    fn help_text(&self) -> &Option<String> {
        &self.node_data().help_text
    }

    /// Hidden nodes are still found for matching, but are
    /// hidden from completion.
    fn hidden(&self) -> bool {
        self.node_data().hidden
    }

    /// The name of this node.
    fn name(&self) -> &String {
        &self.node_data().name
    }

    /// This priority of this node during matching and completion.
    fn priority(&self) -> i32 {
        self.node_data().priority
    }

    /// Nodes that are children of this node. Used to
    /// by the `Parser` during `advance`, `complete`, etc.
    fn successors(&self) -> &Vec<Rc<Node>> {
        &self.node_data().successors
    }
}

impl PartialEq for Node {
    /// Nodes are equal based on pointer equality.
    fn eq(&self, other: &Self) -> bool {
        self as *const _ == other as *const _
    }
}

/// A parse tree node.
#[doc(hidden)]
pub struct NodeFields {
    /// The name of this node.
    name: String,
    /// The text used to identify this node in help text.
    /// This is typically the node name, either in plain
    /// form or decorated for parameters.
    help_symbol: String,
    /// Help text describing this node.
    help_text: Option<String>,
    /// Hidden nodes are not completed. This doesn't modify matching.
    hidden: bool,
    /// Match and complete priority.
    priority: i32,
    /// Possible successor nodes. Collected while building.
    successors: Vec<Rc<Node>>,
}

/// The root of a command tree.
///
/// ```
/// use commands::parser::nodes::RootNode;
///
/// let root = RootNode::new(vec![]);
/// ```
pub struct RootNode {
    node_fields: NodeFields,
}

impl RootNode {
    /// Create a new `RootNode`
    pub fn new(successors: Vec<Rc<Node>>) -> Rc<Self> {
        Rc::new(RootNode {
            node_fields: NodeFields {
                name: "__root__".to_string(),
                help_symbol: "".to_string(),
                help_text: None,
                hidden: false,
                priority: PRIORITY_DEFAULT,
                successors: successors,
            },
        })
    }
}

impl Node for RootNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

/// A node representing a command.
pub struct CommandNode {
    node_fields: NodeFields,
    command_fields: CommandNodeFields,
}

struct CommandNodeFields {
    handler: Option<fn(&node: Node) -> ()>,
    parameters: Vec<Rc<ParameterNode>>,
}

impl CommandNode {
    /// Construct a new `CommandNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               handler: Option<fn(&node: Node) -> ()>,
               parameters: Vec<Rc<ParameterNode>>)
               -> Self {
        CommandNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: name.to_string(),
                help_text: help_text.or_else(|| Some("Command".to_string())),
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            command_fields: CommandNodeFields {
                handler: handler,
                parameters: parameters,
            },
        }
    }

    /// The handler which is executed once this node has been accepted.
    pub fn handler(&self) -> Option<fn(&node: Node) -> ()> {
        self.command_fields.handler
    }

    /// Get the parameter nodes for this command.
    pub fn parameters(&self) -> &Vec<Rc<ParameterNode>> {
        &self.command_fields.parameters
    }
}

impl Node for CommandNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

/// A wrapper node wraps another command.
///
/// This is used for the help command so that it can complete
/// normal commands.
///
/// The `successors` will be those of the wrapped node.
pub struct WrapperNode {
    node_fields: NodeFields,
    #[allow(dead_code)]
    command_fields: CommandNodeFields,
    root: Rc<Node>,
}

impl Node for WrapperNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }

    fn successors(&self) -> &Vec<Rc<Node>> {
        self.root.successors()
    }
}

/// A repeatable node is an internal helper for representing
/// nodes that can be repeated, like some parameters.
pub trait RepeatableNode: Node {
    /// Internal data for a repeatable node.
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields;

    /// Whether or not this node can be repeated. A repeated
    /// node can be `accept`ed multiple times.
    fn repeatable(&self) -> bool {
        self.repeatable_data().repeatable
    }

    /// If present, this node will no longer be `acceptable`.
    fn repeat_marker(&self) -> &Option<Rc<Node>> {
        &self.repeatable_data().repeat_marker
    }
}

/// The data for a repeatable node.
#[doc(hidden)]
pub struct RepeatableNodeFields {
    repeatable: bool,
    repeat_marker: Option<Rc<Node>>,
}

/// A node that represented the name portion of a named
/// parameter.
pub struct ParameterNameNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    /// The `parameter` named by this node.
    pub parameter: Rc<ParameterNode>,
}

impl ParameterNameNode {
    /// Construct a new `ParameterNameNode`.
    pub fn new(name: &str,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               parameter: Rc<ParameterNode>)
               -> Self {
        let help_text = parameter.help_text().clone();
        let help_symbol = name.to_string() + " " + parameter.help_symbol().as_str();
        ParameterNameNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: help_symbol,
                help_text: help_text,
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter: parameter,
        }
    }
}

impl Node for ParameterNameNode {
    #[doc(hidden)]
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for ParameterNameNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

/// Parameter nodes.
pub trait ParameterNode: Node + RepeatableNode {
    /// Internal data for a parameter node.
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields;

    /// A `required` parameter must be supplied for the
    /// command line being parsed to be valid.
    fn required(&self) -> bool {
        self.parameter_data().required
    }
}

/// Data for parameter nodes.
#[doc(hidden)]
pub struct ParameterNodeFields {
    required: bool,
}

/// A flag parameter node.
///
/// When implemented, this will only have a value of
/// true when it is present.
pub struct FlagParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for FlagParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for FlagParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for FlagParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl FlagParameterNode {
    /// Construct a new `FlagParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        let help_symbol = String::from("<") + name +
                          if repeatable {
            ">..."
        } else {
            ">"
        };
        FlagParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: help_symbol,
                help_text: help_text.or_else(|| Some("Flag".to_string())),
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}

/// A named parameter node.
pub struct NamedParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for NamedParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for NamedParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for NamedParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl NamedParameterNode {
    /// Construct a new `NamedParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        NamedParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: name.to_string(),
                help_text: help_text.or_else(|| Some("Parameter".to_string())),
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}

/// A simple parameter node. This is only present in a command
/// line as a value.
pub struct SimpleParameterNode {
    node_fields: NodeFields,
    repeatable_fields: RepeatableNodeFields,
    parameter_fields: ParameterNodeFields,
}

impl Node for SimpleParameterNode {
    fn node_data(&self) -> &NodeFields {
        &self.node_fields
    }
}

impl RepeatableNode for SimpleParameterNode {
    #[doc(hidden)]
    fn repeatable_data(&self) -> &RepeatableNodeFields {
        &self.repeatable_fields
    }
}

impl ParameterNode for SimpleParameterNode {
    #[doc(hidden)]
    fn parameter_data(&self) -> &ParameterNodeFields {
        &self.parameter_fields
    }
}

impl SimpleParameterNode {
    /// Construct a new `SimpleParameterNode`.
    pub fn new(name: &str,
               help_text: Option<String>,
               hidden: bool,
               priority: i32,
               successors: Vec<Rc<Node>>,
               repeatable: bool,
               repeat_marker: Option<Rc<Node>>,
               required: bool)
               -> Self {
        SimpleParameterNode {
            node_fields: NodeFields {
                name: name.to_string(),
                help_symbol: name.to_string(),
                help_text: help_text.or_else(|| Some("Parameter".to_string())),
                hidden: hidden,
                priority: priority,
                successors: successors,
            },
            repeatable_fields: RepeatableNodeFields {
                repeatable: repeatable,
                repeat_marker: repeat_marker,
            },
            parameter_fields: ParameterNodeFields { required: required },
        }
    }
}
<|endoftext|>


<commit_before>use perlin::*;

const ZOOM: usize = 10;
const ZOOM_F: f64 = ZOOM as f64;

const WIDTH: usize = 4;
const HEIGHT: usize = 4;

#[test]
fn demo() {
    let perlin = PerlinGrid::new(WIDTH, HEIGHT, PerlinWrapType::Regenerate).unwrap();

    for i in 0..(ZOOM * HEIGHT) {
        for j in 0..(ZOOM * WIDTH) {
            let noise = perlin.noise(j as f64 / ZOOM_F,
                                     i as f64 / ZOOM_F).unwrap();

            if noise < -0.2 || noise > 0.2 {
                print!("#");
            } else {
                print!(".");
            }
        }
        print!("\n");
    }
}
<commit_msg>Fixed PerlinGrid construction in perlin test<commit_after>use rand::{StdRng, SeedableRng};
use perlin::*;

const ZOOM: usize = 10;
const ZOOM_F: f64 = ZOOM as f64;

const WIDTH: usize = 4;
const HEIGHT: usize = 4;

#[test]
fn demo() {
    let mut rng = StdRng::from_seed(&[0]);
    let perlin = PerlinGrid::new(WIDTH, HEIGHT, PerlinWrapType::Regenerate, &mut rng);

    for i in 0..(ZOOM * HEIGHT) {
        for j in 0..(ZOOM * WIDTH) {
            let noise = perlin.noise(j as f64 / ZOOM_F,
                                     i as f64 / ZOOM_F).unwrap();

            if noise < -0.2 || noise > 0.2 {
                print!("#");
            } else {
                print!(".");
            }
        }
        print!("\n");
    }
}
<|endoftext|>


<commit_before>use std::path::PathBuf;

pub fn spawn(cmd: &str, updated_paths: Vec<PathBuf>, no_shell: bool) -> Process {
    self::imp::Process::new(cmd, updated_paths, no_shell).expect("unable to spawn process")
}

pub use self::imp::Process;

#[cfg(target_family = "unix")]
mod imp {
    use libc::*;
    use std::io::Result;
    use std::path::PathBuf;
    use std::process::Command;
    use std::sync::*;
    use signal::Signal;

    pub struct Process {
        pgid: pid_t,
        lock: Mutex<bool>,
        cvar: Condvar,
    }

    #[allow(unknown_lints)]
    #[allow(mutex_atomic)]
    impl Process {
        pub fn new(cmd: &str, updated_paths: Vec<PathBuf>, no_shell: bool) -> Result<Process> {
            use nix::unistd::*;
            use std::io;
            use std::os::unix::process::CommandExt;

            // Assemble command to run.
            // This is either the first argument from cmd (if no_shell was given) or "sh".
            // Using "sh -c" gives us features like supportin pipes and redirects,
            // but is a little less performant and can cause trouble when using custom signals
            // (e.g. --signal SIGHUP)
            let mut iter_args = cmd.split_whitespace();
            let arg0 = if no_shell {
                iter_args.next().unwrap()
            } else {
                "sh"
            };

            // TODO: There might be a better way of doing this with &str.
            //       I've had to fall back to String, as I wasn't able to join(" ") a Vec<&str>
            //       into a &str
            let args: Vec<String> = if no_shell {
                iter_args.map(str::to_string).collect()
            } else {
                vec!["-c".to_string(), iter_args.collect::<Vec<&str>>().join(" ")]
            };

            let mut command = Command::new(arg0);
            command.args(args);
            debug!("Assembled command {:?}", command);

            if let Some(single_path) = super::get_single_updated_path(&updated_paths) {
                command.env("WATCHEXEC_UPDATED_PATH", single_path);
            }

            if let Some(common_path) = super::get_longest_common_path(&updated_paths) {
                command.env("WATCHEXEC_COMMON_PATH", common_path);
            }

            command
                .before_exec(|| setpgid(0, 0).map_err(io::Error::from))
                .spawn()
                .and_then(|p| {
                              Ok(Process {
                                     pgid: p.id() as i32,
                                     lock: Mutex::new(false),
                                     cvar: Condvar::new(),
                                 })
                          })
        }

        pub fn reap(&self) {
            use nix::sys::wait::*;

            let mut finished = true;
            loop {
                match waitpid(-self.pgid, Some(WNOHANG)) {
                    Ok(WaitStatus::Exited(_, _)) |
                    Ok(WaitStatus::Signaled(_, _, _)) => finished = finished && true,
                    Ok(_) => {
                        finished = false;
                        break;
                    }
                    Err(_) => break,
                }
            }

            if finished {
                let mut done = self.lock.lock().unwrap();
                *done = true;
                self.cvar.notify_one();
            }
        }

        pub fn signal(&self, signal: Signal) {
            use signal::ConvertToLibc;

            let signo = signal.convert_to_libc();
            debug!("Sending {:?} (int: {}) to child process", signal, signo);
            self.c_signal(signo);
        }

        fn c_signal(&self, sig: c_int) {
            extern "C" {
                fn killpg(pgrp: pid_t, sig: c_int) -> c_int;
            }

            unsafe {
                killpg(self.pgid, sig);
            }

        }

        pub fn wait(&self) {
            let mut done = self.lock.lock().unwrap();
            while !*done {
                done = self.cvar.wait(done).unwrap();
            }
        }
    }
}

#[cfg(target_family = "windows")]
mod imp {
    use std::io;
    use std::io::Result;
    use std::mem;
    use std::path::PathBuf;
    use std::process::Command;
    use kernel32::*;
    use winapi::*;
    use signal::Signal;

    pub struct Process {
        job: HANDLE,
    }

    impl Process {
        pub fn new(cmd: &str, updated_paths: Vec<PathBuf>, no_shell: bool) -> Result<Process> {
            use std::os::windows::io::IntoRawHandle;

            fn last_err() -> io::Error {
                io::Error::last_os_error()
            }

            let job = unsafe { CreateJobObjectW(0 as *mut _, 0 as *const _) };
            if job.is_null() {
                panic!("failed to create job object: {}", last_err());
            }

            let mut info: JOBOBJECT_EXTENDED_LIMIT_INFORMATION = unsafe { mem::zeroed() };
            info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
            let r = unsafe {
                SetInformationJobObject(job,
                                        JobObjectExtendedLimitInformation,
                                        &mut info as *mut _ as LPVOID,
                                        mem::size_of_val(&info) as DWORD)
            };
            if r == 0 {
                panic!("failed to set job info: {}", last_err());
            }

            let mut iter_args = cmd.split_whitespace();
            let arg0 = match no_shell {
                true => iter_args.next().unwrap(),
                false => "cmd.exe",
            };

            // TODO: There might be a better way of doing this with &str.
            //       I've had to fall back to String, as I wasn't able to join(" ") a Vec<&str>
            //       into a &str
            let args: Vec<String> = match no_shell {
                true => iter_args.map(str::to_string).collect(),
                false => vec!["/C".to_string(), iter_args.collect::<Vec<&str>>().join(" ")],
            };

            let mut command = Command::new(arg0);
            command.args(args);
            debug!("Assembled command {:?}", command);

            if let Some(single_path) = super::get_single_updated_path(&updated_paths) {
                command.env("WATCHEXEC_UPDATED_PATH", single_path);
            }

            if let Some(common_path) = super::get_longest_common_path(&updated_paths) {
                command.env("WATCHEXEC_COMMON_PATH", common_path);
            }

            command
                .spawn()
                .and_then(|p| {
                              let r = unsafe { AssignProcessToJobObject(job, p.into_raw_handle()) };
                              if r == 0 {
                                  panic!("failed to add to job object: {}", last_err());
                              }

                              Ok(Process { job: job })
                          })
        }

        pub fn reap(&self) {}

        pub fn signal(&self, signal: Signal) {
            debug!("Ignoring signal {:?} (not supported by Windows)", signal);
            unsafe {
                let _ = TerminateJobObject(self.job, 1);
            }
        }

        pub fn wait(&self) {
            unsafe {
                let _ = WaitForSingleObject(self.job, INFINITE);
            }
        }
    }

    impl Drop for Process {
        fn drop(&mut self) {
            unsafe {
                let _ = CloseHandle(self.job);
            }
        }
    }

    unsafe impl Send for Process {}
    unsafe impl Sync for Process {}
}

fn get_single_updated_path(paths: &[PathBuf]) -> Option<&str> {
    paths.get(0).and_then(|p| p.to_str())
}

fn get_longest_common_path(paths: &[PathBuf]) -> Option<String> {
    match paths.len() {
        0 => return None,
        1 => return paths[0].to_str().map(|ref_val| ref_val.to_string()),
        _ => {}
    };

    let mut longest_path: Vec<_> = paths[0].components().collect();

    for path in &paths[1..] {
        let mut greatest_distance = 0;
        for component_pair in path.components().zip(longest_path.iter()) {
            if component_pair.0 != *component_pair.1 {
                break;
            }

            greatest_distance += 1;
        }

        if greatest_distance != longest_path.len() {
            longest_path.truncate(greatest_distance);
        }
    }

    let mut result = PathBuf::new();
    for component in longest_path {
        result.push(component.as_os_str());
    }

    result.to_str().map(|ref_val| ref_val.to_string())
}

#[cfg(test)]
#[cfg(target_family = "unix")]
mod tests {
    use std::path::PathBuf;

    use super::spawn;
    use super::get_longest_common_path;

    #[test]
    fn test_start() {
        let _ = spawn("echo hi", vec![], true);
    }

    #[test]
    fn longest_common_path_should_return_correct_value() {
        let single_path = vec![PathBuf::from("/tmp/random/")];
        let single_result = get_longest_common_path(&single_path).unwrap();
        assert_eq!(single_result, "/tmp/random/");

        let common_paths = vec![PathBuf::from("/tmp/logs/hi"),
                                PathBuf::from("/tmp/logs/bye"),
                                PathBuf::from("/tmp/logs/bye"),
                                PathBuf::from("/tmp/logs/fly")];

        let common_result = get_longest_common_path(&common_paths).unwrap();
        assert_eq!(common_result, "/tmp/logs");

        let diverging_paths = vec![PathBuf::from("/tmp/logs/hi"), PathBuf::from("/var/logs/hi")];

        let diverging_result = get_longest_common_path(&diverging_paths).unwrap();
        assert_eq!(diverging_result, "/");

        let uneven_paths = vec![PathBuf::from("/tmp/logs/hi"),
                                PathBuf::from("/tmp/logs/"),
                                PathBuf::from("/tmp/logs/bye")];

        let uneven_result = get_longest_common_path(&uneven_paths).unwrap();
        assert_eq!(uneven_result, "/tmp/logs");
    }
}
<commit_msg>Refactor command assembly<commit_after>use std::path::PathBuf;

pub fn spawn(cmd: &str, updated_paths: Vec<PathBuf>, no_shell: bool) -> Process {
    self::imp::Process::new(cmd, updated_paths, no_shell).expect("unable to spawn process")
}

pub use self::imp::Process;

#[cfg(target_family = "unix")]
mod imp {
    use libc::*;
    use std::io::Result;
    use std::path::PathBuf;
    use std::process::Command;
    use std::sync::*;
    use signal::Signal;

    pub struct Process {
        pgid: pid_t,
        lock: Mutex<bool>,
        cvar: Condvar,
    }

    #[allow(unknown_lints)]
    #[allow(mutex_atomic)]
    impl Process {
        pub fn new(cmd: &str, updated_paths: Vec<PathBuf>, no_shell: bool) -> Result<Process> {
            use nix::unistd::*;
            use std::io;
            use std::os::unix::process::CommandExt;

            // Assemble command to run.
            // This is either the first argument from cmd (if no_shell was given) or "sh".
            // Using "sh -c" gives us features like supportin pipes and redirects,
            // but is a little less performant and can cause trouble when using custom signals
            // (e.g. --signal SIGHUP)
            let mut command = if no_shell {
                let mut split = cmd.split_whitespace();
                let mut command = Command::new(split.next().unwrap());
                command.args(split);
                command
            } else {
                let mut command = Command::new("sh");
                command.arg("-c").arg(cmd);
                command
            };

            debug!("Assembled command {:?}", command);

            if let Some(single_path) = super::get_single_updated_path(&updated_paths) {
                command.env("WATCHEXEC_UPDATED_PATH", single_path);
            }

            if let Some(common_path) = super::get_longest_common_path(&updated_paths) {
                command.env("WATCHEXEC_COMMON_PATH", common_path);
            }

            command
                .before_exec(|| setpgid(0, 0).map_err(io::Error::from))
                .spawn()
                .and_then(|p| {
                              Ok(Process {
                                     pgid: p.id() as i32,
                                     lock: Mutex::new(false),
                                     cvar: Condvar::new(),
                                 })
                          })
        }

        pub fn reap(&self) {
            use nix::sys::wait::*;

            let mut finished = true;
            loop {
                match waitpid(-self.pgid, Some(WNOHANG)) {
                    Ok(WaitStatus::Exited(_, _)) |
                    Ok(WaitStatus::Signaled(_, _, _)) => finished = finished && true,
                    Ok(_) => {
                        finished = false;
                        break;
                    }
                    Err(_) => break,
                }
            }

            if finished {
                let mut done = self.lock.lock().unwrap();
                *done = true;
                self.cvar.notify_one();
            }
        }

        pub fn signal(&self, signal: Signal) {
            use signal::ConvertToLibc;

            let signo = signal.convert_to_libc();
            debug!("Sending {:?} (int: {}) to child process", signal, signo);
            self.c_signal(signo);
        }

        fn c_signal(&self, sig: c_int) {
            extern "C" {
                fn killpg(pgrp: pid_t, sig: c_int) -> c_int;
            }

            unsafe {
                killpg(self.pgid, sig);
            }

        }

        pub fn wait(&self) {
            let mut done = self.lock.lock().unwrap();
            while !*done {
                done = self.cvar.wait(done).unwrap();
            }
        }
    }
}

#[cfg(target_family = "windows")]
mod imp {
    use std::io;
    use std::io::Result;
    use std::mem;
    use std::path::PathBuf;
    use std::process::Command;
    use kernel32::*;
    use winapi::*;
    use signal::Signal;

    pub struct Process {
        job: HANDLE,
    }

    impl Process {
        pub fn new(cmd: &str, updated_paths: Vec<PathBuf>, no_shell: bool) -> Result<Process> {
            use std::os::windows::io::IntoRawHandle;

            fn last_err() -> io::Error {
                io::Error::last_os_error()
            }

            let job = unsafe { CreateJobObjectW(0 as *mut _, 0 as *const _) };
            if job.is_null() {
                panic!("failed to create job object: {}", last_err());
            }

            let mut info: JOBOBJECT_EXTENDED_LIMIT_INFORMATION = unsafe { mem::zeroed() };
            info.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
            let r = unsafe {
                SetInformationJobObject(job,
                                        JobObjectExtendedLimitInformation,
                                        &mut info as *mut _ as LPVOID,
                                        mem::size_of_val(&info) as DWORD)
            };
            if r == 0 {
                panic!("failed to set job info: {}", last_err());
            }

            let mut iter_args = cmd.split_whitespace();
            let arg0 = match no_shell {
                true => iter_args.next().unwrap(),
                false => "cmd.exe",
            };

            // TODO: There might be a better way of doing this with &str.
            //       I've had to fall back to String, as I wasn't able to join(" ") a Vec<&str>
            //       into a &str
            let args: Vec<String> = match no_shell {
                true => iter_args.map(str::to_string).collect(),
                false => vec!["/C".to_string(), iter_args.collect::<Vec<&str>>().join(" ")],
            };

            let mut command = Command::new(arg0);
            command.args(args);
            debug!("Assembled command {:?}", command);

            if let Some(single_path) = super::get_single_updated_path(&updated_paths) {
                command.env("WATCHEXEC_UPDATED_PATH", single_path);
            }

            if let Some(common_path) = super::get_longest_common_path(&updated_paths) {
                command.env("WATCHEXEC_COMMON_PATH", common_path);
            }

            command
                .spawn()
                .and_then(|p| {
                              let r = unsafe { AssignProcessToJobObject(job, p.into_raw_handle()) };
                              if r == 0 {
                                  panic!("failed to add to job object: {}", last_err());
                              }

                              Ok(Process { job: job })
                          })
        }

        pub fn reap(&self) {}

        pub fn signal(&self, signal: Signal) {
            debug!("Ignoring signal {:?} (not supported by Windows)", signal);
            unsafe {
                let _ = TerminateJobObject(self.job, 1);
            }
        }

        pub fn wait(&self) {
            unsafe {
                let _ = WaitForSingleObject(self.job, INFINITE);
            }
        }
    }

    impl Drop for Process {
        fn drop(&mut self) {
            unsafe {
                let _ = CloseHandle(self.job);
            }
        }
    }

    unsafe impl Send for Process {}
    unsafe impl Sync for Process {}
}

fn get_single_updated_path(paths: &[PathBuf]) -> Option<&str> {
    paths.get(0).and_then(|p| p.to_str())
}

fn get_longest_common_path(paths: &[PathBuf]) -> Option<String> {
    match paths.len() {
        0 => return None,
        1 => return paths[0].to_str().map(|ref_val| ref_val.to_string()),
        _ => {}
    };

    let mut longest_path: Vec<_> = paths[0].components().collect();

    for path in &paths[1..] {
        let mut greatest_distance = 0;
        for component_pair in path.components().zip(longest_path.iter()) {
            if component_pair.0 != *component_pair.1 {
                break;
            }

            greatest_distance += 1;
        }

        if greatest_distance != longest_path.len() {
            longest_path.truncate(greatest_distance);
        }
    }

    let mut result = PathBuf::new();
    for component in longest_path {
        result.push(component.as_os_str());
    }

    result.to_str().map(|ref_val| ref_val.to_string())
}

#[cfg(test)]
#[cfg(target_family = "unix")]
mod tests {
    use std::path::PathBuf;

    use super::spawn;
    use super::get_longest_common_path;

    #[test]
    fn test_start() {
        let _ = spawn("echo hi", vec![], true);
    }

    #[test]
    fn longest_common_path_should_return_correct_value() {
        let single_path = vec![PathBuf::from("/tmp/random/")];
        let single_result = get_longest_common_path(&single_path).unwrap();
        assert_eq!(single_result, "/tmp/random/");

        let common_paths = vec![PathBuf::from("/tmp/logs/hi"),
                                PathBuf::from("/tmp/logs/bye"),
                                PathBuf::from("/tmp/logs/bye"),
                                PathBuf::from("/tmp/logs/fly")];

        let common_result = get_longest_common_path(&common_paths).unwrap();
        assert_eq!(common_result, "/tmp/logs");

        let diverging_paths = vec![PathBuf::from("/tmp/logs/hi"), PathBuf::from("/var/logs/hi")];

        let diverging_result = get_longest_common_path(&diverging_paths).unwrap();
        assert_eq!(diverging_result, "/");

        let uneven_paths = vec![PathBuf::from("/tmp/logs/hi"),
                                PathBuf::from("/tmp/logs/"),
                                PathBuf::from("/tmp/logs/bye")];

        let uneven_result = get_longest_common_path(&uneven_paths).unwrap();
        assert_eq!(uneven_result, "/tmp/logs");
    }
}
<|endoftext|>


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

use toml::Value;

use dep::{DeclaredDep, DepKind};
use graph::DepGraph;
use error::{CliErrorKind, CliResult};
use config::Config;
use util;

#[derive(Debug)]
pub struct Project<'c, 'o>
    where 'o: 'c
{
    cfg: &'c Config<'o>,
}

impl<'c, 'o> Project<'c, 'o> {
    pub fn with_config(cfg: &'c Config<'o>) -> CliResult<Self> {
        Ok(Project { cfg: cfg })
    }

    pub fn graph(mut self) -> CliResult<DepGraph<'c, 'o>> {
        let (root_deps, root_name, root_version) = try!(self.parse_root_deps());
        let mut dg = try!(self.parse_lock_file());
        if !dg.set_root(&root_name, &root_version) {
            return Err(From::from(CliErrorKind::TomlNoName));
        }
        self.set_resolved_kind(&root_deps, &mut dg);
        if !self.cfg.include_vers {
            Project::show_version_on_duplicates(&mut dg);
        }
        Ok(dg)
    }

    /// Forces the version to be displayed on dependencies
    /// that have the same name (but a different version) as another dependency.
    fn show_version_on_duplicates(dg: &mut DepGraph<'c, 'o>) {
        // Build a list of node IDs, sorted by the name of the dependency on that node.
        let dep_ids_sorted_by_name = {
            let mut deps = dg.nodes.iter().enumerate().collect::<Vec<_>>();
            deps.sort_by_key(|dep| &*dep.1.name);
            deps.iter().map(|dep| dep.0).collect::<Vec<_>>()
        };

        for (i, &dep_id_i) in dep_ids_sorted_by_name.iter().enumerate().take(dep_ids_sorted_by_name.len() - 1) {
            // Find other nodes with the same name
            // We need to iterate one more time after the last node to handle the break.
            for (j, &dep) in dep_ids_sorted_by_name.iter().enumerate().take(dep_ids_sorted_by_name.len() + 1).skip(i + 1) {
                // Stop once we've found a node with a different name
                // or reached the end of the list.
                if j >= dep_ids_sorted_by_name.len() ||
                   dg.nodes[dep_id_i].name != dg.nodes[dep].name {
                    // If there are at least two nodes with the same name
                    if j >= i + 2 {
                        // Set force_write_ver = true on all nodes
                        // from dep_ids_sorted_by_name[i] to dep_ids_sorted_by_name[j - 1].
                        // Remember: j is pointing on the next node with a *different* name!
                        // Remember also: i..j includes i but excludes j.
						for &dep_id_k in dep_ids_sorted_by_name.iter().take(j).skip(i) {
                            dg.nodes[dep_id_k].force_write_ver = true;
                        }
                    }

                    break;
                }
            }
        }
    }

    /// Sets the kind of dependency on each dependency
    /// based on how the dependencies are declared in the manifest.
    fn set_resolved_kind(&mut self, declared_deps: &[DeclaredDep], dg: &mut DepGraph<'c, 'o>) {
        let declared_deps_map =
            declared_deps.iter().map(|dd| (&*dd.name, dd.kind)).collect::<HashMap<_, _>>();

        dg.nodes[0].is_build = true;

        dg.edges.sort(); // make sure to process edges from the root node first
        for ed in dg.edges.iter() {
            if ed.0 == 0 {
                // If this is an edge from the root node,
                // set the kind based on how the dependency is declared in the manifest file.
                if let Some(kind) = declared_deps_map.get(&*dg.nodes[ed.1].name) {
                    match *kind {
                        DepKind::Build => dg.nodes[ed.1].is_build = true,
                        DepKind::Dev => dg.nodes[ed.1].is_dev = true,
                        DepKind::Optional => dg.nodes[ed.1].is_optional = true,
                        _ => (),
                    }
                }
            } else {
                // If this is an edge from a dependency node, propagate the kind.
                // This is a set of flags because a dependency can appear several times in the graph,
                // and the kind of dependency may vary based on the path to that dependency.
                // The flags start at false, and once they become true, they stay true.
                // ResolvedDep::kind() will pick a kind based on their priority.
                if dg.nodes[ed.0].is_build {
                    dg.nodes[ed.1].is_build = true;
                }

                if dg.nodes[ed.0].is_dev {
                    dg.nodes[ed.1].is_dev = true;
                }

                if dg.nodes[ed.0].is_optional {
                    dg.nodes[ed.1].is_optional = true;
                }
            }
        }

        // Remove the nodes that the user doesn't want.
        // Start at 1 to keep the root node.
        for id in (1..dg.nodes.len()).rev() {
            let kind = dg.nodes[id].kind();
            if (kind == DepKind::Build && !self.cfg.build_deps) ||
               (kind == DepKind::Dev && !self.cfg.dev_deps) ||
               (kind == DepKind::Optional && !self.cfg.optional_deps) {
                dg.remove(id);
            }
        }

        dg.remove_orphans();
    }

    /// Builds a graph of the resolved dependencies declared in the lock file.
    fn parse_lock_file(&mut self) -> CliResult<DepGraph<'c, 'o>> {
        fn parse_package<'c, 'o>(dg: &mut DepGraph<'c, 'o>, pkg: &Value) {
            let name = pkg.lookup("name")
                          .expect("no 'name' field in Cargo.lock [package] or [root] table")
                          .as_str()
                          .expect("'name' field of [package] or [root] table in Cargo.lock was not a \
                                   valid string")
                          .to_owned();
            let ver = pkg.lookup("version")
                         .expect("no 'version' field in Cargo.lock [package] or [root] table")
                         .as_str()
                         .expect("'version' field of [package] or [root] table in Cargo.lock was not a \
                                  valid string")
                         .to_owned();

            let id = dg.find_or_add(&*name, &*ver);

            if let Some(&Value::Array(ref deps)) = pkg.lookup("dependencies") {
                for dep in deps {
                    let dep_vec = dep.as_str().unwrap_or("").split(' ').collect::<Vec<_>>();
                    let dep_string = dep_vec[0].to_owned();
                    let ver = dep_vec[1];
                    dg.add_child(id, &*dep_string, ver);
                }
            }
        }

        let lock_path = try!(util::find_manifest_file(self.cfg.lock_file));
        let lock_toml = try!(util::toml_from_file(lock_path));

        let mut dg = DepGraph::new(self.cfg);

        if let Some(root) = lock_toml.get("root") {
            parse_package(&mut dg, root);
        } else {
            return Err(From::from(CliErrorKind::TomlTableRoot));
        }

        if let Some(&Value::Array(ref packages)) = lock_toml.get("package") {
            for pkg in packages {
                parse_package(&mut dg, pkg);
            }
        }

        debugln!("return=parse_lock_file; self={:#?}", self);
        debugln!("return=parse_lock_file; dg={:#?}", dg);
        Ok(dg)
    }

    /// Builds a list of the dependencies declared in the manifest file.
    pub fn parse_root_deps(&mut self) -> CliResult<(Vec<DeclaredDep>, String, String)> {
        debugln!("executing; parse_root_deps;");
        let manifest_path = try!(util::find_manifest_file(self.cfg.manifest_file));
        let manifest_toml = try!(util::toml_from_file(manifest_path));

        let mut declared_deps = vec![];
        let mut v = vec![];

        let (root_name, root_version) = {
            let mut name = None;
            let mut version = None;
            if let Some(table) = manifest_toml.get("package") {
                if let Some(table) = table.as_table() {
                    if let Some(&Value::String(ref n)) = table.get("name") {
                        name = Some(n);
                    }
                    if let Some(&Value::String(ref v)) = table.get("version") {
                        version = Some(v);
                    }
                }
            }
            if let (Some(n), Some(v)) = (name, version) {
                (n.to_owned(), v.to_owned())
            } else {
                return Err(From::from(CliErrorKind::TomlNoName));
            }
        };

        if let Some(table) = manifest_toml.get("dependencies") {
            if let Some(table) = table.as_table() {
                for (name, dep_table) in table.into_iter() {
                    if let Some(&Value::Boolean(true)) = dep_table.lookup("optional") {
                        declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Optional));
                    } else {
                        declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Build));
                    }
                    v.push(name.clone());
                }
            }
        }

        if let Some(table) = manifest_toml.get("dev-dependencies") {
            if let Some(table) = table.as_table() {
                for (name, _) in table.into_iter() {
                    declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Dev));
                    v.push(name.clone());
                }
            }
        }

        debugln!("return=parse_root_deps; self={:#?}", self);
        debugln!("return=parse_root_deps; declared_deps={:#?}", declared_deps);
        debugln!("return=parse_root_deps; root_name={:#?}", root_name);
        Ok((declared_deps, root_name, root_version))
    }
}
<commit_msg>Recent cargo don't include [root], don't fail<commit_after>use std::collections::HashMap;

use toml::Value;

use dep::{DeclaredDep, DepKind};
use graph::DepGraph;
use error::{CliErrorKind, CliResult};
use config::Config;
use util;

#[derive(Debug)]
pub struct Project<'c, 'o>
    where 'o: 'c
{
    cfg: &'c Config<'o>,
}

impl<'c, 'o> Project<'c, 'o> {
    pub fn with_config(cfg: &'c Config<'o>) -> CliResult<Self> {
        Ok(Project { cfg: cfg })
    }

    pub fn graph(mut self) -> CliResult<DepGraph<'c, 'o>> {
        let (root_deps, root_name, root_version) = try!(self.parse_root_deps());
        let mut dg = try!(self.parse_lock_file());
        if !dg.set_root(&root_name, &root_version) {
            return Err(From::from(CliErrorKind::TomlNoName));
        }
        self.set_resolved_kind(&root_deps, &mut dg);
        if !self.cfg.include_vers {
            Project::show_version_on_duplicates(&mut dg);
        }
        Ok(dg)
    }

    /// Forces the version to be displayed on dependencies
    /// that have the same name (but a different version) as another dependency.
    fn show_version_on_duplicates(dg: &mut DepGraph<'c, 'o>) {
        // Build a list of node IDs, sorted by the name of the dependency on that node.
        let dep_ids_sorted_by_name = {
            let mut deps = dg.nodes.iter().enumerate().collect::<Vec<_>>();
            deps.sort_by_key(|dep| &*dep.1.name);
            deps.iter().map(|dep| dep.0).collect::<Vec<_>>()
        };

        for (i, &dep_id_i) in dep_ids_sorted_by_name.iter().enumerate().take(dep_ids_sorted_by_name.len() - 1) {
            // Find other nodes with the same name
            // We need to iterate one more time after the last node to handle the break.
            for (j, &dep) in dep_ids_sorted_by_name.iter().enumerate().take(dep_ids_sorted_by_name.len() + 1).skip(i + 1) {
                // Stop once we've found a node with a different name
                // or reached the end of the list.
                if j >= dep_ids_sorted_by_name.len() ||
                   dg.nodes[dep_id_i].name != dg.nodes[dep].name {
                    // If there are at least two nodes with the same name
                    if j >= i + 2 {
                        // Set force_write_ver = true on all nodes
                        // from dep_ids_sorted_by_name[i] to dep_ids_sorted_by_name[j - 1].
                        // Remember: j is pointing on the next node with a *different* name!
                        // Remember also: i..j includes i but excludes j.
						for &dep_id_k in dep_ids_sorted_by_name.iter().take(j).skip(i) {
                            dg.nodes[dep_id_k].force_write_ver = true;
                        }
                    }

                    break;
                }
            }
        }
    }

    /// Sets the kind of dependency on each dependency
    /// based on how the dependencies are declared in the manifest.
    fn set_resolved_kind(&mut self, declared_deps: &[DeclaredDep], dg: &mut DepGraph<'c, 'o>) {
        let declared_deps_map =
            declared_deps.iter().map(|dd| (&*dd.name, dd.kind)).collect::<HashMap<_, _>>();

        dg.nodes[0].is_build = true;

        dg.edges.sort(); // make sure to process edges from the root node first
        for ed in dg.edges.iter() {
            if ed.0 == 0 {
                // If this is an edge from the root node,
                // set the kind based on how the dependency is declared in the manifest file.
                if let Some(kind) = declared_deps_map.get(&*dg.nodes[ed.1].name) {
                    match *kind {
                        DepKind::Build => dg.nodes[ed.1].is_build = true,
                        DepKind::Dev => dg.nodes[ed.1].is_dev = true,
                        DepKind::Optional => dg.nodes[ed.1].is_optional = true,
                        _ => (),
                    }
                }
            } else {
                // If this is an edge from a dependency node, propagate the kind.
                // This is a set of flags because a dependency can appear several times in the graph,
                // and the kind of dependency may vary based on the path to that dependency.
                // The flags start at false, and once they become true, they stay true.
                // ResolvedDep::kind() will pick a kind based on their priority.
                if dg.nodes[ed.0].is_build {
                    dg.nodes[ed.1].is_build = true;
                }

                if dg.nodes[ed.0].is_dev {
                    dg.nodes[ed.1].is_dev = true;
                }

                if dg.nodes[ed.0].is_optional {
                    dg.nodes[ed.1].is_optional = true;
                }
            }
        }

        // Remove the nodes that the user doesn't want.
        // Start at 1 to keep the root node.
        for id in (1..dg.nodes.len()).rev() {
            let kind = dg.nodes[id].kind();
            if (kind == DepKind::Build && !self.cfg.build_deps) ||
               (kind == DepKind::Dev && !self.cfg.dev_deps) ||
               (kind == DepKind::Optional && !self.cfg.optional_deps) {
                dg.remove(id);
            }
        }

        dg.remove_orphans();
    }

    /// Builds a graph of the resolved dependencies declared in the lock file.
    fn parse_lock_file(&mut self) -> CliResult<DepGraph<'c, 'o>> {
        fn parse_package<'c, 'o>(dg: &mut DepGraph<'c, 'o>, pkg: &Value) {
            let name = pkg.lookup("name")
                          .expect("no 'name' field in Cargo.lock [package] or [root] table")
                          .as_str()
                          .expect("'name' field of [package] or [root] table in Cargo.lock was not a \
                                   valid string")
                          .to_owned();
            let ver = pkg.lookup("version")
                         .expect("no 'version' field in Cargo.lock [package] or [root] table")
                         .as_str()
                         .expect("'version' field of [package] or [root] table in Cargo.lock was not a \
                                  valid string")
                         .to_owned();

            let id = dg.find_or_add(&*name, &*ver);

            if let Some(&Value::Array(ref deps)) = pkg.lookup("dependencies") {
                for dep in deps {
                    let dep_vec = dep.as_str().unwrap_or("").split(' ').collect::<Vec<_>>();
                    let dep_string = dep_vec[0].to_owned();
                    let ver = dep_vec[1];
                    dg.add_child(id, &*dep_string, ver);
                }
            }
        }

        let lock_path = try!(util::find_manifest_file(self.cfg.lock_file));
        let lock_toml = try!(util::toml_from_file(lock_path));

        let mut dg = DepGraph::new(self.cfg);

        if let Some(root) = lock_toml.get("root") {
            parse_package(&mut dg, root);
        }

        if let Some(&Value::Array(ref packages)) = lock_toml.get("package") {
            for pkg in packages {
                parse_package(&mut dg, pkg);
            }
        }

        debugln!("return=parse_lock_file; self={:#?}", self);
        debugln!("return=parse_lock_file; dg={:#?}", dg);
        Ok(dg)
    }

    /// Builds a list of the dependencies declared in the manifest file.
    pub fn parse_root_deps(&mut self) -> CliResult<(Vec<DeclaredDep>, String, String)> {
        debugln!("executing; parse_root_deps;");
        let manifest_path = try!(util::find_manifest_file(self.cfg.manifest_file));
        let manifest_toml = try!(util::toml_from_file(manifest_path));

        let mut declared_deps = vec![];
        let mut v = vec![];

        let (root_name, root_version) = {
            let mut name = None;
            let mut version = None;
            if let Some(table) = manifest_toml.get("package") {
                if let Some(table) = table.as_table() {
                    if let Some(&Value::String(ref n)) = table.get("name") {
                        name = Some(n);
                    }
                    if let Some(&Value::String(ref v)) = table.get("version") {
                        version = Some(v);
                    }
                }
            }
            if let (Some(n), Some(v)) = (name, version) {
                (n.to_owned(), v.to_owned())
            } else {
                return Err(From::from(CliErrorKind::TomlNoName));
            }
        };

        if let Some(table) = manifest_toml.get("dependencies") {
            if let Some(table) = table.as_table() {
                for (name, dep_table) in table.into_iter() {
                    if let Some(&Value::Boolean(true)) = dep_table.lookup("optional") {
                        declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Optional));
                    } else {
                        declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Build));
                    }
                    v.push(name.clone());
                }
            }
        }

        if let Some(table) = manifest_toml.get("dev-dependencies") {
            if let Some(table) = table.as_table() {
                for (name, _) in table.into_iter() {
                    declared_deps.push(DeclaredDep::with_kind(name.clone(), DepKind::Dev));
                    v.push(name.clone());
                }
            }
        }

        debugln!("return=parse_root_deps; self={:#?}", self);
        debugln!("return=parse_root_deps; declared_deps={:#?}", declared_deps);
        debugln!("return=parse_root_deps; root_name={:#?}", root_name);
        Ok((declared_deps, root_name, root_version))
    }
}
<|endoftext|>


<commit_before>use serde::de::{Deserialize, Error as DeError, MapAccess, Visitor};
use std::fmt::{Display, Formatter, Result as FmtResult, Write as FmtWrite};
use internal::prelude::*;
use model::*;

#[cfg(feature = "cache")]
use CACHE;
#[cfg(feature = "model")]
use http;

/// An emoji reaction to a message.
#[derive(Clone, Debug, Deserialize)]
pub struct Reaction {
    /// The [`Channel`] of the associated [`Message`].
    ///
    /// [`Channel`]: enum.Channel.html
    /// [`Message`]: struct.Message.html
    pub channel_id: ChannelId,
    /// The reactive emoji used.
    pub emoji: ReactionType,
    /// The Id of the [`Message`] that was reacted to.
    ///
    /// [`Message`]: struct.Message.html
    pub message_id: MessageId,
    /// The Id of the [`User`] that sent the reaction.
    ///
    /// [`User`]: struct.User.html
    pub user_id: UserId,
}

#[cfg(feature = "model")]
impl Reaction {
    /// Deletes the reaction, but only if the current user is the user who made
    /// the reaction or has permission to.
    ///
    /// **Note**: Requires the [Manage Messages] permission, _if_ the current
    /// user did not perform the reaction.
    ///
    /// # Errors
    ///
    /// If the `cache` is enabled, then returns a
    /// [`ModelError::InvalidPermissions`] if the current user does not have
    /// the required [permissions].
    ///
    /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions
    /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html
    /// [permissions]: permissions
    pub fn delete(&self) -> Result<()> {
        let user_id =
            feature_cache! {{
            let user = if self.user_id == CACHE.read().unwrap().user.id {
                None
            } else {
                Some(self.user_id.0)
            };

            // If the reaction is one _not_ made by the current user, then ensure
            // that the current user has permission* to delete the reaction.
            //
            // Normally, users can only delete their own reactions.
            //
            // * The `Manage Messages` permission.
            if user.is_some() {
                let req = permissions::MANAGE_MESSAGES;

                if !utils::user_has_perms(self.channel_id, req).unwrap_or(true) {
                    return Err(Error::Model(ModelError::InvalidPermissions(req)));
                }
            }

            user
        } else {
            Some(self.user_id.0)
        }};

        http::delete_reaction(self.channel_id.0, self.message_id.0, user_id, &self.emoji)
    }

    /// Retrieves the list of [`User`]s who have reacted to a [`Message`] with a
    /// certain [`Emoji`].
    ///
    /// The default `limit` is `50` - specify otherwise to receive a different
    /// maximum number of users. The maximum that may be retrieve at a time is
    /// `100`, if a greater number is provided then it is automatically reduced.
    ///
    /// The optional `after` attribute is to retrieve the users after a certain
    /// user. This is useful for pagination.
    ///
    /// **Note**: Requires the [Read Message History] permission.
    ///
    /// # Errors
    ///
    /// Returns a [`ModelError::InvalidPermissions`] if the current user does
    /// not have the required [permissions].
    ///
    /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions
    /// [`Emoji`]: struct.Emoji.html
    /// [`Message`]: struct.Message.html
    /// [`User`]: struct.User.html
    /// [Read Message History]: permissions/constant.READ_MESSAGE_HISTORY.html
    /// [permissions]: permissions
    pub fn users<R, U>(&self,
                       reaction_type: R,
                       limit: Option<u8>,
                       after: Option<U>)
                       -> Result<Vec<User>>
        where R: Into<ReactionType>, U: Into<UserId> {
        http::get_reaction_users(
            self.channel_id.0,
            self.message_id.0,
            &reaction_type.into(),
            limit.unwrap_or(50),
            after.map(|u| u.into().0),
        )
    }
}

/// The type of a [`Reaction`] sent.
///
/// [`Reaction`]: struct.Reaction.html
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum ReactionType {
    /// A reaction with a [`Guild`]s custom [`Emoji`], which is unique to the
    /// guild.
    ///
    /// [`Emoji`]: struct.Emoji.html
    /// [`Guild`]: struct.Guild.html
    Custom {
        /// The Id of the custom [`Emoji`].
        ///
        /// [`Emoji`]: struct.Emoji.html
        id: EmojiId,
        /// The name of the custom emoji. This is primarily used for decoration
        /// and distinguishing the emoji client-side.
        name: Option<String>,
    },
    /// A reaction with a twemoji.
    Unicode(String),
}

impl<'de> Deserialize<'de> for ReactionType {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
        #[derive(Deserialize)]
        #[serde(field_identifier)]
        enum Field {
            Id,
            Name,
        }

        struct ReactionTypeVisitor;

        impl<'de> Visitor<'de> for ReactionTypeVisitor {
            type Value = ReactionType;

            fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
                formatter.write_str("enum ReactionType")
            }

            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> StdResult<Self::Value, V::Error> {
                let mut id = None;
                let mut name = None;

                while let Some(key) = map.next_key()? {
                    match key {
                        Field::Id => {
                            if id.is_some() {
                                return Err(DeError::duplicate_field("id"));
                            }

                            if let Ok(emoji_id) = map.next_value::<EmojiId>() {
                                id = Some(emoji_id)
                            }
                        },
                        Field::Name => {
                            if name.is_some() {
                                return Err(DeError::duplicate_field("name"));
                            }

                            name = Some(map.next_value()?);
                        },
                    }
                }

                let name = name.ok_or_else(|| DeError::missing_field("name"))?;

                Ok(if let Some(id) = id {
                    ReactionType::Custom {
                        id: id,
                        name: name,
                    }
                } else {
                    ReactionType::Unicode(name.unwrap())
                })
            }
        }

        const FIELDS: &'static [&'static str] = &["id", "name"];

        deserializer.deserialize_struct("ReactionType", FIELDS, ReactionTypeVisitor)
    }
}

#[cfg(any(feature = "model", feature = "http"))]
impl ReactionType {
    /// Creates a data-esque display of the type. This is not very useful for
    /// displaying, as the primary client can not render it, but can be useful
    /// for debugging.
    ///
    /// **Note**: This is mainly for use internally. There is otherwise most
    /// likely little use for it.
    pub fn as_data(&self) -> String {
        match *self {
            ReactionType::Custom {
                id,
                ref name,
            } => format!("{}:{}", name.as_ref().map_or("", |s| s.as_str()), id),
            ReactionType::Unicode(ref unicode) => unicode.clone(),
        }
    }
}

#[cfg(feature = "model")]
impl From<char> for ReactionType {
    /// Creates a `ReactionType` from a `char`.
    ///
    /// # Examples
    ///
    /// Reacting to a message with an apple:
    ///
    /// ```rust,no_run
    /// # use serenity::model::ChannelId;
    /// # use std::error::Error;
    /// #
    /// # fn try_main() -> Result<(), Box<Error>> {
    /// #     let message = ChannelId(0).message(0)?;
    /// #
    /// message.react('🍎')?;
    /// #     Ok(())
    /// # }
    /// #
    /// # fn main() {
    /// #     try_main().unwrap();
    /// # }
    /// ```
    fn from(ch: char) -> ReactionType { ReactionType::Unicode(ch.to_string()) }
}

impl From<Emoji> for ReactionType {
    fn from(emoji: Emoji) -> ReactionType {
        ReactionType::Custom {
            id: emoji.id,
            name: Some(emoji.name),
        }
    }
}

impl From<String> for ReactionType {
    fn from(unicode: String) -> ReactionType { ReactionType::Unicode(unicode) }
}

impl<'a> From<&'a str> for ReactionType {
    /// Creates a `ReactionType` from a string slice.
    ///
    /// # Examples
    ///
    /// Creating a `ReactionType` from a `🍎`, modeling a similar API as the
    /// rest of the library:
    ///
    /// ```rust
    /// use serenity::model::ReactionType;
    ///
    /// fn foo<R: Into<ReactionType>>(bar: R) {
    ///     println!("{:?}", bar.into());
    /// }
    ///
    /// foo("🍎");
    /// ```
    fn from(unicode: &str) -> ReactionType { ReactionType::Unicode(unicode.to_owned()) }
}

impl Display for ReactionType {
    /// Formats the reaction type, displaying the associated emoji in a
    /// way that clients can understand.
    ///
    /// If the type is a [custom][`ReactionType::Custom`] emoji, then refer to
    /// the documentation for [emoji's formatter][`Emoji::fmt`] on how this is
    /// displayed. Otherwise, if the type is a
    /// [unicode][`ReactionType::Unicode`], then the inner unicode is displayed.
    ///
    /// [`Emoji::fmt`]: struct.Emoji.html#method.fmt
    /// [`ReactionType::Custom`]: enum.ReactionType.html#variant.Custom
    /// [`ReactionType::Unicode`]: enum.ReactionType.html#variant.Unicode
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        match *self {
            ReactionType::Custom {
                id,
                ref name,
            } => {
                f.write_char('<')?;
                f.write_char(':')?;
                f.write_str(name.as_ref().map_or("", |s| s.as_str()))?;
                f.write_char(':')?;
                Display::fmt(&id, f)?;
                f.write_char('>')
            },
            ReactionType::Unicode(ref unicode) => f.write_str(unicode),
        }
    }
}
<commit_msg>Revert back to `deserialize_map`<commit_after>use serde::de::{Deserialize, Error as DeError, MapAccess, Visitor};
use std::fmt::{Display, Formatter, Result as FmtResult, Write as FmtWrite};
use internal::prelude::*;
use model::*;

#[cfg(feature = "cache")]
use CACHE;
#[cfg(feature = "model")]
use http;

/// An emoji reaction to a message.
#[derive(Clone, Debug, Deserialize)]
pub struct Reaction {
    /// The [`Channel`] of the associated [`Message`].
    ///
    /// [`Channel`]: enum.Channel.html
    /// [`Message`]: struct.Message.html
    pub channel_id: ChannelId,
    /// The reactive emoji used.
    pub emoji: ReactionType,
    /// The Id of the [`Message`] that was reacted to.
    ///
    /// [`Message`]: struct.Message.html
    pub message_id: MessageId,
    /// The Id of the [`User`] that sent the reaction.
    ///
    /// [`User`]: struct.User.html
    pub user_id: UserId,
}

#[cfg(feature = "model")]
impl Reaction {
    /// Deletes the reaction, but only if the current user is the user who made
    /// the reaction or has permission to.
    ///
    /// **Note**: Requires the [Manage Messages] permission, _if_ the current
    /// user did not perform the reaction.
    ///
    /// # Errors
    ///
    /// If the `cache` is enabled, then returns a
    /// [`ModelError::InvalidPermissions`] if the current user does not have
    /// the required [permissions].
    ///
    /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions
    /// [Manage Messages]: permissions/constant.MANAGE_MESSAGES.html
    /// [permissions]: permissions
    pub fn delete(&self) -> Result<()> {
        let user_id =
            feature_cache! {{
            let user = if self.user_id == CACHE.read().unwrap().user.id {
                None
            } else {
                Some(self.user_id.0)
            };

            // If the reaction is one _not_ made by the current user, then ensure
            // that the current user has permission* to delete the reaction.
            //
            // Normally, users can only delete their own reactions.
            //
            // * The `Manage Messages` permission.
            if user.is_some() {
                let req = permissions::MANAGE_MESSAGES;

                if !utils::user_has_perms(self.channel_id, req).unwrap_or(true) {
                    return Err(Error::Model(ModelError::InvalidPermissions(req)));
                }
            }

            user
        } else {
            Some(self.user_id.0)
        }};

        http::delete_reaction(self.channel_id.0, self.message_id.0, user_id, &self.emoji)
    }

    /// Retrieves the list of [`User`]s who have reacted to a [`Message`] with a
    /// certain [`Emoji`].
    ///
    /// The default `limit` is `50` - specify otherwise to receive a different
    /// maximum number of users. The maximum that may be retrieve at a time is
    /// `100`, if a greater number is provided then it is automatically reduced.
    ///
    /// The optional `after` attribute is to retrieve the users after a certain
    /// user. This is useful for pagination.
    ///
    /// **Note**: Requires the [Read Message History] permission.
    ///
    /// # Errors
    ///
    /// Returns a [`ModelError::InvalidPermissions`] if the current user does
    /// not have the required [permissions].
    ///
    /// [`ModelError::InvalidPermissions`]: enum.ModelError.html#variant.InvalidPermissions
    /// [`Emoji`]: struct.Emoji.html
    /// [`Message`]: struct.Message.html
    /// [`User`]: struct.User.html
    /// [Read Message History]: permissions/constant.READ_MESSAGE_HISTORY.html
    /// [permissions]: permissions
    pub fn users<R, U>(&self,
                       reaction_type: R,
                       limit: Option<u8>,
                       after: Option<U>)
                       -> Result<Vec<User>>
        where R: Into<ReactionType>, U: Into<UserId> {
        http::get_reaction_users(
            self.channel_id.0,
            self.message_id.0,
            &reaction_type.into(),
            limit.unwrap_or(50),
            after.map(|u| u.into().0),
        )
    }
}

/// The type of a [`Reaction`] sent.
///
/// [`Reaction`]: struct.Reaction.html
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub enum ReactionType {
    /// A reaction with a [`Guild`]s custom [`Emoji`], which is unique to the
    /// guild.
    ///
    /// [`Emoji`]: struct.Emoji.html
    /// [`Guild`]: struct.Guild.html
    Custom {
        /// The Id of the custom [`Emoji`].
        ///
        /// [`Emoji`]: struct.Emoji.html
        id: EmojiId,
        /// The name of the custom emoji. This is primarily used for decoration
        /// and distinguishing the emoji client-side.
        name: Option<String>,
    },
    /// A reaction with a twemoji.
    Unicode(String),
}

impl<'de> Deserialize<'de> for ReactionType {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
        #[derive(Deserialize)]
        #[serde(field_identifier)]
        enum Field {
            Id,
            Name,
        }

        struct ReactionTypeVisitor;

        impl<'de> Visitor<'de> for ReactionTypeVisitor {
            type Value = ReactionType;

            fn expecting(&self, formatter: &mut Formatter) -> FmtResult {
                formatter.write_str("enum ReactionType")
            }

            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> StdResult<Self::Value, V::Error> {
                let mut id = None;
                let mut name = None;

                while let Some(key) = map.next_key()? {
                    match key {
                        Field::Id => {
                            if id.is_some() {
                                return Err(DeError::duplicate_field("id"));
                            }

                            if let Ok(emoji_id) = map.next_value::<EmojiId>() {
                                id = Some(emoji_id)
                            }
                        },
                        Field::Name => {
                            if name.is_some() {
                                return Err(DeError::duplicate_field("name"));
                            }

                            name = Some(map.next_value()?);
                        },
                    }
                }

                let name = name.ok_or_else(|| DeError::missing_field("name"))?;

                Ok(if let Some(id) = id {
                    ReactionType::Custom {
                        id: id,
                        name: name,
                    }
                } else {
                    ReactionType::Unicode(name.unwrap())
                })
            }
        }

        deserializer.deserialize_map(ReactionTypeVisitor)
    }
}

#[cfg(any(feature = "model", feature = "http"))]
impl ReactionType {
    /// Creates a data-esque display of the type. This is not very useful for
    /// displaying, as the primary client can not render it, but can be useful
    /// for debugging.
    ///
    /// **Note**: This is mainly for use internally. There is otherwise most
    /// likely little use for it.
    pub fn as_data(&self) -> String {
        match *self {
            ReactionType::Custom {
                id,
                ref name,
            } => format!("{}:{}", name.as_ref().map_or("", |s| s.as_str()), id),
            ReactionType::Unicode(ref unicode) => unicode.clone(),
        }
    }
}

#[cfg(feature = "model")]
impl From<char> for ReactionType {
    /// Creates a `ReactionType` from a `char`.
    ///
    /// # Examples
    ///
    /// Reacting to a message with an apple:
    ///
    /// ```rust,no_run
    /// # use serenity::model::ChannelId;
    /// # use std::error::Error;
    /// #
    /// # fn try_main() -> Result<(), Box<Error>> {
    /// #     let message = ChannelId(0).message(0)?;
    /// #
    /// message.react('🍎')?;
    /// #     Ok(())
    /// # }
    /// #
    /// # fn main() {
    /// #     try_main().unwrap();
    /// # }
    /// ```
    fn from(ch: char) -> ReactionType { ReactionType::Unicode(ch.to_string()) }
}

impl From<Emoji> for ReactionType {
    fn from(emoji: Emoji) -> ReactionType {
        ReactionType::Custom {
            id: emoji.id,
            name: Some(emoji.name),
        }
    }
}

impl From<String> for ReactionType {
    fn from(unicode: String) -> ReactionType { ReactionType::Unicode(unicode) }
}

impl<'a> From<&'a str> for ReactionType {
    /// Creates a `ReactionType` from a string slice.
    ///
    /// # Examples
    ///
    /// Creating a `ReactionType` from a `🍎`, modeling a similar API as the
    /// rest of the library:
    ///
    /// ```rust
    /// use serenity::model::ReactionType;
    ///
    /// fn foo<R: Into<ReactionType>>(bar: R) {
    ///     println!("{:?}", bar.into());
    /// }
    ///
    /// foo("🍎");
    /// ```
    fn from(unicode: &str) -> ReactionType { ReactionType::Unicode(unicode.to_owned()) }
}

impl Display for ReactionType {
    /// Formats the reaction type, displaying the associated emoji in a
    /// way that clients can understand.
    ///
    /// If the type is a [custom][`ReactionType::Custom`] emoji, then refer to
    /// the documentation for [emoji's formatter][`Emoji::fmt`] on how this is
    /// displayed. Otherwise, if the type is a
    /// [unicode][`ReactionType::Unicode`], then the inner unicode is displayed.
    ///
    /// [`Emoji::fmt`]: struct.Emoji.html#method.fmt
    /// [`ReactionType::Custom`]: enum.ReactionType.html#variant.Custom
    /// [`ReactionType::Unicode`]: enum.ReactionType.html#variant.Unicode
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        match *self {
            ReactionType::Custom {
                id,
                ref name,
            } => {
                f.write_char('<')?;
                f.write_char(':')?;
                f.write_str(name.as_ref().map_or("", |s| s.as_str()))?;
                f.write_char(':')?;
                Display::fmt(&id, f)?;
                f.write_char('>')
            },
            ReactionType::Unicode(ref unicode) => f.write_str(unicode),
        }
    }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use eutil::fptr_is_null;
use libc::{c_int};
use std::collections::TreeMap;
use std::mem;
use std::slice;
use std::str;
use std::string::String;
use string::{cef_string_userfree_utf8_alloc,cef_string_userfree_utf8_free,cef_string_utf8_set};
use types::{cef_string_map_t,cef_string_t};

fn string_map_to_treemap(sm: *mut cef_string_map_t) -> *mut TreeMap<String, *mut cef_string_t> {
    sm as *mut TreeMap<String, *mut cef_string_t>
}

//cef_string_map

#[no_mangle]
pub extern "C" fn cef_string_map_alloc() -> *mut cef_string_map_t {
    unsafe {
         let sm: Box<TreeMap<String, *mut cef_string_t>> = box TreeMap::new();
         mem::transmute(sm)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_map_size(sm: *mut cef_string_map_t) -> c_int {
    unsafe {
        if fptr_is_null(mem::transmute(sm)) { return 0; }
        let v = string_map_to_treemap(sm);
        (*v).len() as c_int
    }
}
<commit_msg>embedding: cef_string_map_append()<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use eutil::fptr_is_null;
use libc::{c_int};
use std::collections::TreeMap;
use std::mem;
use std::slice;
use std::str;
use std::string::String;
use string::{cef_string_userfree_utf8_alloc,cef_string_userfree_utf8_free,cef_string_utf8_set};
use types::{cef_string_map_t,cef_string_t};

fn string_map_to_treemap(sm: *mut cef_string_map_t) -> *mut TreeMap<String, *mut cef_string_t> {
    sm as *mut TreeMap<String, *mut cef_string_t>
}

//cef_string_map

#[no_mangle]
pub extern "C" fn cef_string_map_alloc() -> *mut cef_string_map_t {
    unsafe {
         let sm: Box<TreeMap<String, *mut cef_string_t>> = box TreeMap::new();
         mem::transmute(sm)
    }
}

#[no_mangle]
pub extern "C" fn cef_string_map_size(sm: *mut cef_string_map_t) -> c_int {
    unsafe {
        if fptr_is_null(mem::transmute(sm)) { return 0; }
        let v = string_map_to_treemap(sm);
        (*v).len() as c_int
    }
}

#[no_mangle]
pub extern "C" fn cef_string_map_append(sm: *mut cef_string_map_t, key: *const cef_string_t, value: *const cef_string_t) -> c_int {
    unsafe {
        if fptr_is_null(mem::transmute(sm)) { return 0; }
        let v = string_map_to_treemap(sm);
        slice::raw::buf_as_slice(mem::transmute((*key).str), (*key).length as uint, |result| {
            match str::from_utf8(result) {
                Some(k) => {
                    let s = String::from_str(k);
                    let csv = cef_string_userfree_utf8_alloc();
                    cef_string_utf8_set(mem::transmute((*value).str), (*value).length, csv, 1);
                    (*v).insert(s, csv);
                    1
                },
                None => 0
            }
        })
    }
}
<|endoftext|>


<commit_before>extern crate num;

use num::bigint::BigUint;
use num::bigint::ToBigUint;
use num::mod_floor;

use std::os;

fn to_biguint (i : u64) -> BigUint {
    i.to_biguint().unwrap()
}

/* Since we use Miller-Rabin, this function technically finds if a number is
 * *probably* correct.
 */
fn is_prime(n : BigUint) -> bool {
    let zero = to_biguint(0);
    let one = to_biguint(1);
    let two = to_biguint(2);
    let three = to_biguint(3);
    if n.eq(&two) || n.eq(&three) {
        true
    } else if n.eq(&one) || mod_floor(n, two).eq(&zero) {
        false
    } else {
        true
    }
}

fn main () {
    let args : ~[~str] = os::args();
    if args.len() < 2 {
        println!("You need to provide a natural number as an input argument.")
    } else {
        match from_str::<BigUint>(args[1]) {
            Some(n) => {
                let p : bool = is_prime(n.clone());
                println!("Is {} is prime? {}", n, if p {"Yes"} else {"No"});
            },
            None => println!(
                "You need to provide a natural number as an input argument.")
        };
    }

}<commit_msg>Add Miller-Rabin (doesn't compile)<commit_after>extern crate num;
extern crate rand;

use num::bigint::{BigUint, ToBigUint,RandBigInt};
use num::{mod_floor, div_mod_floor};
use std::num::pow;
use rand::{task_rng, Rng};

use std::os;

fn to_biguint (i : u64) -> BigUint {
    i.to_biguint().unwrap()
}

/* Since we use Miller-Rabin, this function technically finds if a number is
 * *probably* correct.
 */
fn is_prime(n : BigUint) -> bool {
    let zero = to_biguint(0);
    let one = to_biguint(1);
    let two = to_biguint(2);
    let three = to_biguint(3);
    let mut s = zero;
    let mut d = n-one;
    let num_trials = 20;
    if n.eq(&two) || n.eq(&three) {
        return true
    } else if n.eq(&one) || mod_floor(n, two).eq(&zero) {
        return false
    } else {
        while true {
            let (quotient, remainder) = div_mod_floor(d, two);
            if remainder == one { break }
            s = s + one;
            d = quotient;
        }
    }

    fn try_composite(a : BigUint, d : BigUint, n : BigUint, s : BigUint) -> bool {
        let one = to_biguint(1);
        if (mod_floor(pow(a, d), n) == one) { return false }
        for i in range(0, s) {
            if (mod_floor(pow(a, (pow(2,i) * d)), n) == n-one) { return false }
        }
        return true;
    }

    for i in range(0, num_trials) {
        let mut rng = task_rng();
        let a : BigUint = rng.gen_biguint_range(&two, &n);
        if try_composite(a, d, n, s) { return false }
    }
    return true;
}

fn main () {
    let args : ~[~str] = os::args();
    if args.len() < 2 {
        println!("You need to provide a natural number as an input argument.")
    } else {
        match from_str::<BigUint>(args[1]) {
            Some(n) => {
                let p : bool = is_prime(n.clone());
                println!("Is {} is prime? {}", n, if p {"Yes"} else {"No"});
            },
            None => println!(
                "You need to provide a natural number as an input argument.")
        };
    }

}<|endoftext|>