dioxus_switch_macro/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{Data, DeriveInput, Token, parse_macro_input, punctuated::Punctuated};
4
5#[proc_macro_derive(Switch)]
6pub fn switch(input: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(input as DeriveInput);
8 if let Data::Enum(data_enum) = input.data {
9 let switch_ident = input.ident;
10 let match_arms = data_enum.variants.into_iter().map(|variant| {
11 let component = variant.ident;
12 let keys = variant
13 .fields
14 .into_iter()
15 .map(|f| f.ident.expect("expected enum variants to be named"));
16
17 let keys = Punctuated::<_, Token![,]>::from_iter(keys);
18
19 quote! {
20 Self::#component { #keys } => {
21 rsx! {
22 #component { #keys }
23 }
24 }
25 }
26 });
27
28 let match_arms = Punctuated::<_, Token![,]>::from_iter(match_arms);
29
30 let output = quote! {
31 impl Switchable for #switch_ident {
32 fn component(self) -> Element {
33 match self {
34 #match_arms
35 }
36 }
37 }
38 };
39
40 output.into()
41 } else {
42 panic!("switch can only be used on enums");
43 }
44}