Skip to content

Commit e29f014

Browse files
authored
Merge pull request #4068 from danielparks/issue-3785-derive-id-attr-v3
v3 fix(derive): Add "id" attribute
2 parents bc84fc0 + d8e2549 commit e29f014

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

clap_derive/src/attrs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,7 @@ impl Attrs {
450450
}
451451

452452
fn push_method(&mut self, name: Ident, arg: impl ToTokens) {
453-
if name == "name" {
453+
if name == "name" || name == "id" {
454454
self.name = Name::Assigned(quote!(#arg));
455455
} else if name == "value_parser" {
456456
self.value_parser = Some(ValueParser::Explicit(Method::new(name, quote!(#arg))));

src/_derive/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,10 @@
181181
//! - e.g. `#[clap(max_values(3))]` would translate to `arg.max_values(3)`
182182
//!
183183
//! **Magic attributes**:
184-
//! - `name = <expr>`: [`Arg::id`][crate::Arg::id]
184+
//! - `id = <expr>`: [`Arg::id`][crate::Arg::id]
185185
//! - When not present: case-converted field name is used
186+
//! - `name = <expr>`: [`Arg::id`][crate::Arg::id]
187+
//! - **Deprecated:** use `id`
186188
//! - `value_parser [= <expr>]`: [`Arg::value_parser`][crate::Arg::value_parser]
187189
//! - When not present: will auto-select an implementation based on the field type using
188190
//! [`value_parser!][crate::value_parser!]

tests/derive/naming.rs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,34 @@ fn test_standalone_long_ignores_afterwards_defined_custom_name() {
5757
);
5858
}
5959

60+
#[test]
61+
fn test_standalone_long_uses_previous_defined_custom_id() {
62+
#[derive(Parser, Debug, PartialEq)]
63+
struct Opt {
64+
#[clap(id = "foo", long)]
65+
foo_option: bool,
66+
}
67+
68+
assert_eq!(
69+
Opt { foo_option: true },
70+
Opt::try_parse_from(&["test", "--foo"]).unwrap()
71+
);
72+
}
73+
74+
#[test]
75+
fn test_standalone_long_ignores_afterwards_defined_custom_id() {
76+
#[derive(Parser, Debug, PartialEq)]
77+
struct Opt {
78+
#[clap(long, id = "foo")]
79+
foo_option: bool,
80+
}
81+
82+
assert_eq!(
83+
Opt { foo_option: true },
84+
Opt::try_parse_from(&["test", "--foo-option"]).unwrap()
85+
);
86+
}
87+
6088
#[test]
6189
fn test_standalone_short_generates_kebab_case() {
6290
#[derive(Parser, Debug, PartialEq)]
@@ -114,6 +142,34 @@ fn test_standalone_short_ignores_afterwards_defined_custom_name() {
114142
);
115143
}
116144

145+
#[test]
146+
fn test_standalone_short_uses_previous_defined_custom_id() {
147+
#[derive(Parser, Debug, PartialEq)]
148+
struct Opt {
149+
#[clap(id = "option", short)]
150+
foo_option: bool,
151+
}
152+
153+
assert_eq!(
154+
Opt { foo_option: true },
155+
Opt::try_parse_from(&["test", "-o"]).unwrap()
156+
);
157+
}
158+
159+
#[test]
160+
fn test_standalone_short_ignores_afterwards_defined_custom_id() {
161+
#[derive(Parser, Debug, PartialEq)]
162+
struct Opt {
163+
#[clap(short, id = "option")]
164+
foo_option: bool,
165+
}
166+
167+
assert_eq!(
168+
Opt { foo_option: true },
169+
Opt::try_parse_from(&["test", "-f"]).unwrap()
170+
);
171+
}
172+
117173
#[test]
118174
fn test_standalone_long_uses_previous_defined_casing() {
119175
#[derive(Parser, Debug, PartialEq)]

0 commit comments

Comments
 (0)