Skip to main content

nidus_http/
router.rs

1//! Axum router composition.
2
3mod metadata;
4mod path;
5
6use axum::{Router, handler::Handler, routing};
7use http::Method;
8
9use crate::error::RoutePathError;
10
11pub use metadata::{OpenApiSchemaRegistrar, RouteMetadata};
12pub(crate) use path::join_paths;
13use path::normalize_path;
14
15/// A route declaration that can be mounted by a controller.
16pub struct RouteDefinition {
17    method: Method,
18    path: String,
19    route: routing::MethodRouter,
20}
21
22impl RouteDefinition {
23    /// Creates a GET route.
24    pub fn get<H, T>(path: impl Into<String>, handler: H) -> Self
25    where
26        H: Handler<T, ()> + Clone + Send + Sync + 'static,
27        T: 'static,
28    {
29        Self::try_get(path, handler).unwrap_or_else(|error| panic!("{error}"))
30    }
31
32    /// Tries to create a GET route.
33    pub fn try_get<H, T>(path: impl Into<String>, handler: H) -> Result<Self, RoutePathError>
34    where
35        H: Handler<T, ()> + Clone + Send + Sync + 'static,
36        T: 'static,
37    {
38        Self::try_new(Method::GET, path, routing::get(handler))
39    }
40
41    /// Creates a POST route.
42    pub fn post<H, T>(path: impl Into<String>, handler: H) -> Self
43    where
44        H: Handler<T, ()> + Clone + Send + Sync + 'static,
45        T: 'static,
46    {
47        Self::try_post(path, handler).unwrap_or_else(|error| panic!("{error}"))
48    }
49
50    /// Tries to create a POST route.
51    pub fn try_post<H, T>(path: impl Into<String>, handler: H) -> Result<Self, RoutePathError>
52    where
53        H: Handler<T, ()> + Clone + Send + Sync + 'static,
54        T: 'static,
55    {
56        Self::try_new(Method::POST, path, routing::post(handler))
57    }
58
59    /// Creates a PUT route.
60    pub fn put<H, T>(path: impl Into<String>, handler: H) -> Self
61    where
62        H: Handler<T, ()> + Clone + Send + Sync + 'static,
63        T: 'static,
64    {
65        Self::try_put(path, handler).unwrap_or_else(|error| panic!("{error}"))
66    }
67
68    /// Tries to create a PUT route.
69    pub fn try_put<H, T>(path: impl Into<String>, handler: H) -> Result<Self, RoutePathError>
70    where
71        H: Handler<T, ()> + Clone + Send + Sync + 'static,
72        T: 'static,
73    {
74        Self::try_new(Method::PUT, path, routing::put(handler))
75    }
76
77    /// Creates a PATCH route.
78    pub fn patch<H, T>(path: impl Into<String>, handler: H) -> Self
79    where
80        H: Handler<T, ()> + Clone + Send + Sync + 'static,
81        T: 'static,
82    {
83        Self::try_patch(path, handler).unwrap_or_else(|error| panic!("{error}"))
84    }
85
86    /// Tries to create a PATCH route.
87    pub fn try_patch<H, T>(path: impl Into<String>, handler: H) -> Result<Self, RoutePathError>
88    where
89        H: Handler<T, ()> + Clone + Send + Sync + 'static,
90        T: 'static,
91    {
92        Self::try_new(Method::PATCH, path, routing::patch(handler))
93    }
94
95    /// Creates a DELETE route.
96    pub fn delete<H, T>(path: impl Into<String>, handler: H) -> Self
97    where
98        H: Handler<T, ()> + Clone + Send + Sync + 'static,
99        T: 'static,
100    {
101        Self::try_delete(path, handler).unwrap_or_else(|error| panic!("{error}"))
102    }
103
104    /// Tries to create a DELETE route.
105    pub fn try_delete<H, T>(path: impl Into<String>, handler: H) -> Result<Self, RoutePathError>
106    where
107        H: Handler<T, ()> + Clone + Send + Sync + 'static,
108        T: 'static,
109    {
110        Self::try_new(Method::DELETE, path, routing::delete(handler))
111    }
112
113    /// Returns the route path.
114    pub fn path(&self) -> &str {
115        &self.path
116    }
117
118    /// Returns the route method.
119    pub fn method(&self) -> &Method {
120        &self.method
121    }
122
123    pub(crate) fn into_router(self, full_path: String) -> Router {
124        Router::new().route(&full_path, self.route)
125    }
126
127    fn try_new(
128        method: Method,
129        path: impl Into<String>,
130        route: routing::MethodRouter,
131    ) -> Result<Self, RoutePathError> {
132        Ok(Self {
133            method,
134            path: normalize_path(path.into())?,
135            route,
136        })
137    }
138}