xitca_service/service/
mod.rs

1mod and_then;
2mod enclosed;
3mod ext;
4mod function;
5mod opt;
6
7pub use self::{
8    ext::ServiceExt,
9    function::{FnService, fn_build, fn_service},
10};
11
12use core::{future::Future, ops::Deref, pin::Pin};
13
14/// Trait for simulate `Fn<(&Self, Arg)> -> impl Future<Output = Result<T, E>> + '_`.
15/// The function call come from stateful type that can be referenced within returned opaque future.
16pub trait Service<Req = ()> {
17    /// The Ok part of output future.
18    type Response;
19
20    /// The Err part of output future.
21    type Error;
22
23    fn call(&self, req: Req) -> impl Future<Output = Result<Self::Response, Self::Error>>;
24}
25
26impl<S, Req> Service<Req> for Pin<S>
27where
28    S: Deref,
29    S::Target: Service<Req>,
30{
31    type Response = <S::Target as Service<Req>>::Response;
32    type Error = <S::Target as Service<Req>>::Error;
33
34    #[inline]
35    async fn call(&self, req: Req) -> Result<Self::Response, Self::Error> {
36        self.as_ref().get_ref().call(req).await
37    }
38}
39
40#[cfg(feature = "alloc")]
41impl<S, Req> Service<Req> for alloc::sync::Arc<S>
42where
43    S: Service<Req> + ?Sized,
44{
45    type Response = S::Response;
46    type Error = S::Error;
47
48    #[inline]
49    async fn call(&self, req: Req) -> Result<Self::Response, Self::Error> {
50        Service::call(&**self, req).await
51    }
52}
53
54#[cfg(feature = "alloc")]
55#[cfg(test)]
56mod test {
57    use super::*;
58
59    use alloc::string::String;
60
61    use xitca_unsafe_collection::futures::NowOrPanic;
62
63    struct Layer1<S> {
64        name: String,
65        service: S,
66    }
67
68    struct Layer2<S> {
69        name: String,
70        service: S,
71    }
72
73    impl<'r, S, Res, Err> Service<&'r str> for Layer1<S>
74    where
75        S: for<'r2> Service<(&'r2 str, &'r2 str), Response = Res, Error = Err> + 'static,
76    {
77        type Response = Res;
78        type Error = Err;
79
80        async fn call(&self, req: &'r str) -> Result<Self::Response, Self::Error> {
81            let req = (req, self.name.as_str());
82            self.service.call(req).await
83        }
84    }
85
86    impl<'r, S, Res, Err> Service<(&'r str, &'r str)> for Layer2<S>
87    where
88        S: for<'r2> Service<(&'r2 str, &'r2 str, &'r2 str), Response = Res, Error = Err> + 'static,
89    {
90        type Response = Res;
91        type Error = Err;
92
93        async fn call(&self, req: (&'r str, &'r str)) -> Result<Self::Response, Self::Error> {
94            let req = (req.0, req.1, self.name.as_str());
95            self.service.call(req).await
96        }
97    }
98
99    struct DummyService;
100
101    impl<'r> Service<(&'r str, &'r str, &'r str)> for DummyService {
102        type Response = String;
103        type Error = ();
104
105        async fn call(&self, req: (&'r str, &'r str, &'r str)) -> Result<Self::Response, Self::Error> {
106            let mut res = String::new();
107            res.push_str(req.0);
108            res.push_str(req.1);
109            res.push_str(req.2);
110
111            Ok(res)
112        }
113    }
114
115    #[test]
116    fn nest_service() {
117        let service = Layer2 {
118            name: String::from("Layer2"),
119            service: DummyService,
120        };
121
122        let service = Layer1 {
123            name: String::from("Layer1"),
124            service,
125        };
126
127        let req = "Request";
128
129        let res = service.call(req).now_or_panic().unwrap();
130
131        assert_eq!(res, String::from("RequestLayer1Layer2"));
132    }
133}