// Copyright (c) 2021 Soni L. // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. // Documentation and comments licensed under CC BY-SA 4.0. //! Command syntax tree. use ::std::borrow::Cow; use ::std::collections::HashMap; use ::std::collections::HashSet; use ::std::hash::Hash; use ::std::sync::Arc; use crate::Command; use crate::args::{ArgumentType, ArgumentTypeAny}; use crate::strcursor::StringReader; // FIXME move use crate::args::CommandContext; /// The kind of node. enum NodeKind<'a, Source, Error> { /// Root node. Root, /// Literal node. Literal { /// The literal of the node. literal: Cow<'a, str>, }, /// Argument node. Argument { /// The label of the node. label: Cow<'a, str>, /// The argument type. arg: Arc>, }, } impl<'a, Source, Error> Clone for NodeKind<'a, Source, Error> { fn clone(&self) -> Self { match self { &Self::Root => Self::Root, &Self::Literal { ref literal, } => Self::Literal { literal: Cow::clone(literal), }, &Self::Argument { ref label, ref arg, } => Self::Argument { label: Cow::clone(label), arg: Arc::clone(arg), }, } } } /// A node of the command parse graph. pub struct CommandNode<'a, Type, Source, Error> { /// The command to run for this node. command: Option>, /// Nodes. nodes: HashMap, Cow<'a, CommandNode<'a, Type, Source, Error>>>, /// Literal nodes. literals: HashSet>, /// Argument nodes. arguments: HashSet>, /// The kind of node. kind: NodeKind<'a, Source, Error>, } impl<'a, Type, Source, Error> Clone for CommandNode<'a, Type, Source, Error> { fn clone(&self) -> Self { Self { command: self.command.clone(), nodes: self.nodes.clone(), literals: self.literals.clone(), arguments: self.arguments.clone(), kind: self.kind.clone(), } } } //impl CommandNode { // /// Creates a new root node. // pub fn root() -> Self { // CommandNode { // command: None, // nodes: (), // literals: (), // arguments: (), // kind: NodeKind::Root, // } // } // // /// Creates a new literal node. // pub fn literal( // word: Cow<'static, str>, // command: Option>, // ) -> Self { // CommandNode { // command: command, // nodes: (), // literals: (), // arguments: (), // kind: NodeKind::Literal { // literal: word, // }, // } // } // // /// Creates a new argument node. // pub fn argument + 'static + Send + Sync + Eq + Hash>( // name: Cow<'static, str>, // command: Option>, // argument: A, // ) -> Self { // CommandNode { // command: command, // nodes: (), // literals: (), // arguments: (), // kind: NodeKind::Argument { // label: name, // arg: Box::new(argument), // }, // } // } // // /// Returns the name of this node. // /// // /// For literal nodes, this is the literal itself. For argument nodes, this // /// is the name of the argument. // pub fn get_name(&self) -> &str { // match self.kind { // NodeKind::Root => "", // NodeKind::Literal { ref literal, .. } => literal, // NodeKind::Argument { ref label, .. } => label, // } // } //}