From 1376c5a617be5c25655d0d7cb63e3beaa5a6e026 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:20:39 +0200 Subject: Merging upstream version 1.70.0+dfsg1. Signed-off-by: Daniel Baumann --- vendor/clap_derive/src/derives/args.rs | 119 +++--- vendor/clap_derive/src/derives/into_app.rs | 22 +- vendor/clap_derive/src/derives/parser.rs | 54 ++- vendor/clap_derive/src/derives/subcommand.rs | 554 +++++++++++++-------------- vendor/clap_derive/src/derives/value_enum.rs | 83 ++-- 5 files changed, 415 insertions(+), 417 deletions(-) (limited to 'vendor/clap_derive/src/derives') diff --git a/vendor/clap_derive/src/derives/args.rs b/vendor/clap_derive/src/derives/args.rs index b5d51bfca..e8611b6bd 100644 --- a/vendor/clap_derive/src/derives/args.rs +++ b/vendor/clap_derive/src/derives/args.rs @@ -13,38 +13,33 @@ // MIT/Apache 2.0 license. use proc_macro2::{Ident, Span, TokenStream}; -use proc_macro_error::{abort, abort_call_site}; use quote::{format_ident, quote, quote_spanned}; -use syn::ext::IdentExt; use syn::{ punctuated::Punctuated, spanned::Spanned, token::Comma, Data, DataStruct, DeriveInput, Field, Fields, Generics, }; -use crate::dummies; use crate::item::{Item, Kind, Name}; use crate::utils::{inner_type, sub_type, Sp, Ty}; -pub fn derive_args(input: &DeriveInput) -> TokenStream { +pub fn derive_args(input: &DeriveInput) -> Result { let ident = &input.ident; - dummies::args(ident); - match input.data { Data::Struct(DataStruct { fields: Fields::Named(ref fields), .. }) => { let name = Name::Derived(ident.clone()); - let item = Item::from_args_struct(input, 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()); - (field, item) + let item = Item::from_args_field(field, item.casing(), item.env_casing())?; + Ok((field, item)) }) - .collect::>(); + .collect::, syn::Error>>()?; gen_for_struct(&item, ident, &input.generics, &fields) } Data::Struct(DataStruct { @@ -52,15 +47,15 @@ pub fn derive_args(input: &DeriveInput) -> TokenStream { .. }) => { let name = Name::Derived(ident.clone()); - let item = Item::from_args_struct(input, name); + let item = Item::from_args_struct(input, name)?; let fields = Punctuated::::new(); let fields = fields .iter() .map(|field| { - let item = Item::from_args_field(field, item.casing(), item.env_casing()); - (field, item) + let item = Item::from_args_field(field, item.casing(), item.env_casing())?; + Ok((field, item)) }) - .collect::>(); + .collect::, syn::Error>>()?; gen_for_struct(&item, ident, &input.generics, &fields) } _ => abort_call_site!("`#[derive(Args)]` only supports non-tuple structs"), @@ -72,7 +67,7 @@ pub fn gen_for_struct( item_name: &Ident, generics: &Generics, fields: &[(&Field, Item)], -) -> TokenStream { +) -> Result { if !matches!(&*item.kind(), Kind::Command(_)) { abort! { item.kind().span(), "`{}` cannot be used with `command`", @@ -82,22 +77,22 @@ pub fn gen_for_struct( let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - let constructor = gen_constructor(fields); - let updater = gen_updater(fields, true); + let constructor = gen_constructor(fields)?; + let updater = gen_updater(fields, true)?; let raw_deprecated = raw_deprecated(); let app_var = Ident::new("__clap_app", Span::call_site()); - let augmentation = gen_augment(fields, &app_var, item, false); - let augmentation_update = gen_augment(fields, &app_var, item, true); + let augmentation = gen_augment(fields, &app_var, item, false)?; + let augmentation_update = gen_augment(fields, &app_var, item, true)?; let group_id = if item.skip_group() { quote!(None) } else { - let group_id = item.ident().unraw().to_string(); + let group_id = item.group_id(); quote!(Some(clap::Id::from(#group_id))) }; - quote! { + Ok(quote! { #[allow(dead_code, unreachable_code, unused_variables, unused_braces)] #[allow( clippy::style, @@ -109,8 +104,8 @@ pub fn gen_for_struct( clippy::nursery, clippy::cargo, clippy::suspicious_else_formatting, + clippy::almost_swapped, )] - #[deny(clippy::correctness)] 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::from_arg_matches_mut(&mut __clap_arg_matches.clone()) @@ -144,8 +139,8 @@ pub fn gen_for_struct( clippy::nursery, clippy::cargo, clippy::suspicious_else_formatting, + clippy::almost_swapped, )] - #[deny(clippy::correctness)] impl #impl_generics clap::Args for #item_name #ty_generics #where_clause { fn group_id() -> Option { #group_id @@ -157,7 +152,7 @@ pub fn gen_for_struct( #augmentation_update } } - } + }) } /// Generate a block of code to add arguments/subcommands corresponding to @@ -167,11 +162,12 @@ pub fn gen_augment( app_var: &Ident, parent_item: &Item, override_required: bool, -) -> TokenStream { +) -> Result { let mut subcommand_specified = false; - let args = fields.iter().filter_map(|(field, item)| { + let mut args = Vec::new(); + for (field, item) in fields { let kind = item.kind(); - match &*kind { + let genned = match &*kind { Kind::Command(_) | Kind::Value | Kind::Skip(_, _) @@ -179,7 +175,10 @@ pub fn gen_augment( | Kind::ExternalSubcommand => None, Kind::Subcommand(ty) => { if subcommand_specified { - abort!(field.span(), "`#[command(subcommand)]` can only be used once per container"); + abort!( + field.span(), + "`#[command(subcommand)]` can only be used once per container" + ); } subcommand_specified = true; @@ -354,8 +353,9 @@ pub fn gen_augment( }); }) } - } - }); + }; + args.push(genned); + } let deprecations = if !override_required { parent_item.deprecations() @@ -367,7 +367,7 @@ pub fn gen_augment( let group_app_methods = if parent_item.skip_group() { quote!() } else { - let group_id = parent_item.ident().unraw().to_string(); + let group_id = parent_item.group_id(); let literal_group_members = fields .iter() .filter_map(|(_field, item)| { @@ -400,15 +400,18 @@ pub fn gen_augment( }}; } + let group_methods = parent_item.group_methods(); + quote!( .group( clap::ArgGroup::new(#group_id) .multiple(true) + #group_methods .args(#literal_group_members) ) ) }; - quote! {{ + Ok(quote! {{ #deprecations let #app_var = #app_var #initial_app_methods @@ -416,15 +419,15 @@ pub fn gen_augment( ; #( #args )* #app_var #final_app_methods - }} + }}) } -pub fn gen_constructor(fields: &[(&Field, Item)]) -> TokenStream { +pub fn gen_constructor(fields: &[(&Field, Item)]) -> Result { let fields = fields.iter().map(|(field, item)| { let field_name = field.ident.as_ref().unwrap(); let kind = item.kind(); let arg_matches = format_ident!("__clap_arg_matches"); - match &*kind { + let genned = match &*kind { Kind::Command(_) | Kind::Value | Kind::ExternalSubcommand => { @@ -519,18 +522,20 @@ pub fn gen_constructor(fields: &[(&Field, Item)]) -> TokenStream { }, Kind::Arg(ty) | Kind::FromGlobal(ty) => { - gen_parsers(item, ty, field_name, field, None) + gen_parsers(item, ty, field_name, field, None)? } - } - }); + }; + Ok(genned) + }).collect::, syn::Error>>()?; - quote! {{ + Ok(quote! {{ #( #fields ),* - }} + }}) } -pub fn gen_updater(fields: &[(&Field, Item)], use_self: bool) -> TokenStream { - let fields = fields.iter().map(|(field, item)| { +pub fn gen_updater(fields: &[(&Field, Item)], use_self: bool) -> Result { + let mut genned_fields = Vec::new(); + for (field, item) in fields { let field_name = field.ident.as_ref().unwrap(); let kind = item.kind(); @@ -544,10 +549,8 @@ pub fn gen_updater(fields: &[(&Field, Item)], use_self: bool) -> TokenStream { }; let arg_matches = format_ident!("__clap_arg_matches"); - match &*kind { - Kind::Command(_) - | Kind::Value - | Kind::ExternalSubcommand => { + let genned = match &*kind { + Kind::Command(_) | Kind::Value | Kind::ExternalSubcommand => { abort! { kind.span(), "`{}` cannot be used with `arg`", kind.name(), @@ -617,17 +620,20 @@ pub fn gen_updater(fields: &[(&Field, Item)], use_self: bool) -> TokenStream { #updater } } - }, + } Kind::Skip(_, _) => quote!(), - Kind::Arg(ty) | Kind::FromGlobal(ty) => gen_parsers(item, ty, field_name, field, Some(&access)), - } - }); - - quote! { - #( #fields )* + Kind::Arg(ty) | Kind::FromGlobal(ty) => { + gen_parsers(item, ty, field_name, field, Some(&access))? + } + }; + genned_fields.push(genned); } + + Ok(quote! { + #( #genned_fields )* + }) } fn gen_parsers( @@ -636,7 +642,7 @@ fn gen_parsers( field_name: &Ident, field: &Field, update: Option<&TokenStream>, -) -> TokenStream { +) -> Result { let span = ty.span(); let convert_type = inner_type(&field.ty); let id = item.id(); @@ -709,7 +715,7 @@ fn gen_parsers( } }; - if let Some(access) = update { + let genned = if let Some(access) = update { quote_spanned! { field.span()=> if #arg_matches.contains_id(#id) { #access @@ -718,7 +724,8 @@ fn gen_parsers( } } else { quote_spanned!(field.span()=> #field_name: #field_value ) - } + }; + Ok(genned) } #[cfg(feature = "raw-deprecated")] diff --git a/vendor/clap_derive/src/derives/into_app.rs b/vendor/clap_derive/src/derives/into_app.rs index a45667ab2..72f081fd8 100644 --- a/vendor/clap_derive/src/derives/into_app.rs +++ b/vendor/clap_derive/src/derives/into_app.rs @@ -18,7 +18,11 @@ use syn::{Generics, Ident}; use crate::item::Item; -pub fn gen_for_struct(item: &Item, item_name: &Ident, generics: &Generics) -> TokenStream { +pub fn gen_for_struct( + item: &Item, + item_name: &Ident, + generics: &Generics, +) -> Result { let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let name = item.cased_name(); @@ -36,8 +40,8 @@ pub fn gen_for_struct(item: &Item, item_name: &Ident, generics: &Generics) -> To clippy::nursery, clippy::cargo, clippy::suspicious_else_formatting, + clippy::almost_swapped, )] - #[deny(clippy::correctness)] impl #impl_generics clap::CommandFactory for #item_name #ty_generics #where_clause { fn command<'b>() -> clap::Command { let #app_var = clap::Command::new(#name); @@ -51,16 +55,20 @@ pub fn gen_for_struct(item: &Item, item_name: &Ident, generics: &Generics) -> To } }; - tokens + Ok(tokens) } -pub fn gen_for_enum(item: &Item, item_name: &Ident, generics: &Generics) -> TokenStream { +pub fn gen_for_enum( + item: &Item, + item_name: &Ident, + generics: &Generics, +) -> Result { let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); let name = item.cased_name(); let app_var = Ident::new("__clap_app", Span::call_site()); - quote! { + Ok(quote! { #[allow(dead_code, unreachable_code, unused_variables, unused_braces)] #[allow( clippy::style, @@ -72,8 +80,8 @@ pub fn gen_for_enum(item: &Item, item_name: &Ident, generics: &Generics) -> Toke clippy::nursery, clippy::cargo, clippy::suspicious_else_formatting, + clippy::almost_swapped, )] - #[deny(clippy::correctness)] impl #impl_generics clap::CommandFactory for #item_name #ty_generics #where_clause { fn command<'b>() -> clap::Command { let #app_var = clap::Command::new(#name) @@ -89,5 +97,5 @@ pub fn gen_for_enum(item: &Item, item_name: &Ident, generics: &Generics) -> Toke .arg_required_else_help(false) } } - } + }) } diff --git a/vendor/clap_derive/src/derives/parser.rs b/vendor/clap_derive/src/derives/parser.rs index 617857cac..39b0b8a77 100644 --- a/vendor/clap_derive/src/derives/parser.rs +++ b/vendor/clap_derive/src/derives/parser.rs @@ -13,7 +13,6 @@ // MIT/Apache 2.0 license. use proc_macro2::TokenStream; -use proc_macro_error::abort_call_site; use quote::quote; use syn::Ident; use syn::Variant; @@ -23,11 +22,10 @@ use syn::{ }; use crate::derives::{args, into_app, subcommand}; -use crate::dummies; use crate::item::Item; use crate::item::Name; -pub fn derive_parser(input: &DeriveInput) -> TokenStream { +pub fn derive_parser(input: &DeriveInput) -> Result { let ident = &input.ident; let pkg_name = std::env::var("CARGO_PKG_NAME").ok().unwrap_or_default(); @@ -36,52 +34,46 @@ pub fn derive_parser(input: &DeriveInput) -> TokenStream { fields: Fields::Named(ref fields), .. }) => { - dummies::parser_struct(ident); - let name = Name::Assigned(quote!(#pkg_name)); - let item = Item::from_args_struct(input, 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()); - (field, item) + let item = Item::from_args_field(field, item.casing(), item.env_casing())?; + Ok((field, item)) }) - .collect::>(); + .collect::, syn::Error>>()?; gen_for_struct(&item, ident, &input.generics, &fields) } Data::Struct(DataStruct { fields: Fields::Unit, .. }) => { - dummies::parser_struct(ident); - let name = Name::Assigned(quote!(#pkg_name)); - let item = Item::from_args_struct(input, name); + let item = Item::from_args_struct(input, name)?; let fields = Punctuated::::new(); let fields = fields .iter() .map(|field| { - let item = Item::from_args_field(field, item.casing(), item.env_casing()); - (field, item) + let item = Item::from_args_field(field, item.casing(), item.env_casing())?; + Ok((field, item)) }) - .collect::>(); + .collect::, syn::Error>>()?; gen_for_struct(&item, ident, &input.generics, &fields) } Data::Enum(ref e) => { - dummies::parser_enum(ident); - let name = Name::Assigned(quote!(#pkg_name)); - let item = Item::from_subcommand_enum(input, name); + 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) + Item::from_subcommand_variant(variant, item.casing(), item.env_casing())?; + Ok((variant, item)) }) - .collect::>(); + .collect::, syn::Error>>()?; gen_for_enum(&item, ident, &input.generics, &variants) } _ => abort_call_site!("`#[derive(Parser)]` only supports non-tuple structs and enums"), @@ -93,18 +85,18 @@ fn gen_for_struct( item_name: &Ident, generics: &Generics, fields: &[(&Field, Item)], -) -> TokenStream { +) -> Result { let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - let into_app = into_app::gen_for_struct(item, item_name, generics); - let args = args::gen_for_struct(item, item_name, generics, fields); + let into_app = into_app::gen_for_struct(item, item_name, generics)?; + let args = args::gen_for_struct(item, item_name, generics, fields)?; - quote! { + Ok(quote! { impl #impl_generics clap::Parser for #item_name #ty_generics #where_clause {} #into_app #args - } + }) } fn gen_for_enum( @@ -112,16 +104,16 @@ fn gen_for_enum( item_name: &Ident, generics: &Generics, variants: &[(&Variant, Item)], -) -> TokenStream { +) -> Result { let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - let into_app = into_app::gen_for_enum(item, item_name, generics); - let subcommand = subcommand::gen_for_enum(item, item_name, generics, variants); + let into_app = into_app::gen_for_enum(item, item_name, generics)?; + let subcommand = subcommand::gen_for_enum(item, item_name, generics, variants)?; - quote! { + Ok(quote! { impl #impl_generics clap::Parser for #item_name #ty_generics #where_clause {} #into_app #subcommand - } + }) } diff --git a/vendor/clap_derive/src/derives/subcommand.rs b/vendor/clap_derive/src/derives/subcommand.rs index 8a44e0c42..403fe4557 100644 --- a/vendor/clap_derive/src/derives/subcommand.rs +++ b/vendor/clap_derive/src/derives/subcommand.rs @@ -13,33 +13,29 @@ // MIT/Apache 2.0 license. use proc_macro2::{Ident, Span, TokenStream}; -use proc_macro_error::{abort, abort_call_site}; use quote::{format_ident, quote, quote_spanned}; 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 { +pub fn derive_subcommand(input: &DeriveInput) -> Result { let ident = &input.ident; - dummies::subcommand(ident); - match input.data { Data::Enum(ref e) => { let name = Name::Derived(ident.clone()); - let item = Item::from_subcommand_enum(input, name); + 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) + Item::from_subcommand_variant(variant, item.casing(), item.env_casing())?; + Ok((variant, item)) }) - .collect::>(); + .collect::, syn::Error>>()?; gen_for_enum(&item, ident, &input.generics, &variants) } _ => abort_call_site!("`#[derive(Subcommand)]` only supports enums"), @@ -51,7 +47,7 @@ pub fn gen_for_enum( item_name: &Ident, generics: &Generics, variants: &[(&Variant, Item)], -) -> TokenStream { +) -> Result { if !matches!(&*item.kind(), Kind::Command(_)) { abort! { item.kind().span(), "`{}` cannot be used with `command`", @@ -61,14 +57,14 @@ pub fn gen_for_enum( let (impl_generics, ty_generics, where_clause) = generics.split_for_impl(); - let from_arg_matches = gen_from_arg_matches(variants); - let update_from_arg_matches = gen_update_from_arg_matches(variants); + 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); + let augmentation = gen_augment(variants, item, false)?; + let augmentation_update = gen_augment(variants, item, true)?; + let has_subcommand = gen_has_subcommand(variants)?; - quote! { + Ok(quote! { #[allow(dead_code, unreachable_code, unused_variables, unused_braces)] #[allow( clippy::style, @@ -80,8 +76,8 @@ pub fn gen_for_enum( clippy::nursery, clippy::cargo, clippy::suspicious_else_formatting, + clippy::almost_swapped, )] - #[deny(clippy::correctness)] 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::from_arg_matches_mut(&mut __clap_arg_matches.clone()) @@ -106,8 +102,8 @@ pub fn gen_for_enum( clippy::nursery, clippy::cargo, clippy::suspicious_else_formatting, + clippy::almost_swapped, )] - #[deny(clippy::correctness)] impl #impl_generics clap::Subcommand for #item_name #ty_generics #where_clause { fn augment_subcommands <'b>(__clap_app: clap::Command) -> clap::Command { #augmentation @@ -119,225 +115,222 @@ pub fn gen_for_enum( #has_subcommand } } - } + }) } fn gen_augment( variants: &[(&Variant, Item)], parent_item: &Item, override_required: bool, -) -> TokenStream { +) -> Result { use syn::Fields::*; let app_var = Ident::new("__clap_app", Span::call_site()); - let subcommands: Vec<_> = variants - .iter() - .filter_map(|(variant, item)| { - let kind = item.kind(); + let mut subcommands = Vec::new(); + for (variant, item) in variants { + let kind = item.kind(); - match &*kind { - Kind::Skip(_, _) | - Kind::Arg(_) | - Kind::FromGlobal(_) | - Kind::Value => None, + let genned = match &*kind { + Kind::Skip(_, _) | Kind::Arg(_) | Kind::FromGlobal(_) | Kind::Value => None, - Kind::ExternalSubcommand => { - let ty = match variant.fields { - Unnamed(ref fields) if fields.unnamed.len() == 1 => &fields.unnamed[0].ty, + Kind::ExternalSubcommand => { + 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` \ or `Vec`." - ), - }; + ), + }; + let deprecations = if !override_required { + item.deprecations() + } else { + quote!() + }; + let subty = subty_if_name(ty, "Vec").ok_or_else(|| { + format_err!( + 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 { + Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => { + let ty = &unnamed[0]; 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)); + let next_help_heading = item.next_help_heading(); + let next_display_order = item.next_display_order(); + let subcommand = if override_required { + quote! { + #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); + } + } else { + quote! { + #deprecations + let #app_var = #app_var + #next_help_heading + #next_display_order; + let #app_var = <#ty as clap::Subcommand>::augment_subcommands(#app_var); + } }; Some(subcommand) } + _ => abort!( + variant, + "`flatten` is usable only with single-typed tuple variants" + ), + }, - Kind::Flatten(_) => match variant.fields { + Kind::Subcommand(_) => { + let subcommand_var = Ident::new("__clap_subcommand", Span::call_site()); + let arg_block = match variant.fields { + Named(_) => { + abort!(variant, "non single-typed tuple enums are not supported") + } + Unit => quote!( #subcommand_var ), Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => { let ty = &unnamed[0]; - 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! { - #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); + if override_required { + quote_spanned! { ty.span()=> + { + <#ty as clap::Subcommand>::augment_subcommands_for_update(#subcommand_var) + } } } else { - quote! { - #deprecations - let #app_var = #app_var - #next_help_heading - #next_display_order; - let #app_var = <#ty as clap::Subcommand>::augment_subcommands(#app_var); - } - }; - Some(subcommand) - } - _ => abort!( - variant, - "`flatten` is usable only with single-typed tuple variants" - ), - }, - - Kind::Subcommand(_) => { - let subcommand_var = Ident::new("__clap_subcommand", Span::call_site()); - let arg_block = match variant.fields { - Named(_) => { - abort!(variant, "non single-typed tuple enums are not supported") - } - Unit => quote!( #subcommand_var ), - Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => { - let ty = &unnamed[0]; - if override_required { - quote_spanned! { ty.span()=> - { - <#ty as clap::Subcommand>::augment_subcommands_for_update(#subcommand_var) - } - } - } else { - quote_spanned! { ty.span()=> - { - <#ty as clap::Subcommand>::augment_subcommands(#subcommand_var) - } + quote_spanned! { ty.span()=> + { + <#ty as clap::Subcommand>::augment_subcommands(#subcommand_var) } } } - Unnamed(..) => { - abort!(variant, "non single-typed tuple enums are not supported") - } - }; + } + Unnamed(..) => { + abort!(variant, "non single-typed tuple enums are not supported") + } + }; - 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 override_methods = if override_required { - quote_spanned! { kind.span()=> - .subcommand_required(false) - .arg_required_else_help(false) - } - } else { - quote!() - }; - let subcommand = quote! { - let #app_var = #app_var.subcommand({ - #deprecations; - let #subcommand_var = clap::Command::new(#name); - let #subcommand_var = #subcommand_var - .subcommand_required(true) - .arg_required_else_help(true); + 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 override_methods = if override_required { + quote_spanned! { kind.span()=> + .subcommand_required(false) + .arg_required_else_help(false) + } + } else { + quote!() + }; + let subcommand = quote! { + let #app_var = #app_var.subcommand({ + #deprecations; + let #subcommand_var = clap::Command::new(#name); + let #subcommand_var = #subcommand_var + .subcommand_required(true) + .arg_required_else_help(true); + let #subcommand_var = #subcommand_var #initial_app_methods; + let #subcommand_var = #arg_block; + #subcommand_var #final_from_attrs #override_methods + }); + }; + 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 + let fields = fields + .named + .iter() + .map(|field| { + let item = + Item::from_args_field(field, item.casing(), item.env_casing())?; + Ok((field, item)) + }) + .collect::, syn::Error>>()?; + args::gen_augment(&fields, &subcommand_var, item, override_required)? + } + Unit => { + let arg_block = quote!( #subcommand_var ); + 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; - #subcommand_var #final_from_attrs #override_methods - }); - }; - 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 - let fields = fields - .named - .iter() - .map(|field| { - let item = Item::from_args_field(field, item.casing(), item.env_casing()); - (field, item) - }) - .collect::>(); - args::gen_augment(&fields, &subcommand_var, item, override_required) + #subcommand_var #final_from_attrs } - Unit => { - let arg_block = quote!( #subcommand_var ); - 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; - #subcommand_var #final_from_attrs - } - }, - Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => { - let ty = &unnamed[0]; - let arg_block = if override_required { - quote_spanned! { ty.span()=> - { - <#ty as clap::Args>::augment_args_for_update(#subcommand_var) - } + } + Unnamed(FieldsUnnamed { ref unnamed, .. }) if unnamed.len() == 1 => { + let ty = &unnamed[0]; + let arg_block = if override_required { + quote_spanned! { ty.span()=> + { + <#ty as clap::Args>::augment_args_for_update(#subcommand_var) } - } else { - quote_spanned! { ty.span()=> - { - <#ty as clap::Args>::augment_args(#subcommand_var) - } + } + } else { + quote_spanned! { ty.span()=> + { + <#ty as clap::Args>::augment_args(#subcommand_var) } - }; - 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; - #subcommand_var #final_from_attrs } + }; + 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; + #subcommand_var #final_from_attrs } - Unnamed(..) => { - abort!(variant, "non single-typed tuple enums are not supported") - } - }; + } + Unnamed(..) => { + abort!(variant, "non single-typed tuple enums are not supported") + } + }; - 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 - }); - }; - Some(subcommand) - } + 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 + }); + }; + Some(subcommand) } - }) - .collect(); + }; + subcommands.push(genned); + } let deprecations = if !override_required { parent_item.deprecations() @@ -346,15 +339,15 @@ fn gen_augment( }; let initial_app_methods = parent_item.initial_top_level_methods(); let final_app_methods = parent_item.final_top_level_methods(); - quote! { + Ok(quote! { #deprecations; let #app_var = #app_var #initial_app_methods; #( #subcommands )*; #app_var #final_app_methods - } + }) } -fn gen_has_subcommand(variants: &[(&Variant, Item)]) -> TokenStream { +fn gen_has_subcommand(variants: &[(&Variant, Item)]) -> Result { use syn::Fields::*; let mut ext_subcmd = false; @@ -391,19 +384,20 @@ fn gen_has_subcommand(variants: &[(&Variant, Item)]) -> TokenStream { .map(|(variant, _attrs)| match variant.fields { Unnamed(ref fields) if fields.unnamed.len() == 1 => { let ty = &fields.unnamed[0]; - quote! { + Ok(quote! { if <#ty as clap::Subcommand>::has_subcommand(__clap_name) { return true; } - } + }) } _ => abort!( variant, "`flatten` is usable only with single-typed tuple variants" ), - }); + }) + .collect::, syn::Error>>()?; - if ext_subcmd { + let genned = if ext_subcmd { quote! { true } } else { quote! { @@ -413,77 +407,79 @@ fn gen_has_subcommand(variants: &[(&Variant, Item)]) -> TokenStream { false } - } + }; + Ok(genned) } -fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream { +fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> Result { use syn::Fields::*; - let mut ext_subcmd = None; - let subcommand_name_var = format_ident!("__clap_name"); let sub_arg_matches_var = format_ident!("__clap_arg_matches"); - let (flatten_variants, variants): (Vec<_>, Vec<_>) = variants - .iter() - .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`, \ + let mut ext_subcmd = None; + let mut flatten_variants = Vec::new(); + let mut unflatten_variants = Vec::new(); + for (variant, item) in variants { + let kind = item.kind(); + match &*kind { + Kind::Skip(_, _) | Kind::Arg(_) | Kind::FromGlobal(_) | Kind::Value => {} + + 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` \ or `Vec`." - ), - }; - - 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` or `Vec` \ + ), + }; + + 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` or `Vec` \ to be used with `external_subcommand`." - ); - } + ); } + } - None => abort!( - ty.span(), - "The type must be either `Vec` or `Vec` \ + None => abort!( + ty.span(), + "The type must be either `Vec` or `Vec` \ to be used with `external_subcommand`." - ), - }; + ), + }; - ext_subcmd = Some((span, &variant.ident, str_ty)); - None + ext_subcmd = Some((span, &variant.ident, str_ty)); + } + Kind::Flatten(_) | Kind::Subcommand(_) | Kind::Command(_) => { + if matches!(&*item.kind(), Kind::Flatten(_)) { + flatten_variants.push((variant, item)); + } else { + unflatten_variants.push((variant, item)); } - Kind::Flatten(_) | Kind::Subcommand(_) | Kind::Command(_) => Some((variant, item)), } - }) - .partition(|(_, item)| { - let kind = item.kind(); - matches!(&*kind, Kind::Flatten(_)) - }); + } + } - let subcommands = variants.iter().map(|(variant, item)| { + let subcommands = unflatten_variants.iter().map(|(variant, item)| { let sub_name = item.cased_name(); let variant_name = &variant.ident; let constructor_block = match variant.fields { @@ -492,11 +488,11 @@ fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream { .named .iter() .map(|field| { - let item = Item::from_args_field(field, item.casing(), item.env_casing()); - (field, item) + let item = Item::from_args_field(field, item.casing(), item.env_casing())?; + Ok((field, item)) }) - .collect::>(); - args::gen_constructor(&fields) + .collect::, syn::Error>>()?; + args::gen_constructor(&fields)? }, Unit => quote!(), Unnamed(ref fields) if fields.unnamed.len() == 1 => { @@ -506,18 +502,18 @@ fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream { Unnamed(..) => abort_call_site!("{}: tuple enums are not supported", variant.ident), }; - quote! { + Ok(quote! { if #subcommand_name_var == #sub_name && !#sub_arg_matches_var.contains_id("") { return ::std::result::Result::Ok(Self :: #variant_name #constructor_block) } - } - }); + }) + }).collect::, syn::Error>>()?; let child_subcommands = flatten_variants.iter().map(|(variant, _attrs)| { let variant_name = &variant.ident; match variant.fields { Unnamed(ref fields) if fields.unnamed.len() == 1 => { let ty = &fields.unnamed[0]; - quote! { + Ok(quote! { if __clap_arg_matches .subcommand_name() .map(|__clap_name| <#ty as clap::Subcommand>::has_subcommand(__clap_name)) @@ -526,14 +522,14 @@ fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream { let __clap_res = <#ty as clap::FromArgMatches>::from_arg_matches_mut(__clap_arg_matches)?; return ::std::result::Result::Ok(Self :: #variant_name (__clap_res)); } - } + }) } _ => abort!( variant, "`flatten` is usable only with single-typed tuple variants" ), } - }); + }).collect::, syn::Error>>()?; let wildcard = match ext_subcmd { Some((span, var_name, str_ty)) => quote_spanned! { span=> @@ -555,7 +551,7 @@ fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream { }; let raw_deprecated = args::raw_deprecated(); - quote! { + Ok(quote! { fn from_arg_matches_mut(__clap_arg_matches: &mut clap::ArgMatches) -> ::std::result::Result { #raw_deprecated @@ -570,10 +566,10 @@ fn gen_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream { ::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(variants: &[(&Variant, Item)]) -> TokenStream { +fn gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> Result { use syn::Fields::*; let (flatten, variants): (Vec<_>, Vec<_>) = variants @@ -607,11 +603,11 @@ fn gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream { .named .iter() .map(|field| { - let item = Item::from_args_field(field, item.casing(), item.env_casing()); - (field, item) + let item = Item::from_args_field(field, item.casing(), item.env_casing())?; + Ok((field, item)) }) - .collect::>(); - let update = args::gen_updater(&fields, false); + .collect::, syn::Error>>()?; + let update = args::gen_updater(&fields, false)?; (quote!( { #( #field_names, )* }), quote!( { #update } )) } Unit => (quote!(), quote!({})), @@ -630,38 +626,38 @@ fn gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream { } }; - quote! { + Ok(quote! { 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 } - } - }); + }) + }).collect::, _>>()?; let child_subcommands = flatten.iter().map(|(variant, _attrs)| { let variant_name = &variant.ident; match variant.fields { Unnamed(ref fields) if fields.unnamed.len() == 1 => { let ty = &fields.unnamed[0]; - quote! { + Ok(quote! { if <#ty as clap::Subcommand>::has_subcommand(__clap_name) { 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(()); } } - } + }) } _ => abort!( variant, "`flatten` is usable only with single-typed tuple variants" ), } - }); + }).collect::, _>>()?; let raw_deprecated = args::raw_deprecated(); - quote! { + Ok(quote! { fn update_from_arg_matches_mut<'b>( &mut self, __clap_arg_matches: &mut clap::ArgMatches, @@ -679,5 +675,5 @@ fn gen_update_from_arg_matches(variants: &[(&Variant, Item)]) -> TokenStream { } ::std::result::Result::Ok(()) } - } + }) } diff --git a/vendor/clap_derive/src/derives/value_enum.rs b/vendor/clap_derive/src/derives/value_enum.rs index a1411d02a..6f107c01c 100644 --- a/vendor/clap_derive/src/derives/value_enum.rs +++ b/vendor/clap_derive/src/derives/value_enum.rs @@ -9,39 +9,36 @@ // except according to those terms. use proc_macro2::TokenStream; -use proc_macro_error::{abort, abort_call_site}; use quote::quote; use quote::quote_spanned; use syn::{spanned::Spanned, Data, DeriveInput, Fields, Ident, Variant}; -use crate::dummies; use crate::item::{Item, Kind, Name}; -pub fn derive_value_enum(input: &DeriveInput) -> TokenStream { +pub fn derive_value_enum(input: &DeriveInput) -> Result { let ident = &input.ident; - dummies::value_enum(ident); - match input.data { Data::Enum(ref e) => { let name = Name::Derived(ident.clone()); - let item = Item::from_value_enum(input, name); - let variants = e - .variants - .iter() - .map(|variant| { - let item = - Item::from_value_enum_variant(variant, item.casing(), item.env_casing()); - (variant, item) - }) - .collect::>(); + let item = Item::from_value_enum(input, name)?; + let mut variants = Vec::new(); + for variant in &e.variants { + let item = + Item::from_value_enum_variant(variant, item.casing(), item.env_casing())?; + variants.push((variant, item)); + } gen_for_enum(&item, ident, &variants) } _ => abort_call_site!("`#[derive(ValueEnum)]` only supports enums"), } } -pub fn gen_for_enum(item: &Item, item_name: &Ident, variants: &[(&Variant, Item)]) -> TokenStream { +pub fn gen_for_enum( + item: &Item, + item_name: &Ident, + variants: &[(&Variant, Item)], +) -> Result { if !matches!(&*item.kind(), Kind::Value) { abort! { item.kind().span(), "`{}` cannot be used with `value`", @@ -49,11 +46,11 @@ pub fn gen_for_enum(item: &Item, item_name: &Ident, variants: &[(&Variant, Item) } } - let lits = lits(variants); + let lits = lits(variants)?; let value_variants = gen_value_variants(&lits); let to_possible_value = gen_to_possible_value(item, &lits); - quote! { + Ok(quote! { #[allow(dead_code, unreachable_code, unused_variables, unused_braces)] #[allow( clippy::style, @@ -65,39 +62,37 @@ pub fn gen_for_enum(item: &Item, item_name: &Ident, variants: &[(&Variant, Item) clippy::nursery, clippy::cargo, clippy::suspicious_else_formatting, + clippy::almost_swapped, )] - #[deny(clippy::correctness)] impl clap::ValueEnum for #item_name { #value_variants #to_possible_value } - } + }) } -fn lits(variants: &[(&Variant, Item)]) -> Vec<(TokenStream, Ident)> { - variants - .iter() - .filter_map(|(variant, item)| { - 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 = item.field_methods(); - let deprecations = item.deprecations(); - let name = item.cased_name(); - Some(( - quote_spanned! { variant.span()=> { - #deprecations - clap::builder::PossibleValue::new(#name) - #fields - }}, - variant.ident.clone(), - )) - } - }) - .collect::>() +fn lits(variants: &[(&Variant, Item)]) -> Result, syn::Error> { + let mut genned = Vec::new(); + for (variant, item) in variants { + if let Kind::Skip(_, _) = &*item.kind() { + continue; + } + if !matches!(variant.fields, Fields::Unit) { + abort!(variant.span(), "`#[derive(ValueEnum)]` only supports unit variants. Non-unit variants must be skipped"); + } + let fields = item.field_methods(); + let deprecations = item.deprecations(); + let name = item.cased_name(); + genned.push(( + quote_spanned! { variant.span()=> { + #deprecations + clap::builder::PossibleValue::new(#name) + #fields + }}, + variant.ident.clone(), + )); + } + Ok(genned) } fn gen_value_variants(lits: &[(TokenStream, Ident)]) -> TokenStream { -- cgit v1.2.3