diff options
Diffstat (limited to 'vendor/clap_derive/src/derives/value_enum.rs')
-rw-r--r-- | vendor/clap_derive/src/derives/value_enum.rs | 85 |
1 files changed, 44 insertions, 41 deletions
diff --git a/vendor/clap_derive/src/derives/value_enum.rs b/vendor/clap_derive/src/derives/value_enum.rs index 06d514f0e..a1411d02a 100644 --- a/vendor/clap_derive/src/derives/value_enum.rs +++ b/vendor/clap_derive/src/derives/value_enum.rs @@ -8,20 +8,14 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use crate::{ - attrs::{Attrs, Kind, Name, DEFAULT_CASING, DEFAULT_ENV_CASING}, - dummies, - utils::Sp, -}; - -use proc_macro2::{Span, TokenStream}; +use proc_macro2::TokenStream; use proc_macro_error::{abort, abort_call_site}; use quote::quote; use quote::quote_spanned; -use syn::{ - punctuated::Punctuated, spanned::Spanned, token::Comma, Attribute, Data, DataEnum, DeriveInput, - Fields, Ident, Variant, -}; +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 { let ident = &input.ident; @@ -29,23 +23,35 @@ pub fn derive_value_enum(input: &DeriveInput) -> TokenStream { dummies::value_enum(ident); match input.data { - Data::Enum(ref e) => gen_for_enum(ident, &input.attrs, e), + 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::<Vec<_>>(); + gen_for_enum(&item, ident, &variants) + } _ => abort_call_site!("`#[derive(ValueEnum)]` only supports enums"), } } -pub fn gen_for_enum(name: &Ident, 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), - ); +pub fn gen_for_enum(item: &Item, item_name: &Ident, variants: &[(&Variant, Item)]) -> TokenStream { + if !matches!(&*item.kind(), Kind::Value) { + abort! { item.kind().span(), + "`{}` cannot be used with `value`", + item.kind().name(), + } + } - let lits = lits(&e.variants, &attrs); + let lits = lits(variants); let value_variants = gen_value_variants(&lits); - let to_possible_value = gen_to_possible_value(&lits); + let to_possible_value = gen_to_possible_value(item, &lits); quote! { #[allow(dead_code, unreachable_code, unused_variables, unused_braces)] @@ -61,38 +67,32 @@ pub fn gen_for_enum(name: &Ident, attrs: &[Attribute], e: &DataEnum) -> TokenStr clippy::suspicious_else_formatting, )] #[deny(clippy::correctness)] - impl clap::ValueEnum for #name { + impl clap::ValueEnum for #item_name { #value_variants #to_possible_value } } } -fn lits( - variants: &Punctuated<Variant, Comma>, - parent_attribute: &Attrs, -) -> Vec<(TokenStream, Ident)> { +fn lits(variants: &[(&Variant, Item)]) -> Vec<(TokenStream, Ident)> { variants .iter() - .filter_map(|variant| { - let attrs = Attrs::from_value_enum_variant( - variant, - parent_attribute.casing(), - parent_attribute.env_casing(), - ); - if let Kind::Skip(_) = &*attrs.kind() { + .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 = attrs.field_methods(false); - let name = attrs.cased_name(); + let fields = item.field_methods(); + let deprecations = item.deprecations(); + let name = item.cased_name(); Some(( - quote_spanned! { variant.span()=> - clap::PossibleValue::new(#name) + quote_spanned! { variant.span()=> { + #deprecations + clap::builder::PossibleValue::new(#name) #fields - }, + }}, variant.ident.clone(), )) } @@ -110,11 +110,14 @@ fn gen_value_variants(lits: &[(TokenStream, Ident)]) -> TokenStream { } } -fn gen_to_possible_value(lits: &[(TokenStream, Ident)]) -> TokenStream { +fn gen_to_possible_value(item: &Item, lits: &[(TokenStream, Ident)]) -> TokenStream { let (lit, variant): (Vec<TokenStream>, Vec<Ident>) = lits.iter().cloned().unzip(); + let deprecations = item.deprecations(); + quote! { - fn to_possible_value<'a>(&self) -> ::std::option::Option<clap::PossibleValue<'a>> { + fn to_possible_value<'a>(&self) -> ::std::option::Option<clap::builder::PossibleValue> { + #deprecations match self { #(Self::#variant => Some(#lit),)* _ => None |