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

use std::rc::Rc;
use super::constants::*;
use super::nodes::*;

/// Store a command tree while populating it. This is used
/// to construct a [`RootNode`] to be used with the [`Parser`].
///
/// The lifetime parameter `'a` refers to the lifetime
/// of the strings used for [command] and [parameter] names and
/// help text.
///
/// [command]: struct.Command.html
/// [parameter]: struct.Parameter.html
/// [`Parser`]: struct.Parser.html
/// [`RootNode`]: struct.RootNode.html
pub struct CommandTree<'a> {
    commands: Vec<Command<'a>>,
}

impl<'a> Default for CommandTree<'a> {
    fn default() -> Self {
        CommandTree { commands: vec![] }
    }
}

impl<'a> CommandTree<'a> {
    /// Create a new `CommandTree`.
    pub fn new() -> Self {
        Default::default()
    }

    /// Add a `Command` to the `CommandTree`.
    pub fn command(&mut self, command: Command<'a>) {
        self.commands.push(command);
    }

    /// Construct the `CommandTree` and produce a `RootNode`.
    pub fn finalize(&self) -> Rc<Node> {
        let mut successors: Vec<Rc<Node>> = vec![];
        for c in &self.commands {
            successors.push(Rc::new(Node::Command(self.build_command(c))));
        }
        Rc::new(Node::Root(RootNode::new(successors)))
    }

    fn build_command(&self, command: &Command) -> CommandNode {
        let mut parameters: Vec<Rc<Node>> = vec![];
        let mut successors: Vec<Rc<Node>> = vec![];
        for parameter in &command.parameters {
            match parameter.kind {
                ParameterKind::Flag => {
                    self.build_flag_parameter(parameter, &mut parameters, &mut successors);
                }
                ParameterKind::Named => {
                    self.build_named_parameter(parameter, &mut parameters, &mut successors);
                }
                ParameterKind::Simple => {
                    self.build_simple_parameter(parameter, &mut parameters, &mut successors);
                }
            };
        }
        // We'll want to find the right node for the wrapped_root
        // and pass it along here.
        CommandNode::new(command.name,
                         command.help_text,
                         command.hidden,
                         command.priority,
                         successors,
                         None,
                         parameters)
    }

    fn build_flag_parameter(&self,
                            parameter: &Parameter,
                            parameters: &mut Vec<Rc<Node>>,
                            successors: &mut Vec<Rc<Node>>) {
        let p = ParameterNode::new(parameter.name,
                                   parameter.help_text,
                                   parameter.hidden,
                                   parameter.priority.unwrap_or(PRIORITY_DEFAULT),
                                   vec![],
                                   parameter.repeatable,
                                   None,
                                   parameter.kind,
                                   parameter.required);
        let p = Rc::new(Node::Parameter(p));
        parameters.push(p.clone());
        successors.push(p);
    }

    fn build_named_parameter(&self,
                             parameter: &Parameter,
                             parameters: &mut Vec<Rc<Node>>,
                             successors: &mut Vec<Rc<Node>>) {
        let p = ParameterNode::new(parameter.name,
                                   parameter.help_text,
                                   parameter.hidden,
                                   parameter.priority
                                            .unwrap_or(PRIORITY_PARAMETER),
                                   vec![],
                                   parameter.repeatable,
                                   None,
                                   parameter.kind,
                                   parameter.required);
        let p = Rc::new(Node::Parameter(p));
        parameters.push(p.clone());
        let n = ParameterNameNode::new(parameter.name,
                                       parameter.hidden,
                                       PRIORITY_DEFAULT,
                                       vec![p.clone()],
                                       parameter.repeatable,
                                       Some(p.clone()),
                                       p.clone());
        successors.push(Rc::new(Node::ParameterName(n)));
        for alias in &parameter.aliases {
            let a = ParameterNameNode::new(alias,
                                           parameter.hidden,
                                           PRIORITY_DEFAULT,
                                           vec![p.clone()],
                                           parameter.repeatable,
                                           Some(p.clone()),
                                           p.clone());
            successors.push(Rc::new(Node::ParameterName(a)));
        }
    }

    fn build_simple_parameter(&self,
                              parameter: &Parameter,
                              parameters: &mut Vec<Rc<Node>>,
                              successors: &mut Vec<Rc<Node>>) {
        let p = ParameterNode::new(parameter.name,
                                   parameter.help_text,
                                   parameter.hidden,
                                   parameter.priority.unwrap_or(PRIORITY_PARAMETER),
                                   vec![],
                                   parameter.repeatable,
                                   None,
                                   parameter.kind,
                                   parameter.required);
        let p = Rc::new(Node::Parameter(p));
        parameters.push(p.clone());
        successors.push(p.clone());
    }
}

/// Description of a command to be added to the [`CommandTree`].
///
/// The lifetime parameter `'a` refers to the lifetime
/// of the strings used for command names and help text.
///
/// [`CommandTree`]: struct.CommandTree.html
pub struct Command<'a> {
    hidden: bool,
    priority: i32,
    name: &'a str,
    help_text: Option<&'a str>,
    parameters: Vec<Parameter<'a>>,
    wrapped_root: Option<String>,
}

impl<'a> Command<'a> {
    /// Construct a default (blank) command with the given `name`.
    pub fn new(name: &'a str) -> Self {
        Command {
            hidden: false,
            priority: PRIORITY_DEFAULT,
            name: name,
            help_text: None,
            parameters: vec![],
            wrapped_root: None,
        }
    }

    /// Mark the command as hidden. Hidden commands will match
    /// within the parser, but are not listed during completion.
    pub fn hidden(mut self, hidden: bool) -> Self {
        self.hidden = hidden;
        self
    }

    /// Give the command a priority. This is used when sorting
    /// out conflicts during matching and completion.
    pub fn priority(mut self, priority: i32) -> Self {
        self.priority = priority;
        self
    }

    /// Supply help text for the command.
    pub fn help(mut self, help_text: &'a str) -> Self {
        self.help_text = Some(help_text);
        self
    }

    /// Add a [`Parameter`] to the command.
    ///
    /// [`Parameter`]: struct.Parameter.html
    pub fn parameter(mut self, parameter: Parameter<'a>) -> Self {
        self.parameters.push(parameter);
        self
    }

    /// Create a [`WrapperNode`] instead of a [`CommandNode`]. The
    /// `wrapped_root` signifies the path to the command that should
    /// be wrapped by this command.
    ///
    /// [`CommandNode`]: struct.CommandNode.html
    /// [`WrapperNode`]: struct.WrapperNode.html
    pub fn wraps(mut self, wrapped_root: String) -> Self {
        self.wrapped_root = Some(wrapped_root);
        self
    }
}

/// Description of a parameter to be added to the [`Command`].
///
/// The lifetime parameter `'a` refers to the lifetime
/// of the strings used for parameter names, aliases and
/// help text.
///
/// [`Command`]: struct.Command.html
pub struct Parameter<'a> {
    hidden: bool,
    priority: Option<i32>,
    name: &'a str,
    repeatable: bool,
    aliases: Vec<&'a str>,
    help_text: Option<&'a str>,
    kind: ParameterKind,
    required: bool,
}

impl<'a> Parameter<'a> {<commit_msg>Remove reference to the defunct WrapperNode.<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.

use std::rc::Rc;
use super::constants::*;
use super::nodes::*;

/// Store a command tree while populating it. This is used
/// to construct a [`RootNode`] to be used with the [`Parser`].
///
/// The lifetime parameter `'a` refers to the lifetime
/// of the strings used for [command] and [parameter] names and
/// help text.
///
/// [command]: struct.Command.html
/// [parameter]: struct.Parameter.html
/// [`Parser`]: struct.Parser.html
/// [`RootNode`]: struct.RootNode.html
pub struct CommandTree<'a> {
    commands: Vec<Command<'a>>,
}

impl<'a> Default for CommandTree<'a> {
    fn default() -> Self {
        CommandTree { commands: vec![] }
    }
}

impl<'a> CommandTree<'a> {
    /// Create a new `CommandTree`.
    pub fn new() -> Self {
        Default::default()
    }

    /// Add a `Command` to the `CommandTree`.
    pub fn command(&mut self, command: Command<'a>) {
        self.commands.push(command);
    }

    /// Construct the `CommandTree` and produce a `RootNode`.
    pub fn finalize(&self) -> Rc<Node> {
        let mut successors: Vec<Rc<Node>> = vec![];
        for c in &self.commands {
            successors.push(Rc::new(Node::Command(self.build_command(c))));
        }
        Rc::new(Node::Root(RootNode::new(successors)))
    }

    fn build_command(&self, command: &Command) -> CommandNode {
        let mut parameters: Vec<Rc<Node>> = vec![];
        let mut successors: Vec<Rc<Node>> = vec![];
        for parameter in &command.parameters {
            match parameter.kind {
                ParameterKind::Flag => {
                    self.build_flag_parameter(parameter, &mut parameters, &mut successors);
                }
                ParameterKind::Named => {
                    self.build_named_parameter(parameter, &mut parameters, &mut successors);
                }
                ParameterKind::Simple => {
                    self.build_simple_parameter(parameter, &mut parameters, &mut successors);
                }
            };
        }
        // We'll want to find the right node for the wrapped_root
        // and pass it along here.
        CommandNode::new(command.name,
                         command.help_text,
                         command.hidden,
                         command.priority,
                         successors,
                         None,
                         parameters)
    }

    fn build_flag_parameter(&self,
                            parameter: &Parameter,
                            parameters: &mut Vec<Rc<Node>>,
                            successors: &mut Vec<Rc<Node>>) {
        let p = ParameterNode::new(parameter.name,
                                   parameter.help_text,
                                   parameter.hidden,
                                   parameter.priority.unwrap_or(PRIORITY_DEFAULT),
                                   vec![],
                                   parameter.repeatable,
                                   None,
                                   parameter.kind,
                                   parameter.required);
        let p = Rc::new(Node::Parameter(p));
        parameters.push(p.clone());
        successors.push(p);
    }

    fn build_named_parameter(&self,
                             parameter: &Parameter,
                             parameters: &mut Vec<Rc<Node>>,
                             successors: &mut Vec<Rc<Node>>) {
        let p = ParameterNode::new(parameter.name,
                                   parameter.help_text,
                                   parameter.hidden,
                                   parameter.priority
                                            .unwrap_or(PRIORITY_PARAMETER),
                                   vec![],
                                   parameter.repeatable,
                                   None,
                                   parameter.kind,
                                   parameter.required);
        let p = Rc::new(Node::Parameter(p));
        parameters.push(p.clone());
        let n = ParameterNameNode::new(parameter.name,
                                       parameter.hidden,
                                       PRIORITY_DEFAULT,
                                       vec![p.clone()],
                                       parameter.repeatable,
                                       Some(p.clone()),
                                       p.clone());
        successors.push(Rc::new(Node::ParameterName(n)));
        for alias in &parameter.aliases {
            let a = ParameterNameNode::new(alias,
                                           parameter.hidden,
                                           PRIORITY_DEFAULT,
                                           vec![p.clone()],
                                           parameter.repeatable,
                                           Some(p.clone()),
                                           p.clone());
            successors.push(Rc::new(Node::ParameterName(a)));
        }
    }

    fn build_simple_parameter(&self,
                              parameter: &Parameter,
                              parameters: &mut Vec<Rc<Node>>,
                              successors: &mut Vec<Rc<Node>>) {
        let p = ParameterNode::new(parameter.name,
                                   parameter.help_text,
                                   parameter.hidden,
                                   parameter.priority.unwrap_or(PRIORITY_PARAMETER),
                                   vec![],
                                   parameter.repeatable,
                                   None,
                                   parameter.kind,
                                   parameter.required);
        let p = Rc::new(Node::Parameter(p));
        parameters.push(p.clone());
        successors.push(p.clone());
    }
}

/// Description of a command to be added to the [`CommandTree`].
///
/// The lifetime parameter `'a` refers to the lifetime
/// of the strings used for command names and help text.
///
/// [`CommandTree`]: struct.CommandTree.html
pub struct Command<'a> {
    hidden: bool,
    priority: i32,
    name: &'a str,
    help_text: Option<&'a str>,
    parameters: Vec<Parameter<'a>>,
    wrapped_root: Option<String>,
}

impl<'a> Command<'a> {
    /// Construct a default (blank) command with the given `name`.
    pub fn new(name: &'a str) -> Self {
        Command {
            hidden: false,
            priority: PRIORITY_DEFAULT,
            name: name,
            help_text: None,
            parameters: vec![],
            wrapped_root: None,
        }
    }

    /// Mark the command as hidden. Hidden commands will match
    /// within the parser, but are not listed during completion.
    pub fn hidden(mut self, hidden: bool) -> Self {
        self.hidden = hidden;
        self
    }

    /// Give the command a priority. This is used when sorting
    /// out conflicts during matching and completion.
    pub fn priority(mut self, priority: i32) -> Self {
        self.priority = priority;
        self
    }

    /// Supply help text for the command.
    pub fn help(mut self, help_text: &'a str) -> Self {
        self.help_text = Some(help_text);
        self
    }

    /// Add a [`Parameter`] to the command.
    ///
    /// [`Parameter`]: struct.Parameter.html
    pub fn parameter(mut self, parameter: Parameter<'a>) -> Self {
        self.parameters.push(parameter);
        self
    }

    /// The `wrapped_root` signifies the path to the command that should
    /// be wrapped by this command. This is used for the `help` command.
    ///
    /// [`CommandNode`]: struct.CommandNode.html
    pub fn wraps(mut self, wrapped_root: String) -> Self {
        self.wrapped_root = Some(wrapped_root);
        self
    }
}

/// Description of a parameter to be added to the [`Command`].
///
/// The lifetime parameter `'a` refers to the lifetime
/// of the strings used for parameter names, aliases and
/// help text.
///
/// [`Command`]: struct.Command.html
pub struct Parameter<'a> {
    hidden: bool,
    priority: Option<i32>,
    name: &'a str,
    repeatable: bool,
    aliases: Vec<&'a str>,
    help_text: Option<&'a str>,
    kind: ParameterKind,
    required: bool,
}

impl<'a> Parameter<'a> {
{'fraction_non_alphanumeric': 0.11471235096654706, 'fraction_numerical': 0.0011575413821044102, 'mean_word_length': 1.37642690138908, 'pattern_counts': {'":': 0, '<': 89, '<?xml version=': 0, '>': 115, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 88, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '621529', 'n_tokens_mistral': 4359, 'n_tokens_neox': 4274, 'n_words': 1141}