diff options
Diffstat (limited to 'src/tree.rs')
-rw-r--r-- | src/tree.rs | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/src/tree.rs b/src/tree.rs new file mode 100644 index 0000000..b534754 --- /dev/null +++ b/src/tree.rs @@ -0,0 +1,105 @@ +// 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 crate::Command; +use crate::args::{ArgumentType, ArgumentTypeAny}; +use crate::strcursor::StringReader; +// FIXME +use crate::args::CommandContext; + +/// The kind of node. +enum NodeKind<S, E> { + /// Root node. + Root, + /// Literal node. + Literal { + /// The literal of the node. + literal: Cow<'static, str>, + }, + /// Argument node. + Argument { + /// The label of the node. + label: Cow<'static, str>, + /// The argument type. + arg: Box<dyn ArgumentTypeAny<S, E>>, + }, +} + +/// A node in the syntax tree. +pub struct CommandNode<T, S, E> { + /// The command to run for this node. + command: Option<Command<T, S, E>>, + /// Nodes. + nodes: (), + /// Literal nodes. + literals: (), + /// Argument nodes. + arguments: (), + /// The kind of node. + kind: NodeKind<S, E>, +} + +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>( + 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, + } + } +} |