use proc_macro::TokenStream;
use quote::quote;
use syn::{Data, DeriveInput, Token, parse_macro_input, punctuated::Punctuated};
#[proc_macro_derive(Switch)]
pub fn switch(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
if let Data::Enum(data_enum) = input.data {
let switch_ident = input.ident;
let match_arms = data_enum.variants.into_iter().map(|variant| {
let component = variant.ident;
let keys = variant
.fields
.into_iter()
.map(|f| f.ident.expect("expected enum variants to be named"));
let keys = Punctuated::<_, Token![,]>::from_iter(keys);
quote! {
Self::#component { #keys } => {
rsx! {
#component { #keys }
}
}
}
});
let match_arms = Punctuated::<_, Token![,]>::from_iter(match_arms);
let output = quote! {
impl Switchable for #switch_ident {
fn component(self) -> Element {
match self {
#match_arms
}
}
}
};
output.into()
} else {
panic!("switch can only be used on enums");
}
}