enum_dict_derive 0.1.0

Derive macros for enum_dict.
Documentation
use proc_macro::TokenStream;
use quote::quote;
use syn::spanned::Spanned;
use syn::{Data, DeriveInput, Error, Fields, LitStr, parse_macro_input};

#[proc_macro_derive(DictKey)]
pub fn derive_dict_key(input: TokenStream) -> TokenStream {
    let input: DeriveInput = parse_macro_input!(input);
    let ident = &input.ident;

    let mut ident_names = vec![];

    match &input.data {
        Data::Enum(data) => {
            for variant in &data.variants {
                let ident = &variant.ident;
                let name = LitStr::new(&ident.to_string(), ident.span());
                ident_names.push(quote! { #name });

                match &variant.fields {
                    Fields::Unit => {}
                    _ => {
                        return Error::new(variant.span(), "DictKey can only be derived for unit variants")
                            .to_compile_error()
                            .into();
                    }
                }
            }
        }
        _ => {
            return Error::new(input.span(), "DictKey can only be derived for enums")
                .to_compile_error()
                .into();
        }
    }

    quote! {
        impl DictKey for #ident {
            const FIELDS: &'static [&'static str] = &[#(#ident_names),*];

            fn into_usize(self) -> usize {
                self as usize
            }
        }
    }
    .into()
}