xitca_service/service/
mod.rs1mod 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
14pub trait Service<Req = ()> {
17 type Response;
19
20 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}