diff --git a/forc-util/src/cli.rs b/forc-util/src/cli.rs index e3b44b556f9..4bbdac862b7 100644 --- a/forc-util/src/cli.rs +++ b/forc-util/src/cli.rs @@ -72,6 +72,17 @@ impl CommandInfo { cmd.get_arguments() .map(|opt| ArgInfo { name: opt.get_name().to_string(), + possible_values: opt + .get_possible_values() + .map(|x| { + x.iter() + .map(|x| PossibleValues { + name: x.get_name().to_owned(), + help: x.get_help().unwrap_or_default().to_owned(), + }) + .collect::>() + }) + .unwrap_or_default(), short: opt.get_short_and_visible_aliases(), aliases: opt .get_long_and_visible_aliases() @@ -89,9 +100,18 @@ impl CommandInfo { } } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct PossibleValues { + pub name: String, + pub help: String, +} + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ArgInfo { pub name: String, + #[serde(skip_serializing_if = "Vec::is_empty")] + #[serde(default)] + pub possible_values: Vec, #[serde(skip_serializing_if = "Option::is_none")] #[serde(default)] pub short: Option>, @@ -122,6 +142,14 @@ impl ArgInfo { if let Some(long_help) = &self.long_help { arg = arg.long_help(long_help.as_str()); } + if !self.possible_values.is_empty() { + arg = arg.possible_values( + self.possible_values + .iter() + .map(|pv| clap::PossibleValue::new(pv.name.as_str()).help(pv.help.as_str())) + .collect::>(), + ); + } if self.is_repeatable { arg = arg.multiple(true); } diff --git a/forc/src/cli/commands/completions.rs b/forc/src/cli/commands/completions.rs index 5c6de0c24c3..95b49424206 100644 --- a/forc/src/cli/commands/completions.rs +++ b/forc/src/cli/commands/completions.rs @@ -4,7 +4,7 @@ use clap_complete::{generate, Generator, Shell as BuiltInShell}; use forc_util::cli::CommandInfo; use forc_util::ForcResult; use std::collections::HashMap; -use std::str::FromStr; +use std::{fmt::Display, str::FromStr}; use crate::cli::plugin::find_all; @@ -15,6 +15,15 @@ enum Target { Fig, } +impl Display for Target { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.to_possible_value() + .expect("no values are skipped") + .get_name() + .fmt(f) + } +} + impl FromStr for Target { type Err = String;