Skip to main content

doxa_docs/
routes_macro.rs

1//! [`routes!`](crate::routes) — drop-in replacement for
2//! [`utoipa_axum::routes!`] that additionally collects schemas
3//! referenced by handler-argument types.
4//!
5//! See the `utoipa_axum::routes!` expansion for the primary
6//! plumbing; we wrap it to also extend the collected schemas with
7//! those referenced by each handler's argument types through its
8//! generated [`ApidocHandlerSchemas`](crate::ApidocHandlerSchemas)
9//! impl. Caller-facing syntax is unchanged.
10
11/// Wraps [`utoipa_axum::routes!`] and augments the schemas vector
12/// with everything each handler's argument types reference.
13///
14/// Accepts either `ident` handlers (`routes!(list_models)`) or
15/// qualified paths (`routes!(pets::get_pet)`), matching the upstream
16/// macro's caller surface.
17#[macro_export]
18macro_rules! routes {
19    // Top-level entry: utoipa-axum captures handlers as `:path` and
20    // the capture becomes opaque to subsequent :ident matchers, so
21    // we parse handler paths here as `:tt` sequences that we can
22    // walk token-by-token in the recursion below. The list is
23    // forwarded verbatim to `utoipa_axum::routes!`.
24    //
25    // The grammar is: a handler is one or more `ident` tokens
26    // separated by `::`. Handlers are separated by `,`.
27    ($($handler_seg:ident $(:: $handler_rest:ident)*),+ $(,)?) => {{
28        let mut __routes_result = $crate::__private::utoipa_axum_routes!(
29            $($handler_seg $(:: $handler_rest)*),+
30        );
31        $(
32            $crate::routes!(
33                @collect __routes_result,
34                prefix: [],
35                rest: $handler_seg $(:: $handler_rest)*
36            );
37        )+
38        __routes_result
39    }};
40
41    // Muncher: accumulate prefix tokens while more `::` segments
42    // follow, then paste the final `__path_<last>` into the
43    // prefix-qualified path.
44    (@collect $r:ident, prefix: [$($prefix:tt)*], rest: $head:ident :: $($tail:tt)+) => {
45        $crate::routes!(
46            @collect $r,
47            prefix: [$($prefix)* $head ::],
48            rest: $($tail)+
49        )
50    };
51    (@collect $r:ident, prefix: [$($prefix:tt)*], rest: $last:ident) => {
52        $crate::__private::paste::paste! {
53            <$($prefix)* [<__path_ $last>]
54                as $crate::ApidocHandlerSchemas>::collect(&mut $r.0);
55            <$($prefix)* [<__path_ $last>]
56                as $crate::ApidocHandlerOps>::augment(&mut $r.1);
57        }
58    };
59}