Skip to content

Instantly share code, notes, and snippets.

@tadzik

tadzik/cli-matcher.rs Secret

Last active Jan 4, 2020
Embed
What would you like to do?
enum DispatchResult<'a, T> {
Matched(&'a T),
Ambiguous(Vec<&'a String>),
NotFound,
}
fn dispatch<'a, T>(command: &str, candidates: &'a Vec<(String, T)>) -> DispatchResult<'a, T> {
let matches = candidates.iter()
.filter(|c| c.0.starts_with(command))
.collect::<Vec<_>>();
if matches.len() == 1 {
DispatchResult::Matched(&matches[0].1)
} else if matches.len() == 0 {
DispatchResult::NotFound
} else {
DispatchResult::Ambiguous(matches.iter().map(|c| &c.0).collect::<Vec<_>>())
}
}
fn main() {
let commands: Vec<(String, Box<dyn Fn()>)> = vec![
(String::from("start"), Box::new(|| start_work())),
(String::from("status"), Box::new(|| show_status())),
];
match env::args().nth(1) {
Some(command) => match dispatch(&command, &commands) {
DispatchResult::Matched(target) => target(),
DispatchResult::Ambiguous(matches) => {
println!("More than one command matches prefix '{}':", command);
for m in matches {
println!("\t{}", m);
}
println!("Please be more specific");
},
DispatchResult::NotFound => usage(),
}
None => usage(),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.