Skip to main content

nestforge_core/
route_builder.rs

1use axum::{
2    routing::{get, post, put},
3    Router,
4};
5
6use crate::{Container, ControllerBasePath};
7
8/*
9RouteBuilder<T> helps us build routes cleanly in generated code.
10It prefixes method routes using the controller base path from #[controller("...")].
11*/
12pub struct RouteBuilder<T> {
13    router: Router<Container>,
14    _marker: std::marker::PhantomData<T>,
15}
16
17impl<T> RouteBuilder<T>
18where
19    T: ControllerBasePath,
20{
21    pub fn new() -> Self {
22        Self {
23            router: Router::new(),
24            _marker: std::marker::PhantomData,
25        }
26    }
27
28    fn full_path(path: &str) -> String {
29        let base = T::base_path().trim_end_matches('/');
30        let path = path.trim();
31
32        let sub = if path == "/" {
33            ""
34        } else {
35            path.trim_start_matches('/')
36        };
37
38        if base.is_empty() {
39            if sub.is_empty() {
40                "/".to_string()
41            } else {
42                format!("/{}", sub)
43            }
44        } else if sub.is_empty() {
45            base.to_string()
46        } else {
47            format!("{}/{}", base, sub)
48        }
49    }
50
51    pub fn get<H, TState>(self, path: &str, handler: H) -> Self
52    where
53        H: axum::handler::Handler<TState, Container> + Clone + Send + Sync + 'static,
54        TState: 'static,
55    {
56        let full = Self::full_path(path);
57
58        Self {
59            router: self.router.route(&full, get(handler)),
60            _marker: std::marker::PhantomData,
61        }
62    }
63
64    pub fn post<H, TState>(self, path: &str, handler: H) -> Self
65    where
66        H: axum::handler::Handler<TState, Container> + Clone + Send + Sync + 'static,
67        TState: 'static,
68    {
69        let full = Self::full_path(path);
70
71        Self {
72            router: self.router.route(&full, post(handler)),
73            _marker: std::marker::PhantomData,
74        }
75    }
76
77    pub fn put<H, TState>(self, path: &str, handler: H) -> Self
78    where
79        H: axum::handler::Handler<TState, Container> + Clone + Send + Sync + 'static,
80        TState: 'static,
81    {
82        let full = Self::full_path(path);
83
84        Self {
85            router: self.router.route(&full, put(handler)),
86            _marker: std::marker::PhantomData,
87        }
88    }
89
90    pub fn build(self) -> Router<Container> {
91        self.router
92    }
93}