use crate::handler::Handler;
use crate::internal_prelude::*;
use crate::state;
use std::any::type_name;
use std::convert::TryInto;
use std::marker::PhantomData;
use std::sync::Arc;
mod sealed {
use std::future::Future;
pub trait AsyncFn<'a, A>: Send + Sync + 'a {
type Future: Future<Output = Self::Output> + Send + 'a;
type Output: 'a;
fn call<'t: 'a>(&'t self, args: A) -> Self::Future;
}
macro_rules! impl_async_fn {
(($($ty:tt,)+),($($id:tt,)+)) => {
impl<'a, $($ty,)+ F, U, O> AsyncFn<'a, ($($ty,)+)> for F
where
$($ty:'a,)+
F: Fn($($ty,)+) -> U + Send + Sync + 'a,
U: Future<Output = O> + Send + 'a,
O: 'a,
{
type Future = U;
type Output = O;
fn call<'t: 'a>(&'t self, ($($id,)+): ($($ty,)+)) -> Self::Future {
(self)($($id,)+)
}
}
};
}
impl_async_fn!((A0,), (a0,));
impl_async_fn!((A0, A1,), (a0, a1,));
impl_async_fn!((A0, A1, A2,), (a0, a1, a2,));
}
use self::sealed::AsyncFn;
pub fn handler<F>(f: F) -> HandlerFn<F> {
HandlerFn { f }
}
pub struct HandlerFn<F> {
f: F,
}
impl<F, R> Handler for HandlerFn<F>
where
F: for<'a> AsyncFn<'a, (Request,), Output = R>,
R: TryInto<Response>,
R::Error: Into<Error>,
{
fn handle<'t, 'a>(&'t self, req: Request) -> BoxFuture<'a, Result<Response>>
where
't: 'a,
Self: 'a,
{
Box::pin(async move {
AsyncFn::call(&self.f, (req,))
.await
.try_into()
.map_err(Into::into)
})
}
}
impl<F> Clone for HandlerFn<F>
where
F: Clone,
{
fn clone(&self) -> Self {
Self { f: self.f.clone() }
}
}
pub fn ref_handler<S, F>(f: F) -> RefHandlerFn<S, F> {
RefHandlerFn {
f,
_marker: PhantomData,
}
}
pub struct RefHandlerFn<S, F> {
f: F,
_marker: PhantomData<fn(&S)>,
}
impl<S, F, R> Handler for RefHandlerFn<S, F>
where
S: Send + Sync + 'static,
F: for<'a> AsyncFn<'a, (&'a S, Request), Output = R>,
R: TryInto<Response>,
R::Error: Into<Error>,
{
#[track_caller]
fn handle<'t, 'a>(&'t self, req: Request) -> BoxFuture<'a, Result<Response>>
where
't: 'a,
Self: 'a,
{
let state = match state::inject::<S>() {
Some(s) => s,
None => panic!(
"failed to inject state <{}> for handler <{}>",
type_name::<S>(),
type_name::<F>(),
),
};
Box::pin(async move {
AsyncFn::call(&self.f, (&*state, req))
.await
.try_into()
.map_err(Into::into)
})
}
}
impl<S, F> Clone for RefHandlerFn<S, F>
where
F: Clone,
{
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
_marker: PhantomData,
}
}
}
pub fn arc_handler<S, F>(f: F) -> ArcHandlerFn<S, F> {
ArcHandlerFn {
f,
_marker: PhantomData,
}
}
pub struct ArcHandlerFn<S, F> {
f: F,
_marker: PhantomData<fn(Arc<S>)>,
}
impl<S, F, R> Handler for ArcHandlerFn<S, F>
where
S: Send + Sync + 'static,
F: for<'a> AsyncFn<'a, (Arc<S>, Request), Output = R>,
R: TryInto<Response>,
R::Error: Into<Error>,
{
#[track_caller]
fn handle<'t, 'a>(&'t self, req: Request) -> BoxFuture<'a, Result<Response>>
where
't: 'a,
Self: 'a,
{
let state = match state::inject::<S>() {
Some(s) => s,
None => panic!(
"failed to inject state <{}> for handler <{}>",
type_name::<S>(),
type_name::<F>(),
),
};
Box::pin(async move {
AsyncFn::call(&self.f, (state, req))
.await
.try_into()
.map_err(Into::into)
})
}
}
impl<S, F> Clone for ArcHandlerFn<S, F>
where
F: Clone,
{
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
_marker: PhantomData,
}
}
}
pub fn middleware<F>(f: F) -> MiddlewareFn<F> {
MiddlewareFn { f }
}
pub struct MiddlewareFn<F> {
f: F,
}
impl<F> Middleware for MiddlewareFn<F>
where
F: for<'a> AsyncFn<'a, (Request, &'a dyn Handler), Output = Result<Response>>,
{
fn handle<'t, 'n, 'a>(
&'t self,
req: Request,
next: &'a dyn Handler,
) -> BoxFuture<'a, Result<Response>>
where
't: 'a,
'n: 'a,
Self: 'a,
{
Box::pin(AsyncFn::call(&self.f, (req, next)))
}
}
impl<F> Clone for MiddlewareFn<F>
where
F: Clone,
{
fn clone(&self) -> Self {
Self { f: self.f.clone() }
}
}
pub fn ref_middleware<S, F>(f: F) -> RefMiddlewareFn<S, F>
where
S: Send + Sync + 'static,
F: for<'a> AsyncFn<'a, (&'a S, Request, &'a dyn Handler)>,
{
RefMiddlewareFn {
f,
_marker: PhantomData,
}
}
pub struct RefMiddlewareFn<S, F> {
f: F,
_marker: PhantomData<fn(&S)>,
}
impl<S, F> Middleware for RefMiddlewareFn<S, F>
where
S: Send + Sync + 'static,
F: for<'a> AsyncFn<'a, (&'a S, Request, &'a dyn Handler), Output = Result<Response>>,
{
fn handle<'t, 'n, 'a>(
&'t self,
req: Request,
next: &'a dyn Handler,
) -> BoxFuture<'a, Result<Response>>
where
't: 'a,
'n: 'a,
Self: 'a,
{
let state = match state::inject::<S>() {
Some(s) => s,
None => panic!(
"failed to inject state <{}> for middleware <{}>",
type_name::<S>(),
type_name::<F>(),
),
};
Box::pin(async move { AsyncFn::call(&self.f, (&*state, req, next)).await })
}
}
impl<S, F> Clone for RefMiddlewareFn<S, F>
where
F: Clone,
{
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
_marker: PhantomData,
}
}
}
pub fn arc_middleware<S, F>(f: F) -> ArcMiddlewareFn<S, F>
where
S: Send + Sync + 'static,
F: for<'a> AsyncFn<'a, (Arc<S>, Request, &'a dyn Handler)>,
{
ArcMiddlewareFn {
f,
_marker: PhantomData,
}
}
pub struct ArcMiddlewareFn<S, F> {
f: F,
_marker: PhantomData<fn(&S)>,
}
impl<S, F> Middleware for ArcMiddlewareFn<S, F>
where
S: Send + Sync + 'static,
F: for<'a> AsyncFn<'a, (Arc<S>, Request, &'a dyn Handler), Output = Result<Response>>,
{
fn handle<'t, 'n, 'a>(
&'t self,
req: Request,
next: &'a dyn Handler,
) -> BoxFuture<'a, Result<Response>>
where
't: 'a,
'n: 'a,
Self: 'a,
{
let state = match state::inject::<S>() {
Some(s) => s,
None => panic!(
"failed to inject state <{}> for middleware <{}>",
type_name::<S>(),
type_name::<F>(),
),
};
Box::pin(async move { AsyncFn::call(&self.f, (state, req, next)).await })
}
}
impl<S, F> Clone for ArcMiddlewareFn<S, F>
where
F: Clone,
{
fn clone(&self) -> Self {
Self {
f: self.f.clone(),
_marker: PhantomData,
}
}
}