multi_rpc_macros/
lib.rs

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    // ✅ Create the module name (e.g., `greeter_impls`) from the trait name.
44    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        // ✅ Wrap all generated code in the namespaced module.
64        pub mod #impls_mod_ident {
65            // `use super::*;` allows the generated code to find `MyGreeter`, `greeter_generated`, etc.
66            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}