use proc_macro::TokenStream;
#[proc_macro_attribute]
pub fn handler(_attr: TokenStream, tokens: TokenStream) -> TokenStream {
let mut components = Vec::new();
let mut next_function_name = false;
let mut filtered: Vec<proc_macro::TokenTree> = Vec::new();
for t in tokens {
match t {
proc_macro::TokenTree::Group(g) => {
if filtered.len() == 1 {
for group in g.stream() {
match group {
proc_macro::TokenTree::Ident(token) => match token.to_string().as_str() {
"Request" => components.push("req"),
"Response" => components.push("res"),
_ => {},
},
_ => {},
}
}
}
filtered.push(g.into());
},
proc_macro::TokenTree::Ident(i) => {
if next_function_name {
filtered.push(i.into());
next_function_name = false;
continue;
}
if i.to_string().eq("fn") {
next_function_name = true;
}
}
_ => {}
}
}
format!(r#"
#[allow(non_camel_case_types)]
struct {name};
#[allow(non_camel_case_types)]
impl ::core::fmt::Debug for {name} {{
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {{
::core::fmt::Formatter::write_str(f, "{name}")
}}
}}
impl {name} {{
async fn {name}{args} {{
{body}
}}
}}
impl yadro::router::Handler for {name} {{
#[must_use = "handle future must be used"]
#[allow(clippy::type_complexity,clippy::type_repetition_in_bounds)]
fn handle<'life0,'life1,'life2,'async_trait>(
&'life0 self,req: &'life1 mut yadro::http::Request,res: &'life2 mut yadro::http::Response
) -> ::core::pin::Pin<Box<dyn ::core::future::Future<Output = ()> + ::core::marker::Send+'async_trait> >
where 'life0:'async_trait,'life1:'async_trait,'life2:'async_trait,Self:'async_trait {{
Box::pin(async move {{
let __self = self;
let () = {{ Self::{name}({}).await }};
}})
}}
}}"#,
components.join(","),
name = &filtered[0],
args = &filtered[1],
body = &filtered[2],
).parse().unwrap()
}