summary refs log tree commit diff stats
path: root/src/tree.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tree.rs')
-rw-r--r--src/tree.rs105
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,
+        }
+    }
+}