lambda_router_macros/router_macro/
ast.rs

1use quote::{quote, ToTokens, TokenStreamExt};
2use syn::ItemFn;
3
4use super::arguments::Arguments;
5
6#[derive(Debug)]
7pub struct Ast {
8    pub item_fn: ItemFn,
9    pub arguments: Arguments,
10}
11
12impl ToTokens for Ast {
13    fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
14        let item_fn = &self.item_fn;
15        let vis = &self.item_fn.vis;
16        let ident = &self.item_fn.sig.ident;
17
18        let method = &self.arguments.method;
19        let route = &self.arguments.route;
20
21        let wrapped_func = quote! {
22            #vis async fn #ident(event: &lambda_http::Request) -> Result<Option<lambda_http::Response<lambda_http::Body>>,lambda_http::Error> {
23                #item_fn;
24
25                use lambda_http::RequestExt;
26                let path_params = event.path_parameters();
27                let inbound = path_params.first("route");
28
29                let method = lambda_http::http::Method:: #method;
30                let route = #route;
31
32                let (message, status_code) = match lambda_router::runtime::try_route::try_route(event, method, route, inbound) {
33                    Ok(payload) => {
34                        let result = #ident(payload).await;
35                        let status_code = match result.is_ok() {
36                            true => 200,
37                            false => 400,
38                        };
39                        let message = lambda_router::runtime::json::json(&result)?;
40                        (message, status_code)
41                    },
42                    Err(err) => {
43                        if err.is_not_found() {
44                            return Ok(None);
45                        }
46                        let status_code = err.status_code();
47                        let serialized = err.json()?;
48                        (serialized, status_code)
49                    },
50                };
51
52                let resp = lambda_http::Response::builder()
53                    .status(status_code)
54                    .header("content-type", "application/json")
55                    .body(message.into())
56                    .map_err(Box::new)?;
57
58                Ok(Some(resp))
59            }
60        };
61
62        tokens.append_all(wrapped_func);
63    }
64}