Skip to main content

const_router_macros/
lib.rs

1use proc_macro::TokenStream;
2use proc_macro2::TokenStream as TokenStream2;
3use syn::{Error, Result};
4
5mod handler;
6mod router;
7
8/// Builds a `const_router::Router` with routes sorted by static string key.
9///
10/// The first input is the fallback handler. The remaining inputs use
11/// `"/path" => handler` entries separated by commas.
12/// Each handler should be produced by `#[const_router::handler]`.
13/// Duplicate keys are rejected at macro expansion time.
14#[proc_macro]
15pub fn router(input: TokenStream) -> TokenStream {
16    compile(router::expand(input.into()))
17}
18
19/// Converts a synchronous or asynchronous function returning `Result` into a
20/// `const_router` handler.
21///
22/// The function may take either no request argument or one request argument:
23///
24/// - `fn() -> Result<TResponse, TError>`
25/// - `fn(TRequest) -> Result<TResponse, TError>`
26/// - `async fn() -> Result<TResponse, TError>`
27/// - `async fn(TRequest) -> Result<TResponse, TError>`
28#[proc_macro_attribute]
29pub fn handler(attr: TokenStream, item: TokenStream) -> TokenStream {
30    if !attr.is_empty() {
31        return Error::new(
32            proc_macro2::Span::call_site(),
33            "`handler` does not accept arguments",
34        )
35        .into_compile_error()
36        .into();
37    }
38
39    compile(handler::expand(item.into()))
40}
41
42fn compile(result: Result<TokenStream2>) -> TokenStream {
43    result.unwrap_or_else(Error::into_compile_error).into()
44}