1#![allow(clippy::type_complexity)]
2use std::{fmt, marker::PhantomData};
3
4use crate::and_then::{AndThen, AndThenFactory};
5use crate::apply::{Apply, ApplyCtx, ApplyFactory};
6use crate::ctx::ServiceCtx;
7use crate::inspect::{Inspect, InspectErr, InspectErrFactory, InspectFactory};
8use crate::map::{Map, MapFactory};
9use crate::map_err::{MapErr, MapErrFactory};
10use crate::map_init_err::MapInitErr;
11use crate::middleware::{ApplyMiddleware, Middleware};
12use crate::then::{Then, ThenFactory};
13use crate::{IntoService, IntoServiceFactory, Pipeline, Service, ServiceFactory};
14
15pub fn chain<Svc, Req, F>(service: F) -> ServiceChain<Svc, Req>
17where
18 Svc: Service<Req>,
19 F: IntoService<Svc, Req>,
20{
21 ServiceChain {
22 service: service.into_service(),
23 _t: PhantomData,
24 }
25}
26
27pub fn chain_factory<Fac, Req, C, F>(factory: F) -> ServiceChainFactory<Fac, Req, C>
29where
30 Fac: ServiceFactory<Req, C>,
31 F: IntoServiceFactory<Fac, Req, C>,
32{
33 ServiceChainFactory {
34 factory: factory.into_factory(),
35 _t: PhantomData,
36 }
37}
38
39pub struct ServiceChain<Svc, Req> {
41 service: Svc,
42 _t: PhantomData<Req>,
43}
44
45impl<Svc: Service<Req>, Req> ServiceChain<Svc, Req> {
46 pub fn and_then<Next, F>(self, service: F) -> ServiceChain<AndThen<Svc, Next>, Req>
56 where
57 Self: Sized,
58 F: IntoService<Next, Svc::Response>,
59 Next: Service<Svc::Response, Error = Svc::Error>,
60 {
61 ServiceChain {
62 service: AndThen::new(self.service, service.into_service()),
63 _t: PhantomData,
64 }
65 }
66
67 pub fn then<Next, F>(self, service: F) -> ServiceChain<Then<Svc, Next>, Req>
70 where
71 Self: Sized,
72 F: IntoService<Next, Result<Svc::Response, Svc::Error>>,
73 Next: Service<Result<Svc::Response, Svc::Error>, Error = Svc::Error>,
74 {
75 ServiceChain {
76 service: Then::new(self.service, service.into_service()),
77 _t: PhantomData,
78 }
79 }
80
81 pub fn map<F, Res>(self, f: F) -> ServiceChain<Map<Svc, F, Req, Res>, Req>
87 where
88 Self: Sized,
89 F: Fn(Svc::Response) -> Res,
90 {
91 ServiceChain {
92 service: Map::new(self.service, f),
93 _t: PhantomData,
94 }
95 }
96
97 pub fn map_err<F, Err>(self, f: F) -> ServiceChain<MapErr<Svc, F, Err>, Req>
103 where
104 Self: Sized,
105 F: Fn(Svc::Error) -> Err,
106 {
107 ServiceChain {
108 service: MapErr::new(self.service, f),
109 _t: PhantomData,
110 }
111 }
112
113 pub fn inspect<F>(self, f: F) -> ServiceChain<Inspect<Svc, F>, Req>
117 where
118 Self: Sized,
119 F: Fn(&Svc::Response),
120 {
121 ServiceChain {
122 service: Inspect::new(self.service, f),
123 _t: PhantomData,
124 }
125 }
126
127 pub fn inspect_err<F>(self, f: F) -> ServiceChain<InspectErr<Svc, F>, Req>
131 where
132 Self: Sized,
133 F: Fn(&Svc::Error),
134 {
135 ServiceChain {
136 service: InspectErr::new(self.service, f),
137 _t: PhantomData,
138 }
139 }
140
141 pub fn apply_fn<F, In, Out, Err>(
145 self,
146 f: F,
147 ) -> ServiceChain<Apply<Svc, Req, F, In, Out, Err>, In>
148 where
149 F: AsyncFn(In, &ApplyCtx<'_, Svc>) -> Result<Out, Err>,
150 Svc: Service<Req>,
151 Err: From<Svc::Error>,
152 {
153 crate::apply_fn(self.service, f)
154 }
155
156 pub fn into_pipeline(self) -> Pipeline<Svc> {
158 Pipeline::new(self.service)
159 }
160}
161
162impl<Svc, Req> Clone for ServiceChain<Svc, Req>
163where
164 Svc: Clone,
165{
166 fn clone(&self) -> Self {
167 ServiceChain {
168 service: self.service.clone(),
169 _t: PhantomData,
170 }
171 }
172}
173
174impl<Svc, Req> fmt::Debug for ServiceChain<Svc, Req>
175where
176 Svc: fmt::Debug,
177{
178 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179 f.debug_struct("ServiceChain")
180 .field("service", &self.service)
181 .finish()
182 }
183}
184
185impl<Svc: Service<Req>, Req> Service<Req> for ServiceChain<Svc, Req> {
186 type Response = Svc::Response;
187 type Error = Svc::Error;
188
189 crate::forward_poll!(service);
190 crate::forward_ready!(service);
191 crate::forward_shutdown!(service);
192
193 #[inline]
194 async fn call(
195 &self,
196 req: Req,
197 ctx: ServiceCtx<'_, Self>,
198 ) -> Result<Self::Response, Self::Error> {
199 ctx.call(&self.service, req).await
200 }
201}
202
203pub struct ServiceChainFactory<Fac, Req, C = ()> {
205 pub(crate) factory: Fac,
206 pub(crate) _t: PhantomData<(Req, C)>,
207}
208
209impl<Fac: ServiceFactory<Req, C>, Req, C> ServiceChainFactory<Fac, Req, C> {
210 pub fn and_then<F, U>(
212 self,
213 factory: F,
214 ) -> ServiceChainFactory<AndThenFactory<Fac, U>, Req, C>
215 where
216 Self: Sized,
217 F: IntoServiceFactory<U, Fac::Response, C>,
218 U: ServiceFactory<Fac::Response, C, Error = Fac::Error, InitError = Fac::InitError>,
219 {
220 ServiceChainFactory {
221 factory: AndThenFactory::new(self.factory, factory.into_factory()),
222 _t: PhantomData,
223 }
224 }
225
226 pub fn apply<U>(self, tr: U) -> ServiceChainFactory<ApplyMiddleware<U, Fac, C>, Req, C>
230 where
231 U: Middleware<Fac::Service, C>,
232 {
233 crate::apply(tr, self.factory)
234 }
235
236 pub fn apply_fn<F, In, Out, Err>(
240 self,
241 f: F,
242 ) -> ServiceChainFactory<ApplyFactory<Fac, Req, C, F, In, Out, Err>, In, C>
243 where
244 F: AsyncFn(In, &ApplyCtx<'_, Fac::Service>) -> Result<Out, Err> + Clone,
245 Fac: ServiceFactory<Req, C>,
246 Err: From<Fac::Error>,
247 {
248 crate::apply_fn_factory(self.factory, f)
249 }
250
251 pub fn then<F, U>(self, factory: F) -> ServiceChainFactory<ThenFactory<Fac, U>, Req, C>
258 where
259 Self: Sized,
260 C: Clone,
261 F: IntoServiceFactory<U, Result<Fac::Response, Fac::Error>, C>,
262 U: ServiceFactory<
263 Result<Fac::Response, Fac::Error>,
264 C,
265 Error = Fac::Error,
266 InitError = Fac::InitError,
267 >,
268 {
269 ServiceChainFactory {
270 factory: ThenFactory::new(self.factory, factory.into_factory()),
271 _t: PhantomData,
272 }
273 }
274
275 pub fn map<F, Res>(
278 self,
279 f: F,
280 ) -> ServiceChainFactory<MapFactory<Fac, F, Req, Res, C>, Req, C>
281 where
282 Self: Sized,
283 F: Fn(Fac::Response) -> Res + Clone,
284 {
285 ServiceChainFactory {
286 factory: MapFactory::new(self.factory, f),
287 _t: PhantomData,
288 }
289 }
290
291 pub fn map_err<F, E>(
293 self,
294 f: F,
295 ) -> ServiceChainFactory<MapErrFactory<Fac, Req, C, F, E>, Req, C>
296 where
297 Self: Sized,
298 F: Fn(Fac::Error) -> E + Clone,
299 {
300 ServiceChainFactory {
301 factory: MapErrFactory::new(self.factory, f),
302 _t: PhantomData,
303 }
304 }
305
306 pub fn map_init_err<F, E>(
308 self,
309 f: F,
310 ) -> ServiceChainFactory<MapInitErr<Fac, Req, C, F, E>, Req, C>
311 where
312 Self: Sized,
313 F: Fn(Fac::InitError) -> E + Clone,
314 {
315 ServiceChainFactory {
316 factory: MapInitErr::new(self.factory, f),
317 _t: PhantomData,
318 }
319 }
320
321 pub fn inspect<F>(self, f: F) -> ServiceChainFactory<InspectFactory<Fac, F>, Req, C>
325 where
326 Self: Sized,
327 F: Fn(&Fac::Response) + Clone,
328 {
329 ServiceChainFactory {
330 factory: InspectFactory::new(self.factory, f),
331 _t: PhantomData,
332 }
333 }
334
335 pub fn inspect_err<F>(
339 self,
340 f: F,
341 ) -> ServiceChainFactory<InspectErrFactory<Fac, F>, Req, C>
342 where
343 Self: Sized,
344 F: Fn(&Fac::Error) + Clone,
345 {
346 ServiceChainFactory {
347 factory: InspectErrFactory::new(self.factory, f),
348 _t: PhantomData,
349 }
350 }
351
352 pub async fn pipeline(&self, cfg: C) -> Result<Pipeline<Fac::Service>, Fac::InitError>
354 where
355 Self: Sized,
356 {
357 Ok(Pipeline::new(self.factory.create(cfg).await?))
358 }
359}
360
361impl<Fac, R, C> Clone for ServiceChainFactory<Fac, R, C>
362where
363 Fac: Clone,
364{
365 fn clone(&self) -> Self {
366 ServiceChainFactory {
367 factory: self.factory.clone(),
368 _t: PhantomData,
369 }
370 }
371}
372
373impl<Fac, R, C> fmt::Debug for ServiceChainFactory<Fac, R, C>
374where
375 Fac: fmt::Debug,
376{
377 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378 f.debug_struct("ServiceChainFactory")
379 .field("factory", &self.factory)
380 .finish()
381 }
382}
383
384impl<Fac: ServiceFactory<Req, C>, Req, C> ServiceFactory<Req, C>
385 for ServiceChainFactory<Fac, Req, C>
386{
387 type Response = Fac::Response;
388 type Error = Fac::Error;
389 type Service = Fac::Service;
390 type InitError = Fac::InitError;
391
392 #[inline]
393 async fn create(&self, cfg: C) -> Result<Self::Service, Self::InitError> {
394 self.factory.create(cfg).await
395 }
396}