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 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 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 if dependencies.contains_key(&Self::name()) {
59 return;
60 }
61
62 dependencies.insert(Self::name(), Self::inline());
64
65 #(<#fields as rstrpc::TypeDependencies>::get_deps(dependencies);)*
67 }
68 }
69 }
70 .into()
71}