nestforge_core/
route_builder.rs1use axum::{
2 routing::{get, post, put},
3 Router,
4};
5
6use crate::{Container, ControllerBasePath};
7
8pub 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}