Skip to main content

oxapi_impl/
router.rs

1//! Router generation for axum.
2
3use proc_macro2::TokenStream;
4use quote::{format_ident, quote};
5
6use crate::openapi::HttpMethod;
7
8/// Generator for axum router code.
9pub struct RouterGenerator;
10
11impl RouterGenerator {
12    /// Generate the body of the map_routes function.
13    ///
14    /// The methods parameter is a list of (method_name, http_method, path) tuples.
15    /// The spec_method parameter is an optional (method_name, endpoint_path) for the spec route.
16    pub fn generate_map_routes(
17        &self,
18        methods: &[(syn::Ident, HttpMethod, String)],
19        spec_method: Option<(syn::Ident, String)>,
20    ) -> TokenStream {
21        let routes = methods.iter().map(|(method_name, http_method, path)| {
22            // OpenAPI and axum 0.8+ both use {param} format
23            let method_fn = http_method_to_axum_fn(*http_method);
24
25            quote! {
26                .route(#path, ::axum::routing::#method_fn(Self::#method_name))
27            }
28        });
29
30        let spec_route = spec_method.map(|(method_name, path)| {
31            quote! {
32                .route(#path, ::axum::routing::get(|| async { Self::#method_name() }))
33            }
34        });
35
36        quote! {
37            router
38                #(#routes)*
39                #spec_route
40        }
41    }
42}
43
44/// Get the axum routing function for an HTTP method.
45fn http_method_to_axum_fn(method: HttpMethod) -> syn::Ident {
46    format_ident!("{}", method.as_str())
47}