rpc_toolkit_macro_internals/rpc_handler/
build.rs1use proc_macro2::{Span, TokenStream};
2use quote::quote;
3use syn::spanned::Spanned;
4
5use super::*;
6
7pub fn build(args: RpcHandlerArgs) -> TokenStream {
8 let mut command = args.command;
9 let mut arguments = std::mem::replace(
10 &mut command.segments.last_mut().unwrap().arguments,
11 PathArguments::None,
12 );
13 let command_module = command.clone();
14 if let PathArguments::AngleBracketed(a) = &mut arguments {
15 a.args.push(syn::parse2(quote! { _ }).unwrap());
16 }
17 command.segments.push(PathSegment {
18 ident: Ident::new("rpc_handler", command.span()),
19 arguments,
20 });
21 let ctx = args.ctx;
22 let parent_data = if let Some(data) = args.parent_data {
23 quote! { #data }
24 } else {
25 quote! { () }
26 };
27 let status_fn = args.status_fn.unwrap_or_else(|| {
28 syn::parse2(quote! { |_| ::rpc_toolkit::hyper::StatusCode::OK }).unwrap()
29 });
30 let middleware_name_clone = (0..)
31 .map(|i| {
32 Ident::new(
33 &format!("__rpc_toolkit__rpc_handler__middleware_clone_{}", i),
34 Span::call_site(),
35 )
36 })
37 .take(args.middleware.len());
38 let middleware_name_clone2 = middleware_name_clone.clone();
39 let middleware_name_clone3 = middleware_name_clone.clone();
40 let middleware_name_clone4 = middleware_name_clone.clone();
41 let middleware_name_pre = (0..)
42 .map(|i| Ident::new(&format!("middleware_pre_{}", i), Span::call_site()))
43 .take(args.middleware.len());
44 let middleware_name_pre2 = middleware_name_pre.clone();
45 let middleware_name_post = (0..)
46 .map(|i| Ident::new(&format!("middleware_post_{}", i), Span::call_site()))
47 .take(args.middleware.len());
48 let middleware_name_post_inv = middleware_name_post
49 .clone()
50 .collect::<Vec<_>>()
51 .into_iter()
52 .rev();
53 let middleware_name = (0..)
54 .map(|i| Ident::new(&format!("middleware_{}", i), Span::call_site()))
55 .take(args.middleware.len());
56 let middleware_name2 = middleware_name.clone();
57 let middleware = args.middleware.iter();
58 let res = quote! {
59 {
60 let __rpc_toolkit__rpc_handler__context = #ctx;
61 let __rpc_toolkit__rpc_handler__parent_data = #parent_data;
62 let __rpc_toolkit__rpc_handler__status_fn = #status_fn;
63 #(
64 let #middleware_name_clone = ::std::sync::Arc::new(#middleware);
65 )*
66 let res: ::rpc_toolkit::RpcHandler = ::std::sync::Arc::new(move |mut req| {
67 let ctx = __rpc_toolkit__rpc_handler__context.clone();
68 let parent_data = __rpc_toolkit__rpc_handler__parent_data.clone();
69 let metadata = #command_module::Metadata::default();
70 #(
71 let #middleware_name_clone3 = #middleware_name_clone2.clone();
72 )*
73 ::rpc_toolkit::futures::FutureExt::boxed(async move {
74 #(
75 let #middleware_name_pre = match ::rpc_toolkit::rpc_server_helpers::constrain_middleware(&*#middleware_name_clone4)(&mut req, metadata).await? {
76 Ok(a) => a,
77 Err(res) => return Ok(res),
78 };
79 )*
80 let (mut req_parts, req_body) = req.into_parts();
81 let (mut res_parts, _) = ::rpc_toolkit::hyper::Response::new(()).into_parts();
82 let rpc_req = ::rpc_toolkit::rpc_server_helpers::make_request(&req_parts, req_body).await;
83 match rpc_req {
84 Ok(mut rpc_req) => {
85 #(
86 let #middleware_name_post = match #middleware_name_pre2(&mut req_parts, &mut rpc_req).await? {
87 Ok(a) => a,
88 Err(res) => return Ok(res),
89 };
90 )*
91 let mut rpc_res = match ::rpc_toolkit::serde_json::from_value(::rpc_toolkit::serde_json::Value::Object(rpc_req.params)) {
92 Ok(params) => #command(ctx, parent_data, &req_parts, &mut res_parts, ::rpc_toolkit::yajrc::RpcMethod::as_str(&rpc_req.method), params).await,
93 Err(e) => Err(e.into())
94 };
95 #(
96 let #middleware_name = match #middleware_name_post_inv(&mut res_parts, &mut rpc_res).await? {
97 Ok(a) => a,
98 Err(res) => return Ok(res),
99 };
100 )*
101 let mut res = ::rpc_toolkit::rpc_server_helpers::to_response(
102 &req_parts.headers,
103 res_parts,
104 Ok((
105 rpc_req.id,
106 rpc_res,
107 )),
108 __rpc_toolkit__rpc_handler__status_fn,
109 )?;
110 #(
111 #middleware_name2(&mut res).await?;
112 )*
113 Ok::<_, ::rpc_toolkit::hyper::http::Error>(res)
114 }
115 Err(e) => ::rpc_toolkit::rpc_server_helpers::to_response(
116 &req_parts.headers,
117 res_parts,
118 Err(e),
119 __rpc_toolkit__rpc_handler__status_fn,
120 ),
121 }
122 })
123 });
124 res
125 }
126 };
127 res
129}