autowired_derive/
lib.rs

1use quote::quote;
2use proc_macro::TokenStream;
3use syn::{ItemFn, AttributeArgs, NestedMeta};
4
5#[proc_macro_derive(Component)]
6pub fn component_derive(input: TokenStream) -> TokenStream {
7    let ast: syn::DeriveInput = syn::parse(input).unwrap();
8    let name = &ast.ident;
9    let gen = quote! {
10        impl autowired::Component for #name {
11            fn new_instance() -> Option<Self> {
12               Some(Default::default())
13            }
14        }
15        autowired::submit! {
16            autowired::Bean::new_unchecked::<#name>()
17        }
18    };
19
20    gen.into()
21}
22
23#[proc_macro_derive(LazyComponent)]
24pub fn lazy_component_derive(input: TokenStream) -> TokenStream {
25    let ast: syn::DeriveInput = syn::parse(input).unwrap();
26    let name = &ast.ident;
27    let gen = quote! {
28        impl autowired::Component for #name {
29            fn new_instance() -> Option<Self> {
30               Some(Default::default())
31            }
32        }
33        autowired::submit! {
34            autowired::Bean::new_unchecked_lazy::<#name>()
35        }
36    };
37    gen.into()
38}
39
40#[proc_macro_attribute]
41pub fn bean(args: TokenStream, input: TokenStream) -> TokenStream {
42    let args = syn::parse_macro_input!(args as AttributeArgs);
43
44    let mut is_lazy = false;
45    let mut is_option = false;
46    for meta in args {
47        if let NestedMeta::Meta(nv) = meta {
48            if nv.path().is_ident("lazy") {
49                is_lazy = true;
50            }
51
52            if nv.path().is_ident("option") {
53                is_option = true;
54            }
55        }
56    }
57
58    let func = syn::parse_macro_input!(input as ItemFn);
59
60    let block = &func.block;
61    let vis = &func.vis;
62    let name = &func.sig.ident;
63    let output = &func.sig.output;
64
65    let submit_method = if is_option {
66        quote! { autowired::Bean::from_fn_return_option(#name, #is_lazy) }
67    } else {
68        quote! { autowired::Bean::from_fn(#name, #is_lazy) }
69    };
70
71    let gen = quote! {
72        #vis fn #name() #output {
73            #block
74        }
75        autowired::submit! {
76            #submit_method
77        }
78    };
79
80    gen.into()
81}
82