Skip to main content

dioxus_modal_macros/
lib.rs

1use proc_macro::TokenStream;
2use quote::{format_ident, quote};
3use syn::{ItemFn, parse_macro_input};
4
5#[proc_macro_attribute]
6pub fn modal(_attr: TokenStream, item: TokenStream) -> TokenStream {
7    let input_fn = parse_macro_input!(item as ItemFn);
8    let vis = &input_fn.vis;
9    let sig = &input_fn.sig;
10    let block = &input_fn.block;
11    let fn_name = &sig.ident;
12    let fn_args = &sig.inputs;
13
14    let new_component_name = format_ident!("_{}", fn_name);
15
16    let arg_names = fn_args.iter().filter_map(|arg| {
17        if let syn::FnArg::Typed(pat_type) = arg {
18            if let syn::Pat::Ident(ident) = &*pat_type.pat {
19                Some(ident.ident.clone())
20            } else {
21                None
22            }
23        } else {
24            None
25        }
26    });
27
28    let generated = quote! {
29        #[allow(non_snake_case)]
30        #vis fn #fn_name(#fn_args) -> Element {
31            rsx! {
32                #new_component_name {
33                    #(#arg_names),*
34                }
35            }
36        }
37
38        #[component]
39        fn #new_component_name(#fn_args) -> Element {
40            #block
41        }
42    };
43
44    generated.into()
45}