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",
CliCommand::new(datastore::delete())
.arg_param(vec!["name"])
.completion_cb("name", apitest::config::datastore::complete_datastore_name)
.into());
cmd_def.into()

View File

@ -84,8 +84,22 @@ fn handle_nested_command(def: &CliCommandMap, mut args: Vec<String>) -> Result<(
Ok(())
}
fn print_property_completion(schema: &Schema, arg: &str) {
// fixme: implement completion functions
fn print_property_completion(
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 ApiStringFormat::Enum(list) = format.as_ref() {
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 args.is_empty() {
print_property_completion(schema, "");
print_property_completion(schema, prop_name, &cli_cmd.completion_functions, "");
} else {
print_property_completion(schema, &args[0]);
print_property_completion(schema, prop_name, &cli_cmd.completion_functions, &args[0]);
}
}
return;
@ -152,7 +166,7 @@ fn print_simple_completion(
if last.starts_with("--") && last.len() > 2 {
let prop_name = &last[2..];
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;
}
@ -248,16 +262,23 @@ pub fn run_cli_command(def: &CommandLineInterface) -> Result<(), Error> {
}
}
pub type CompletionFunction = fn() -> Vec<String>;
pub struct CliCommand {
pub info: ApiMethod,
pub arg_param: Vec<&'static str>,
pub fixed_param: Vec<&'static str>,
pub completion_functions: HashMap<String, CompletionFunction>,
}
impl CliCommand {
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 {
@ -269,6 +290,11 @@ impl CliCommand {
self.fixed_param = args;
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 {

View File

@ -76,3 +76,21 @@ pub fn save_config(config: &SectionConfigData) -> Result<(), Error> {
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
}