cli/command.rs: add new type CliCommandMap

This commit is contained in:
Dietmar Maurer 2018-12-11 11:31:36 +01:00
parent bf7f103944
commit 6460764dbb
2 changed files with 39 additions and 27 deletions

View File

@ -7,32 +7,28 @@ use apitest::cli::command::*;
fn datastore_commands() -> CommandLineInterface { fn datastore_commands() -> CommandLineInterface {
let mut cmd_def = HashMap::<String, CommandLineInterface>::new();
use apitest::api3::config::datastore; use apitest::api3::config::datastore;
cmd_def.insert("list".to_owned(), CliCommand::new(datastore::get()).into()); let cmd_def = CliCommandMap::new()
.insert("list", CliCommand::new(datastore::get()).into())
cmd_def.insert("create".to_owned(), .insert("create",
CliCommand::new(datastore::post()) CliCommand::new(datastore::post())
.arg_param(vec!["name", "path"]) .arg_param(vec!["name", "path"])
.into()); .into())
.insert("remove",
cmd_def.insert("remove".to_owned(), CliCommand::new(datastore::delete())
CliCommand::new(api3::config::datastore::delete()) .arg_param(vec!["name"])
.arg_param(vec!["name"]) .into());
.into());
cmd_def.into() cmd_def.into()
} }
fn main() { fn main() {
let mut cmd_def = HashMap::new(); let cmd_def = CliCommandMap::new()
.insert("datastore".to_owned(), datastore_commands());
cmd_def.insert("datastore".to_owned(), datastore_commands()); if let Err(err) = run_cli_command(&cmd_def.into()) {
if let Err(err) = run_cli_command(&CommandLineInterface::Nested(cmd_def)) {
eprintln!("Error: {}", err); eprintln!("Error: {}", err);
print_cli_usage(); print_cli_usage();
std::process::exit(-1); std::process::exit(-1);

View File

@ -27,32 +27,32 @@ fn handle_simple_command(cli_cmd: &CliCommand, args: Vec<String>) -> Result<(),
Ok(()) Ok(())
} }
fn find_command<'a>(def: &'a HashMap<String, CommandLineInterface>, name: &str) -> Option<&'a CommandLineInterface> { fn find_command<'a>(def: &'a CliCommandMap, name: &str) -> Option<&'a CommandLineInterface> {
if let Some(sub_cmd) = def.get(name) { if let Some(sub_cmd) = def.commands.get(name) {
return Some(sub_cmd); return Some(sub_cmd);
}; };
let mut matches: Vec<&str> = vec![]; let mut matches: Vec<&str> = vec![];
for cmd in def.keys() { for cmd in def.commands.keys() {
if cmd.starts_with(name) { if cmd.starts_with(name) {
matches.push(cmd); } matches.push(cmd); }
} }
if matches.len() != 1 { return None; } if matches.len() != 1 { return None; }
if let Some(sub_cmd) = def.get(matches[0]) { if let Some(sub_cmd) = def.commands.get(matches[0]) {
return Some(sub_cmd); return Some(sub_cmd);
}; };
None None
} }
fn handle_nested_command(def: &HashMap<String, CommandLineInterface>, mut args: Vec<String>) -> Result<(), Error> { fn handle_nested_command(def: &CliCommandMap, mut args: Vec<String>) -> Result<(), Error> {
if args.len() < 1 { if args.len() < 1 {
let mut cmds: Vec<&String> = def.keys().collect(); let mut cmds: Vec<&String> = def.commands.keys().collect();
cmds.sort(); cmds.sort();
let list = cmds.iter().fold(String::new(),|mut s,item| { let list = cmds.iter().fold(String::new(),|mut s,item| {
@ -116,9 +116,25 @@ impl CliCommand {
} }
} }
pub struct CliCommandMap {
pub commands: HashMap<String, CommandLineInterface>,
}
impl CliCommandMap {
pub fn new() -> Self {
Self { commands: HashMap:: new() }
}
pub fn insert<S: Into<String>>(mut self, name: S, cli: CommandLineInterface) -> Self {
self.commands.insert(name.into(), cli);
self
}
}
pub enum CommandLineInterface { pub enum CommandLineInterface {
Simple(CliCommand), Simple(CliCommand),
Nested(HashMap<String, CommandLineInterface>), Nested(CliCommandMap),
} }
impl From<CliCommand> for CommandLineInterface { impl From<CliCommand> for CommandLineInterface {
@ -127,8 +143,8 @@ impl From<CliCommand> for CommandLineInterface {
} }
} }
impl From<HashMap<String, CommandLineInterface>> for CommandLineInterface { impl From<CliCommandMap> for CommandLineInterface {
fn from(map: HashMap<String, CommandLineInterface>) -> Self { fn from(list: CliCommandMap) -> Self {
CommandLineInterface::Nested(map) CommandLineInterface::Nested(list)
} }
} }