summary refs log blame commit diff stats
path: root/src/tree.rs
blob: ae408a8c942135fac59ef466fef1e555d272f837 (plain) (tree)
1
2
3
4
5
6
7
8







                                                            



                                



                                                 
             


                                
                                  




                                    
                              



                                  
                            
                              
                                                     


      





















                                                               
                                         
                                                  
              
                                                                                
                      
                                    
                       
                                     
                         
                                      

 







                                                                              

         
 
 
 

























































                                                                                 
// 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,
//        }
//    }
//}