1use proc_macro::{Span, TokenStream};
2use quote::quote;
3use syn::{parse_macro_input, token::Pub, FnArg, Ident, ItemFn, Visibility};
4
5#[proc_macro_attribute]
7pub fn handler(_attr: TokenStream, item: TokenStream) -> TokenStream {
8 let mut input = parse_macro_input!(item as ItemFn);
9
10 let struct_name = input.sig.ident.clone();
11
12 let mod_name = Ident::new(
13 &format!("__rusnap_{}", &input.sig.ident),
14 Span::call_site().into(),
15 );
16
17 input.sig.ident = mod_name.clone();
18
19 let mut arg_name = Vec::with_capacity(input.sig.inputs.len());
20
21 for (index, arg) in input.sig.inputs.iter().enumerate() {
22 if let FnArg::Typed(_) = arg {
23 let name = Ident::new(&format!("_rh_a{}", index), Span::call_site().into());
24 arg_name.push(name);
25 }
26 }
27
28 let expanded = quote! {
29
30 mod #mod_name {
31 use super::*;
32 use rusnap::{
33 wasm_bindgen::JsValue, exports::{types::{FromRequest, IntoResponse}, Endpoint}, utils::JsResult,
34 };
35
36 #input
37
38 #[allow(non_camel_case_types)]
39 pub struct #struct_name;
40
41 #[rusnap::async_trait(?Send)]
42 impl Endpoint for #struct_name {
43 async fn handle(
44 &self,
45 method: &str,
46 params: JsValue,
47 data: &dyn std::any::Any,
48 _origin: Option<&str>,
49 ) -> JsResult<JsValue> {
50
51 #(
52 let #arg_name = FromRequest::from_request(method, params.clone(), data).await;
53 )*
54
55 let r = #mod_name( #(#arg_name),* ).await;
56
57 Ok(r.into_response().await?)
58 }
59 }
60 }
61
62 pub use #mod_name::#struct_name;
63
64 };
65
66 TokenStream::from(expanded)
67}
68
69#[proc_macro_attribute]
71pub fn main(_attr: TokenStream, item: TokenStream) -> TokenStream {
72 let mut input = parse_macro_input!(item as ItemFn);
73
74 input.vis = Visibility::Public(Pub::default());
75
76 let expanded = quote! {
77 mod __rusnp_entry {
78 use rusnap::{wasm_bindgen::{self, JsValue}, wasm_bindgen_futures, exports, utils::JsResult};
79
80 use super::*;
81
82 #[wasm_bindgen::prelude::wasm_bindgen(js_name = _entry)]
83 #input
84
85 #[wasm_bindgen::prelude::wasm_bindgen]
86 pub async fn on_rpc_request(
87 origin: &str,
88 method: &str,
89 req: JsValue
90 ) -> JsResult<JsValue> {
91 exports::on_rpc_request(origin, method, req).await
92 }
93
94 #[wasm_bindgen::prelude::wasm_bindgen]
95 pub async fn on_transaction(
96 transaction: JsValue,
97 chainid: u64,
98 req: JsValue
99 ) -> JsResult<JsValue> {
100 exports::on_transaction(transaction, chainid, req).await
101 }
102
103 #[wasm_bindgen::prelude::wasm_bindgen]
104 pub async fn on_cronjob(method: &str, params: JsValue) -> JsResult<JsValue> {
105 exports::on_cronjob(method, params).await
106 }
107 }
108 };
109
110 TokenStream::from(expanded)
111}