diff options
author | Daniel Mueller <deso@posteo.net> | 2019-01-15 18:07:08 -0800 |
---|---|---|
committer | Daniel Mueller <deso@posteo.net> | 2019-01-15 18:07:08 -0800 |
commit | ca71373ce37e6377d199ac285df999230049ab8e (patch) | |
tree | e40849d803126db8826bc314b19510645e6d7b69 | |
parent | 984f5fadd1bfcd0184af8bddc4973acfe8affb64 (diff) | |
download | nitrocli-ca71373ce37e6377d199ac285df999230049ab8e.tar.gz nitrocli-ca71373ce37e6377d199ac285df999230049ab8e.tar.bz2 |
Auto-generate help text for Option-based arguments
The previous change to properly format the help text for optional
arguments left one thing out: parameters that are based on an Option as
opposed to an enum. The problem with those is that we cannot simply ask
the value (i.e., the Option) for all the variants of the inner type.
Instead, we have to reference the actual type of the inner enum in order
to retrieve all its possible variants.
-rw-r--r-- | nitrocli/src/arg_util.rs | 6 | ||||
-rw-r--r-- | nitrocli/src/args.rs | 32 |
2 files changed, 24 insertions, 14 deletions
diff --git a/nitrocli/src/arg_util.rs b/nitrocli/src/arg_util.rs index b1ced25..9fa254b 100644 --- a/nitrocli/src/arg_util.rs +++ b/nitrocli/src/arg_util.rs @@ -109,8 +109,10 @@ macro_rules! Enum { /// replaced with a generated version of the enum's variants. macro_rules! fmt_enum { ( $enm:ident ) => {{ - $enm - .all() + fmt_enum!($enm.all()) + }}; + ( $all:expr ) => {{ + $all .iter() .map(::std::convert::AsRef::as_ref) .collect::<::std::vec::Vec<_>>() diff --git a/nitrocli/src/args.rs b/nitrocli/src/args.rs index e6267e7..bf252c3 100644 --- a/nitrocli/src/args.rs +++ b/nitrocli/src/args.rs @@ -420,7 +420,7 @@ fn otp_get(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { pub fn otp_set(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { let mut slot: u8 = 0; let mut algorithm = OtpAlgorithm::Totp; - let help = format!( + let algo_help = format!( "The OTP algorithm to use ({}, default: {})", fmt_enum!(algorithm), algorithm @@ -432,6 +432,10 @@ pub fn otp_set(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { let mut time_window: u16 = 30; let mut ascii = false; let mut secret_format: Option<OtpSecretFormat> = None; + let fmt_help = format!( + "The format of the secret ({})", + fmt_enum!(OtpSecretFormat::all_variants()) + ); let mut parser = argparse::ArgumentParser::new(); parser.set_description("Configures a one-time password slot"); let _ = @@ -439,9 +443,10 @@ pub fn otp_set(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { .refer(&mut slot) .required() .add_argument("slot", argparse::Store, "The OTP slot to use"); - let _ = parser - .refer(&mut algorithm) - .add_option(&["-a", "--algorithm"], argparse::Store, &help); + let _ = + parser + .refer(&mut algorithm) + .add_option(&["-a", "--algorithm"], argparse::Store, &algo_help); let _ = parser.refer(&mut name).required().add_argument( "name", argparse::Store, @@ -475,7 +480,7 @@ pub fn otp_set(ctx: &mut ExecCtx<'_>, args: Vec<String>) -> Result<()> { let _ = parser.refer(&mut secret_format).add_option( &["-f", "--format"], argparse::StoreOption, - "The format of the secret (ascii|base32|hex)", + &fmt_help, ); parse(ctx, &parser, args)?; drop(parser); @@ -744,9 +749,13 @@ fn parse_arguments<'io, 'ctx: 'io>( args: Vec<String>, ) -> Result<(Command, ExecCtx<'io>, Vec<String>)> { let mut model: Option<DeviceModel> = None; + let model_help = format!( + "Select the device model to connect to ({})", + fmt_enum!(DeviceModel::all_variants()) + ); let mut verbosity = 0; let mut command = Command::Status; - let help = cmd_help!(command); + let cmd_help = cmd_help!(command); let mut subargs = vec![]; let mut parser = argparse::ArgumentParser::new(); let _ = parser.refer(&mut verbosity).add_option( @@ -754,16 +763,15 @@ fn parse_arguments<'io, 'ctx: 'io>( argparse::IncrBy::<u64>(1), "Increase the log level (can be supplied multiple times)", ); - let _ = parser.refer(&mut model).add_option( - &["-m", "--model"], - argparse::StoreOption, - "Select the device model to connect to (pro|storage)", - ); + let _ = + parser + .refer(&mut model) + .add_option(&["-m", "--model"], argparse::StoreOption, &model_help); parser.set_description("Provides access to a Nitrokey device"); let _ = parser .refer(&mut command) .required() - .add_argument("command", argparse::Store, &help); + .add_argument("command", argparse::Store, &cmd_help); let _ = parser.refer(&mut subargs).add_argument( "arguments", argparse::List, |