1pub use rovo_macros::rovo;
2
3pub use aide;
5
6use ::axum::Extension;
7use aide::axum::ApiRouter as AideApiRouter;
8
9pub struct Router<S = ()> {
33 inner: AideApiRouter<S>,
34}
35
36impl<S> Router<S>
37where
38 S: Clone + Send + Sync + 'static,
39{
40 pub fn new() -> Self {
42 Self {
43 inner: AideApiRouter::new(),
44 }
45 }
46
47 pub fn route<M>(mut self, path: &str, method_router: M) -> Self
49 where
50 M: Into<aide::axum::routing::ApiMethodRouter<S>>,
51 {
52 self.inner = self.inner.api_route(path, method_router.into());
53 self
54 }
55
56 pub fn nest(mut self, path: &str, router: Router<S>) -> Self {
58 self.inner = self.inner.nest(path, router.inner);
59 self
60 }
61
62 #[cfg(feature = "swagger")]
64 pub fn with_swagger(mut self, swagger_path: &str, api_json_path: &str) -> Self
65 where
66 S: Clone + Send + Sync + 'static,
67 {
68 self.inner = self.inner.route(
69 swagger_path,
70 aide::swagger::Swagger::new(api_json_path).axum_route(),
71 );
72 self
73 }
74
75 #[cfg(feature = "redoc")]
77 pub fn with_redoc(mut self, redoc_path: &str, api_json_path: &str) -> Self
78 where
79 S: Clone + Send + Sync + 'static,
80 {
81 self.inner = self.inner.route(
82 redoc_path,
83 aide::redoc::Redoc::new(api_json_path).axum_route(),
84 );
85 self
86 }
87
88 #[cfg(feature = "scalar")]
90 pub fn with_scalar(mut self, scalar_path: &str, api_json_path: &str) -> Self
91 where
92 S: Clone + Send + Sync + 'static,
93 {
94 self.inner = self.inner.route(
95 scalar_path,
96 aide::scalar::Scalar::new(api_json_path).axum_route(),
97 );
98 self
99 }
100
101 pub fn with_api_json<H, T>(mut self, path: &str, handler: H) -> Self
103 where
104 H: ::axum::handler::Handler<T, S>,
105 S: Clone + Send + Sync + 'static,
106 T: 'static,
107 {
108 self.inner = self.inner.route(path, ::axum::routing::get(handler));
109 self
110 }
111
112 pub fn with_state<S2>(self, state: S) -> Router<S2>
114 where
115 S2: Clone + Send + Sync + 'static,
116 {
117 Router {
118 inner: self.inner.with_state(state),
119 }
120 }
121
122 pub fn finish_api(self, api: &mut aide::openapi::OpenApi) -> ::axum::Router<S> {
124 self.inner.finish_api(api)
125 }
126
127 pub fn finish_api_with_extension(self, api: aide::openapi::OpenApi) -> ::axum::Router<S>
129 where
130 S: Clone + Send + Sync + 'static,
131 {
132 let mut api_mut = api;
133 self.inner
134 .finish_api(&mut api_mut)
135 .layer(Extension(api_mut))
136 }
137
138 pub fn into_inner(self) -> AideApiRouter<S> {
140 self.inner
141 }
142}
143
144impl<S> Default for Router<S>
145where
146 S: Clone + Send + Sync + 'static,
147{
148 fn default() -> Self {
149 Self::new()
150 }
151}
152
153pub trait IntoApiMethodRouter<S = ()> {
161 fn into_get_route(self) -> aide::axum::routing::ApiMethodRouter<S>;
163 fn into_post_route(self) -> aide::axum::routing::ApiMethodRouter<S>;
165 fn into_patch_route(self) -> aide::axum::routing::ApiMethodRouter<S>;
167 fn into_delete_route(self) -> aide::axum::routing::ApiMethodRouter<S>;
169 fn into_put_route(self) -> aide::axum::routing::ApiMethodRouter<S>;
171}
172
173pub struct ApiMethodRouter<S = ()> {
188 inner: aide::axum::routing::ApiMethodRouter<S>,
189}
190
191impl<S> ApiMethodRouter<S>
192where
193 S: Clone + Send + Sync + 'static,
194{
195 pub fn new(inner: aide::axum::routing::ApiMethodRouter<S>) -> Self {
197 Self { inner }
198 }
199
200 pub fn post<H>(self, handler: H) -> Self
202 where
203 H: IntoApiMethodRouter<S>,
204 {
205 Self {
206 inner: self.inner.merge(handler.into_post_route()),
207 }
208 }
209
210 pub fn get<H>(self, handler: H) -> Self
212 where
213 H: IntoApiMethodRouter<S>,
214 {
215 Self {
216 inner: self.inner.merge(handler.into_get_route()),
217 }
218 }
219
220 pub fn patch<H>(self, handler: H) -> Self
222 where
223 H: IntoApiMethodRouter<S>,
224 {
225 Self {
226 inner: self.inner.merge(handler.into_patch_route()),
227 }
228 }
229
230 pub fn delete<H>(self, handler: H) -> Self
232 where
233 H: IntoApiMethodRouter<S>,
234 {
235 Self {
236 inner: self.inner.merge(handler.into_delete_route()),
237 }
238 }
239
240 pub fn put<H>(self, handler: H) -> Self
242 where
243 H: IntoApiMethodRouter<S>,
244 {
245 Self {
246 inner: self.inner.merge(handler.into_put_route()),
247 }
248 }
249}
250
251impl<S> From<ApiMethodRouter<S>> for aide::axum::routing::ApiMethodRouter<S> {
252 fn from(router: ApiMethodRouter<S>) -> Self {
253 router.inner
254 }
255}
256
257pub mod routing {
271 use super::*;
272
273 pub fn get<S, H>(handler: H) -> ApiMethodRouter<S>
275 where
276 H: IntoApiMethodRouter<S>,
277 S: Clone + Send + Sync + 'static,
278 {
279 ApiMethodRouter::new(handler.into_get_route())
280 }
281
282 pub fn post<S, H>(handler: H) -> ApiMethodRouter<S>
284 where
285 H: IntoApiMethodRouter<S>,
286 S: Clone + Send + Sync + 'static,
287 {
288 ApiMethodRouter::new(handler.into_post_route())
289 }
290
291 pub fn patch<S, H>(handler: H) -> ApiMethodRouter<S>
293 where
294 H: IntoApiMethodRouter<S>,
295 S: Clone + Send + Sync + 'static,
296 {
297 ApiMethodRouter::new(handler.into_patch_route())
298 }
299
300 pub fn delete<S, H>(handler: H) -> ApiMethodRouter<S>
302 where
303 H: IntoApiMethodRouter<S>,
304 S: Clone + Send + Sync + 'static,
305 {
306 ApiMethodRouter::new(handler.into_delete_route())
307 }
308
309 pub fn put<S, H>(handler: H) -> ApiMethodRouter<S>
311 where
312 H: IntoApiMethodRouter<S>,
313 S: Clone + Send + Sync + 'static,
314 {
315 ApiMethodRouter::new(handler.into_put_route())
316 }
317}
318
319pub mod axum {
320 pub use aide::axum::{ApiRouter, IntoApiResponse};
321}