// 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<dyn ArgumentTypeAny<Source, Error>>,
},
}
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<Type, Source, Error>>,
/// Nodes.
nodes: HashMap<Cow<'a, str>, Cow<'a, CommandNode<'a, Type, Source, Error>>>,
/// Literal nodes.
literals: HashSet<Cow<'a, str>>,
/// Argument nodes.
arguments: HashSet<Cow<'a, str>>,
/// 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<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,
// }
// }
//}