1use crate::error::{Error, IntoResponse, Result};
2use crate::request::Request;
3use crate::response::Response;
4use std::future::Future;
5use std::pin::Pin;
6use std::sync::Arc;
7
8pub type BoxFuture<T> = Pin<Box<dyn Future<Output = T> + Send>>;
9
10pub type Handler = Arc<dyn Fn(Request) -> BoxFuture<Response> + Send + Sync>;
12
13pub type FallibleHandler =
15 Arc<dyn Fn(Request) -> BoxFuture<Result<Response>> + Send + Sync>;
16
17pub(crate) type ErrorHandlerFn =
18 Arc<dyn Fn(Error) -> BoxFuture<Response> + Send + Sync>;
19
20pub trait IntoHandler<T> {
22 fn into_handler(self) -> FallibleHandler;
23}
24
25pub struct ResponseMarker;
26pub struct ResultMarker;
27
28impl<F, Fut, R> IntoHandler<(ResponseMarker,)> for F
29where
30 F: Fn(Request) -> Fut + Send + Sync + 'static,
31 Fut: Future<Output = R> + Send + 'static,
32 R: IntoResponse,
33{
34 fn into_handler(self) -> FallibleHandler {
35 Arc::new(move |req| {
36 let fut = self(req);
37 Box::pin(async move { Ok(fut.await.into_response()) })
38 })
39 }
40}
41
42impl<F, Fut, R> IntoHandler<(ResultMarker,)> for F
43where
44 F: Fn(Request) -> Fut + Send + Sync + 'static,
45 Fut: Future<Output = Result<R>> + Send + 'static,
46 R: IntoResponse,
47{
48 fn into_handler(self) -> FallibleHandler {
49 Arc::new(move |req| {
50 let fut = self(req);
51 Box::pin(async move { Ok(fut.await?.into_response()) })
52 })
53 }
54}
55
56pub trait ErrorResponse: IntoResponse {}
60
61pub struct FallibleResponseMarker;
63
64impl<F, Fut, R, E> IntoHandler<(FallibleResponseMarker, E)> for F
65where
66 F: Fn(Request) -> Fut + Send + Sync + 'static,
67 Fut: Future<Output = std::result::Result<R, E>> + Send + 'static,
68 R: IntoResponse,
69 E: ErrorResponse + 'static,
70{
71 fn into_handler(self) -> FallibleHandler {
72 Arc::new(move |req| {
73 let fut = self(req);
74 Box::pin(async move {
75 match fut.await {
76 Ok(r) => Ok(r.into_response()),
77 Err(e) => Ok(e.into_response()),
78 }
79 })
80 })
81 }
82}
83
84pub struct NoArgResponseMarker;
86
87impl<F, Fut, R> IntoHandler<(NoArgResponseMarker,)> for F
88where
89 F: Fn() -> Fut + Send + Sync + 'static,
90 Fut: Future<Output = R> + Send + 'static,
91 R: IntoResponse,
92{
93 fn into_handler(self) -> FallibleHandler {
94 Arc::new(move |_req| {
95 let fut = self();
96 Box::pin(async move { Ok(fut.await.into_response()) })
97 })
98 }
99}
100
101impl IntoHandler<()> for FallibleHandler {
102 fn into_handler(self) -> FallibleHandler {
103 self
104 }
105}
106
107pub fn wrap_errors(handler: FallibleHandler, eh: Option<ErrorHandlerFn>) -> Handler {
109 Arc::new(move |req| {
110 let handler = Arc::clone(&handler);
111 let eh = eh.clone();
112 Box::pin(async move {
113 match handler(req).await {
114 Ok(res) => res,
115 Err(Error::Response(res)) => *res,
117 Err(err) => match &eh {
118 Some(hook) => hook(err).await,
119 None => err.into_response(),
120 },
121 }
122 })
123 })
124}