1use crate::extract::FromRequest;
4use crate::request::Request;
5use crate::response::{IntoResponse, Response};
6use rustapi_openapi::{Operation, OperationModifier, ResponseModifier};
7use std::future::Future;
8use std::marker::PhantomData;
9use std::pin::Pin;
10
11pub trait Handler<T>: Clone + Send + Sync + Sized + 'static {
13 type Future: Future<Output = Response> + Send + 'static;
15
16 fn call(self, req: Request) -> Self::Future;
18
19 fn update_operation(op: &mut Operation);
21}
22
23pub struct HandlerService<H, T> {
25 handler: H,
26 _marker: PhantomData<fn() -> T>,
27}
28
29impl<H, T> HandlerService<H, T> {
30 pub fn new(handler: H) -> Self {
31 Self {
32 handler,
33 _marker: PhantomData,
34 }
35 }
36}
37
38impl<H: Clone, T> Clone for HandlerService<H, T> {
39 fn clone(&self) -> Self {
40 Self {
41 handler: self.handler.clone(),
42 _marker: PhantomData,
43 }
44 }
45}
46
47impl<F, Fut, Res> Handler<()> for F
51where
52 F: FnOnce() -> Fut + Clone + Send + Sync + 'static,
53 Fut: Future<Output = Res> + Send + 'static,
54 Res: IntoResponse + ResponseModifier,
55{
56 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
57
58 fn call(self, _req: Request) -> Self::Future {
59 Box::pin(async move {
60 self().await.into_response()
61 })
62 }
63
64 fn update_operation(op: &mut Operation) {
65 Res::update_response(op);
66 }
67}
68
69impl<F, Fut, Res, T1> Handler<(T1,)> for F
71where
72 F: FnOnce(T1) -> Fut + Clone + Send + Sync + 'static,
73 Fut: Future<Output = Res> + Send + 'static,
74 Res: IntoResponse + ResponseModifier,
75 T1: FromRequest + OperationModifier + Send + 'static,
76{
77 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
78
79 fn call(self, mut req: Request) -> Self::Future {
80 Box::pin(async move {
81 let t1 = match T1::from_request(&mut req).await {
82 Ok(v) => v,
83 Err(e) => return e.into_response(),
84 };
85 self(t1).await.into_response()
86 })
87 }
88
89 fn update_operation(op: &mut Operation) {
90 T1::update_operation(op);
91 Res::update_response(op);
92 }
93}
94
95impl<F, Fut, Res, T1, T2> Handler<(T1, T2)> for F
97where
98 F: FnOnce(T1, T2) -> Fut + Clone + Send + Sync + 'static,
99 Fut: Future<Output = Res> + Send + 'static,
100 Res: IntoResponse + ResponseModifier,
101 T1: FromRequest + OperationModifier + Send + 'static,
102 T2: FromRequest + OperationModifier + Send + 'static,
103{
104 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
105
106 fn call(self, mut req: Request) -> Self::Future {
107 Box::pin(async move {
108 let t1 = match T1::from_request(&mut req).await {
109 Ok(v) => v,
110 Err(e) => return e.into_response(),
111 };
112 let t2 = match T2::from_request(&mut req).await {
113 Ok(v) => v,
114 Err(e) => return e.into_response(),
115 };
116 self(t1, t2).await.into_response()
117 })
118 }
119
120 fn update_operation(op: &mut Operation) {
121 T1::update_operation(op);
122 T2::update_operation(op);
123 Res::update_response(op);
124 }
125}
126
127impl<F, Fut, Res, T1, T2, T3> Handler<(T1, T2, T3)> for F
129where
130 F: FnOnce(T1, T2, T3) -> Fut + Clone + Send + Sync + 'static,
131 Fut: Future<Output = Res> + Send + 'static,
132 Res: IntoResponse + ResponseModifier,
133 T1: FromRequest + OperationModifier + Send + 'static,
134 T2: FromRequest + OperationModifier + Send + 'static,
135 T3: FromRequest + OperationModifier + Send + 'static,
136{
137 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
138
139 fn call(self, mut req: Request) -> Self::Future {
140 Box::pin(async move {
141 let t1 = match T1::from_request(&mut req).await {
142 Ok(v) => v,
143 Err(e) => return e.into_response(),
144 };
145 let t2 = match T2::from_request(&mut req).await {
146 Ok(v) => v,
147 Err(e) => return e.into_response(),
148 };
149 let t3 = match T3::from_request(&mut req).await {
150 Ok(v) => v,
151 Err(e) => return e.into_response(),
152 };
153 self(t1, t2, t3).await.into_response()
154 })
155 }
156
157 fn update_operation(op: &mut Operation) {
158 T1::update_operation(op);
159 T2::update_operation(op);
160 T3::update_operation(op);
161 Res::update_response(op);
162 }
163}
164
165impl<F, Fut, Res, T1, T2, T3, T4> Handler<(T1, T2, T3, T4)> for F
167where
168 F: FnOnce(T1, T2, T3, T4) -> Fut + Clone + Send + Sync + 'static,
169 Fut: Future<Output = Res> + Send + 'static,
170 Res: IntoResponse + ResponseModifier,
171 T1: FromRequest + OperationModifier + Send + 'static,
172 T2: FromRequest + OperationModifier + Send + 'static,
173 T3: FromRequest + OperationModifier + Send + 'static,
174 T4: FromRequest + OperationModifier + Send + 'static,
175{
176 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
177
178 fn call(self, mut req: Request) -> Self::Future {
179 Box::pin(async move {
180 let t1 = match T1::from_request(&mut req).await {
181 Ok(v) => v,
182 Err(e) => return e.into_response(),
183 };
184 let t2 = match T2::from_request(&mut req).await {
185 Ok(v) => v,
186 Err(e) => return e.into_response(),
187 };
188 let t3 = match T3::from_request(&mut req).await {
189 Ok(v) => v,
190 Err(e) => return e.into_response(),
191 };
192 let t4 = match T4::from_request(&mut req).await {
193 Ok(v) => v,
194 Err(e) => return e.into_response(),
195 };
196 self(t1, t2, t3, t4).await.into_response()
197 })
198 }
199
200 fn update_operation(op: &mut Operation) {
201 T1::update_operation(op);
202 T2::update_operation(op);
203 T3::update_operation(op);
204 T4::update_operation(op);
205 Res::update_response(op);
206 }
207}
208
209impl<F, Fut, Res, T1, T2, T3, T4, T5> Handler<(T1, T2, T3, T4, T5)> for F
211where
212 F: FnOnce(T1, T2, T3, T4, T5) -> Fut + Clone + Send + Sync + 'static,
213 Fut: Future<Output = Res> + Send + 'static,
214 Res: IntoResponse + ResponseModifier,
215 T1: FromRequest + OperationModifier + Send + 'static,
216 T2: FromRequest + OperationModifier + Send + 'static,
217 T3: FromRequest + OperationModifier + Send + 'static,
218 T4: FromRequest + OperationModifier + Send + 'static,
219 T5: FromRequest + OperationModifier + Send + 'static,
220{
221 type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
222
223 fn call(self, mut req: Request) -> Self::Future {
224 Box::pin(async move {
225 let t1 = match T1::from_request(&mut req).await {
226 Ok(v) => v,
227 Err(e) => return e.into_response(),
228 };
229 let t2 = match T2::from_request(&mut req).await {
230 Ok(v) => v,
231 Err(e) => return e.into_response(),
232 };
233 let t3 = match T3::from_request(&mut req).await {
234 Ok(v) => v,
235 Err(e) => return e.into_response(),
236 };
237 let t4 = match T4::from_request(&mut req).await {
238 Ok(v) => v,
239 Err(e) => return e.into_response(),
240 };
241 let t5 = match T5::from_request(&mut req).await {
242 Ok(v) => v,
243 Err(e) => return e.into_response(),
244 };
245 self(t1, t2, t3, t4, t5).await.into_response()
246 })
247 }
248
249 fn update_operation(op: &mut Operation) {
250 T1::update_operation(op);
251 T2::update_operation(op);
252 T3::update_operation(op);
253 T4::update_operation(op);
254 T5::update_operation(op);
255 Res::update_response(op);
256 }
257}
258
259pub(crate) type BoxedHandler = Box<
261 dyn Fn(Request) -> Pin<Box<dyn Future<Output = Response> + Send>> + Send + Sync
262>;
263
264pub(crate) fn into_boxed_handler<H, T>(handler: H) -> BoxedHandler
266where
267 H: Handler<T>,
268 T: 'static,
269{
270 Box::new(move |req| {
271 let handler = handler.clone();
272 Box::pin(async move {
273 handler.call(req).await
274 })
275 })
276}
277
278pub trait RouteHandler<T>: Handler<T> {
283 const PATH: &'static str;
285 const METHOD: &'static str;
287}
288
289pub struct Route {
291 pub(crate) path: &'static str,
292 pub(crate) method: &'static str,
293 pub(crate) handler: BoxedHandler,
294 pub(crate) operation: Operation,
295}
296
297impl Route {
298 pub fn new<H, T>(path: &'static str, method: &'static str, handler: H) -> Self
300 where
301 H: Handler<T>,
302 T: 'static,
303 {
304 let mut operation = Operation::new();
305 H::update_operation(&mut operation);
306
307 Self {
308 path,
309 method,
310 handler: into_boxed_handler(handler),
311 operation,
312 }
313 }
314 pub fn summary(mut self, summary: impl Into<String>) -> Self {
316 self.operation = self.operation.summary(summary);
317 self
318 }
319
320 pub fn description(mut self, description: impl Into<String>) -> Self {
322 self.operation = self.operation.description(description);
323 self
324 }
325
326 pub fn tag(mut self, tag: impl Into<String>) -> Self {
328 let tag = tag.into();
329 let mut tags = self.operation.tags.take().unwrap_or_default();
330 tags.push(tag);
331 self.operation.tags = Some(tags);
332 self
333 }
334}
335
336#[macro_export]
338macro_rules! route {
339 ($handler:ident) => {{
340 $crate::Route::new(
341 $handler::PATH,
342 $handler::METHOD,
343 $handler,
344 )
345 }};
346}
347
348pub fn get_route<H, T>(path: &'static str, handler: H) -> Route
350where
351 H: Handler<T>,
352 T: 'static,
353{
354 Route::new(path, "GET", handler)
355}
356
357pub fn post_route<H, T>(path: &'static str, handler: H) -> Route
359where
360 H: Handler<T>,
361 T: 'static,
362{
363 Route::new(path, "POST", handler)
364}
365
366pub fn put_route<H, T>(path: &'static str, handler: H) -> Route
368where
369 H: Handler<T>,
370 T: 'static,
371{
372 Route::new(path, "PUT", handler)
373}
374
375pub fn patch_route<H, T>(path: &'static str, handler: H) -> Route
377where
378 H: Handler<T>,
379 T: 'static,
380{
381 Route::new(path, "PATCH", handler)
382}
383
384pub fn delete_route<H, T>(path: &'static str, handler: H) -> Route
386where
387 H: Handler<T>,
388 T: 'static,
389{
390 Route::new(path, "DELETE", handler)
391}