xitca_service/middleware/
async_fn.rs

1use crate::{
2    pipeline::{PipelineT, marker},
3    service::Service,
4};
5
6/// transform given async function to middleware that can be implied to certain service
7/// through [ServiceExt::enclosed] API.
8///
9/// [ServiceExt::enclosed]: crate::service::ServiceExt::enclosed
10pub struct AsyncFn<F>(pub F);
11
12impl<F> Clone for AsyncFn<F>
13where
14    F: Clone,
15{
16    fn clone(&self) -> Self {
17        Self(self.0.clone())
18    }
19}
20
21impl<S, E, F> Service<Result<S, E>> for AsyncFn<F>
22where
23    F: Clone,
24{
25    type Response = PipelineT<S, F, marker::AsyncFn>;
26    type Error = E;
27
28    async fn call(&self, arg: Result<S, E>) -> Result<Self::Response, Self::Error> {
29        arg.map(|service| PipelineT::new(service, self.0.clone()))
30    }
31}
32
33impl<S, Req, F, Res, Err> Service<Req> for PipelineT<S, F, marker::AsyncFn>
34where
35    F: core::ops::AsyncFn(&S, Req) -> Result<Res, Err>,
36{
37    type Response = Res;
38    type Error = Err;
39
40    #[inline]
41    async fn call(&self, req: Req) -> Result<Self::Response, Self::Error> {
42        (self.second)(&self.first, req).await
43    }
44}