more_convert_derive_internal/
enum_array.rs1use proc_macro2::TokenStream;
2use syn::Ident;
3
4use crate::require_enum;
5
6struct EnumArrayData<'a> {
7 ident: &'a Ident,
8 impl_generics: syn::ImplGenerics<'a>,
9 ty_generics: syn::TypeGenerics<'a>,
10 where_clause: Option<&'a syn::WhereClause>,
11 variants: Vec<&'a Ident>,
12}
13
14impl<'a> EnumArrayData<'a> {
15 fn from_input(input: &'a syn::DeriveInput) -> syn::Result<Self> {
16 let variants = require_enum(input)?;
17 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
18
19 Ok(Self {
20 ident: &input.ident,
21 impl_generics,
22 ty_generics,
23 where_clause,
24 variants: variants.iter().map(|f| &f.ident).collect(),
25 })
26 }
27}
28
29fn generate_code(data: EnumArrayData) -> TokenStream {
30 let EnumArrayData {
31 ident,
32 impl_generics,
33 ty_generics,
34 where_clause,
35 variants,
36 } = data;
37
38 let count = variants.len();
39
40 quote::quote! {
41 impl #impl_generics #ident #ty_generics #where_clause {
42 pub const COUNT: usize = #count;
43 pub const VARIANTS: &[Self] = &[#(Self::#variants),*];
44 }
45 }
46}
47
48pub fn derive_enum_array(input: syn::DeriveInput) -> syn::Result<TokenStream> {
49 let data = EnumArrayData::from_input(&input)?;
50 Ok(generate_code(data))
51}