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())
}
};
output.into()
}