1use super::definition::RouteDefinition;
2use crate::routing::handler::RouteHandler;
3use crate::{
4 BootRequest, BootResponse, HttpMethod, ModuleRef, OpenApiResponse, Result, SseEvent, Validate,
5};
6use futures_core::Stream;
7use serde::de::DeserializeOwned;
8use serde::Serialize;
9use std::future::Future;
10
11impl RouteDefinition {
12 pub fn all<H>(path: impl Into<String>, handler: H) -> Result<Self>
13 where
14 H: RouteHandler,
15 {
16 Self::new(HttpMethod::All, path, handler)
17 }
18
19 pub fn all_scoped<F, H>(path: impl Into<String>, factory: F) -> Result<Self>
20 where
21 F: Fn(&ModuleRef) -> Result<H> + Send + Sync + 'static,
22 H: RouteHandler,
23 {
24 Self::new_scoped(HttpMethod::All, path, factory)
25 }
26
27 pub fn all_json<H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
28 where
29 H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
30 Fut: Future<Output = Result<R>> + Send + 'static,
31 R: Serialize + Send + 'static,
32 {
33 Self::all_json_with_status(path, 200, handler)
34 }
35
36 pub fn all_json_with_status<H, Fut, R>(
37 path: impl Into<String>,
38 status: u16,
39 handler: H,
40 ) -> Result<Self>
41 where
42 H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
43 Fut: Future<Output = Result<R>> + Send + 'static,
44 R: Serialize + Send + 'static,
45 {
46 Self::json_response_with_status(HttpMethod::All, path, status, handler)
47 }
48
49 pub fn get<H>(path: impl Into<String>, handler: H) -> Result<Self>
50 where
51 H: RouteHandler,
52 {
53 Self::new(HttpMethod::Get, path, handler)
54 }
55
56 pub fn get_scoped<F, H>(path: impl Into<String>, factory: F) -> Result<Self>
57 where
58 F: Fn(&ModuleRef) -> Result<H> + Send + Sync + 'static,
59 H: RouteHandler,
60 {
61 Self::new_scoped(HttpMethod::Get, path, factory)
62 }
63
64 pub fn get_json<H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
65 where
66 H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
67 Fut: Future<Output = Result<R>> + Send + 'static,
68 R: Serialize + Send + 'static,
69 {
70 Self::get_json_with_status(path, 200, handler)
71 }
72
73 pub fn get_json_with_status<H, Fut, R>(
74 path: impl Into<String>,
75 status: u16,
76 handler: H,
77 ) -> Result<Self>
78 where
79 H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
80 Fut: Future<Output = Result<R>> + Send + 'static,
81 R: Serialize + Send + 'static,
82 {
83 Self::json_response_with_status(HttpMethod::Get, path, status, handler)
84 }
85
86 pub fn sse<H, Fut, S>(path: impl Into<String>, handler: H) -> Result<Self>
87 where
88 H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
89 Fut: Future<Output = Result<S>> + Send + 'static,
90 S: Stream<Item = Result<SseEvent>> + Send + 'static,
91 {
92 Self::new(HttpMethod::Get, path, move |request: BootRequest| {
93 let future = request
94 .require_accepts_event_stream()
95 .map(|()| handler(request));
96 async move {
97 let stream = future?.await?;
98 Ok(BootResponse::sse(stream))
99 }
100 })
101 }
102
103 pub fn post<H>(path: impl Into<String>, handler: H) -> Result<Self>
104 where
105 H: RouteHandler,
106 {
107 Self::new(HttpMethod::Post, path, handler)
108 }
109
110 pub fn post_scoped<F, H>(path: impl Into<String>, factory: F) -> Result<Self>
111 where
112 F: Fn(&ModuleRef) -> Result<H> + Send + Sync + 'static,
113 H: RouteHandler,
114 {
115 Self::new_scoped(HttpMethod::Post, path, factory)
116 }
117
118 pub fn post_json<T, H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
119 where
120 T: DeserializeOwned + Send + 'static,
121 H: Fn(T) -> Fut + Send + Sync + 'static,
122 Fut: Future<Output = Result<R>> + Send + 'static,
123 R: Serialize + Send + 'static,
124 {
125 Self::post_json_with_status(path, 200, handler)
126 }
127
128 pub fn post_json_with_status<T, H, Fut, R>(
129 path: impl Into<String>,
130 status: u16,
131 handler: H,
132 ) -> Result<Self>
133 where
134 T: DeserializeOwned + Send + 'static,
135 H: Fn(T) -> Fut + Send + Sync + 'static,
136 Fut: Future<Output = Result<R>> + Send + 'static,
137 R: Serialize + Send + 'static,
138 {
139 Self::json_with_status(HttpMethod::Post, path, status, handler)
140 }
141
142 pub fn post_validated_json<T, H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
143 where
144 T: DeserializeOwned + Validate + Send + 'static,
145 H: Fn(T) -> Fut + Send + Sync + 'static,
146 Fut: Future<Output = Result<R>> + Send + 'static,
147 R: Serialize + Send + 'static,
148 {
149 Self::post_validated_json_with_status(path, 200, handler)
150 }
151
152 pub fn post_validated_json_with_status<T, H, Fut, R>(
153 path: impl Into<String>,
154 status: u16,
155 handler: H,
156 ) -> Result<Self>
157 where
158 T: DeserializeOwned + Validate + Send + 'static,
159 H: Fn(T) -> Fut + Send + Sync + 'static,
160 Fut: Future<Output = Result<R>> + Send + 'static,
161 R: Serialize + Send + 'static,
162 {
163 Self::validated_json_with_status(HttpMethod::Post, path, status, handler)
164 }
165
166 pub fn put<H>(path: impl Into<String>, handler: H) -> Result<Self>
167 where
168 H: RouteHandler,
169 {
170 Self::new(HttpMethod::Put, path, handler)
171 }
172
173 pub fn put_scoped<F, H>(path: impl Into<String>, factory: F) -> Result<Self>
174 where
175 F: Fn(&ModuleRef) -> Result<H> + Send + Sync + 'static,
176 H: RouteHandler,
177 {
178 Self::new_scoped(HttpMethod::Put, path, factory)
179 }
180
181 pub fn put_json<T, H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
182 where
183 T: DeserializeOwned + Send + 'static,
184 H: Fn(T) -> Fut + Send + Sync + 'static,
185 Fut: Future<Output = Result<R>> + Send + 'static,
186 R: Serialize + Send + 'static,
187 {
188 Self::put_json_with_status(path, 200, handler)
189 }
190
191 pub fn put_json_with_status<T, H, Fut, R>(
192 path: impl Into<String>,
193 status: u16,
194 handler: H,
195 ) -> Result<Self>
196 where
197 T: DeserializeOwned + Send + 'static,
198 H: Fn(T) -> Fut + Send + Sync + 'static,
199 Fut: Future<Output = Result<R>> + Send + 'static,
200 R: Serialize + Send + 'static,
201 {
202 Self::json_with_status(HttpMethod::Put, path, status, handler)
203 }
204
205 pub fn put_validated_json<T, H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
206 where
207 T: DeserializeOwned + Validate + Send + 'static,
208 H: Fn(T) -> Fut + Send + Sync + 'static,
209 Fut: Future<Output = Result<R>> + Send + 'static,
210 R: Serialize + Send + 'static,
211 {
212 Self::put_validated_json_with_status(path, 200, handler)
213 }
214
215 pub fn put_validated_json_with_status<T, H, Fut, R>(
216 path: impl Into<String>,
217 status: u16,
218 handler: H,
219 ) -> Result<Self>
220 where
221 T: DeserializeOwned + Validate + Send + 'static,
222 H: Fn(T) -> Fut + Send + Sync + 'static,
223 Fut: Future<Output = Result<R>> + Send + 'static,
224 R: Serialize + Send + 'static,
225 {
226 Self::validated_json_with_status(HttpMethod::Put, path, status, handler)
227 }
228
229 pub fn patch<H>(path: impl Into<String>, handler: H) -> Result<Self>
230 where
231 H: RouteHandler,
232 {
233 Self::new(HttpMethod::Patch, path, handler)
234 }
235
236 pub fn patch_scoped<F, H>(path: impl Into<String>, factory: F) -> Result<Self>
237 where
238 F: Fn(&ModuleRef) -> Result<H> + Send + Sync + 'static,
239 H: RouteHandler,
240 {
241 Self::new_scoped(HttpMethod::Patch, path, factory)
242 }
243
244 pub fn patch_json<T, H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
245 where
246 T: DeserializeOwned + Send + 'static,
247 H: Fn(T) -> Fut + Send + Sync + 'static,
248 Fut: Future<Output = Result<R>> + Send + 'static,
249 R: Serialize + Send + 'static,
250 {
251 Self::patch_json_with_status(path, 200, handler)
252 }
253
254 pub fn patch_json_with_status<T, H, Fut, R>(
255 path: impl Into<String>,
256 status: u16,
257 handler: H,
258 ) -> Result<Self>
259 where
260 T: DeserializeOwned + Send + 'static,
261 H: Fn(T) -> Fut + Send + Sync + 'static,
262 Fut: Future<Output = Result<R>> + Send + 'static,
263 R: Serialize + Send + 'static,
264 {
265 Self::json_with_status(HttpMethod::Patch, path, status, handler)
266 }
267
268 pub fn patch_validated_json<T, H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
269 where
270 T: DeserializeOwned + Validate + Send + 'static,
271 H: Fn(T) -> Fut + Send + Sync + 'static,
272 Fut: Future<Output = Result<R>> + Send + 'static,
273 R: Serialize + Send + 'static,
274 {
275 Self::patch_validated_json_with_status(path, 200, handler)
276 }
277
278 pub fn patch_validated_json_with_status<T, H, Fut, R>(
279 path: impl Into<String>,
280 status: u16,
281 handler: H,
282 ) -> Result<Self>
283 where
284 T: DeserializeOwned + Validate + Send + 'static,
285 H: Fn(T) -> Fut + Send + Sync + 'static,
286 Fut: Future<Output = Result<R>> + Send + 'static,
287 R: Serialize + Send + 'static,
288 {
289 Self::validated_json_with_status(HttpMethod::Patch, path, status, handler)
290 }
291
292 pub fn delete<H>(path: impl Into<String>, handler: H) -> Result<Self>
293 where
294 H: RouteHandler,
295 {
296 Self::new(HttpMethod::Delete, path, handler)
297 }
298
299 pub fn delete_scoped<F, H>(path: impl Into<String>, factory: F) -> Result<Self>
300 where
301 F: Fn(&ModuleRef) -> Result<H> + Send + Sync + 'static,
302 H: RouteHandler,
303 {
304 Self::new_scoped(HttpMethod::Delete, path, factory)
305 }
306
307 pub fn delete_json<H, Fut, R>(path: impl Into<String>, handler: H) -> Result<Self>
308 where
309 H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
310 Fut: Future<Output = Result<R>> + Send + 'static,
311 R: Serialize + Send + 'static,
312 {
313 Self::delete_json_with_status(path, 200, handler)
314 }
315
316 pub fn delete_json_with_status<H, Fut, R>(
317 path: impl Into<String>,
318 status: u16,
319 handler: H,
320 ) -> Result<Self>
321 where
322 H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
323 Fut: Future<Output = Result<R>> + Send + 'static,
324 R: Serialize + Send + 'static,
325 {
326 Self::json_response_with_status(HttpMethod::Delete, path, status, handler)
327 }
328
329 pub fn options<H>(path: impl Into<String>, handler: H) -> Result<Self>
330 where
331 H: RouteHandler,
332 {
333 Self::new(HttpMethod::Options, path, handler)
334 }
335
336 pub fn options_scoped<F, H>(path: impl Into<String>, factory: F) -> Result<Self>
337 where
338 F: Fn(&ModuleRef) -> Result<H> + Send + Sync + 'static,
339 H: RouteHandler,
340 {
341 Self::new_scoped(HttpMethod::Options, path, factory)
342 }
343
344 pub fn head<H>(path: impl Into<String>, handler: H) -> Result<Self>
345 where
346 H: RouteHandler,
347 {
348 Self::new(HttpMethod::Head, path, handler)
349 }
350
351 pub fn head_scoped<F, H>(path: impl Into<String>, factory: F) -> Result<Self>
352 where
353 F: Fn(&ModuleRef) -> Result<H> + Send + Sync + 'static,
354 H: RouteHandler,
355 {
356 Self::new_scoped(HttpMethod::Head, path, factory)
357 }
358
359 fn json_with_status<T, H, Fut, R>(
360 method: HttpMethod,
361 path: impl Into<String>,
362 status: u16,
363 handler: H,
364 ) -> Result<Self>
365 where
366 T: DeserializeOwned + Send + 'static,
367 H: Fn(T) -> Fut + Send + Sync + 'static,
368 Fut: Future<Output = Result<R>> + Send + 'static,
369 R: Serialize + Send + 'static,
370 {
371 Self::new(method, path, move |request: BootRequest| {
372 let future = request
373 .require_json_content_type()
374 .and_then(|()| request.require_accepts_json())
375 .and_then(|()| request.json::<T>())
376 .map(&handler);
377 async move {
378 let body = future?.await?;
379 BootResponse::json_with_status(status, &body)
380 }
381 })
382 .map(|route| route.with_response(status, OpenApiResponse::description("Success")))
383 }
384
385 fn json_response_with_status<H, Fut, R>(
386 method: HttpMethod,
387 path: impl Into<String>,
388 status: u16,
389 handler: H,
390 ) -> Result<Self>
391 where
392 H: Fn(BootRequest) -> Fut + Send + Sync + 'static,
393 Fut: Future<Output = Result<R>> + Send + 'static,
394 R: Serialize + Send + 'static,
395 {
396 Self::new(method, path, move |request: BootRequest| {
397 let future = request.require_accepts_json().map(|()| handler(request));
398 async move {
399 let body = future?.await?;
400 BootResponse::json_with_status(status, &body)
401 }
402 })
403 .map(|route| route.with_response(status, OpenApiResponse::description("Success")))
404 }
405
406 fn validated_json_with_status<T, H, Fut, R>(
407 method: HttpMethod,
408 path: impl Into<String>,
409 status: u16,
410 handler: H,
411 ) -> Result<Self>
412 where
413 T: DeserializeOwned + Validate + Send + 'static,
414 H: Fn(T) -> Fut + Send + Sync + 'static,
415 Fut: Future<Output = Result<R>> + Send + 'static,
416 R: Serialize + Send + 'static,
417 {
418 Self::json_with_status(method, path, status, handler)
419 .map(|route| route.with_body_validation::<T>().with_validation())
420 }
421}