schala/schala-repl/src/repl/command_tree.rs

87 lines
2.6 KiB
Rust
Raw Normal View History

use super::Repl;
pub type BoxedCommandFunction = Box<(fn(&mut Repl, &[&str]) -> Option<String>)>;
2018-10-15 20:52:34 -07:00
2019-05-22 03:10:12 -07:00
/// A CommandTree is either a `Terminal` or a `NonTerminal`. When command parsing reaches the first
2019-06-01 18:41:55 -07:00
/// Terminal, it will use the `ReplAction` found there to find an appropriate function to execute,
/// and then execute it with any remaining arguments
//TODO remove function: BoxedCommandFunction
2018-10-15 20:52:34 -07:00
#[derive(Clone)]
pub enum CommandTree {
Terminal {
name: String,
children: Vec<CommandTree>,
2018-10-15 20:52:34 -07:00
help_msg: Option<String>,
function: BoxedCommandFunction,
2019-06-01 18:41:55 -07:00
action: ReplAction,
2018-10-15 20:52:34 -07:00
},
NonTerminal {
name: String,
children: Vec<CommandTree>,
help_msg: Option<String>,
2019-06-01 18:41:55 -07:00
action: ReplAction,
2018-10-15 20:52:34 -07:00
},
2019-06-01 18:41:55 -07:00
//TODO get rid of Top
2018-10-15 20:52:34 -07:00
Top(Vec<CommandTree>),
}
2019-06-01 18:41:55 -07:00
#[derive(Debug, Clone)]
pub enum ReplAction {
Null,
Help,
QuitProgram
}
2018-10-15 20:52:34 -07:00
impl CommandTree {
pub fn nonterm_no_further_tab_completions(s: &str, help: Option<&str>) -> CommandTree {
2019-06-01 18:41:55 -07:00
CommandTree::NonTerminal {name: s.to_string(), help_msg: help.map(|x| x.to_string()), children: vec![], action: ReplAction::Null }
2018-10-15 20:52:34 -07:00
}
2018-10-15 21:46:27 -07:00
2019-05-22 03:10:12 -07:00
pub fn terminal(s: &str, help: Option<&str>, children: Vec<CommandTree>, function: BoxedCommandFunction) -> CommandTree {
2019-06-01 18:41:55 -07:00
CommandTree::Terminal {name: s.to_string(), help_msg: help.map(|x| x.to_string()), function, children, action: ReplAction::Null }
}
2018-10-15 21:46:27 -07:00
pub fn nonterm(s: &str, help: Option<&str>, children: Vec<CommandTree>) -> CommandTree {
CommandTree::NonTerminal {
name: s.to_string(),
help_msg: help.map(|x| x.to_string()),
children,
2019-06-01 18:41:55 -07:00
action: ReplAction::Null
}
}
/*
pub fn nonterm_with_function(s: &str, help: Option<&str>, children: Vec<CommandTree>, func: BoxedCommandFunction) -> CommandTree {
CommandTree::NonTerminal {
name: s.to_string(),
help_msg: help.map(|x| x.to_string()),
children,
function: Some(func),
2018-10-15 21:46:27 -07:00
}
}
*/
2018-10-15 21:46:27 -07:00
2018-10-15 20:52:34 -07:00
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> {
2019-03-27 02:20:43 -07:00
use CommandTree::*;
2018-10-15 20:52:34 -07:00
match self {
2019-03-27 02:20:43 -07:00
Terminal { children, .. } |
NonTerminal { children, .. } |
Top(children) => children.iter().map(|x| x.get_cmd()).collect()
2018-10-15 20:52:34 -07:00
}
}
}