aboutsummaryrefslogtreecommitdiff
path: root/src/derives/subcommand.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/derives/subcommand.rs')
-rw-r--r--src/derives/subcommand.rs485
1 files changed, 241 insertions, 244 deletions
diff --git a/src/derives/subcommand.rs b/src/derives/subcommand.rs
index 07bdce5..009684b 100644
--- a/src/derives/subcommand.rs
+++ b/src/derives/subcommand.rs
@@ -11,20 +11,16 @@
// This work was derived from Structopt (https://github.com/TeXitoi/structopt)
// commit#ea76fa1b1b273e65e3b0b1046643715b49bec51f which is licensed under the
// MIT/Apache 2.0 license.
-use crate::{
- attrs::{Attrs, Kind, Name, DEFAULT_CASING, DEFAULT_ENV_CASING},
- derives::args,
- dummies,
- utils::{is_simple_ty, subty_if_name, Sp},
-};
use proc_macro2::{Ident, Span, TokenStream};
use proc_macro_error::{abort, abort_call_site};
use quote::{format_ident, quote, quote_spanned};
-use syn::{
- punctuated::Punctuated, spanned::Spanned, Attribute, Data, DataEnum, DeriveInput,
- FieldsUnnamed, Generics, Token, Variant,
-};
+use syn::{spanned::Spanned, Data, DeriveInput, FieldsUnnamed, Generics, Variant};
+
+use crate::derives::args;
+use crate::dummies;
+use crate::item::{Item, Kind, Name};
+use crate::utils::{is_simple_ty, subty_if_name};
pub fn derive_subcommand(input: &DeriveInput) -> TokenStream {
let ident = &input.ident;
@@ -32,35 +28,47 @@ pub fn derive_subcommand(input: &DeriveInput) -> TokenStream {
dummies::subcommand(ident);
match input.data {
- Data::Enum(ref e) => gen_for_enum(ident, &input.generics, &input.attrs, e),
+ Data::Enum(ref e) => {
+ let name = Name::Derived(ident.clone());
+ let item = Item::from_subcommand_enum(input, name);
+ let variants = e
+ .variants
+ .iter()
+ .map(|variant| {
+ let item =
+ Item::from_subcommand_variant(variant, item.casing(), item.env_casing());
+ (variant, item)
+ })
+ .collect::<Vec<_>>();
+ gen_for_enum(&item, ident, &input.generics, &variants)
+ }
_ => abort_call_site!("`#[derive(Subcommand)]` only supports enums"),
}
}
pub fn gen_for_enum(
- enum_name: &Ident,
+ item: &Item,
+ item_name: &Ident,
generics: &Generics,
- attrs: &[Attribute],
- e: &DataEnum,
+ variants: &[(&Variant, Item)],
) -> TokenStream {
- let from_arg_matches = gen_from_arg_matches_for_enum(enum_name, generics, attrs, e);
-
- let attrs = Attrs::from_struct(
- Span::call_site(),
- attrs,
- Name::Derived(enum_name.clone()),
- Sp::call_site(DEFAULT_CASING),
- Sp::call_site(DEFAULT_ENV_CASING),
- );
- let augmentation = gen_augment(&e.variants, &attrs, false);
- let augmentation_update = gen_augment(&e.variants, &attrs, true);
- let has_subcommand = gen_has_subcommand(&e.variants, &attrs);
+ if !matches!(&*item.kind(), Kind::Command(_)) {
+ abort! { item.kind().span(),
+ "`{}` cannot be used with `command`",
+ item.kind().name(),
+ }
+ }
let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
- quote! {
- #from_arg_matches
+ let from_arg_matches = gen_from_arg_matches(variants);
+ let update_from_arg_matches = gen_update_from_arg_matches(variants);
+
+ let augmentation = gen_augment(variants, item, false);
+ let augmentation_update = gen_augment(variants, item, true);
+ let has_subcommand = gen_has_subcommand(variants);
+ quote! {
#[allow(dead_code, unreachable_code, unused_variables, unused_braces)]
#[allow(
clippy::style,
@@ -74,40 +82,19 @@ pub fn gen_for_enum(
clippy::suspicious_else_formatting,
)]
#[deny(clippy::correctness)]
- impl #impl_generics clap::Subcommand for #enum_name #ty_generics #where_clause {
- fn augment_subcommands <'b>(__clap_app: clap::Command<'b>) -> clap::Command<'b> {
- #augmentation
- }
- fn augment_subcommands_for_update <'b>(__clap_app: clap::Command<'b>) -> clap::Command<'b> {
- #augmentation_update
- }
- fn has_subcommand(__clap_name: &str) -> bool {
- #has_subcommand
+ impl #impl_generics clap::FromArgMatches for #item_name #ty_generics #where_clause {
+ fn from_arg_matches(__clap_arg_matches: &clap::ArgMatches) -> ::std::result::Result<Self, clap::Error> {
+ Self::from_arg_matches_mut(&mut __clap_arg_matches.clone())
}
- }
- }
-}
-
-fn gen_from_arg_matches_for_enum(
- name: &Ident,
- generics: &Generics,
- attrs: &[Attribute],
- e: &DataEnum,
-) -> TokenStream {
- let attrs = Attrs::from_struct(
- Span::call_site(),
- attrs,
- Name::Derived(name.clone()),
- Sp::call_site(DEFAULT_CASING),
- Sp::call_site(DEFAULT_ENV_CASING),
- );
- let from_arg_matches = gen_from_arg_matches(name, &e.variants, &attrs);
- let update_from_arg_matches = gen_update_from_arg_matches(name, &e.variants, &attrs);
+ #from_arg_matches
- let (impl_generics, ty_generics, where_clause) = generics.split_for_impl();
+ fn update_from_arg_matches(&mut self, __clap_arg_matches: &clap::ArgMatches) -> ::std::result::Result<(), clap::Error> {
+ self.update_from_arg_matches_mut(&mut __clap_arg_matches.clone())
+ }
+ #update_from_arg_matches
+ }
- quote! {
#[allow(dead_code, unreachable_code, unused_variables, unused_braces)]
#[allow(
clippy::style,
@@ -121,24 +108,23 @@ fn gen_from_arg_matches_for_enum(
clippy::suspicious_else_formatting,
)]
#[deny(clippy::correctness)]
- impl #impl_generics clap::FromArgMatches for #name #ty_generics #where_clause {
- fn from_arg_matches(__clap_arg_matches: &clap::ArgMatches) -> ::std::result::Result<Self, clap::Error> {
- Self::from_arg_matches_mut(&mut __clap_arg_matches.clone())
+ impl #impl_generics clap::Subcommand for #item_name #ty_generics #where_clause {
+ fn augment_subcommands <'b>(__clap_app: clap::Command) -> clap::Command {
+ #augmentation
}
-
- #from_arg_matches
-
- fn update_from_arg_matches(&mut self, __clap_arg_matches: &clap::ArgMatches) -> ::std::result::Result<(), clap::Error> {
- self.update_from_arg_matches_mut(&mut __clap_arg_matches.clone())
+ fn augment_subcommands_for_update <'b>(__clap_app: clap::Command) -> clap::Command {
+ #augmentation_update
+ }
+ fn has_subcommand(__clap_name: &str) -> bool {
+ #has_subcommand
}
- #update_from_arg_matches
}
}
}
fn gen_augment(
- variants: &Punctuated<Variant, Token![,]>,
- parent_attribute: &Attrs,
+ variants: &[(&Variant, Item)],
+ parent_item: &Item,
override_required: bool,
) -> TokenStream {
use syn::Fields::*;
@@ -147,16 +133,14 @@ fn gen_augment(
let subcommands: Vec<_> = variants
.iter()
- .filter_map(|variant| {
- let attrs = Attrs::from_variant(
- variant,
- parent_attribute.casing(),
- parent_attribute.env_casing(),
- );
- let kind = attrs.kind();
+ .filter_map(|(variant, item)| {
+ let kind = item.kind();
match &*kind {
- Kind::Skip(_) => None,
+ Kind::Skip(_, _) |
+ Kind::Arg(_) |
+ Kind::FromGlobal(_) |
+ Kind::Value => None,
Kind::ExternalSubcommand => {
let ty = match variant.fields {
@@ -169,47 +153,51 @@ fn gen_augment(
or `Vec<OsString>`."
),
};
- let subcommand = match subty_if_name(ty, "Vec") {
- Some(subty) => {
- if is_simple_ty(subty, "OsString") {
- quote_spanned! { kind.span()=>
- let #app_var = #app_var.allow_external_subcommands(true).allow_invalid_utf8_for_external_subcommands(true);
- }
- } else {
- quote_spanned! { kind.span()=>
- let #app_var = #app_var.allow_external_subcommands(true);
- }
- }
- }
-
- None => abort!(
+ let deprecations = if !override_required {
+ item.deprecations()
+ } else {
+ quote!()
+ };
+ let subty = subty_if_name(ty, "Vec").unwrap_or_else(|| {
+ abort!(
ty.span(),
"The type must be `Vec<_>` \
to be used with `external_subcommand`."
- ),
+ )
+ });
+ let subcommand = quote_spanned! { kind.span()=>
+ #deprecations
+ let #app_var = #app_var
+ .external_subcommand_value_parser(clap::value_parser!(#subty));
};
Some(subcommand)
}
- Kind::Flatten => match variant.fields {
+ Kind::Flatten(_) => match variant.fields {
Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => {
let ty = &unnamed[0];
- let old_heading_var = format_ident!("__clap_old_heading");
- let next_help_heading = attrs.next_help_heading();
- let next_display_order = attrs.next_display_order();
+ let deprecations = if !override_required {
+ item.deprecations()
+ } else {
+ quote!()
+ };
+ let next_help_heading = item.next_help_heading();
+ let next_display_order = item.next_display_order();
let subcommand = if override_required {
quote! {
- let #old_heading_var = #app_var.get_next_help_heading();
- let #app_var = #app_var #next_help_heading #next_display_order;
+ #deprecations
+ let #app_var = #app_var
+ #next_help_heading
+ #next_display_order;
let #app_var = <#ty as clap::Subcommand>::augment_subcommands_for_update(#app_var);
- let #app_var = #app_var.next_help_heading(#old_heading_var);
}
} else {
quote! {
- let #old_heading_var = #app_var.get_next_help_heading();
- let #app_var = #app_var #next_help_heading #next_display_order;
+ #deprecations
+ let #app_var = #app_var
+ #next_help_heading
+ #next_display_order;
let #app_var = <#ty as clap::Subcommand>::augment_subcommands(#app_var);
- let #app_var = #app_var.next_help_heading(#old_heading_var);
}
};
Some(subcommand)
@@ -248,33 +236,48 @@ fn gen_augment(
}
};
- let name = attrs.cased_name();
- let initial_app_methods = attrs.initial_top_level_methods();
- let final_from_attrs = attrs.final_top_level_methods();
+ let name = item.cased_name();
+ let deprecations = if !override_required {
+ item.deprecations()
+ } else {
+ quote!()
+ };
+ let initial_app_methods = item.initial_top_level_methods();
+ let final_from_attrs = item.final_top_level_methods();
let subcommand = quote! {
let #app_var = #app_var.subcommand({
+ #deprecations;
let #subcommand_var = clap::Command::new(#name);
let #subcommand_var = #subcommand_var #initial_app_methods;
let #subcommand_var = #arg_block;
- #[allow(deprecated)]
- let #subcommand_var = #subcommand_var.setting(clap::AppSettings::SubcommandRequiredElseHelp);
+ let #subcommand_var = #subcommand_var
+ .subcommand_required(true)
+ .arg_required_else_help(true);
#subcommand_var #final_from_attrs
});
};
Some(subcommand)
}
- _ => {
+ Kind::Command(_) => {
let subcommand_var = Ident::new("__clap_subcommand", Span::call_site());
let sub_augment = match variant.fields {
Named(ref fields) => {
// Defer to `gen_augment` for adding cmd methods
- args::gen_augment(&fields.named, &subcommand_var, &attrs, override_required)
+ let fields = fields
+ .named
+ .iter()
+ .map(|field| {
+ let item = Item::from_args_field(field, item.casing(), item.env_casing());
+ (field, item)
+ })
+ .collect::<Vec<_>>();
+ args::gen_augment(&fields, &subcommand_var, item, override_required)
}
Unit => {
let arg_block = quote!( #subcommand_var );
- let initial_app_methods = attrs.initial_top_level_methods();
- let final_from_attrs = attrs.final_top_level_methods();
+ let initial_app_methods = item.initial_top_level_methods();
+ let final_from_attrs = item.final_top_level_methods();
quote! {
let #subcommand_var = #subcommand_var #initial_app_methods;
let #subcommand_var = #arg_block;
@@ -296,8 +299,8 @@ fn gen_augment(
}
}
};
- let initial_app_methods = attrs.initial_top_level_methods();
- let final_from_attrs = attrs.final_top_level_methods();
+ let initial_app_methods = item.initial_top_level_methods();
+ let final_from_attrs = item.final_top_level_methods();
quote! {
let #subcommand_var = #subcommand_var #initial_app_methods;
let #subcommand_var = #arg_block;
@@ -309,9 +312,15 @@ fn gen_augment(
}
};
- let name = attrs.cased_name();
+ let deprecations = if !override_required {
+ item.deprecations()
+ } else {
+ quote!()
+ };
+ let name = item.cased_name();
let subcommand = quote! {
let #app_var = #app_var.subcommand({
+ #deprecations
let #subcommand_var = clap::Command::new(#name);
#sub_augment
});
@@ -322,46 +331,47 @@ fn gen_augment(
})
.collect();
- let initial_app_methods = parent_attribute.initial_top_level_methods();
- let final_app_methods = parent_attribute.final_top_level_methods();
+ let deprecations = if !override_required {
+ parent_item.deprecations()
+ } else {
+ quote!()
+ };
+ let initial_app_methods = parent_item.initial_top_level_methods();
+ let final_app_methods = parent_item.final_top_level_methods();
quote! {
- let #app_var = #app_var #initial_app_methods;
- #( #subcommands )*;
- #app_var #final_app_methods
+ #deprecations;
+ let #app_var = #app_var #initial_app_methods;
+ #( #subcommands )*;
+ #app_var #final_app_methods
}
}
-fn gen_has_subcommand(
- variants: &Punctuated<Variant, Token![,]>,
- parent_attribute: &Attrs,
-) -> TokenStream {
+fn gen_has_subcommand(variants: &[(&Variant, Item)]) -> TokenStream {
use syn::Fields::*;
let mut ext_subcmd = false;
let (flatten_variants, variants): (Vec<_>, Vec<_>) = variants
.iter()
- .filter_map(|variant| {
- let attrs = Attrs::from_variant(
- variant,
- parent_attribute.casing(),
- parent_attribute.env_casing(),
- );
+ .filter_map(|(variant, item)| {
+ let kind = item.kind();
+ match &*kind {
+ Kind::Skip(_, _) | Kind::Arg(_) | Kind::FromGlobal(_) | Kind::Value => None,
- if let Kind::ExternalSubcommand = &*attrs.kind() {
- ext_subcmd = true;
- None
- } else {
- Some((variant, attrs))
+ Kind::ExternalSubcommand => {
+ ext_subcmd = true;
+ None
+ }
+ Kind::Flatten(_) | Kind::Subcommand(_) | Kind::Command(_) => Some((variant, item)),
}
})
- .partition(|(_, attrs)| {
- let kind = attrs.kind();
- matches!(&*kind, Kind::Flatten)
+ .partition(|(_, item)| {
+ let kind = item.kind();
+ matches!(&*kind, Kind::Flatten(_))
});
- let subcommands = variants.iter().map(|(_variant, attrs)| {
- let sub_name = attrs.cased_name();
+ let subcommands = variants.iter().map(|(_variant, item)| {
+ let sub_name = item.cased_name();
quote! {
if #sub_name == __clap_name {
return true
@@ -398,11 +408,7 @@ fn gen_has_subcommand(
}
}
-fn gen_from_arg_matches(
- name: &Ident,
- variants: &Punctuated<Variant, Token![,]>,
- parent_attribute: &Attrs,
-) -> TokenStream {
+fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream {
use syn::Fields::*;
let mut ext_subcmd = None;
@@ -411,71 +417,79 @@ fn gen_from_arg_matches(
let sub_arg_matches_var = format_ident!("__clap_arg_matches");
let (flatten_variants, variants): (Vec<_>, Vec<_>) = variants
.iter()
- .filter_map(|variant| {
- let attrs = Attrs::from_variant(
- variant,
- parent_attribute.casing(),
- parent_attribute.env_casing(),
- );
-
- if let Kind::ExternalSubcommand = &*attrs.kind() {
- if ext_subcmd.is_some() {
- abort!(
- attrs.kind().span(),
- "Only one variant can be marked with `external_subcommand`, \
+ .filter_map(|(variant, item)| {
+ let kind = item.kind();
+ match &*kind {
+ Kind::Skip(_, _) | Kind::Arg(_) | Kind::FromGlobal(_) | Kind::Value => None,
+
+ Kind::ExternalSubcommand => {
+ if ext_subcmd.is_some() {
+ abort!(
+ item.kind().span(),
+ "Only one variant can be marked with `external_subcommand`, \
this is the second"
- );
- }
+ );
+ }
- let ty = match variant.fields {
- Unnamed(ref fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty,
+ let ty = match variant.fields {
+ Unnamed(ref fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty,
- _ => abort!(
- variant,
- "The enum variant marked with `external_subcommand` must be \
+ _ => abort!(
+ variant,
+ "The enum variant marked with `external_subcommand` must be \
a single-typed tuple, and the type must be either `Vec<String>` \
or `Vec<OsString>`."
- ),
- };
-
- let (span, str_ty) = match subty_if_name(ty, "Vec") {
- Some(subty) => {
- if is_simple_ty(subty, "String") {
- (subty.span(), quote!(::std::string::String))
- } else if is_simple_ty(subty, "OsString") {
- (subty.span(), quote!(::std::ffi::OsString))
- } else {
- abort!(
- ty.span(),
- "The type must be either `Vec<String>` or `Vec<OsString>` \
+ ),
+ };
+
+ let (span, str_ty) = match subty_if_name(ty, "Vec") {
+ Some(subty) => {
+ if is_simple_ty(subty, "String") {
+ (subty.span(), quote!(::std::string::String))
+ } else if is_simple_ty(subty, "OsString") {
+ (subty.span(), quote!(::std::ffi::OsString))
+ } else {
+ abort!(
+ ty.span(),
+ "The type must be either `Vec<String>` or `Vec<OsString>` \
to be used with `external_subcommand`."
- );
+ );
+ }
}
- }
- None => abort!(
- ty.span(),
- "The type must be either `Vec<String>` or `Vec<OsString>` \
+ None => abort!(
+ ty.span(),
+ "The type must be either `Vec<String>` or `Vec<OsString>` \
to be used with `external_subcommand`."
- ),
- };
+ ),
+ };
- ext_subcmd = Some((span, &variant.ident, str_ty));
- None
- } else {
- Some((variant, attrs))
+ ext_subcmd = Some((span, &variant.ident, str_ty));
+ None
+ }
+ Kind::Flatten(_) | Kind::Subcommand(_) | Kind::Command(_) => Some((variant, item)),
}
})
- .partition(|(_, attrs)| {
- let kind = attrs.kind();
- matches!(&*kind, Kind::Flatten)
+ .partition(|(_, item)| {
+ let kind = item.kind();
+ matches!(&*kind, Kind::Flatten(_))
});
- let subcommands = variants.iter().map(|(variant, attrs)| {
- let sub_name = attrs.cased_name();
+ let subcommands = variants.iter().map(|(variant, item)| {
+ let sub_name = item.cased_name();
let variant_name = &variant.ident;
let constructor_block = match variant.fields {
- Named(ref fields) => args::gen_constructor(&fields.named, attrs),
+ Named(ref fields) => {
+ let fields = fields
+ .named
+ .iter()
+ .map(|field| {
+ let item = Item::from_args_field(field, item.casing(), item.env_casing());
+ (field, item)
+ })
+ .collect::<Vec<_>>();
+ args::gen_constructor(&fields)
+ },
Unit => quote!(),
Unnamed(ref fields) if fields.unnamed.len() == 1 => {
let ty = &fields.unnamed[0];
@@ -484,17 +498,9 @@ fn gen_from_arg_matches(
Unnamed(..) => abort_call_site!("{}: tuple enums are not supported", variant.ident),
};
- if cfg!(feature = "unstable-v4") {
- quote! {
- if #sub_name == #subcommand_name_var && !#sub_arg_matches_var.contains_id("") {
- return ::std::result::Result::Ok(#name :: #variant_name #constructor_block)
- }
- }
- } else {
- quote! {
- if #sub_name == #subcommand_name_var {
- return ::std::result::Result::Ok(#name :: #variant_name #constructor_block)
- }
+ quote! {
+ if #subcommand_name_var == #sub_name && !#sub_arg_matches_var.contains_id("") {
+ return ::std::result::Result::Ok(Self :: #variant_name #constructor_block)
}
}
});
@@ -510,7 +516,7 @@ fn gen_from_arg_matches(
.unwrap_or_default()
{
let __clap_res = <#ty as clap::FromArgMatches>::from_arg_matches_mut(__clap_arg_matches)?;
- return ::std::result::Result::Ok(#name :: #variant_name (__clap_res));
+ return ::std::result::Result::Ok(Self :: #variant_name (__clap_res));
}
}
}
@@ -523,12 +529,12 @@ fn gen_from_arg_matches(
let wildcard = match ext_subcmd {
Some((span, var_name, str_ty)) => quote_spanned! { span=>
- ::std::result::Result::Ok(#name::#var_name(
+ ::std::result::Result::Ok(Self::#var_name(
::std::iter::once(#str_ty::from(#subcommand_name_var))
.chain(
#sub_arg_matches_var
.remove_many::<#str_ty>("")
- .into_iter().flatten() // `""` isn't present, bug in `unstable-v4`
+ .unwrap()
.map(#str_ty::from)
)
.collect::<::std::vec::Vec<_>>()
@@ -536,7 +542,7 @@ fn gen_from_arg_matches(
},
None => quote! {
- ::std::result::Result::Err(clap::Error::raw(clap::ErrorKind::UnrecognizedSubcommand, format!("The subcommand '{}' wasn't recognized", #subcommand_name_var)))
+ ::std::result::Result::Err(clap::Error::raw(clap::error::ErrorKind::InvalidSubcommand, format!("The subcommand '{}' wasn't recognized", #subcommand_name_var)))
},
};
@@ -553,61 +559,52 @@ fn gen_from_arg_matches(
#wildcard
} else {
- ::std::result::Result::Err(clap::Error::raw(clap::ErrorKind::MissingSubcommand, "A subcommand is required but one was not provided."))
+ ::std::result::Result::Err(clap::Error::raw(clap::error::ErrorKind::MissingSubcommand, "A subcommand is required but one was not provided."))
}
}
}
}
-fn gen_update_from_arg_matches(
- name: &Ident,
- variants: &Punctuated<Variant, Token![,]>,
- parent_attribute: &Attrs,
-) -> TokenStream {
+fn gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream {
use syn::Fields::*;
let (flatten, variants): (Vec<_>, Vec<_>) = variants
.iter()
- .filter_map(|variant| {
- let attrs = Attrs::from_variant(
- variant,
- parent_attribute.casing(),
- parent_attribute.env_casing(),
- );
-
- match &*attrs.kind() {
+ .filter_map(|(variant, item)| {
+ let kind = item.kind();
+ match &*kind {
// Fallback to `from_arg_matches_mut`
- Kind::ExternalSubcommand => None,
- _ => Some((variant, attrs)),
+ Kind::Skip(_, _)
+ | Kind::Arg(_)
+ | Kind::FromGlobal(_)
+ | Kind::Value
+ | Kind::ExternalSubcommand => None,
+ Kind::Flatten(_) | Kind::Subcommand(_) | Kind::Command(_) => Some((variant, item)),
}
})
- .partition(|(_, attrs)| {
- let kind = attrs.kind();
- matches!(&*kind, Kind::Flatten)
+ .partition(|(_, item)| {
+ let kind = item.kind();
+ matches!(&*kind, Kind::Flatten(_))
});
- let subcommands = variants.iter().map(|(variant, attrs)| {
- let sub_name = attrs.cased_name();
+ let subcommands = variants.iter().map(|(variant, item)| {
+ let sub_name = item.cased_name();
let variant_name = &variant.ident;
let (pattern, updater) = match variant.fields {
Named(ref fields) => {
- let (fields, update): (Vec<_>, Vec<_>) = fields
+ let field_names = fields.named.iter().map(|field| {
+ field.ident.as_ref().unwrap()
+ }).collect::<Vec<_>>();
+ let fields = fields
.named
.iter()
.map(|field| {
- let attrs = Attrs::from_field(
- field,
- parent_attribute.casing(),
- parent_attribute.env_casing(),
- );
- let field_name = field.ident.as_ref().unwrap();
- (
- quote!( ref mut #field_name ),
- args::gen_updater(&fields.named, &attrs, false),
- )
+ let item = Item::from_args_field(field, item.casing(), item.env_casing());
+ (field, item)
})
- .unzip();
- (quote!( { #( #fields, )* }), quote!( { #( #update )* } ))
+ .collect::<Vec<_>>();
+ let update = args::gen_updater(&fields, false);
+ (quote!( { #( #field_names, )* }), quote!( { #update } ))
}
Unit => (quote!(), quote!({})),
Unnamed(ref fields) => {
@@ -626,7 +623,7 @@ fn gen_update_from_arg_matches(
};
quote! {
- #name :: #variant_name #pattern if #sub_name == __clap_name => {
+ Self :: #variant_name #pattern if #sub_name == __clap_name => {
let (_, mut __clap_arg_sub_matches) = __clap_arg_matches.remove_subcommand().unwrap();
let __clap_arg_matches = &mut __clap_arg_sub_matches;
#updater
@@ -641,7 +638,7 @@ fn gen_update_from_arg_matches(
let ty = &fields.unnamed[0];
quote! {
if <#ty as clap::Subcommand>::has_subcommand(__clap_name) {
- if let #name :: #variant_name (child) = s {
+ if let Self :: #variant_name (child) = s {
<#ty as clap::FromArgMatches>::update_from_arg_matches_mut(child, __clap_arg_matches)?;
return ::std::result::Result::Ok(());
}