implement completion functions

This commit is contained in:
Dietmar Maurer 2018-12-12 12:18:28 +01:00
parent 91643d9012
commit 30d2e99c77
3 changed files with 51 additions and 6 deletions

View File

@ -18,6 +18,7 @@ fn datastore_commands() -> CommandLineInterface {
.insert("remove", .insert("remove",
CliCommand::new(datastore::delete()) CliCommand::new(datastore::delete())
.arg_param(vec!["name"]) .arg_param(vec!["name"])
.completion_cb("name", apitest::config::datastore::complete_datastore_name)
.into()); .into());
cmd_def.into() cmd_def.into()

View File

@ -84,8 +84,22 @@ fn handle_nested_command(def: &CliCommandMap, mut args: Vec<String>) -> Result<(
Ok(()) Ok(())
} }
fn print_property_completion(schema: &Schema, arg: &str) { fn print_property_completion(
// fixme: implement completion functions schema: &Schema,
name: &str,
completion_functions: &HashMap<String, CompletionFunction>,
arg: &str)
{
if let Some(callback) = completion_functions.get(name) {
let list = (callback)();
for value in list {
if value.starts_with(arg) {
println!("{}", value);
}
}
return;
}
if let Schema::String(StringSchema { format: Some(format), ..} ) = schema { if let Schema::String(StringSchema { format: Some(format), ..} ) = schema {
if let ApiStringFormat::Enum(list) = format.as_ref() { if let ApiStringFormat::Enum(list) = format.as_ref() {
for value in list { for value in list {
@ -133,9 +147,9 @@ fn print_simple_completion(
} }
if let Some((_, schema)) = cli_cmd.info.parameters.properties.get(prop_name) { if let Some((_, schema)) = cli_cmd.info.parameters.properties.get(prop_name) {
if args.is_empty() { if args.is_empty() {
print_property_completion(schema, ""); print_property_completion(schema, prop_name, &cli_cmd.completion_functions, "");
} else { } else {
print_property_completion(schema, &args[0]); print_property_completion(schema, prop_name, &cli_cmd.completion_functions, &args[0]);
} }
} }
return; return;
@ -152,7 +166,7 @@ fn print_simple_completion(
if last.starts_with("--") && last.len() > 2 { if last.starts_with("--") && last.len() > 2 {
let prop_name = &last[2..]; let prop_name = &last[2..];
if let Some((_, schema)) = cli_cmd.info.parameters.properties.get(prop_name) { if let Some((_, schema)) = cli_cmd.info.parameters.properties.get(prop_name) {
print_property_completion(schema, &prefix); print_property_completion(schema, prop_name, &cli_cmd.completion_functions, &prefix);
} }
return; return;
} }
@ -248,16 +262,23 @@ pub fn run_cli_command(def: &CommandLineInterface) -> Result<(), Error> {
} }
} }
pub type CompletionFunction = fn() -> Vec<String>;
pub struct CliCommand { pub struct CliCommand {
pub info: ApiMethod, pub info: ApiMethod,
pub arg_param: Vec<&'static str>, pub arg_param: Vec<&'static str>,
pub fixed_param: Vec<&'static str>, pub fixed_param: Vec<&'static str>,
pub completion_functions: HashMap<String, CompletionFunction>,
} }
impl CliCommand { impl CliCommand {
pub fn new(info: ApiMethod) -> Self { pub fn new(info: ApiMethod) -> Self {
Self { info, arg_param: vec![], fixed_param: vec![] } Self {
info, arg_param: vec![],
fixed_param: vec![],
completion_functions: HashMap::new(),
}
} }
pub fn arg_param(mut self, names: Vec<&'static str>) -> Self { pub fn arg_param(mut self, names: Vec<&'static str>) -> Self {
@ -269,6 +290,11 @@ impl CliCommand {
self.fixed_param = args; self.fixed_param = args;
self self
} }
pub fn completion_cb(mut self, param_name: &str, cb: CompletionFunction) -> Self {
self.completion_functions.insert(param_name.into(), cb);
self
}
} }
pub struct CliCommandMap { pub struct CliCommandMap {

View File

@ -76,3 +76,21 @@ pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
Ok(()) Ok(())
} }
// shell completion helper
pub fn complete_datastore_name() -> Vec<String> {
let data = match config() {
Ok(data) => data,
Err(_) => return vec![],
};
//let test = data.sections
let mut res = vec![];
for (id, _) in data.sections {
res.push(id);
}
res
}