1use crate::extract::FromRequest;
58use crate::request::Request;
59use crate::response::{IntoResponse, Response};
60use rustapi_openapi::{Operation, OperationModifier, ResponseModifier};
61use std::future::Future;
62use std::marker::PhantomData;
63use std::pin::Pin;
64
65pub trait Handler<T>: Clone + Send + Sync + Sized + 'static {
67 type Future: Future<Output = Response> + Send + 'static;
69
70 fn call(self, req: Request) -> Self::Future;
72
73 fn update_operation(op: &mut Operation);
75}
76
77pub struct HandlerService<H, T> {
79 handler: H,
80 _marker: PhantomData<fn() -> T>,
81}
82
83impl<H, T> HandlerService<H, T> {
84 pub fn new(handler: H) -> Self {
85 Self {
86 handler,
87 _marker: PhantomData,
88 }
89 }
90}
91
92impl<H: Clone, T> Clone for HandlerService<H, T> {
93 fn clone(&self) -> Self {
94 Self {
95 handler: self.handler.clone(),
96 _marker: PhantomData,
97 }
98 }
99}
100
101impl<F, Fut, Res> Handler<()> for F
105where
106 F: FnOnce() -> Fut + Clone + Send + Sync + 'static,
107 Fut: Future<Output = Res> + Send + 'static,
108 Res: IntoResponse + ResponseModifier,
109{
110 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
111
112 fn call(self, _req: Request) -> Self::Future {
113 Box::pin(async move { self().await.into_response() })
114 }
115
116 fn update_operation(op: &mut Operation) {
117 Res::update_response(op);
118 }
119}
120
121impl<F, Fut, Res, T1> Handler<(T1,)> for F
123where
124 F: FnOnce(T1) -> Fut + Clone + Send + Sync + 'static,
125 Fut: Future<Output = Res> + Send + 'static,
126 Res: IntoResponse + ResponseModifier,
127 T1: FromRequest + OperationModifier + Send + 'static,
128{
129 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
130
131 fn call(self, mut req: Request) -> Self::Future {
132 Box::pin(async move {
133 let t1 = match T1::from_request(&mut req).await {
134 Ok(v) => v,
135 Err(e) => return e.into_response(),
136 };
137 self(t1).await.into_response()
138 })
139 }
140
141 fn update_operation(op: &mut Operation) {
142 T1::update_operation(op);
143 Res::update_response(op);
144 }
145}
146
147impl<F, Fut, Res, T1, T2> Handler<(T1, T2)> for F
149where
150 F: FnOnce(T1, T2) -> Fut + Clone + Send + Sync + 'static,
151 Fut: Future<Output = Res> + Send + 'static,
152 Res: IntoResponse + ResponseModifier,
153 T1: FromRequest + OperationModifier + Send + 'static,
154 T2: FromRequest + OperationModifier + Send + 'static,
155{
156 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
157
158 fn call(self, mut req: Request) -> Self::Future {
159 Box::pin(async move {
160 let t1 = match T1::from_request(&mut req).await {
161 Ok(v) => v,
162 Err(e) => return e.into_response(),
163 };
164 let t2 = match T2::from_request(&mut req).await {
165 Ok(v) => v,
166 Err(e) => return e.into_response(),
167 };
168 self(t1, t2).await.into_response()
169 })
170 }
171
172 fn update_operation(op: &mut Operation) {
173 T1::update_operation(op);
174 T2::update_operation(op);
175 Res::update_response(op);
176 }
177}
178
179impl<F, Fut, Res, T1, T2, T3> Handler<(T1, T2, T3)> for F
181where
182 F: FnOnce(T1, T2, T3) -> Fut + Clone + Send + Sync + 'static,
183 Fut: Future<Output = Res> + Send + 'static,
184 Res: IntoResponse + ResponseModifier,
185 T1: FromRequest + OperationModifier + Send + 'static,
186 T2: FromRequest + OperationModifier + Send + 'static,
187 T3: FromRequest + OperationModifier + Send + 'static,
188{
189 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
190
191 fn call(self, mut req: Request) -> Self::Future {
192 Box::pin(async move {
193 let t1 = match T1::from_request(&mut req).await {
194 Ok(v) => v,
195 Err(e) => return e.into_response(),
196 };
197 let t2 = match T2::from_request(&mut req).await {
198 Ok(v) => v,
199 Err(e) => return e.into_response(),
200 };
201 let t3 = match T3::from_request(&mut req).await {
202 Ok(v) => v,
203 Err(e) => return e.into_response(),
204 };
205 self(t1, t2, t3).await.into_response()
206 })
207 }
208
209 fn update_operation(op: &mut Operation) {
210 T1::update_operation(op);
211 T2::update_operation(op);
212 T3::update_operation(op);
213 Res::update_response(op);
214 }
215}
216
217impl<F, Fut, Res, T1, T2, T3, T4> Handler<(T1, T2, T3, T4)> for F
219where
220 F: FnOnce(T1, T2, T3, T4) -> Fut + Clone + Send + Sync + 'static,
221 Fut: Future<Output = Res> + Send + 'static,
222 Res: IntoResponse + ResponseModifier,
223 T1: FromRequest + OperationModifier + Send + 'static,
224 T2: FromRequest + OperationModifier + Send + 'static,
225 T3: FromRequest + OperationModifier + Send + 'static,
226 T4: FromRequest + OperationModifier + Send + 'static,
227{
228 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
229
230 fn call(self, mut req: Request) -> Self::Future {
231 Box::pin(async move {
232 let t1 = match T1::from_request(&mut req).await {
233 Ok(v) => v,
234 Err(e) => return e.into_response(),
235 };
236 let t2 = match T2::from_request(&mut req).await {
237 Ok(v) => v,
238 Err(e) => return e.into_response(),
239 };
240 let t3 = match T3::from_request(&mut req).await {
241 Ok(v) => v,
242 Err(e) => return e.into_response(),
243 };
244 let t4 = match T4::from_request(&mut req).await {
245 Ok(v) => v,
246 Err(e) => return e.into_response(),
247 };
248 self(t1, t2, t3, t4).await.into_response()
249 })
250 }
251
252 fn update_operation(op: &mut Operation) {
253 T1::update_operation(op);
254 T2::update_operation(op);
255 T3::update_operation(op);
256 T4::update_operation(op);
257 Res::update_response(op);
258 }
259}
260
261impl<F, Fut, Res, T1, T2, T3, T4, T5> Handler<(T1, T2, T3, T4, T5)> for F
263where
264 F: FnOnce(T1, T2, T3, T4, T5) -> Fut + Clone + Send + Sync + 'static,
265 Fut: Future<Output = Res> + Send + 'static,
266 Res: IntoResponse + ResponseModifier,
267 T1: FromRequest + OperationModifier + Send + 'static,
268 T2: FromRequest + OperationModifier + Send + 'static,
269 T3: FromRequest + OperationModifier + Send + 'static,
270 T4: FromRequest + OperationModifier + Send + 'static,
271 T5: FromRequest + OperationModifier + Send + 'static,
272{
273 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
274
275 fn call(self, mut req: Request) -> Self::Future {
276 Box::pin(async move {
277 let t1 = match T1::from_request(&mut req).await {
278 Ok(v) => v,
279 Err(e) => return e.into_response(),
280 };
281 let t2 = match T2::from_request(&mut req).await {
282 Ok(v) => v,
283 Err(e) => return e.into_response(),
284 };
285 let t3 = match T3::from_request(&mut req).await {
286 Ok(v) => v,
287 Err(e) => return e.into_response(),
288 };
289 let t4 = match T4::from_request(&mut req).await {
290 Ok(v) => v,
291 Err(e) => return e.into_response(),
292 };
293 let t5 = match T5::from_request(&mut req).await {
294 Ok(v) => v,
295 Err(e) => return e.into_response(),
296 };
297 self(t1, t2, t3, t4, t5).await.into_response()
298 })
299 }
300
301 fn update_operation(op: &mut Operation) {
302 T1::update_operation(op);
303 T2::update_operation(op);
304 T3::update_operation(op);
305 T4::update_operation(op);
306 T5::update_operation(op);
307 Res::update_response(op);
308 }
309}
310
311pub(crate) type BoxedHandler =
313 std::sync::Arc<dyn Fn(Request) -> Pin<Box<dyn Future<Output = Response> + Send>> + Send + Sync>;
314
315pub(crate) fn into_boxed_handler<H, T>(handler: H) -> BoxedHandler
317where
318 H: Handler<T>,
319 T: 'static,
320{
321 std::sync::Arc::new(move |req| {
322 let handler = handler.clone();
323 Box::pin(async move { handler.call(req).await })
324 })
325}
326
327pub trait RouteHandler<T>: Handler<T> {
332 const PATH: &'static str;
334 const METHOD: &'static str;
336}
337
338pub struct Route {
340 pub(crate) path: &'static str,
341 pub(crate) method: &'static str,
342 pub(crate) handler: BoxedHandler,
343 pub(crate) operation: Operation,
344}
345
346impl Route {
347 pub fn new<H, T>(path: &'static str, method: &'static str, handler: H) -> Self
349 where
350 H: Handler<T>,
351 T: 'static,
352 {
353 let mut operation = Operation::new();
354 H::update_operation(&mut operation);
355
356 Self {
357 path,
358 method,
359 handler: into_boxed_handler(handler),
360 operation,
361 }
362 }
363 pub fn summary(mut self, summary: impl Into<String>) -> Self {
365 self.operation = self.operation.summary(summary);
366 self
367 }
368
369 pub fn description(mut self, description: impl Into<String>) -> Self {
371 self.operation = self.operation.description(description);
372 self
373 }
374
375 pub fn tag(mut self, tag: impl Into<String>) -> Self {
377 let tag = tag.into();
378 let mut tags = self.operation.tags.take().unwrap_or_default();
379 tags.push(tag);
380 self.operation.tags = Some(tags);
381 self
382 }
383}
384
385#[macro_export]
387macro_rules! route {
388 ($handler:ident) => {{
389 $crate::Route::new($handler::PATH, $handler::METHOD, $handler)
390 }};
391}
392
393pub fn get_route<H, T>(path: &'static str, handler: H) -> Route
395where
396 H: Handler<T>,
397 T: 'static,
398{
399 Route::new(path, "GET", handler)
400}
401
402pub fn post_route<H, T>(path: &'static str, handler: H) -> Route
404where
405 H: Handler<T>,
406 T: 'static,
407{
408 Route::new(path, "POST", handler)
409}
410
411pub fn put_route<H, T>(path: &'static str, handler: H) -> Route
413where
414 H: Handler<T>,
415 T: 'static,
416{
417 Route::new(path, "PUT", handler)
418}
419
420pub fn patch_route<H, T>(path: &'static str, handler: H) -> Route
422where
423 H: Handler<T>,
424 T: 'static,
425{
426 Route::new(path, "PATCH", handler)
427}
428
429pub fn delete_route<H, T>(path: &'static str, handler: H) -> Route
431where
432 H: Handler<T>,
433 T: 'static,
434{
435 Route::new(path, "DELETE", handler)
436}