yadro-codegen 0.0.1

generatative macros for yadro
Documentation
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()
}