use proc_macro::TokenStream;
use quote::quote;
use syn::{Data, DataEnum, DeriveInput, Fields, parse_macro_input};
#[proc_macro_derive(ClosedAxis)]
pub fn derive_closed_axis(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let self_name = &input.ident;
let de = match &input.data {
Data::Enum(de) => de,
_ => {
return syn::Error::new_spanned(self_name, "EnumFoldDerive requires an enum")
.to_compile_error()
.into();
}
};
for v in &de.variants {
if !matches!(v.fields, Fields::Unit) {
return syn::Error::new_spanned(
&v.ident,
"EnumFoldDerive (unit-only) requires all variants be unit variants",
)
.to_compile_error()
.into();
}
}
let fold_count = de.variants.len();
let fold_count_lit = proc_macro2::Literal::usize_unsuffixed(fold_count);
let _ = fold_count_lit.clone();
let fragments: Vec<_> = de
.variants
.iter()
.map(|v| {
let variant_name = &v.ident;
let variant_str = variant_name.to_string();
quote! {
Self::# variant_name
}
})
.collect();
let _ = &fragments;
let expanded = quote! {
impl # self_name { pub const ALL : &'static [Self] = & [# (# fragments),*]; }
impl ::shikumi::ClosedAxis for # self_name { const ALL : &'static [Self] = & [#
(# fragments),*]; }
};
TokenStream::from(expanded)
}