rstrpc_macros/
lib.rs

1use handler::{generate_handler, HandlerKind};
2use quote::quote;
3use syn::{meta, parse_macro_input, spanned::Spanned, Error, Item};
4
5mod handler;
6
7#[proc_macro_attribute]
8pub fn handler(
9    attr: proc_macro::TokenStream,
10    input: proc_macro::TokenStream,
11) -> proc_macro::TokenStream {
12    // Extract information from the attribute
13    let kind = {
14        let mut kind = HandlerKind::Query;
15
16        let attribute_parser = meta::parser(|meta| kind.parse(meta));
17
18        parse_macro_input!(attr with attribute_parser);
19
20        kind
21    };
22
23    // Attempt to match as a function
24    syn::parse::<Item>(input)
25        .and_then(|item| {
26            if let Item::Fn(handler) = item {
27                generate_handler(handler, kind)
28            } else {
29                Err(Error::new(item.span(), "handlers must be a method"))
30            }
31        })
32        .unwrap_or_else(Error::into_compile_error)
33        .into()
34}
35
36#[proc_macro_attribute]
37pub fn exported_type(
38    _attrs: proc_macro::TokenStream,
39    input: proc_macro::TokenStream,
40) -> proc_macro::TokenStream {
41    let s = syn::parse::<Item>(input).unwrap();
42
43    let (target_struct, fields) = match s {
44        Item::Struct(ref s) => (
45            s.ident.clone(),
46            s.fields.iter().map(|field| field.ty.clone()),
47        ),
48        _ => unimplemented!(),
49    };
50
51    quote! {
52        #[derive(TS)]
53        #s
54
55        impl rstrpc::TypeDependencies for #target_struct {
56            fn get_deps(dependencies: &mut std::collections::BTreeMap<std::string::String, std::string::String>) {
57                // Short circuit if this type has already been added
58                if dependencies.contains_key(&Self::name()) {
59                    return;
60                }
61
62                // Insert this type
63                dependencies.insert(Self::name(), Self::inline());
64
65                // Insert field types
66                #(<#fields as rstrpc::TypeDependencies>::get_deps(dependencies);)*
67            }
68        }
69    }
70    .into()
71}