use proc_macro::TokenStream;
use syn::{Item, ItemStruct, parse_macro_input};
mod app;
mod body_input;
mod codegen;
mod define_route_input;
mod handler;
mod json;
mod lifetimes;
mod model;
mod request;
mod response;
mod route_compiler;
mod util;
#[proc_macro]
pub fn body(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as body_input::BodyInput);
input.expand().into()
}
fn emit(result: syn::Result<proc_macro2::TokenStream>) -> TokenStream {
match result {
Ok(tokens) => tokens.into(),
Err(error) => error.into_compile_error().into(),
}
}
#[proc_macro]
pub fn define_route(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as define_route_input::DefineRouteInput);
emit(app::define_route(input))
}
#[proc_macro_attribute]
pub fn handler(attr_args: TokenStream, item: TokenStream) -> TokenStream {
if !attr_args.is_empty() {
return syn::Error::new(
proc_macro2::Span::call_site(),
"#[sark_gen::handler] takes no arguments; path and method belong to define_route!",
)
.to_compile_error()
.into();
}
let item = parse_macro_input!(item as Item);
emit(match item {
Item::Fn(fun) => handler::Handler::new(fun).and_then(handler::Handler::expand),
other => Err(syn::Error::new_spanned(
other,
"#[sark_gen::handler] supports only fn",
)),
})
}
#[proc_macro_attribute]
pub fn json(attr: TokenStream, item: TokenStream) -> TokenStream {
let st = parse_macro_input!(item as ItemStruct);
let mode = parse_macro_input!(attr as json::JsonMode);
emit(mode.expand(st))
}
#[proc_macro_attribute]
pub fn request(attr: TokenStream, item: TokenStream) -> TokenStream {
let mode = parse_macro_input!(attr as request::Mode);
let st = parse_macro_input!(item as ItemStruct);
emit(mode.expand(st))
}
#[proc_macro_attribute]
pub fn response(attr: TokenStream, item: TokenStream) -> TokenStream {
let mode = parse_macro_input!(attr as response::Mode);
let st = parse_macro_input!(item as ItemStruct);
emit(mode.expand(st))
}