1use proc_macro::TokenStream;
32use syn::{Item, ItemStruct, parse_macro_input};
33
34mod app;
35mod body_input;
36mod codegen;
37mod define_route_input;
38mod handler;
39mod json;
40mod lifetimes;
41mod model;
42mod request;
43mod response;
44mod route_compiler;
45mod util;
46
47#[proc_macro]
48pub fn body(input: TokenStream) -> TokenStream {
49 let input = parse_macro_input!(input as body_input::BodyInput);
50 input.expand().into()
51}
52
53fn emit(result: syn::Result<proc_macro2::TokenStream>) -> TokenStream {
54 match result {
55 Ok(tokens) => tokens.into(),
56 Err(error) => error.into_compile_error().into(),
57 }
58}
59
60#[proc_macro]
61pub fn define_route(input: TokenStream) -> TokenStream {
62 let input = parse_macro_input!(input as define_route_input::DefineRouteInput);
63 emit(app::define_route(input))
64}
65
66#[proc_macro_attribute]
67pub fn handler(attr_args: TokenStream, item: TokenStream) -> TokenStream {
68 if !attr_args.is_empty() {
69 return syn::Error::new(
70 proc_macro2::Span::call_site(),
71 "#[sark_gen::handler] takes no arguments; path and method belong to define_route!",
72 )
73 .to_compile_error()
74 .into();
75 }
76 let item = parse_macro_input!(item as Item);
77 emit(match item {
78 Item::Fn(fun) => handler::Handler::new(fun).and_then(handler::Handler::expand),
79 other => Err(syn::Error::new_spanned(
80 other,
81 "#[sark_gen::handler] supports only fn",
82 )),
83 })
84}
85
86#[proc_macro_attribute]
87pub fn json(attr: TokenStream, item: TokenStream) -> TokenStream {
88 let st = parse_macro_input!(item as ItemStruct);
89 let mode = parse_macro_input!(attr as json::JsonMode);
90 emit(mode.expand(st))
91}
92
93#[proc_macro_attribute]
94pub fn request(attr: TokenStream, item: TokenStream) -> TokenStream {
95 let mode = parse_macro_input!(attr as request::Mode);
96 let st = parse_macro_input!(item as ItemStruct);
97 emit(mode.expand(st))
98}
99
100#[proc_macro_attribute]
101pub fn response(attr: TokenStream, item: TokenStream) -> TokenStream {
102 let mode = parse_macro_input!(attr as response::Mode);
103 let st = parse_macro_input!(item as ItemStruct);
104 emit(mode.expand(st))
105}