1#![allow(clippy::type_complexity)]
2use std::{fmt, future::Future, marker::PhantomData};
3
4use crate::and_then::{AndThen, AndThenFactory};
5use crate::apply::{Apply, ApplyFactory};
6use crate::ctx::ServiceCtx;
7use crate::map::{Map, MapFactory};
8use crate::map_err::{MapErr, MapErrFactory};
9use crate::map_init_err::MapInitErr;
10use crate::middleware::{ApplyMiddleware, ApplyMiddleware2, Middleware, Middleware2};
11use crate::then::{Then, ThenFactory};
12use crate::{IntoService, IntoServiceFactory, Pipeline, Service, ServiceFactory};
13
14pub fn chain<Svc, Req, F>(service: F) -> ServiceChain<Svc, Req>
16where
17 Svc: Service<Req>,
18 F: IntoService<Svc, Req>,
19{
20 ServiceChain {
21 service: service.into_service(),
22 _t: PhantomData,
23 }
24}
25
26pub fn chain_factory<T, R, C, F>(factory: F) -> ServiceChainFactory<T, R, C>
28where
29 T: ServiceFactory<R, C>,
30 F: IntoServiceFactory<T, R, C>,
31{
32 ServiceChainFactory {
33 factory: factory.into_factory(),
34 _t: PhantomData,
35 }
36}
37
38pub struct ServiceChain<Svc, Req> {
40 service: Svc,
41 _t: PhantomData<Req>,
42}
43
44impl<Svc: Service<Req>, Req> ServiceChain<Svc, Req> {
45 pub fn and_then<Next, F>(self, service: F) -> ServiceChain<AndThen<Svc, Next>, Req>
55 where
56 Self: Sized,
57 F: IntoService<Next, Svc::Response>,
58 Next: Service<Svc::Response, Error = Svc::Error>,
59 {
60 ServiceChain {
61 service: AndThen::new(self.service, service.into_service()),
62 _t: PhantomData,
63 }
64 }
65
66 pub fn then<Next, F>(self, service: F) -> ServiceChain<Then<Svc, Next>, Req>
72 where
73 Self: Sized,
74 F: IntoService<Next, Result<Svc::Response, Svc::Error>>,
75 Next: Service<Result<Svc::Response, Svc::Error>, Error = Svc::Error>,
76 {
77 ServiceChain {
78 service: Then::new(self.service, service.into_service()),
79 _t: PhantomData,
80 }
81 }
82
83 pub fn map<F, Res>(self, f: F) -> ServiceChain<Map<Svc, F, Req, Res>, Req>
93 where
94 Self: Sized,
95 F: Fn(Svc::Response) -> Res,
96 {
97 ServiceChain {
98 service: Map::new(self.service, f),
99 _t: PhantomData,
100 }
101 }
102
103 pub fn map_err<F, Err>(self, f: F) -> ServiceChain<MapErr<Svc, F, Err>, Req>
112 where
113 Self: Sized,
114 F: Fn(Svc::Error) -> Err,
115 {
116 ServiceChain {
117 service: MapErr::new(self.service, f),
118 _t: PhantomData,
119 }
120 }
121
122 pub fn apply_fn<F, R, In, Out, Err>(
126 self,
127 f: F,
128 ) -> ServiceChain<Apply<Svc, Req, F, R, In, Out, Err>, In>
129 where
130 F: Fn(In, Pipeline<Svc>) -> R,
131 R: Future<Output = Result<Out, Err>>,
132 Svc: Service<Req>,
133 Err: From<Svc::Error>,
134 {
135 ServiceChain {
136 service: Apply::new(self.service, f),
137 _t: PhantomData,
138 }
139 }
140
141 pub fn into_pipeline(self) -> Pipeline<Svc> {
143 Pipeline::new(self.service)
144 }
145}
146
147impl<Svc, Req> Clone for ServiceChain<Svc, Req>
148where
149 Svc: Clone,
150{
151 fn clone(&self) -> Self {
152 ServiceChain {
153 service: self.service.clone(),
154 _t: PhantomData,
155 }
156 }
157}
158
159impl<Svc, Req> fmt::Debug for ServiceChain<Svc, Req>
160where
161 Svc: fmt::Debug,
162{
163 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164 f.debug_struct("ServiceChain")
165 .field("service", &self.service)
166 .finish()
167 }
168}
169
170impl<Svc: Service<Req>, Req> Service<Req> for ServiceChain<Svc, Req> {
171 type Response = Svc::Response;
172 type Error = Svc::Error;
173
174 crate::forward_poll!(service);
175 crate::forward_ready!(service);
176 crate::forward_shutdown!(service);
177
178 #[inline]
179 async fn call(
180 &self,
181 req: Req,
182 ctx: ServiceCtx<'_, Self>,
183 ) -> Result<Self::Response, Self::Error> {
184 ctx.call(&self.service, req).await
185 }
186}
187
188pub struct ServiceChainFactory<T, Req, C = ()> {
190 factory: T,
191 _t: PhantomData<(Req, C)>,
192}
193
194impl<T: ServiceFactory<Req, C>, Req, C> ServiceChainFactory<T, Req, C> {
195 pub fn and_then<F, U>(
197 self,
198 factory: F,
199 ) -> ServiceChainFactory<AndThenFactory<T, U>, Req, C>
200 where
201 Self: Sized,
202 F: IntoServiceFactory<U, T::Response, C>,
203 U: ServiceFactory<T::Response, C, Error = T::Error, InitError = T::InitError>,
204 {
205 ServiceChainFactory {
206 factory: AndThenFactory::new(self.factory, factory.into_factory()),
207 _t: PhantomData,
208 }
209 }
210
211 pub fn apply<U>(self, tr: U) -> ServiceChainFactory<ApplyMiddleware<U, T, C>, Req, C>
215 where
216 U: Middleware<T::Service>,
217 {
218 ServiceChainFactory {
219 factory: ApplyMiddleware::new(tr, self.factory),
220 _t: PhantomData,
221 }
222 }
223
224 pub fn apply2<U>(self, tr: U) -> ServiceChainFactory<ApplyMiddleware2<U, T, C>, Req, C>
228 where
229 U: Middleware2<T::Service, C>,
230 {
231 ServiceChainFactory {
232 factory: ApplyMiddleware2::new(tr, self.factory),
233 _t: PhantomData,
234 }
235 }
236
237 pub fn apply_fn<F, R, In, Out, Err>(
241 self,
242 f: F,
243 ) -> ServiceChainFactory<ApplyFactory<T, Req, C, F, R, In, Out, Err>, In, C>
244 where
245 F: Fn(In, Pipeline<T::Service>) -> R + Clone,
246 R: Future<Output = Result<Out, Err>>,
247 T: ServiceFactory<Req, C>,
248 Err: From<T::Error>,
249 {
250 ServiceChainFactory {
251 factory: ApplyFactory::new(self.factory, f),
252 _t: PhantomData,
253 }
254 }
255
256 pub fn then<F, U>(self, factory: F) -> ServiceChainFactory<ThenFactory<T, U>, Req, C>
263 where
264 Self: Sized,
265 C: Clone,
266 F: IntoServiceFactory<U, Result<T::Response, T::Error>, C>,
267 U: ServiceFactory<
268 Result<T::Response, T::Error>,
269 C,
270 Error = T::Error,
271 InitError = T::InitError,
272 >,
273 {
274 ServiceChainFactory {
275 factory: ThenFactory::new(self.factory, factory.into_factory()),
276 _t: PhantomData,
277 }
278 }
279
280 pub fn map<F, Res>(
283 self,
284 f: F,
285 ) -> ServiceChainFactory<MapFactory<T, F, Req, Res, C>, Req, C>
286 where
287 Self: Sized,
288 F: Fn(T::Response) -> Res + Clone,
289 {
290 ServiceChainFactory {
291 factory: MapFactory::new(self.factory, f),
292 _t: PhantomData,
293 }
294 }
295
296 pub fn map_err<F, E>(
298 self,
299 f: F,
300 ) -> ServiceChainFactory<MapErrFactory<T, Req, C, F, E>, Req, C>
301 where
302 Self: Sized,
303 F: Fn(T::Error) -> E + Clone,
304 {
305 ServiceChainFactory {
306 factory: MapErrFactory::new(self.factory, f),
307 _t: PhantomData,
308 }
309 }
310
311 pub fn map_init_err<F, E>(
313 self,
314 f: F,
315 ) -> ServiceChainFactory<MapInitErr<T, Req, C, F, E>, Req, C>
316 where
317 Self: Sized,
318 F: Fn(T::InitError) -> E + Clone,
319 {
320 ServiceChainFactory {
321 factory: MapInitErr::new(self.factory, f),
322 _t: PhantomData,
323 }
324 }
325
326 pub async fn pipeline(&self, cfg: C) -> Result<Pipeline<T::Service>, T::InitError>
328 where
329 Self: Sized,
330 {
331 Ok(Pipeline::new(self.factory.create(cfg).await?))
332 }
333}
334
335impl<T, R, C> Clone for ServiceChainFactory<T, R, C>
336where
337 T: Clone,
338{
339 fn clone(&self) -> Self {
340 ServiceChainFactory {
341 factory: self.factory.clone(),
342 _t: PhantomData,
343 }
344 }
345}
346
347impl<T, R, C> fmt::Debug for ServiceChainFactory<T, R, C>
348where
349 T: fmt::Debug,
350{
351 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352 f.debug_struct("ServiceChainFactory")
353 .field("factory", &self.factory)
354 .finish()
355 }
356}
357
358impl<T: ServiceFactory<R, C>, R, C> ServiceFactory<R, C> for ServiceChainFactory<T, R, C> {
359 type Response = T::Response;
360 type Error = T::Error;
361 type Service = T::Service;
362 type InitError = T::InitError;
363
364 #[inline]
365 async fn create(&self, cfg: C) -> Result<Self::Service, Self::InitError> {
366 self.factory.create(cfg).await
367 }
368}