fix(derive): Don't mix implicit and explicit value_names

It turns out `value_name` appends, so by setting an implicit and
explicit `value_name`, the user gets both and `num_vals=2`.

There is still a question on `value_name` and whether its documentation
or behavior needs updating.  If that changes, then this can be
simplified by reverting back.

Fixes #2632
This commit is contained in:
Ed Page 2021-07-28 09:13:19 -05:00
parent 35db529b36
commit 78aa86cfbb
2 changed files with 35 additions and 7 deletions

View file

@ -231,7 +231,15 @@ pub fn gen_augment(
_ => quote!(),
};
let value_name = attrs.value_name();
let value_name = if attrs.has_method("value_name") {
// `value_name` appends, so don't touch it if the user does.
quote!()
} else {
let value_name = attrs.value_name();
quote_spanned! { func.span()=>
.value_name(#value_name)
}
};
let modifier = match **ty {
Ty::Bool => quote!(),
@ -247,7 +255,7 @@ pub fn gen_augment(
quote_spanned! { ty.span()=>
.takes_value(true)
.value_name(#value_name)
#value_name
#possible_values
#validator
}
@ -255,7 +263,7 @@ pub fn gen_augment(
Ty::OptionOption => quote_spanned! { ty.span()=>
.takes_value(true)
.value_name(#value_name)
#value_name
.multiple_values(false)
.min_values(0)
.max_values(1)
@ -264,7 +272,7 @@ pub fn gen_augment(
Ty::OptionVec => quote_spanned! { ty.span()=>
.takes_value(true)
.value_name(#value_name)
#value_name
.multiple_values(true)
.min_values(0)
#validator
@ -281,7 +289,7 @@ pub fn gen_augment(
quote_spanned! { ty.span()=>
.takes_value(true)
.value_name(#value_name)
#value_name
.multiple_values(true)
#possible_values
#validator
@ -307,7 +315,7 @@ pub fn gen_augment(
quote_spanned! { ty.span()=>
.takes_value(true)
.value_name(#value_name)
#value_name
.required(#required)
#possible_values
#validator

View file

@ -86,7 +86,7 @@ fn arguments_safe() {
}
#[test]
fn value_name() {
fn auto_value_name() {
#[derive(Clap, PartialEq, Debug)]
struct Opt {
my_special_arg: i32,
@ -97,4 +97,24 @@ fn value_name() {
let help = String::from_utf8(help).unwrap();
assert!(help.contains("MY_SPECIAL_ARG"));
// Ensure the implicit `num_vals` is just 1
assert_eq!(Opt { my_special_arg: 10 }, Opt::parse_from(&["test", "10"]));
}
#[test]
fn explicit_value_name() {
#[derive(Clap, PartialEq, Debug)]
struct Opt {
#[clap(value_name = "BROWNIE_POINTS")]
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("BROWNIE_POINTS"));
assert!(!help.contains("MY_SPECIAL_ARG"));
// Ensure the implicit `num_vals` is just 1
assert_eq!(Opt { my_special_arg: 10 }, Opt::parse_from(&["test", "10"]));
}