Skip to content

Commit

Permalink
Merge pull request #3188 from epage/default
Browse files Browse the repository at this point in the history
feat(derive): Don't require Display for default ArgEnum
  • Loading branch information
epage committed Dec 16, 2021
2 parents 74d1c08 + 8924dd7 commit b9a9a80
Show file tree
Hide file tree
Showing 7 changed files with 29 additions and 23 deletions.
31 changes: 21 additions & 10 deletions clap_derive/src/attrs.rs
Expand Up @@ -399,7 +399,9 @@ impl Attrs {
fn push_attrs(&mut self, attrs: &[Attribute]) {
use ClapAttr::*;

for attr in parse_clap_attributes(attrs) {
let parsed = parse_clap_attributes(attrs);
for attr in &parsed {
let attr = attr.clone();
match attr {
Short(ident) => {
self.push_method(ident, self.name.clone().translate_char(*self.casing));
Expand Down Expand Up @@ -463,16 +465,25 @@ impl Attrs {
quote!(<#ty as ::std::default::Default>::default())
};

let val = quote_spanned!(ident.span()=> {
clap::lazy_static::lazy_static! {
static ref DEFAULT_VALUE: &'static str = {
let val = if parsed.iter().any(|a| matches!(a, ArgEnum(_))) {
quote_spanned!(ident.span()=> {
{
let val: #ty = #val;
let s = ::std::string::ToString::to_string(&val);
::std::boxed::Box::leak(s.into_boxed_str())
};
}
*DEFAULT_VALUE
});
val.to_possible_value().unwrap().get_name()
}
})
} else {
quote_spanned!(ident.span()=> {
clap::lazy_static::lazy_static! {
static ref DEFAULT_VALUE: &'static str = {
let val: #ty = #val;
let s = ::std::string::ToString::to_string(&val);
::std::boxed::Box::leak(s.into_boxed_str())
};
}
*DEFAULT_VALUE
})
};

let raw_ident = Ident::new("default_value", ident.span());
self.methods.push(Method::new(raw_ident, val));
Expand Down
2 changes: 1 addition & 1 deletion clap_derive/src/derives/arg_enum.rs
Expand Up @@ -51,7 +51,7 @@ pub fn gen_for_enum(name: &Ident, attrs: &[Attribute], e: &DataEnum) -> TokenStr
let to_possible_value = gen_to_possible_value(&lits);

quote! {
#[allow(dead_code, unreachable_code, unused_variables)]
#[allow(dead_code, unreachable_code, unused_variables, unused_braces)]
#[allow(
clippy::style,
clippy::complexity,
Expand Down
2 changes: 1 addition & 1 deletion clap_derive/src/derives/args.rs
Expand Up @@ -73,7 +73,7 @@ pub fn gen_for_struct(
quote! {
#from_arg_matches

#[allow(dead_code, unreachable_code, unused_variables)]
#[allow(dead_code, unreachable_code, unused_variables, unused_braces)]
#[allow(
clippy::style,
clippy::complexity,
Expand Down
1 change: 1 addition & 0 deletions clap_derive/src/parse.rs
Expand Up @@ -21,6 +21,7 @@ pub fn parse_clap_attributes(all_attrs: &[Attribute]) -> Vec<ClapAttr> {
}

#[allow(clippy::large_enum_variant)]
#[derive(Clone)]
pub enum ClapAttr {
// single-identifier attributes
Short(Ident),
Expand Down
2 changes: 1 addition & 1 deletion examples/derive_ref/README.md
Expand Up @@ -174,7 +174,7 @@ In addition to the raw attributes, the following magic attributes are supported:
- Without `<expr>`: fills the field with `Default::default()`
- `default_value = <str>`: `clap::Arg::default_value` and `clap::Arg::required(false)`
- `default_value_t [= <expr>]`: `clap::Arg::default_value` and `clap::Arg::required(false)`
- Requires `std::fmt::Display`
- Requires `std::fmt::Display` or `#[clap(arg_enum)]`
- Without `<expr>`, relies on `Default::default()`

### Arg Types
Expand Down
8 changes: 4 additions & 4 deletions src/build/arg/possible_value.rs
Expand Up @@ -134,13 +134,13 @@ impl<'help> PossibleValue<'help> {
impl<'help> PossibleValue<'help> {
/// Get the name of the argument value
#[inline]
pub fn get_name(&self) -> &str {
pub fn get_name(&self) -> &'help str {
self.name
}

/// Get the help specified for this argument, if any
#[inline]
pub fn get_help(&self) -> Option<&str> {
pub fn get_help(&self) -> Option<&'help str> {
self.help
}

Expand All @@ -151,7 +151,7 @@ impl<'help> PossibleValue<'help> {
}

/// Get the name if argument value is not hidden, `None` otherwise
pub fn get_visible_name(&self) -> Option<&str> {
pub fn get_visible_name(&self) -> Option<&'help str> {
if self.hide {
None
} else {
Expand All @@ -162,7 +162,7 @@ impl<'help> PossibleValue<'help> {
/// Returns all valid values of the argument value.
///
/// Namely the name and all aliases.
pub fn get_name_and_aliases(&self) -> impl Iterator<Item = &str> {
pub fn get_name_and_aliases(&self) -> impl Iterator<Item = &'help str> + '_ {
iter::once(&self.name).chain(&self.aliases).copied()
}

Expand Down
6 changes: 0 additions & 6 deletions tests/derive/arg_enum.rs
Expand Up @@ -52,12 +52,6 @@ fn default_value() {
}
}

impl std::fmt::Display for ArgChoice {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
std::fmt::Display::fmt(self.to_possible_value().unwrap().get_name(), f)
}
}

#[derive(Parser, PartialEq, Debug)]
struct Opt {
#[clap(arg_enum, default_value_t)]
Expand Down

0 comments on commit b9a9a80

Please sign in to comment.