minihttp-codegen 0.1.0

Provides codegen for minnihttp
Documentation
use std::ops::Deref;

use proc_macro::TokenStream;
use quote::quote;
use syn::parse_macro_input;

#[proc_macro_attribute]
pub fn get(attr: TokenStream, item: TokenStream) -> TokenStream {
    eprintln!("{:#?}\n{:#?}", attr, item);
    let args = parse_macro_input!(attr as syn::AttributeArgs);
    let item: syn::ItemFn = syn::parse(item).unwrap();

    let name = item.sig.ident.clone();
    let body = item.block.deref();
    let path = args[0].clone();

    let output = quote! {
        fn #name() -> Box<Route> {

            #[allow(non_camel_case_types)]

            #[derive(Clone)]
            struct route {
                path: &'static str,
                method: Method,
            }

            impl route {
                fn new() -> Self {
                    route {
                        path: #path.into(),
                        method: Method::GET,
                    }
                }
            }

            impl Default for route {
                fn default() -> route {
                    route {
                        path: #path.into(),
                        method: Method::GET,
                    }
                }
            }

            impl Route for route {
                fn get_path(&self) -> &str {
                    self.path
                }
                fn get_method(&self) -> Method {
                    self.method
                }
                fn get_body(&self) -> Vec<u8> {
                    #body.into()
                }
                fn post_body(&self) -> fn(Vec<u8>) -> Vec<u8> {
                    fn panic(post: Vec<u8>) -> Vec<u8> {
                        panic!("NOT A POST ROUTE");
                    };
                    panic
                }
            }

            Box::new(route::new())
        }
    };

    output.into()
}

#[proc_macro_attribute]
pub fn post(attr: TokenStream, item: TokenStream) -> TokenStream {
    eprintln!("{:#?}\n{:#?}", attr, item);
    let args = parse_macro_input!(attr as syn::AttributeArgs);
    let item: syn::ItemFn = syn::parse(item).unwrap();

    let name = item.sig.ident.clone();
    let body = item.block.deref();
    let path = args[0].clone();

    let output = quote! {
        fn #name() -> Box<Route> {

            #[allow(non_camel_case_types)]

            #[derive(Clone)]
            struct route {
                path: &'static str,
                method: Method,
            }

            impl route {
                fn new() -> Self {
                    route {
                        path: #path.into(),
                        method: Method::POST,
                    }
                }
            }

            impl Default for route {
                fn default() -> route {
                    route {
                        path: #path.into(),
                        method: Method::POST,
                    }
                }
            }

            impl Route for route {
                fn get_path(&self) -> &str {
                    self.path
                }
                fn get_method(&self) -> Method {
                    self.method
                }
                fn get_body(&self) -> Vec<u8> {
                    panic!("NOT A GET!");
                }
                fn post_body(&self) -> fn(Vec<u8>) -> Vec<u8> {
                    fn body(post: Vec<u8>) -> Vec<u8> {
                        #body
                    };
                    body
                }
            }

            Box::new(route::new())
        }
    };

    /*let output = quote! {
        fn #name() -> (String, Vec<u8>, Method) {
            fn body() #output {
                #body
            }

            (#path.into(), body().into(), Method::POST)
        }
    };*/

    output.into()
}