1use proc_macro2::TokenStream;
2use quote::quote;
3use syn::Data;
4use syn::Result;
5use syn::{parse_macro_input, DeriveInput};
6
7#[proc_macro_derive(Enumable)]
8pub fn derive_enumable(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
9 derive_enumable_internal(parse_macro_input!(input as DeriveInput))
10 .unwrap_or_else(syn::Error::into_compile_error)
11 .into()
12}
13
14fn derive_enumable_internal(input: DeriveInput) -> Result<TokenStream> {
15 let variants = match &input.data {
16 Data::Enum(data) => &data.variants,
17 _ => {
18 return Err(syn::Error::new_spanned(
19 &input,
20 "Enumable can only be derived for enums",
21 ))
22 }
23 };
24
25 let variants = variants.iter().map(|v| &v.ident);
26
27 let ident = &input.ident;
28 let expanded = quote! {
29 impl enum_table::Enumable for #ident {
30 const VARIANTS: &'static [#ident] = &[#(Self::#variants),*];
31 }
32 };
33
34 Ok(expanded)
35}