use std::future::Future;
use std::pin::Pin;
use crate::body::{BoxBody, Request, Response};
use crate::extract::{FromRequest, FromRequestParts};
use crate::into_response::IntoResponse;
pub trait Handler<T, S>: Clone + Send + Sized + 'static {
type Future: Future<Output = Response> + Send + 'static;
fn call(self, req: Request, state: S) -> Self::Future;
}
impl<F, Fut, R, S> Handler<(), S> for F
where
F: Fn() -> Fut + Clone + Send + 'static,
Fut: Future<Output = R> + Send + 'static,
R: IntoResponse,
{
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
fn call(self, _req: Request, _state: S) -> Self::Future {
Box::pin(async move { (self)().await.into_response() })
}
}
impl<F, Fut, R, S, E> Handler<(E,), S> for F
where
F: Fn(E) -> Fut + Clone + Send + 'static,
Fut: Future<Output = R> + Send + 'static,
R: IntoResponse,
S: Clone + Send + 'static,
E: FromRequest<S, BoxBody> + Send + 'static,
{
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
fn call(self, req: Request, state: S) -> Self::Future {
Box::pin(async move {
let extracted = match E::from_request(req, &state).await {
Ok(v) => v,
Err(rejection) => return rejection.into_response(),
};
(self)(extracted).await.into_response()
})
}
}
impl<F, Fut, R, S, A, B> Handler<(A, B), S> for F
where
F: Fn(A, B) -> Fut + Clone + Send + 'static,
Fut: Future<Output = R> + Send + 'static,
R: IntoResponse,
S: Clone + Send + 'static,
A: FromRequestParts<S> + Send + 'static,
B: FromRequest<S, BoxBody> + Send + 'static,
{
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
fn call(self, req: Request, state: S) -> Self::Future {
Box::pin(async move {
let (mut parts, body) = req.into_parts();
let a = match A::from_request_parts(&mut parts, &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
let b = match B::from_request(Request::from_parts(parts, body), &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
(self)(a, b).await.into_response()
})
}
}
impl<F, Fut, R, S, A, B, C> Handler<(A, B, C), S> for F
where
F: Fn(A, B, C) -> Fut + Clone + Send + 'static,
Fut: Future<Output = R> + Send + 'static,
R: IntoResponse,
S: Clone + Send + 'static,
A: FromRequestParts<S> + Send + 'static,
B: FromRequestParts<S> + Send + 'static,
C: FromRequest<S, BoxBody> + Send + 'static,
{
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
fn call(self, req: Request, state: S) -> Self::Future {
Box::pin(async move {
let (mut parts, body) = req.into_parts();
let a = match A::from_request_parts(&mut parts, &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
let b = match B::from_request_parts(&mut parts, &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
let c = match C::from_request(Request::from_parts(parts, body), &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
(self)(a, b, c).await.into_response()
})
}
}
impl<F, Fut, R, S, A, B, C, D> Handler<(A, B, C, D), S> for F
where
F: Fn(A, B, C, D) -> Fut + Clone + Send + 'static,
Fut: Future<Output = R> + Send + 'static,
R: IntoResponse,
S: Clone + Send + 'static,
A: FromRequestParts<S> + Send + 'static,
B: FromRequestParts<S> + Send + 'static,
C: FromRequestParts<S> + Send + 'static,
D: FromRequest<S, BoxBody> + Send + 'static,
{
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
fn call(self, req: Request, state: S) -> Self::Future {
Box::pin(async move {
let (mut parts, body) = req.into_parts();
let a = match A::from_request_parts(&mut parts, &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
let b = match B::from_request_parts(&mut parts, &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
let c = match C::from_request_parts(&mut parts, &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
let d = match D::from_request(Request::from_parts(parts, body), &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
(self)(a, b, c, d).await.into_response()
})
}
}
impl<F, Fut, R, S, A, B, C, D, E> Handler<(A, B, C, D, E), S> for F
where
F: Fn(A, B, C, D, E) -> Fut + Clone + Send + 'static,
Fut: Future<Output = R> + Send + 'static,
R: IntoResponse,
S: Clone + Send + 'static,
A: FromRequestParts<S> + Send + 'static,
B: FromRequestParts<S> + Send + 'static,
C: FromRequestParts<S> + Send + 'static,
D: FromRequestParts<S> + Send + 'static,
E: FromRequest<S, BoxBody> + Send + 'static,
{
type Future = Pin<Box<dyn Future<Output = Response> + Send>>;
fn call(self, req: Request, state: S) -> Self::Future {
Box::pin(async move {
let (mut parts, body) = req.into_parts();
let a = match A::from_request_parts(&mut parts, &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
let b = match B::from_request_parts(&mut parts, &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
let c = match C::from_request_parts(&mut parts, &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
let d = match D::from_request_parts(&mut parts, &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
let e = match E::from_request(Request::from_parts(parts, body), &state).await {
Ok(v) => v,
Err(e) => return e.into_response(),
};
(self)(a, b, c, d, e).await.into_response()
})
}
}