Skip to content

Commit

Permalink
chore: Dedup clap derive get fields
Browse files Browse the repository at this point in the history
  • Loading branch information
nyurik committed May 4, 2023
1 parent 3e6a77a commit 003b453
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 42 deletions.
25 changes: 16 additions & 9 deletions clap_derive/src/derives/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use proc_macro2::{Ident, Span, TokenStream};
use quote::{format_ident, quote, quote_spanned};
use syn::{
punctuated::Punctuated, spanned::Spanned, token::Comma, Data, DataStruct, DeriveInput, Field,
Fields, Generics,
Fields, FieldsNamed, Generics,
};

use crate::item::{Item, Kind, Name};
Expand All @@ -32,14 +32,7 @@ pub fn derive_args(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
}) => {
let name = Name::Derived(ident.clone());
let item = Item::from_args_struct(input, name)?;
let fields = fields
.named
.iter()
.map(|field| {
let item = Item::from_args_field(field, item.casing(), item.env_casing())?;
Ok((field, item))
})
.collect::<Result<Vec<_>, syn::Error>>()?;
let fields = collect_args_fields(&item, fields)?;
gen_for_struct(&item, ident, &input.generics, &fields)
}
Data::Struct(DataStruct {
Expand Down Expand Up @@ -740,3 +733,17 @@ pub fn raw_deprecated() -> TokenStream {

}
}

pub fn collect_args_fields<'a>(
item: &'a Item,
fields: &'a FieldsNamed,
) -> Result<Vec<(&'a Field, Item)>, syn::Error> {
fields
.named
.iter()
.map(|field| {
let item = Item::from_args_field(field, item.casing(), item.env_casing())?;
Ok((field, item))
})
.collect()
}
10 changes: 2 additions & 8 deletions clap_derive/src/derives/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use syn::{
Generics,
};

use crate::derives::args::collect_args_fields;
use crate::derives::{args, into_app, subcommand};
use crate::item::Item;
use crate::item::Name;
Expand All @@ -36,14 +37,7 @@ pub fn derive_parser(input: &DeriveInput) -> Result<TokenStream, syn::Error> {
}) => {
let name = Name::Assigned(quote!(#pkg_name));
let item = Item::from_args_struct(input, name)?;
let fields = fields
.named
.iter()
.map(|field| {
let item = Item::from_args_field(field, item.casing(), item.env_casing())?;
Ok((field, item))
})
.collect::<Result<Vec<_>, syn::Error>>()?;
let fields = collect_args_fields(&item, fields)?;
gen_for_struct(&item, ident, &input.generics, &fields)
}
Data::Struct(DataStruct {
Expand Down
29 changes: 4 additions & 25 deletions clap_derive/src/derives/subcommand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use quote::{format_ident, quote, quote_spanned};
use syn::{spanned::Spanned, Data, DeriveInput, FieldsUnnamed, Generics, Variant};

use crate::derives::args;
use crate::derives::args::collect_args_fields;
use crate::item::{Item, Kind, Name};
use crate::utils::{is_simple_ty, subty_if_name};

Expand Down Expand Up @@ -264,15 +265,7 @@ fn gen_augment(
let sub_augment = match variant.fields {
Named(ref fields) => {
// Defer to `gen_augment` for adding cmd methods
let fields = fields
.named
.iter()
.map(|field| {
let item =
Item::from_args_field(field, item.casing(), item.env_casing())?;
Ok((field, item))
})
.collect::<Result<Vec<_>, syn::Error>>()?;
let fields = collect_args_fields(item, fields)?;
args::gen_augment(&fields, &subcommand_var, item, override_required)?
}
Unit => {
Expand Down Expand Up @@ -484,14 +477,7 @@ fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> Result<TokenStream, sy
let variant_name = &variant.ident;
let constructor_block = match variant.fields {
Named(ref fields) => {
let fields = fields
.named
.iter()
.map(|field| {
let item = Item::from_args_field(field, item.casing(), item.env_casing())?;
Ok((field, item))
})
.collect::<Result<Vec<_>, syn::Error>>()?;
let fields = collect_args_fields(item, fields)?;
args::gen_constructor(&fields)?
},
Unit => quote!(),
Expand Down Expand Up @@ -599,14 +585,7 @@ fn gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> Result<TokenStr
let field_names = fields.named.iter().map(|field| {
field.ident.as_ref().unwrap()
}).collect::<Vec<_>>();
let fields = fields
.named
.iter()
.map(|field| {
let item = Item::from_args_field(field, item.casing(), item.env_casing())?;
Ok((field, item))
})
.collect::<Result<Vec<_>, syn::Error>>()?;
let fields = collect_args_fields(item, fields)?;
let update = args::gen_updater(&fields, false)?;
(quote!( { #( #field_names, )* }), quote!( { #update } ))
}
Expand Down

0 comments on commit 003b453

Please sign in to comment.