fix(derive): Follow value_name convention

I debated putting this fix inside of the Builder API but I figure this
makes it so you "pay for what you use", with the derive API giving it to
you "for free".

A potential next step is to improve the default value name.  I tend to
use value_name to hint at how to use an argument, which correlates with
types.  We could add a
`ValueName::value_name(fallback: &str) -> &str` with impls for common
types, so we get more of a usage-based result.

Fixes #2608
This commit is contained in:
Ed Page 2021-07-21 11:56:35 -05:00
parent 610d56d1c6
commit c485ae517b
3 changed files with 26 additions and 0 deletions

View file

@ -791,6 +791,10 @@ impl Attrs {
self.name.clone().translate(*self.casing)
}
pub fn value_name(&self) -> TokenStream {
self.name.clone().translate(CasingStyle::ScreamingSnake)
}
pub fn parser(&self) -> &Sp<Parser> {
&self.parser
}

View file

@ -231,6 +231,8 @@ pub fn gen_augment(
_ => quote!(),
};
let value_name = attrs.value_name();
let modifier = match **ty {
Ty::Bool => quote!(),
@ -245,6 +247,7 @@ pub fn gen_augment(
quote_spanned! { ty.span()=>
.takes_value(true)
.value_name(#value_name)
#possible_values
#validator
}
@ -252,6 +255,7 @@ pub fn gen_augment(
Ty::OptionOption => quote_spanned! { ty.span()=>
.takes_value(true)
.value_name(#value_name)
.multiple_values(false)
.min_values(0)
.max_values(1)
@ -260,6 +264,7 @@ pub fn gen_augment(
Ty::OptionVec => quote_spanned! { ty.span()=>
.takes_value(true)
.value_name(#value_name)
.multiple_values(true)
.min_values(0)
#validator
@ -276,6 +281,7 @@ pub fn gen_augment(
quote_spanned! { ty.span()=>
.takes_value(true)
.value_name(#value_name)
.multiple_values(true)
#possible_values
#validator
@ -301,6 +307,7 @@ pub fn gen_augment(
quote_spanned! { ty.span()=>
.takes_value(true)
.value_name(#value_name)
.required(#required)
#possible_values
#validator

View file

@ -13,6 +13,7 @@
// MIT/Apache 2.0 license.
use clap::Clap;
use clap::IntoApp;
#[test]
fn required_argument() {
@ -83,3 +84,17 @@ fn arguments_safe() {
Opt::try_parse_from(&["test", "NOPE"]).err().unwrap().kind
);
}
#[test]
fn value_name() {
#[derive(Clap, PartialEq, Debug)]
struct Opt {
my_special_arg: i32,
}
let mut help = Vec::new();
Opt::into_app().write_help(&mut help).unwrap();
let help = String::from_utf8(help).unwrap();
assert!(help.contains("MY_SPECIAL_ARG"));
}