1use std::{fmt, marker::PhantomData};
2
3use crate::and_then::{AndThen, AndThenFactory};
4use crate::apply::{Apply, ApplyCtx, ApplyFactory};
5use crate::ctx::Ctx;
6use crate::fn_ready::FnReadiness;
7use crate::fn_shutdown::FnShutdown;
8use crate::map::{Map, MapFactory};
9use crate::map_err::{MapErr, MapErrFactory};
10use crate::map_init_err::MapInitErr;
11use crate::middleware::{ApplyMiddleware, Middleware};
12use crate::pipeline::Pipeline;
13use crate::then::{Then, ThenFactory};
14use crate::{IntoService, IntoServiceFactory, Service, ServiceFactory};
15
16pub fn service<S, St, Req>(service: impl IntoService<S, St, Req>) -> ServiceChain<S, St, Req>
18where
19 S: Service<St, Req>,
20{
21 ServiceChain {
22 service: service.into_service(),
23 st: PhantomData,
24 }
25}
26
27pub fn factory<Sf, St, Req>(
29 factory: impl IntoServiceFactory<Sf, St, Req>,
30) -> ServiceChainFactory<Sf, St, Req>
31where
32 Sf: ServiceFactory<St, Req>,
33{
34 ServiceChainFactory {
35 factory: factory.into_factory(),
36 _t: PhantomData,
37 }
38}
39
40pub struct ServiceChain<S, St, Req> {
42 service: S,
43 st: PhantomData<(St, Req)>,
44}
45
46pub struct ServiceChainFactory<Sf, St, Req> {
48 pub(crate) factory: Sf,
49 pub(crate) _t: PhantomData<(St, Req)>,
50}
51
52impl<S: Service<St, Req>, St, Req> ServiceChain<S, St, Req> {
53 pub fn and_then<Next, F>(self, service: F) -> ServiceChain<AndThen<S, Next>, St, Req>
58 where
59 Self: Sized,
60 F: IntoService<Next, St, S::Res>,
61 Next: Service<St, S::Res>,
62 {
63 ServiceChain {
64 service: AndThen::new(self.service, service.into_service()),
65 st: PhantomData,
66 }
67 }
68
69 pub fn then<Next, F>(self, service: F) -> ServiceChain<Then<S, Next>, St, Req>
74 where
75 Self: Sized,
76 F: IntoService<Next, St, Result<S::Res, S::Error>>,
77 Next: Service<St, Result<S::Res, S::Error>>,
78 {
79 ServiceChain {
80 service: Then::new(self.service, service.into_service()),
81 st: PhantomData,
82 }
83 }
84
85 pub fn map<F, Res>(self, f: F) -> ServiceChain<Map<F, S, Res>, St, Req>
89 where
90 Self: Sized,
91 F: Fn(S::Res) -> Res,
92 {
93 ServiceChain {
94 service: Map::new(f, self.service),
95 st: PhantomData,
96 }
97 }
98
99 pub fn map_err<F, Err>(self, f: F) -> ServiceChain<MapErr<F, S, Err>, St, Req>
104 where
105 Self: Sized,
106 F: Fn(S::Error) -> Err,
107 {
108 ServiceChain {
109 service: MapErr::new(f, self.service),
110 st: PhantomData,
111 }
112 }
113
114 pub fn readiness<F>(
119 self,
120 ready: F,
121 ) -> ServiceChain<AndThen<S, FnReadiness<F, S::Error>>, St, Req>
122 where
123 Self: Sized,
124 F: AsyncFn(&St) -> Result<(), S::Error>,
125 {
126 ServiceChain {
127 service: AndThen::new(self.service, FnReadiness::new(ready)),
128 st: PhantomData,
129 }
130 }
131
132 pub fn shutdown<F>(self, sh: F) -> ServiceChain<AndThen<S, FnShutdown<F, S::Error>>, St, Req>
134 where
135 Self: Sized,
136 F: AsyncFnOnce(&St),
137 {
138 ServiceChain {
139 service: AndThen::new(self.service, FnShutdown::new(sh)),
140 st: PhantomData,
141 }
142 }
143
144 pub fn apply_fn<F, In, Out, Err>(
148 self,
149 f: F,
150 ) -> ServiceChain<Apply<S, St, Req, F, In, Out, Err>, St, In>
151 where
152 F: AsyncFn(In, &ApplyCtx<'_, S, St, Req>) -> Result<Out, Err>,
153 Err: From<S::Error>,
154 {
155 crate::apply_fn(self.service, f)
156 }
157}
158
159impl<S: Service<St, Req>, St, Req> Clone for ServiceChain<S, St, Req>
160where
161 S: Clone,
162{
163 fn clone(&self) -> Self {
164 ServiceChain {
165 service: self.service.clone(),
166 st: PhantomData,
167 }
168 }
169}
170
171impl<S: Service<St, Req>, St, Req> fmt::Debug for ServiceChain<S, St, Req>
172where
173 S: fmt::Debug,
174{
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 f.debug_struct("ServiceChain")
177 .field("service", &self.service)
178 .finish()
179 }
180}
181
182impl<S: Service<St, Req>, St, Req> Service<St, Req> for ServiceChain<S, St, Req> {
183 type Res = S::Res;
184 type Error = S::Error;
185
186 #[inline]
187 async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<Self::Res, Self::Error> {
188 ctx.call(&self.service, req).await
189 }
190
191 crate::forward_ready!(St, service);
192 crate::forward_shutdown!(St, service);
193}
194
195impl<Sf: ServiceFactory<St, Req>, St, Req> ServiceChainFactory<Sf, St, Req> {
196 pub fn and_then<U>(
201 self,
202 factory: impl IntoServiceFactory<U, St, Sf::Res>,
203 ) -> ServiceChainFactory<AndThenFactory<Sf, U>, St, Req>
204 where
205 Self: Sized,
206 U: ServiceFactory<St, Sf::Res, Error = Sf::Error, InitError = Sf::InitError>,
207 {
208 ServiceChainFactory {
209 factory: AndThenFactory::new(self.factory, factory.into_factory()),
210 _t: PhantomData,
211 }
212 }
213
214 pub fn apply<U>(self, tr: U) -> ServiceChainFactory<ApplyMiddleware<U, Sf>, St, Req>
218 where
219 U: Middleware<Sf::Service, St>,
220 {
221 crate::apply(tr, self.factory)
222 }
223
224 pub fn apply_fn<F, In, Out, Err>(
229 self,
230 f: F,
231 ) -> ServiceChainFactory<ApplyFactory<F, Sf, St, Req, In, Out, Err>, St, In>
232 where
233 F: AsyncFn(In, &ApplyCtx<'_, Sf::Service, St, Req>) -> Result<Out, Err> + Clone,
234 Err: From<Sf::Error>,
235 {
236 crate::apply_fn_factory(self.factory, f)
237 }
238
239 pub fn then<F, U>(self, factory: F) -> ServiceChainFactory<ThenFactory<Sf, U>, St, Req>
242 where
243 Self: Sized,
244 F: IntoServiceFactory<U, St, Result<Sf::Res, Sf::Error>>,
245 U: ServiceFactory<
246 St,
247 Result<Sf::Res, Sf::Error>,
248 Error = Sf::Error,
249 InitError = Sf::InitError,
250 >,
251 {
252 ServiceChainFactory {
253 factory: ThenFactory::new(self.factory, factory.into_factory()),
254 _t: PhantomData,
255 }
256 }
257
258 pub fn map<F, Res>(self, f: F) -> ServiceChainFactory<MapFactory<F, Sf, Res>, St, Req>
260 where
261 Self: Sized,
262 F: Fn(Sf::Res) -> Res + Clone,
263 {
264 ServiceChainFactory {
265 factory: MapFactory::new(f, self.factory),
266 _t: PhantomData,
267 }
268 }
269
270 pub fn map_err<F, E>(self, f: F) -> ServiceChainFactory<MapErrFactory<F, Sf, E>, St, Req>
272 where
273 Self: Sized,
274 F: Fn(Sf::Error) -> E + Clone,
275 {
276 ServiceChainFactory {
277 factory: MapErrFactory::new(f, self.factory),
278 _t: PhantomData,
279 }
280 }
281
282 pub fn map_init_err<F, E>(self, f: F) -> ServiceChainFactory<MapInitErr<F, Sf, E>, St, Req>
284 where
285 Self: Sized,
286 F: Fn(Sf::InitError) -> E + Clone,
287 {
288 ServiceChainFactory {
289 factory: MapInitErr::new(f, self.factory),
290 _t: PhantomData,
291 }
292 }
293
294 pub fn readiness<F>(
299 self,
300 ready: F,
301 ) -> ServiceChainFactory<AndThenFactory<Sf, FnReadiness<F, Sf::Error>>, St, Req>
302 where
303 Self: Sized,
304 F: AsyncFn(&St) -> Result<(), Sf::Error> + Clone,
305 {
306 ServiceChainFactory {
307 factory: AndThenFactory::new(self.factory, FnReadiness::new(ready)),
308 _t: PhantomData,
309 }
310 }
311
312 pub fn shutdown<F>(
314 self,
315 sh: F,
316 ) -> ServiceChainFactory<AndThenFactory<Sf, FnShutdown<F, Sf::Error>>, St, Req>
317 where
318 Self: Sized,
319 F: AsyncFnOnce(&St) + Clone,
320 {
321 ServiceChainFactory {
322 factory: AndThenFactory::new(self.factory, FnShutdown::new(sh)),
323 _t: PhantomData,
324 }
325 }
326
327 pub async fn pipeline(&self, st: St) -> Result<Pipeline<Req, Sf::Res, Sf::Error>, Sf::InitError>
329 where
330 Sf: 'static,
331 St: 'static,
332 Req: 'static,
333 {
334 let svc = self.factory.create(&st).await?;
335 Ok(Pipeline::new(st, svc))
336 }
337}
338
339impl<Sf, St, Req> Clone for ServiceChainFactory<Sf, St, Req>
340where
341 Sf: Clone,
342{
343 fn clone(&self) -> Self {
344 ServiceChainFactory {
345 factory: self.factory.clone(),
346 _t: PhantomData,
347 }
348 }
349}
350
351impl<Sf, St, Req> fmt::Debug for ServiceChainFactory<Sf, St, Req>
352where
353 Sf: fmt::Debug,
354{
355 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
356 f.debug_struct("ServiceChainFactory")
357 .field("factory", &self.factory)
358 .finish()
359 }
360}
361
362impl<Sf: ServiceFactory<St, Req>, St, Req> ServiceFactory<St, Req>
363 for ServiceChainFactory<Sf, St, Req>
364{
365 type Res = Sf::Res;
366 type Error = Sf::Error;
367
368 type Service = Sf::Service;
369 type InitError = Sf::InitError;
370
371 #[inline]
372 async fn create(&self, st: &St) -> Result<Sf::Service, Sf::InitError> {
373 self.factory.create(st).await
374 }
375}