1use proc_macro::TokenStream;
2use quote::format_ident;
3use quote::quote;
4use syn::parse_macro_input;
5use syn::ItemImpl;
6use syn::ItemTrait;
7
8mod protocols;
9use protocols::JsonRpSee;
10use protocols::Protocol;
11use protocols::RestAxum;
12use protocols::Tarpc;
13
14const PROTOCOLS: &[&dyn Protocol] = &[&Tarpc, &RestAxum, &JsonRpSee];
15
16#[proc_macro_attribute]
17pub fn multi_rpc_trait(_attr: TokenStream, input: TokenStream) -> TokenStream {
18 let item_trait = parse_macro_input!(input as ItemTrait);
19 let trait_ident = item_trait.ident.clone();
20 let generated_mod_ident = format_ident!("{}_generated", trait_ident.to_string().to_lowercase());
21
22 let generated_trait_code: Vec<_> = PROTOCOLS
23 .iter()
24 .map(|p| p.transform_trait(&item_trait))
25 .collect();
26
27 quote! {
28 #item_trait
29 pub mod #generated_mod_ident {
30 use super::*;
31 use std::sync::Arc;
32 use multi_rpc::error::RpcError;
33 #(#generated_trait_code)*
34 }
35 }
36 .into()
37}
38
39#[proc_macro_attribute]
40pub fn multi_rpc_impl(_attr: TokenStream, input: TokenStream) -> TokenStream {
41 let item_impl = parse_macro_input!(input as ItemImpl);
42
43 let trait_ident = &item_impl
45 .trait_
46 .as_ref()
47 .unwrap()
48 .1
49 .segments
50 .last()
51 .unwrap()
52 .ident;
53 let impls_mod_ident = format_ident!("{}_impls", trait_ident.to_string().to_lowercase());
54
55 let generated_impl_code: Vec<_> = PROTOCOLS
56 .iter()
57 .map(|p| p.transform_impl(&item_impl))
58 .collect();
59
60 quote! {
61 #item_impl
62
63 pub mod #impls_mod_ident {
65 use super::*;
67 use std::sync::Arc;
68
69 #(#generated_impl_code)*
70 }
71 }
72 .into()
73}
74
75#[proc_macro_attribute]
76pub fn rest(_attr: TokenStream, item: TokenStream) -> TokenStream {
77 item
78}