Skip to content

Commit 132b5dd

Browse files
authored
Merge pull request #5425 from epage/lit
fix(derive): Re-allow expressions for id's
2 parents 024089b + df915fe commit 132b5dd

File tree

3 files changed

+58
-27
lines changed

3 files changed

+58
-27
lines changed

clap_derive/src/derives/args.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -717,9 +717,21 @@ fn gen_parsers(
717717
},
718718

719719
Ty::Other => {
720-
quote_spanned! { ty.span()=>
721-
#arg_matches.#get_one(#id)
722-
.ok_or_else(|| clap::Error::raw(clap::error::ErrorKind::MissingRequiredArgument, concat!("The following required argument was not provided: ", #id)))?
720+
// Prefer `concat` where possible for reduced code size but fallback to `format!` to
721+
// allow non-literal `id`s
722+
match id {
723+
Name::Assigned(_) => {
724+
quote_spanned! { ty.span()=>
725+
#arg_matches.#get_one(#id)
726+
.ok_or_else(|| clap::Error::raw(clap::error::ErrorKind::MissingRequiredArgument, format!("The following required argument was not provided: {}", #id)))?
727+
}
728+
}
729+
Name::Derived(_) => {
730+
quote_spanned! { ty.span()=>
731+
#arg_matches.#get_one(#id)
732+
.ok_or_else(|| clap::Error::raw(clap::error::ErrorKind::MissingRequiredArgument, concat!("The following required argument was not provided: ", #id)))?
733+
}
734+
}
723735
}
724736
}
725737
};

clap_derive/src/item.rs

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -974,8 +974,8 @@ impl Item {
974974
quote!( #(#doc_comment)* #(#methods)* )
975975
}
976976

977-
pub fn group_id(&self) -> TokenStream {
978-
self.group_id.clone().raw()
977+
pub fn group_id(&self) -> &Name {
978+
&self.group_id
979979
}
980980

981981
pub fn group_methods(&self) -> TokenStream {
@@ -998,8 +998,8 @@ impl Item {
998998
quote!( #(#next_help_heading)* )
999999
}
10001000

1001-
pub fn id(&self) -> TokenStream {
1002-
self.name.clone().raw()
1001+
pub fn id(&self) -> &Name {
1002+
&self.name
10031003
}
10041004

10051005
pub fn cased_name(&self) -> TokenStream {
@@ -1410,16 +1410,6 @@ pub enum Name {
14101410
}
14111411

14121412
impl Name {
1413-
pub fn raw(self) -> TokenStream {
1414-
match self {
1415-
Name::Assigned(tokens) => tokens,
1416-
Name::Derived(ident) => {
1417-
let s = ident.unraw().to_string();
1418-
quote_spanned!(ident.span()=> #s)
1419-
}
1420-
}
1421-
}
1422-
14231413
pub fn translate(self, style: CasingStyle) -> TokenStream {
14241414
use CasingStyle::*;
14251415

@@ -1466,3 +1456,15 @@ impl Name {
14661456
}
14671457
}
14681458
}
1459+
1460+
impl ToTokens for Name {
1461+
fn to_tokens(&self, tokens: &mut TokenStream) {
1462+
match self {
1463+
Name::Assigned(t) => t.to_tokens(tokens),
1464+
Name::Derived(ident) => {
1465+
let s = ident.unraw().to_string();
1466+
quote_spanned!(ident.span()=> #s).to_tokens(tokens)
1467+
}
1468+
}
1469+
}
1470+
}

tests/derive/non_literal_attributes.rs

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,19 +125,19 @@ fn test_bool() {
125125
assert_eq!(result.unwrap_err().kind(), ErrorKind::NoEquals);
126126
}
127127

128-
fn parse_hex(input: &str) -> Result<u64, ParseIntError> {
129-
u64::from_str_radix(input, 16)
130-
}
131-
132-
#[derive(Parser, PartialEq, Debug)]
133-
struct HexOpt {
134-
#[arg(short, value_parser = parse_hex)]
135-
number: u64,
136-
}
137-
138128
#[test]
139129
#[cfg(feature = "error-context")]
140130
fn test_parse_hex_function_path() {
131+
#[derive(Parser, PartialEq, Debug)]
132+
struct HexOpt {
133+
#[arg(short, value_parser = parse_hex)]
134+
number: u64,
135+
}
136+
137+
fn parse_hex(input: &str) -> Result<u64, ParseIntError> {
138+
u64::from_str_radix(input, 16)
139+
}
140+
141141
assert_eq!(
142142
HexOpt { number: 5 },
143143
HexOpt::try_parse_from(["test", "-n", "5"]).unwrap()
@@ -156,3 +156,20 @@ fn test_parse_hex_function_path() {
156156
err
157157
);
158158
}
159+
160+
#[test]
161+
#[cfg(feature = "error-context")]
162+
fn test_const_name() {
163+
#[derive(Parser, PartialEq, Debug)]
164+
struct Opt {
165+
#[arg(id = NAME, short, long)]
166+
number: u64,
167+
}
168+
169+
const NAME: &str = "fun";
170+
171+
assert_eq!(
172+
Opt { number: 5 },
173+
Opt::try_parse_from(["test", "-f", "5"]).unwrap()
174+
);
175+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy