Rearchitect CommandTree
- CommandTree::Term is now terminal only with respect to searching for the debug-handling function to execute, it can have children that only the tab-completion code cares about - CommandTree::NonTerminal never has a function associated with it, if the processing of a list of repl debug commands gets to a NonTerminal leaf, there's just nothing to do
This commit is contained in:
parent
8e9b410e02
commit
004b056232
@ -6,25 +6,25 @@ pub type BoxedCommandFunction = Box<(fn(&mut Repl, &[&str]) -> Option<String>)>;
|
|||||||
pub enum CommandTree {
|
pub enum CommandTree {
|
||||||
Terminal {
|
Terminal {
|
||||||
name: String,
|
name: String,
|
||||||
|
children: Vec<CommandTree>,
|
||||||
help_msg: Option<String>,
|
help_msg: Option<String>,
|
||||||
function: Option<BoxedCommandFunction>,
|
function: BoxedCommandFunction,
|
||||||
},
|
},
|
||||||
NonTerminal {
|
NonTerminal {
|
||||||
name: String,
|
name: String,
|
||||||
children: Vec<CommandTree>,
|
children: Vec<CommandTree>,
|
||||||
help_msg: Option<String>,
|
help_msg: Option<String>,
|
||||||
function: Option<BoxedCommandFunction>,
|
|
||||||
},
|
},
|
||||||
Top(Vec<CommandTree>),
|
Top(Vec<CommandTree>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandTree {
|
impl CommandTree {
|
||||||
pub fn term(s: &str, help: Option<&str>) -> CommandTree {
|
pub fn nonterm_no_further_tab_completions(s: &str, help: Option<&str>) -> CommandTree {
|
||||||
CommandTree::Terminal {name: s.to_string(), help_msg: help.map(|x| x.to_string()), function: None }
|
CommandTree::NonTerminal {name: s.to_string(), help_msg: help.map(|x| x.to_string()), children: vec![] }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn term_with_function(s: &str, help: Option<&str>, func: BoxedCommandFunction) -> CommandTree {
|
pub fn term_with_function(s: &str, help: Option<&str>, function: BoxedCommandFunction) -> CommandTree {
|
||||||
CommandTree::Terminal {name: s.to_string(), help_msg: help.map(|x| x.to_string()), function: Some(func) }
|
CommandTree::Terminal {name: s.to_string(), help_msg: help.map(|x| x.to_string()), function, children: vec![] }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nonterm(s: &str, help: Option<&str>, children: Vec<CommandTree>) -> CommandTree {
|
pub fn nonterm(s: &str, help: Option<&str>, children: Vec<CommandTree>) -> CommandTree {
|
||||||
@ -32,10 +32,10 @@ impl CommandTree {
|
|||||||
name: s.to_string(),
|
name: s.to_string(),
|
||||||
help_msg: help.map(|x| x.to_string()),
|
help_msg: help.map(|x| x.to_string()),
|
||||||
children,
|
children,
|
||||||
function: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
pub fn nonterm_with_function(s: &str, help: Option<&str>, children: Vec<CommandTree>, func: BoxedCommandFunction) -> CommandTree {
|
pub fn nonterm_with_function(s: &str, help: Option<&str>, children: Vec<CommandTree>, func: BoxedCommandFunction) -> CommandTree {
|
||||||
CommandTree::NonTerminal {
|
CommandTree::NonTerminal {
|
||||||
name: s.to_string(),
|
name: s.to_string(),
|
||||||
@ -44,6 +44,7 @@ impl CommandTree {
|
|||||||
function: Some(func),
|
function: Some(func),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
pub fn get_cmd(&self) -> &str {
|
pub fn get_cmd(&self) -> &str {
|
||||||
match self {
|
match self {
|
||||||
|
@ -112,11 +112,8 @@ impl Repl {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
CommandTree::Terminal { name, function, .. } => {
|
CommandTree::Terminal { name, function, .. } => {
|
||||||
break match function.as_ref() {
|
break Ok((function, idx));
|
||||||
Some(f) => Ok((f, idx)),
|
},
|
||||||
None => Err(format!("No action specified for: {:?}", commands)),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,7 +197,7 @@ impl Repl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let passes_directives: Vec<CommandTree> = pass_names.iter()
|
let passes_directives: Vec<CommandTree> = pass_names.iter()
|
||||||
.map(|pass_name| { CommandTree::term(pass_name, None) })
|
.map(|pass_name| { CommandTree::nonterm_no_further_tab_completions(pass_name, None) })
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
CommandTree::Top(vec![
|
CommandTree::Top(vec![
|
||||||
@ -237,20 +234,20 @@ impl Repl {
|
|||||||
CommandTree::nonterm("show", None, passes_directives.clone()),
|
CommandTree::nonterm("show", None, passes_directives.clone()),
|
||||||
CommandTree::nonterm("hide", None, passes_directives.clone()),
|
CommandTree::nonterm("hide", None, passes_directives.clone()),
|
||||||
CommandTree::nonterm("timing", None, vec![
|
CommandTree::nonterm("timing", None, vec![
|
||||||
CommandTree::term("on", None),
|
CommandTree::nonterm_no_further_tab_completions("on", None),
|
||||||
CommandTree::term("off", None),
|
CommandTree::nonterm_no_further_tab_completions("off", None),
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
CommandTree::nonterm("lang",
|
CommandTree::nonterm("lang",
|
||||||
Some("switch between languages, or go directly to a langauge by name"),
|
Some("switch between languages, or go directly to a langauge by name"),
|
||||||
vec![
|
vec![
|
||||||
CommandTree::term("next", None),
|
CommandTree::nonterm_no_further_tab_completions("next", None),
|
||||||
CommandTree::term("prev", None),
|
CommandTree::nonterm_no_further_tab_completions("prev", None),
|
||||||
CommandTree::nonterm("go", None, vec![]),
|
CommandTree::nonterm("go", None, vec![]),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
CommandTree::term("doc", Some("Get language-specific help for an item")),
|
CommandTree::nonterm_no_further_tab_completions("doc", Some("Get language-specific help for an item")),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,7 +336,7 @@ impl<T: Terminal> Completer<T> for TabCompleteHandler {
|
|||||||
let new_ptr: Option<&CommandTree> = command_tree.and_then(|cm| match cm {
|
let new_ptr: Option<&CommandTree> = command_tree.and_then(|cm| match cm {
|
||||||
CommandTree::Top(children) => children.iter().find(|c| c.get_cmd() == s),
|
CommandTree::Top(children) => children.iter().find(|c| c.get_cmd() == s),
|
||||||
CommandTree::NonTerminal { children, .. } => children.iter().find(|c| c.get_cmd() == s),
|
CommandTree::NonTerminal { children, .. } => children.iter().find(|c| c.get_cmd() == s),
|
||||||
CommandTree::Terminal { .. } => None,
|
CommandTree::Terminal { children, .. } => children.iter().find(|c| c.get_cmd() == s),
|
||||||
});
|
});
|
||||||
command_tree = new_ptr;
|
command_tree = new_ptr;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user