pleme_closedaxis_derive/
lib.rs1use proc_macro::TokenStream;
4use quote::quote;
5use syn::{Data, DataEnum, DeriveInput, Fields, parse_macro_input};
6#[proc_macro_derive(ClosedAxis)]
7pub fn derive_closed_axis(input: TokenStream) -> TokenStream {
8 let input = parse_macro_input!(input as DeriveInput);
9 let self_name = &input.ident;
10 let de = match &input.data {
11 Data::Enum(de) => de,
12 _ => {
13 return syn::Error::new_spanned(self_name, "EnumFoldDerive requires an enum")
14 .to_compile_error()
15 .into();
16 }
17 };
18 for v in &de.variants {
19 if !matches!(v.fields, Fields::Unit) {
20 return syn::Error::new_spanned(
21 &v.ident,
22 "EnumFoldDerive (unit-only) requires all variants be unit variants",
23 )
24 .to_compile_error()
25 .into();
26 }
27 }
28 let fold_count = de.variants.len();
29 let fold_count_lit = proc_macro2::Literal::usize_unsuffixed(fold_count);
30 let _ = fold_count_lit.clone();
31 let fragments: Vec<_> = de
32 .variants
33 .iter()
34 .map(|v| {
35 let variant_name = &v.ident;
36 let variant_str = variant_name.to_string();
37 quote! {
38 Self::# variant_name
39 }
40 })
41 .collect();
42 let _ = &fragments;
43 let expanded = quote! {
44 impl # self_name { pub const ALL : &'static [Self] = & [# (# fragments),*]; }
45 impl ::shikumi::ClosedAxis for # self_name { const ALL : &'static [Self] = & [#
46 (# fragments),*]; }
47 };
48 TokenStream::from(expanded)
49}