schala/schala-repl/src/repl/old_command_tree.rs

74 lines
2.3 KiB
Rust

use super::Repl;
pub type BoxedCommandFunction = Box<(fn(&mut Repl, &[&str]) -> Option<String>)>;
/// A OldCommandTree 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 OldCommandTree {
Terminal {
name: String,
children: Vec<OldCommandTree>,
help_msg: Option<String>,
function: BoxedCommandFunction,
},
NonTerminal {
name: String,
children: Vec<OldCommandTree>,
help_msg: Option<String>,
},
Top(Vec<OldCommandTree>),
}
impl OldCommandTree {
pub fn nonterm_no_further_tab_completions(s: &str, help: Option<&str>) -> OldCommandTree {
OldCommandTree::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<OldCommandTree>, function: BoxedCommandFunction) -> OldCommandTree {
OldCommandTree::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<OldCommandTree>) -> OldCommandTree {
OldCommandTree::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<OldCommandTree>, func: BoxedCommandFunction) -> OldCommandTree {
OldCommandTree::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 {
OldCommandTree::Terminal { name, .. } => name.as_str(),
OldCommandTree::NonTerminal {name, ..} => name.as_str(),
OldCommandTree::Top(_) => "",
}
}
pub fn get_help(&self) -> &str {
match self {
OldCommandTree::Terminal { help_msg, ..} => help_msg.as_ref().map(|s| s.as_str()).unwrap_or(""),
OldCommandTree::NonTerminal { help_msg, .. } => help_msg.as_ref().map(|s| s.as_str()).unwrap_or(""),
OldCommandTree::Top(_) => ""
}
}
pub fn get_children(&self) -> Vec<&str> {
use OldCommandTree::*;
match self {
Terminal { children, .. } |
NonTerminal { children, .. } |
Top(children) => children.iter().map(|x| x.get_cmd()).collect()
}
}
}