use proc_macro2::TokenStream;
use quote::quote;
use syn::spanned::Spanned;
use syn::{Data, DeriveInput, Fields};
pub(crate) fn expand(input: &DeriveInput) -> syn::Result<TokenStream> {
let Data::Enum(data) = &input.data else {
return Err(syn::Error::new(
input.ident.span(),
"#[derive(AllVariants)] supports enums only",
));
};
let mut idents = Vec::with_capacity(data.variants.len());
for variant in &data.variants {
if !matches!(variant.fields, Fields::Unit) {
return Err(syn::Error::new(
variant.span(),
"#[derive(AllVariants)] requires every variant to be a unit variant",
));
}
idents.push(&variant.ident);
}
let ident = &input.ident;
let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
let count = idents.len();
Ok(quote! {
impl #impl_generics #ident #ty_generics #where_clause {
pub const ALL: [Self; #count] = [ #(Self::#idents),* ];
}
})
}