diff --git a/clap_derive/src/derives/args.rs b/clap_derive/src/derives/args.rs index ac43cb3d..19ddd9e3 100644 --- a/clap_derive/src/derives/args.rs +++ b/clap_derive/src/derives/args.rs @@ -13,8 +13,8 @@ // MIT/Apache 2.0 license. use crate::{ - attrs::{Attrs, Kind, Name, DEFAULT_CASING, DEFAULT_ENV_CASING}, dummies, + item::{Item, Kind, Name, DEFAULT_CASING, DEFAULT_ENV_CASING}, utils::{inner_type, sub_type, Sp, Ty}, }; @@ -55,7 +55,7 @@ pub fn gen_for_struct( fields: &Punctuated, attrs: &[Attribute], ) -> TokenStream { - let attrs = Attrs::from_args_struct( + let item = Item::from_args_struct( Span::call_site(), attrs, Name::Derived(struct_name.clone()), @@ -65,13 +65,13 @@ pub fn gen_for_struct( let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - let constructor = gen_constructor(fields, &attrs); - let updater = gen_updater(fields, &attrs, true); + let constructor = gen_constructor(fields, &item); + let updater = gen_updater(fields, &item, true); let raw_deprecated = raw_deprecated(); let app_var = Ident::new("__clap_app", Span::call_site()); - let augmentation = gen_augment(fields, &app_var, &attrs, false); - let augmentation_update = gen_augment(fields, &app_var, &attrs, true); + let augmentation = gen_augment(fields, &app_var, &item, false); + let augmentation_update = gen_augment(fields, &app_var, &item, true); quote! { #[allow(dead_code, unreachable_code, unused_variables, unused_braces)] @@ -138,16 +138,16 @@ pub fn gen_for_struct( pub fn gen_augment( fields: &Punctuated, app_var: &Ident, - parent_attribute: &Attrs, + parent_item: &Item, override_required: bool, ) -> TokenStream { let mut subcmds = fields.iter().filter_map(|field| { - let attrs = Attrs::from_args_field( + let item = Item::from_args_field( field, - parent_attribute.casing(), - parent_attribute.env_casing(), + parent_item.casing(), + parent_item.env_casing(), ); - let kind = attrs.kind(); + let kind = item.kind(); if let Kind::Subcommand(ty) = &*kind { let subcmd_type = match (**ty, sub_type(&field.ty)) { (Ty::Option, Some(sub_type)) => sub_type, @@ -188,12 +188,12 @@ pub fn gen_augment( } let args = fields.iter().filter_map(|field| { - let attrs = Attrs::from_args_field( + let item = Item::from_args_field( field, - parent_attribute.casing(), - parent_attribute.env_casing(), + parent_item.casing(), + parent_item.env_casing(), ); - let kind = attrs.kind(); + let kind = item.kind(); match &*kind { Kind::Subcommand(_) | Kind::Skip(_) @@ -202,8 +202,8 @@ pub fn gen_augment( Kind::Flatten => { let ty = &field.ty; 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 next_help_heading = item.next_help_heading(); + let next_display_order = item.next_display_order(); if override_required { Some(quote_spanned! { kind.span()=> let #old_heading_var = #app_var.get_next_help_heading().map(|s| clap::builder::Str::from(s.to_owned())); @@ -221,9 +221,9 @@ pub fn gen_augment( } } Kind::Arg(ty) => { - let value_parser = attrs.value_parser(&field.ty); - let action = attrs.action(&field.ty); - let value_name = attrs.value_name(); + let value_parser = item.value_parser(&field.ty); + let action = item.action(&field.ty); + let value_name = item.value_name(); let implicit_methods = match **ty { Ty::Option => { @@ -242,7 +242,7 @@ pub fn gen_augment( }, Ty::OptionVec => { - if attrs.is_positional() { + if item.is_positional() { quote_spanned! { ty.span()=> .value_name(#value_name) .num_args(1..) // action won't be sufficient for getting multiple @@ -259,7 +259,7 @@ pub fn gen_augment( } Ty::Vec => { - if attrs.is_positional() { + if item.is_positional() { quote_spanned! { ty.span()=> .value_name(#value_name) .num_args(1..) // action won't be sufficient for getting multiple @@ -276,7 +276,7 @@ pub fn gen_augment( } Ty::Other => { - let required = attrs.find_default_method().is_none() && !override_required; + let required = item.find_default_method().is_none() && !override_required; // `ArgAction::takes_values` is assuming `ArgAction::default_value` will be // set though that won't always be true but this should be good enough, // otherwise we'll report an "arg required" error when unwrapping. @@ -290,8 +290,8 @@ pub fn gen_augment( } }; - let id = attrs.id(); - let explicit_methods = attrs.field_methods(true); + let id = item.id(); + let explicit_methods = item.field_methods(true); Some(quote_spanned! { field.span()=> let #app_var = #app_var.arg({ @@ -308,8 +308,8 @@ pub fn gen_augment( } }); - let initial_app_methods = parent_attribute.initial_top_level_methods(); - let final_app_methods = parent_attribute.final_top_level_methods(); + 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; #( #args )* @@ -318,15 +318,15 @@ pub fn gen_augment( }} } -pub fn gen_constructor(fields: &Punctuated, parent_attribute: &Attrs) -> TokenStream { +pub fn gen_constructor(fields: &Punctuated, parent_item: &Item) -> TokenStream { let fields = fields.iter().map(|field| { - let attrs = Attrs::from_args_field( + let item = Item::from_args_field( field, - parent_attribute.casing(), - parent_attribute.env_casing(), + parent_item.casing(), + parent_item.env_casing(), ); let field_name = field.ident.as_ref().unwrap(); - let kind = attrs.kind(); + let kind = item.kind(); let arg_matches = format_ident!("__clap_arg_matches"); match &*kind { Kind::ExternalSubcommand => { @@ -371,7 +371,7 @@ pub fn gen_constructor(fields: &Punctuated, parent_attribute: &Att }, Kind::Arg(ty) | Kind::FromGlobal(ty) => { - gen_parsers(&attrs, ty, field_name, field, None) + gen_parsers(&item, ty, field_name, field, None) } } }); @@ -383,17 +383,17 @@ pub fn gen_constructor(fields: &Punctuated, parent_attribute: &Att pub fn gen_updater( fields: &Punctuated, - parent_attribute: &Attrs, + parent_item: &Item, use_self: bool, ) -> TokenStream { let fields = fields.iter().map(|field| { - let attrs = Attrs::from_args_field( + let item = Item::from_args_field( field, - parent_attribute.casing(), - parent_attribute.env_casing(), + parent_item.casing(), + parent_item.env_casing(), ); let field_name = field.ident.as_ref().unwrap(); - let kind = attrs.kind(); + let kind = item.kind(); let access = if use_self { quote! { @@ -452,7 +452,7 @@ pub fn gen_updater( Kind::Skip(_) => quote!(), - Kind::Arg(ty) | Kind::FromGlobal(ty) => gen_parsers(&attrs, ty, field_name, field, Some(&access)), + Kind::Arg(ty) | Kind::FromGlobal(ty) => gen_parsers(&item, ty, field_name, field, Some(&access)), } }); @@ -462,7 +462,7 @@ pub fn gen_updater( } fn gen_parsers( - attrs: &Attrs, + item: &Item, ty: &Sp, field_name: &Ident, field: &Field, @@ -470,7 +470,7 @@ fn gen_parsers( ) -> TokenStream { let span = ty.span(); let convert_type = inner_type(&field.ty); - let id = attrs.id(); + let id = item.id(); let get_one = quote_spanned!(span=> remove_one::<#convert_type>); let get_many = quote_spanned!(span=> remove_many::<#convert_type>); let deref = quote!(|s| s); diff --git a/clap_derive/src/derives/into_app.rs b/clap_derive/src/derives/into_app.rs index 817a1036..90222202 100644 --- a/clap_derive/src/derives/into_app.rs +++ b/clap_derive/src/derives/into_app.rs @@ -19,7 +19,7 @@ use quote::quote; use syn::{Attribute, Generics, Ident}; use crate::{ - attrs::{Attrs, Name, DEFAULT_CASING, DEFAULT_ENV_CASING}, + item::{Item, Name, DEFAULT_CASING, DEFAULT_ENV_CASING}, utils::Sp, }; @@ -30,14 +30,14 @@ pub fn gen_for_struct( ) -> TokenStream { let app_name = env::var("CARGO_PKG_NAME").ok().unwrap_or_default(); - let attrs = Attrs::from_args_struct( + let item = Item::from_args_struct( Span::call_site(), attrs, Name::Assigned(quote!(#app_name)), Sp::call_site(DEFAULT_CASING), Sp::call_site(DEFAULT_ENV_CASING), ); - let name = attrs.cased_name(); + let name = item.cased_name(); let app_var = Ident::new("__clap_app", Span::call_site()); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); @@ -75,14 +75,14 @@ pub fn gen_for_struct( pub fn gen_for_enum(enum_name: &Ident, generics: &Generics, attrs: &[Attribute]) -> TokenStream { let app_name = env::var("CARGO_PKG_NAME").ok().unwrap_or_default(); - let attrs = Attrs::from_subcommand_enum( + let item = Item::from_subcommand_enum( Span::call_site(), attrs, Name::Assigned(quote!(#app_name)), Sp::call_site(DEFAULT_CASING), Sp::call_site(DEFAULT_ENV_CASING), ); - let name = attrs.cased_name(); + let name = item.cased_name(); let app_var = Ident::new("__clap_app", Span::call_site()); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); diff --git a/clap_derive/src/derives/subcommand.rs b/clap_derive/src/derives/subcommand.rs index db6df143..8099043b 100644 --- a/clap_derive/src/derives/subcommand.rs +++ b/clap_derive/src/derives/subcommand.rs @@ -12,9 +12,9 @@ // 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, + item::{Item, Kind, Name, DEFAULT_CASING, DEFAULT_ENV_CASING}, utils::{is_simple_ty, subty_if_name, Sp}, }; @@ -43,7 +43,7 @@ pub fn gen_for_enum( attrs: &[Attribute], e: &DataEnum, ) -> TokenStream { - let attrs = Attrs::from_subcommand_enum( + let item = Item::from_subcommand_enum( Span::call_site(), attrs, Name::Derived(enum_name.clone()), @@ -51,12 +51,12 @@ pub fn gen_for_enum( Sp::call_site(DEFAULT_ENV_CASING), ); - let from_arg_matches = gen_from_arg_matches(enum_name, &e.variants, &attrs); - let update_from_arg_matches = gen_update_from_arg_matches(enum_name, &e.variants, &attrs); + let from_arg_matches = gen_from_arg_matches(enum_name, &e.variants, &item); + let update_from_arg_matches = gen_update_from_arg_matches(enum_name, &e.variants, &item); - 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); + let augmentation = gen_augment(&e.variants, &item, false); + let augmentation_update = gen_augment(&e.variants, &item, true); + let has_subcommand = gen_has_subcommand(&e.variants, &item); let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); @@ -116,7 +116,7 @@ pub fn gen_for_enum( fn gen_augment( variants: &Punctuated, - parent_attribute: &Attrs, + parent_item: &Item, override_required: bool, ) -> TokenStream { use syn::Fields::*; @@ -126,12 +126,12 @@ fn gen_augment( let subcommands: Vec<_> = variants .iter() .filter_map(|variant| { - let attrs = Attrs::from_subcommand_variant( + let item = Item::from_subcommand_variant( variant, - parent_attribute.casing(), - parent_attribute.env_casing(), + parent_item.casing(), + parent_item.env_casing(), ); - let kind = attrs.kind(); + let kind = item.kind(); match &*kind { Kind::Skip(_) => None, @@ -167,8 +167,8 @@ fn gen_augment( 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 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().map(|s| clap::builder::Str::from(s.to_owned())); @@ -220,9 +220,9 @@ 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 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({ let #subcommand_var = clap::Command::new(#name); @@ -242,12 +242,12 @@ fn gen_augment( 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) + args::gen_augment(&fields.named, &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; @@ -269,8 +269,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; @@ -282,7 +282,7 @@ fn gen_augment( } }; - let name = attrs.cased_name(); + let name = item.cased_name(); let subcommand = quote! { let #app_var = #app_var.subcommand({ let #subcommand_var = clap::Command::new(#name); @@ -295,8 +295,8 @@ 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 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 )*; @@ -306,7 +306,7 @@ fn gen_augment( fn gen_has_subcommand( variants: &Punctuated, - parent_attribute: &Attrs, + parent_item: &Item, ) -> TokenStream { use syn::Fields::*; @@ -315,26 +315,26 @@ fn gen_has_subcommand( let (flatten_variants, variants): (Vec<_>, Vec<_>) = variants .iter() .filter_map(|variant| { - let attrs = Attrs::from_subcommand_variant( + let item = Item::from_subcommand_variant( variant, - parent_attribute.casing(), - parent_attribute.env_casing(), + parent_item.casing(), + parent_item.env_casing(), ); - if let Kind::ExternalSubcommand = &*attrs.kind() { + if let Kind::ExternalSubcommand = &*item.kind() { ext_subcmd = true; None } else { - Some((variant, attrs)) + Some((variant, item)) } }) - .partition(|(_, attrs)| { - let kind = attrs.kind(); + .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 @@ -374,7 +374,7 @@ fn gen_has_subcommand( fn gen_from_arg_matches( name: &Ident, variants: &Punctuated, - parent_attribute: &Attrs, + parent_item: &Item, ) -> TokenStream { use syn::Fields::*; @@ -385,16 +385,16 @@ fn gen_from_arg_matches( let (flatten_variants, variants): (Vec<_>, Vec<_>) = variants .iter() .filter_map(|variant| { - let attrs = Attrs::from_subcommand_variant( + let item = Item::from_subcommand_variant( variant, - parent_attribute.casing(), - parent_attribute.env_casing(), + parent_item.casing(), + parent_item.env_casing(), ); - if let Kind::ExternalSubcommand = &*attrs.kind() { + if let Kind::ExternalSubcommand = &*item.kind() { if ext_subcmd.is_some() { abort!( - attrs.kind().span(), + item.kind().span(), "Only one variant can be marked with `external_subcommand`, \ this is the second" ); @@ -436,19 +436,19 @@ fn gen_from_arg_matches( ext_subcmd = Some((span, &variant.ident, str_ty)); None } else { - Some((variant, attrs)) + Some((variant, item)) } }) - .partition(|(_, attrs)| { - let kind = attrs.kind(); + .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) => args::gen_constructor(&fields.named, item), Unit => quote!(), Unnamed(ref fields) if fields.unnamed.len() == 1 => { let ty = &fields.unnamed[0]; @@ -527,32 +527,32 @@ fn gen_from_arg_matches( fn gen_update_from_arg_matches( name: &Ident, variants: &Punctuated, - parent_attribute: &Attrs, + parent_item: &Item, ) -> TokenStream { use syn::Fields::*; let (flatten, variants): (Vec<_>, Vec<_>) = variants .iter() .filter_map(|variant| { - let attrs = Attrs::from_subcommand_variant( + let item = Item::from_subcommand_variant( variant, - parent_attribute.casing(), - parent_attribute.env_casing(), + parent_item.casing(), + parent_item.env_casing(), ); - match &*attrs.kind() { + match &*item.kind() { // Fallback to `from_arg_matches_mut` Kind::ExternalSubcommand => None, - _ => Some((variant, attrs)), + _ => Some((variant, item)), } }) - .partition(|(_, attrs)| { - let kind = attrs.kind(); + .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) => { @@ -560,15 +560,15 @@ fn gen_update_from_arg_matches( .named .iter() .map(|field| { - let attrs = Attrs::from_args_field( + let item = Item::from_args_field( field, - parent_attribute.casing(), - parent_attribute.env_casing(), + parent_item.casing(), + parent_item.env_casing(), ); let field_name = field.ident.as_ref().unwrap(); ( quote!( ref mut #field_name ), - args::gen_updater(&fields.named, &attrs, false), + args::gen_updater(&fields.named, &item, false), ) }) .unzip(); diff --git a/clap_derive/src/derives/value_enum.rs b/clap_derive/src/derives/value_enum.rs index a63bc693..917a76e3 100644 --- a/clap_derive/src/derives/value_enum.rs +++ b/clap_derive/src/derives/value_enum.rs @@ -9,8 +9,8 @@ // except according to those terms. use crate::{ - attrs::{Attrs, Kind, Name, DEFAULT_CASING, DEFAULT_ENV_CASING}, dummies, + item::{Item, Kind, Name, DEFAULT_CASING, DEFAULT_ENV_CASING}, utils::Sp, }; @@ -35,7 +35,7 @@ pub fn derive_value_enum(input: &DeriveInput) -> TokenStream { } pub fn gen_for_enum(name: &Ident, attrs: &[Attribute], e: &DataEnum) -> TokenStream { - let attrs = Attrs::from_value_enum( + let item = Item::from_value_enum( Span::call_site(), attrs, Name::Derived(name.clone()), @@ -43,7 +43,7 @@ pub fn gen_for_enum(name: &Ident, attrs: &[Attribute], e: &DataEnum) -> TokenStr Sp::call_site(DEFAULT_ENV_CASING), ); - let lits = lits(&e.variants, &attrs); + let lits = lits(&e.variants, &item); let value_variants = gen_value_variants(&lits); let to_possible_value = gen_to_possible_value(&lits); @@ -68,26 +68,23 @@ pub fn gen_for_enum(name: &Ident, attrs: &[Attribute], e: &DataEnum) -> TokenStr } } -fn lits( - variants: &Punctuated, - parent_attribute: &Attrs, -) -> Vec<(TokenStream, Ident)> { +fn lits(variants: &Punctuated, parent_item: &Item) -> Vec<(TokenStream, Ident)> { variants .iter() .filter_map(|variant| { - let attrs = Attrs::from_value_enum_variant( + let item = Item::from_value_enum_variant( variant, - parent_attribute.casing(), - parent_attribute.env_casing(), + parent_item.casing(), + parent_item.env_casing(), ); - if let Kind::Skip(_) = &*attrs.kind() { + if let Kind::Skip(_) = &*item.kind() { None } else { if !matches!(variant.fields, Fields::Unit) { abort!(variant.span(), "`#[derive(ValueEnum)]` only supports unit variants. Non-unit variants must be skipped"); } - let fields = attrs.field_methods(false); - let name = attrs.cased_name(); + let fields = item.field_methods(false); + let name = item.cased_name(); Some(( quote_spanned! { variant.span()=> clap::builder::PossibleValue::new(#name) diff --git a/clap_derive/src/attrs.rs b/clap_derive/src/item.rs similarity index 99% rename from clap_derive/src/attrs.rs rename to clap_derive/src/item.rs index d8f69d6b..ebc83bdc 100644 --- a/clap_derive/src/attrs.rs +++ b/clap_derive/src/item.rs @@ -35,7 +35,7 @@ pub const DEFAULT_CASING: CasingStyle = CasingStyle::Kebab; pub const DEFAULT_ENV_CASING: CasingStyle = CasingStyle::ScreamingSnake; #[derive(Clone)] -pub struct Attrs { +pub struct Item { name: Name, casing: Sp, env_casing: Sp, @@ -53,7 +53,7 @@ pub struct Attrs { kind: Sp, } -impl Attrs { +impl Item { pub fn from_args_struct( span: Span, attrs: &[Attribute], diff --git a/clap_derive/src/lib.rs b/clap_derive/src/lib.rs index 3d134e98..8e33d69f 100644 --- a/clap_derive/src/lib.rs +++ b/clap_derive/src/lib.rs @@ -22,9 +22,9 @@ use proc_macro::TokenStream; use proc_macro_error::proc_macro_error; use syn::{parse_macro_input, DeriveInput}; -mod attrs; mod derives; mod dummies; +mod item; mod parse; mod utils; diff --git a/clap_derive/src/utils/doc_comments.rs b/clap_derive/src/utils/doc_comments.rs index f0a5034d..a815874c 100644 --- a/clap_derive/src/utils/doc_comments.rs +++ b/clap_derive/src/utils/doc_comments.rs @@ -3,7 +3,7 @@ //! #[derive(Parser)] works in terms of "paragraphs". Paragraph is a sequence of //! non-empty adjacent lines, delimited by sequences of blank (whitespace only) lines. -use crate::attrs::Method; +use crate::item::Method; use quote::{format_ident, quote}; use std::iter;