]> git.proxmox.com Git - rustc.git/blobdiff - vendor/clap_derive/src/derives/value_enum.rs
New upstream version 1.68.2+dfsg1
[rustc.git] / vendor / clap_derive / src / derives / value_enum.rs
index 06d514f0ebd5c0943b5176a9740b95b559b3c67b..a1411d02ab0b720e441684624b10fcfde51acb37 100644 (file)
@@ -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