src/cli/command.rs: handle multilevel sub commands in help

This commit is contained in:
Dietmar Maurer 2019-12-01 09:42:51 +01:00
parent b7bf71dfa1
commit b8a82922c7
3 changed files with 23 additions and 18 deletions

View File

@ -78,10 +78,10 @@ impl CliCommandMap {
self self
} }
fn find_command(&self, name: &str) -> Option<&CommandLineInterface> { fn find_command(&self, name: &str) -> Option<(String, &CommandLineInterface)> {
if let Some(sub_cmd) = self.commands.get(name) { if let Some(sub_cmd) = self.commands.get(name) {
return Some(sub_cmd); return Some((name.to_string(), sub_cmd));
}; };
let mut matches: Vec<&str> = vec![]; let mut matches: Vec<&str> = vec![];
@ -94,7 +94,7 @@ impl CliCommandMap {
if matches.len() != 1 { return None; } if matches.len() != 1 { return None; }
if let Some(sub_cmd) = self.commands.get(matches[0]) { if let Some(sub_cmd) = self.commands.get(matches[0]) {
return Some(sub_cmd); return Some((matches[0].to_string(), sub_cmd));
}; };
None None

View File

@ -94,7 +94,7 @@ pub fn handle_nested_command(
let command = args.remove(0); let command = args.remove(0);
let sub_cmd = match def.find_command(&command) { let (_, sub_cmd) = match def.find_command(&command) {
Some(cmd) => cmd, Some(cmd) => cmd,
None => { None => {
let err_msg = format!("no such command '{}'", command); let err_msg = format!("no such command '{}'", command);
@ -331,7 +331,10 @@ const API_METHOD_COMMAND_HELP: ApiMethod = ApiMethod::new(
&[ &[
( "command", ( "command",
true, true,
&StringSchema::new("Command name.").schema() &ArraySchema::new(
"Command",
&StringSchema::new("Name.").schema()
).schema()
), ),
( "verbose", ( "verbose",
true, true,
@ -351,20 +354,18 @@ fn help_command(
_rpcenv: &mut dyn RpcEnvironment, _rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> { ) -> Result<Value, Error> {
let command: Vec<String> = param["command"].as_array().unwrap_or(&Vec::new())
.iter()
.map(|v| v.as_str().unwrap().to_string())
.collect();
let command = param["command"].as_str();
let verbose = param["verbose"].as_bool(); let verbose = param["verbose"].as_bool();
HELP_CONTEXT.with(|ctx| { HELP_CONTEXT.with(|ctx| {
match &*ctx.borrow() { match &*ctx.borrow() {
Some(def) => { Some(def) => {
let mut args = Vec::new(); print_help(def, String::from(""), &command, verbose);
// TODO: Handle multilevel sub commands
if let Some(command) = command {
args.push(command.to_string());
}
print_help(def, String::from(""), &args, verbose);
} }
None => { None => {
eprintln!("Sorry, help context not set - internal error."); eprintln!("Sorry, help context not set - internal error.");

View File

@ -173,15 +173,19 @@ pub fn print_help(
for cmd in args { for cmd in args {
if let CommandLineInterface::Nested(map) = iface { if let CommandLineInterface::Nested(map) = iface {
if let Some(subcmd) = map.find_command(cmd) { if let Some((full_name, subcmd)) = map.find_command(cmd) {
iface = subcmd; iface = subcmd;
prefix.push(' '); if !prefix.is_empty() { prefix.push(' '); }
prefix.push_str(cmd); prefix.push_str(&full_name);
continue; continue;
} }
} }
eprintln!("no such command '{}'", cmd); if prefix.is_empty() {
std::process::exit(-1); eprintln!("no such command '{}'", cmd);
} else {
eprintln!("no such command '{} {}'", prefix, cmd);
}
return;
} }
let format = match verbose.unwrap_or(false) { let format = match verbose.unwrap_or(false) {