diff options
Diffstat (limited to 'src/tree.rs')
-rw-r--r-- | src/tree.rs | 169 |
1 files changed, 103 insertions, 66 deletions
diff --git a/src/tree.rs b/src/tree.rs index 71243be..ae408a8 100644 --- a/src/tree.rs +++ b/src/tree.rs @@ -6,100 +6,137 @@ //! 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 +// FIXME move use crate::args::CommandContext; /// The kind of node. -enum NodeKind<S, E> { +enum NodeKind<'a, Source, Error> { /// Root node. Root, /// Literal node. Literal { /// The literal of the node. - literal: Cow<'static, str>, + literal: Cow<'a, str>, }, /// Argument node. Argument { /// The label of the node. - label: Cow<'static, str>, + label: Cow<'a, str>, /// The argument type. - arg: Box<dyn ArgumentTypeAny<S, E>>, + arg: Arc<dyn ArgumentTypeAny<Source, Error>>, }, } -/// A node in the syntax tree. -pub struct CommandNode<T, S, E> { +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<Command<T, S, E>>, + command: Option<Command<Type, Source, Error>>, /// Nodes. - nodes: (), + nodes: HashMap<Cow<'a, str>, Cow<'a, CommandNode<'a, Type, Source, Error>>>, /// Literal nodes. - literals: (), + literals: HashSet<Cow<'a, str>>, /// Argument nodes. - arguments: (), + arguments: HashSet<Cow<'a, str>>, /// The kind of node. - kind: NodeKind<S, E>, + kind: NodeKind<'a, Source, Error>, } -impl<T, S, E> CommandNode<T, S, E> { - /// 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<Command<T, S, E>>, - ) -> Self { - CommandNode { - command: command, - nodes: (), - literals: (), - arguments: (), - kind: NodeKind::Literal { - literal: word, - }, +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(), } } +} - /// Creates a new argument node. - pub fn argument<A: ArgumentType<S, E> + 'static + Send + Sync>( - name: Cow<'static, str>, - command: Option<Command<T, S, E>>, - 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, - } - } -} +//impl<T, S, E> CommandNode<T, S, E> { +// /// 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<Command<T, S, E>>, +// ) -> Self { +// CommandNode { +// command: command, +// nodes: (), +// literals: (), +// arguments: (), +// kind: NodeKind::Literal { +// literal: word, +// }, +// } +// } +// +// /// Creates a new argument node. +// pub fn argument<A: ArgumentType<S, E> + 'static + Send + Sync + Eq + Hash>( +// name: Cow<'static, str>, +// command: Option<Command<T, S, E>>, +// 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, +// } +// } +//} |