autovariants_derive/
lib.rs

1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{DeriveInput, parse_macro_input};
4
5#[proc_macro_derive(Variants)]
6pub fn variants_derive(input: TokenStream) -> TokenStream {
7    let input = parse_macro_input!(input as DeriveInput);
8    let name = input.ident;
9    let enum_data = match input.data {
10        syn::Data::Struct(_) => panic!("This macro only works for enums"),
11        syn::Data::Enum(data_enum) => data_enum,
12        syn::Data::Union(_) => panic!("This macro only works for enums"),
13    };
14    let vars: Vec<proc_macro2::TokenStream> = enum_data
15        .variants
16        .iter()
17        .map(|v| quote! {Self::#v})
18        .collect();
19    let num_variants = enum_data.variants.len();
20    let expanded = quote! {
21        impl auto_variants::Variants<#num_variants> for #name {
22            const VARIANTS:[Self;#num_variants] =[
23                #(#vars),*
24            ];
25        fn variants() -> &'static [Self]{
26                &Self::VARIANTS
27            }
28        }
29    };
30    proc_macro::TokenStream::from(expanded)
31}