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

View File

@ -27,32 +27,32 @@ fn handle_simple_command(cli_cmd: &CliCommand, args: Vec<String>) -> Result<(),
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);
};
let mut matches: Vec<&str> = vec![];
for cmd in def.keys() {
for cmd in def.commands.keys() {
if cmd.starts_with(name) {
matches.push(cmd); }
}
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);
};
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 {
let mut cmds: Vec<&String> = def.keys().collect();
let mut cmds: Vec<&String> = def.commands.keys().collect();
cmds.sort();
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 {
Simple(CliCommand),
Nested(HashMap<String, CommandLineInterface>),
Nested(CliCommandMap),
}
impl From<CliCommand> for CommandLineInterface {
@ -127,8 +143,8 @@ impl From<CliCommand> for CommandLineInterface {
}
}
impl From<HashMap<String, CommandLineInterface>> for CommandLineInterface {
fn from(map: HashMap<String, CommandLineInterface>) -> Self {
CommandLineInterface::Nested(map)
impl From<CliCommandMap> for CommandLineInterface {
fn from(list: CliCommandMap) -> Self {
CommandLineInterface::Nested(list)
}
}