use super::Repl; pub type BoxedCommandFunction = Box<(fn(&mut Repl, &[&str]) -> Option)>; /// A CommandTree is either a `Terminal` or a `NonTerminal`. When command parsing reaches the first /// Terminal, it will execute the `BoxedCommandFunction` found there with any remaining arguments #[derive(Clone)] pub enum CommandTree { Terminal { name: String, children: Vec, help_msg: Option, function: BoxedCommandFunction, }, NonTerminal { name: String, children: Vec, help_msg: Option, }, Top(Vec), } impl CommandTree { pub fn nonterm_no_further_tab_completions(s: &str, help: Option<&str>) -> CommandTree { CommandTree::NonTerminal {name: s.to_string(), help_msg: help.map(|x| x.to_string()), children: vec![] } } pub fn terminal(s: &str, help: Option<&str>, children: Vec, function: BoxedCommandFunction) -> CommandTree { CommandTree::Terminal {name: s.to_string(), help_msg: help.map(|x| x.to_string()), function, children } } pub fn nonterm(s: &str, help: Option<&str>, children: Vec) -> CommandTree { CommandTree::NonTerminal { name: s.to_string(), help_msg: help.map(|x| x.to_string()), children, } } /* pub fn nonterm_with_function(s: &str, help: Option<&str>, children: Vec, func: BoxedCommandFunction) -> CommandTree { CommandTree::NonTerminal { name: s.to_string(), help_msg: help.map(|x| x.to_string()), children, function: Some(func), } } */ pub fn get_cmd(&self) -> &str { match self { CommandTree::Terminal { name, .. } => name.as_str(), CommandTree::NonTerminal {name, ..} => name.as_str(), CommandTree::Top(_) => "", } } pub fn get_help(&self) -> &str { match self { CommandTree::Terminal { help_msg, ..} => help_msg.as_ref().map(|s| s.as_str()).unwrap_or(""), CommandTree::NonTerminal { help_msg, .. } => help_msg.as_ref().map(|s| s.as_str()).unwrap_or(""), CommandTree::Top(_) => "" } } pub fn get_children(&self) -> Vec<&str> { use CommandTree::*; match self { Terminal { children, .. } | NonTerminal { children, .. } | Top(children) => children.iter().map(|x| x.get_cmd()).collect() } } }