2024-05-18 20:45:35 +02:00
|
|
|
use proc_macro::TokenStream;
|
|
|
|
|
use quote::quote;
|
2024-11-11 21:52:22 +01:00
|
|
|
use syn::punctuated::Punctuated;
|
|
|
|
|
use syn::token::Comma;
|
2024-11-17 17:11:07 +01:00
|
|
|
use syn::{parse2, parse_macro_input, parse_quote, FnArg, ItemFn, Pat, Stmt};
|
2024-05-18 20:45:35 +02:00
|
|
|
|
2024-11-17 16:28:56 +01:00
|
|
|
fn create_struct_fn_arg() -> FnArg {
|
2024-11-11 21:52:22 +01:00
|
|
|
parse2(quote! {
|
2024-11-17 16:28:56 +01:00
|
|
|
tuono_lib::axum::extract::State(state): tuono_lib::axum::extract::State<ApplicationState>
|
2024-11-11 21:52:22 +01:00
|
|
|
})
|
|
|
|
|
.unwrap()
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-17 17:11:07 +01:00
|
|
|
fn import_main_application_state(argument_names: Punctuated<Pat, Comma>) -> Option<Stmt> {
|
2024-11-17 16:28:56 +01:00
|
|
|
if !argument_names.is_empty() {
|
2024-11-17 17:11:07 +01:00
|
|
|
let local: Stmt = parse_quote!(
|
|
|
|
|
use crate::tuono_main_state::ApplicationState;
|
|
|
|
|
);
|
|
|
|
|
return Some(local);
|
2024-11-17 16:28:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn crate_application_state_extractor(argument_names: Punctuated<Pat, Comma>) -> Option<Stmt> {
|
|
|
|
|
if !argument_names.is_empty() {
|
2024-11-17 17:11:07 +01:00
|
|
|
let use_item: Stmt = parse_quote!(let ApplicationState { #argument_names } = state;);
|
|
|
|
|
return Some(use_item);
|
2024-11-17 16:28:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
None
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-11 21:52:22 +01:00
|
|
|
fn params_argument() -> FnArg {
|
|
|
|
|
parse2(quote! {
|
|
|
|
|
tuono_lib::axum::extract::Path(params): tuono_lib::axum::extract::Path<
|
|
|
|
|
std::collections::HashMap<String, String>
|
|
|
|
|
>
|
|
|
|
|
})
|
|
|
|
|
.unwrap()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn request_argument() -> FnArg {
|
|
|
|
|
parse2(quote! {
|
|
|
|
|
request: tuono_lib::axum::extract::Request
|
|
|
|
|
})
|
|
|
|
|
.unwrap()
|
|
|
|
|
}
|
2024-05-18 20:45:35 +02:00
|
|
|
pub fn handler_core(_args: TokenStream, item: TokenStream) -> TokenStream {
|
|
|
|
|
let item = parse_macro_input!(item as ItemFn);
|
|
|
|
|
|
2024-11-11 21:52:22 +01:00
|
|
|
let fn_name = &item.sig.ident;
|
2024-05-18 20:45:35 +02:00
|
|
|
|
2024-11-11 21:52:22 +01:00
|
|
|
let mut argument_names: Punctuated<Pat, Comma> = Punctuated::new();
|
|
|
|
|
let mut axum_arguments: Punctuated<FnArg, Comma> = Punctuated::new();
|
|
|
|
|
|
|
|
|
|
// Fn Arguments minus the first which always is the request
|
|
|
|
|
for (i, arg) in item.sig.inputs.iter().enumerate() {
|
|
|
|
|
if i == 0 {
|
|
|
|
|
axum_arguments.insert(i, params_argument());
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-17 16:28:56 +01:00
|
|
|
if i == 1 {
|
|
|
|
|
axum_arguments.insert(1, create_struct_fn_arg())
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-11 21:52:22 +01:00
|
|
|
if let FnArg::Typed(pat_type) = arg {
|
|
|
|
|
let index = i - 1;
|
|
|
|
|
let argument_name = *pat_type.pat.clone();
|
|
|
|
|
argument_names.insert(index, argument_name.clone());
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-05-18 20:45:35 +02:00
|
|
|
|
2024-11-11 21:52:22 +01:00
|
|
|
axum_arguments.insert(axum_arguments.len(), request_argument());
|
|
|
|
|
|
2024-11-17 16:28:56 +01:00
|
|
|
let application_state_extractor = crate_application_state_extractor(argument_names.clone());
|
|
|
|
|
let application_state_import = import_main_application_state(argument_names.clone());
|
|
|
|
|
|
2024-11-11 21:52:22 +01:00
|
|
|
quote! {
|
2024-11-17 16:28:56 +01:00
|
|
|
#application_state_import
|
|
|
|
|
|
2024-05-18 20:45:35 +02:00
|
|
|
#item
|
|
|
|
|
|
2024-06-02 20:32:53 +02:00
|
|
|
pub async fn route(
|
2024-11-11 21:52:22 +01:00
|
|
|
#axum_arguments
|
|
|
|
|
) -> impl tuono_lib::axum::response::IntoResponse {
|
2024-11-17 16:28:56 +01:00
|
|
|
|
|
|
|
|
#application_state_extractor
|
|
|
|
|
|
2024-07-09 19:00:48 +02:00
|
|
|
let pathname = request.uri();
|
|
|
|
|
let headers = request.headers();
|
2024-05-19 12:22:56 +02:00
|
|
|
|
2024-07-09 19:00:48 +02:00
|
|
|
let req = tuono_lib::Request::new(pathname.to_owned(), headers.to_owned(), params);
|
2024-05-19 12:22:56 +02:00
|
|
|
|
2024-11-11 21:52:22 +01:00
|
|
|
#fn_name(req.clone(), #argument_names).await.render_to_string(req)
|
2024-05-20 21:07:37 +02:00
|
|
|
}
|
|
|
|
|
|
2024-06-02 20:32:53 +02:00
|
|
|
pub async fn api(
|
2024-11-11 21:52:22 +01:00
|
|
|
#axum_arguments
|
|
|
|
|
) -> impl tuono_lib::axum::response::IntoResponse {
|
2024-11-17 16:28:56 +01:00
|
|
|
|
|
|
|
|
#application_state_extractor
|
|
|
|
|
|
2024-07-09 19:00:48 +02:00
|
|
|
let pathname = request.uri();
|
|
|
|
|
let headers = request.headers();
|
2024-05-20 21:07:37 +02:00
|
|
|
|
2024-07-09 19:00:48 +02:00
|
|
|
let req = tuono_lib::Request::new(pathname.to_owned(), headers.to_owned(), params);
|
2024-05-20 21:07:37 +02:00
|
|
|
|
2024-11-11 21:52:22 +01:00
|
|
|
#fn_name(req.clone(), #argument_names).await.json()
|
2024-05-18 20:45:35 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
.into()
|
|
|
|
|
}
|