Skip to content

Commit 86c83d2

Browse files
authored
feat: Add default_value_os_t (#3333)
The order of suffixes allows us to preserve the original builder function name. This is a part of #2813
1 parent e5b06c3 commit 86c83d2

File tree

3 files changed

+49
-0
lines changed

3 files changed

+49
-0
lines changed

clap_derive/src/attrs.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,49 @@ impl Attrs {
489489
self.methods.push(Method::new(raw_ident, val));
490490
}
491491

492+
DefaultValueOsT(ident, expr) => {
493+
let ty = if let Some(ty) = self.ty.as_ref() {
494+
ty
495+
} else {
496+
abort!(
497+
ident,
498+
"#[clap(default_value_os_t)] (without an argument) can be used \
499+
only on field level";
500+
501+
note = "see \
502+
https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
503+
};
504+
505+
let val = if let Some(expr) = expr {
506+
quote!(#expr)
507+
} else {
508+
quote!(<#ty as ::std::default::Default>::default())
509+
};
510+
511+
let val = if parsed.iter().any(|a| matches!(a, ArgEnum(_))) {
512+
quote_spanned!(ident.span()=> {
513+
{
514+
let val: #ty = #val;
515+
clap::ArgEnum::to_possible_value(&val).unwrap().get_name()
516+
}
517+
})
518+
} else {
519+
quote_spanned!(ident.span()=> {
520+
clap::lazy_static::lazy_static! {
521+
static ref DEFAULT_VALUE: &'static ::std::ffi::OsStr = {
522+
let val: #ty = #val;
523+
let s: ::std::ffi::OsString = val.into();
524+
::std::boxed::Box::leak(s.into_boxed_os_str())
525+
};
526+
}
527+
*DEFAULT_VALUE
528+
})
529+
};
530+
531+
let raw_ident = Ident::new("default_value_os", ident.span());
532+
self.methods.push(Method::new(raw_ident, val));
533+
}
534+
492535
HelpHeading(ident, expr) => {
493536
self.help_heading = Some(Method::new(ident, quote!(#expr)));
494537
}

clap_derive/src/parse.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub enum ClapAttr {
5353
// ident = arbitrary_expr
5454
NameExpr(Ident, Expr),
5555
DefaultValueT(Ident, Option<Expr>),
56+
DefaultValueOsT(Ident, Option<Expr>),
5657
HelpHeading(Ident, Expr),
5758

5859
// ident(arbitrary_expr,*)
@@ -129,6 +130,7 @@ impl Parse for ClapAttr {
129130
Ok(expr) => match &*name_str {
130131
"skip" => Ok(Skip(name, Some(expr))),
131132
"default_value_t" => Ok(DefaultValueT(name, Some(expr))),
133+
"default_value_os_t" => Ok(DefaultValueOsT(name, Some(expr))),
132134
"help_heading" => Ok(HelpHeading(name, expr)),
133135
_ => Ok(NameExpr(name, expr)),
134136
},
@@ -203,6 +205,7 @@ impl Parse for ClapAttr {
203205
)
204206
}
205207
"default_value_t" => Ok(DefaultValueT(name, None)),
208+
"default_value_os_t" => Ok(DefaultValueOsT(name, None)),
206209
"about" => (Ok(About(name, None))),
207210
"author" => (Ok(Author(name, None))),
208211
"version" => Ok(Version(name, None)),

examples/derive_ref/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ In addition to the raw attributes, the following magic attributes are supported:
185185
- `default_value_t [= <expr>]`: `clap::Arg::default_value` and `clap::Arg::required(false)`
186186
- Requires `std::fmt::Display` or `#[clap(arg_enum)]`
187187
- Without `<expr>`, relies on `Default::default()`
188+
- `default_value_os_t [= <expr>]`: `clap::Arg::default_value_os` and `clap::Arg::required(false)`
189+
- Requires `std::convert::Into<OsString>` or `#[clap(arg_enum)]`
190+
- Without `<expr>`, relies on `Default::default()`
188191

189192
### Arg Types
190193

0 commit comments

Comments
 (0)