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>
63 where
64 Self: Sized,
65 F: IntoService<Next, St, S::Res>,
66 Next: Service<St, S::Res>,
67 {
68 ServiceChain {
69 service: AndThen::new(self.service, service.into_service()),
70 st: PhantomData,
71 }
72 }
73
74 pub fn then<Next, F>(self, service: F) -> ServiceChain<Then<S, Next>, St, Req>
77 where
78 Self: Sized,
79 F: IntoService<Next, St, Result<S::Res, S::Error>>,
80 Next: Service<St, Result<S::Res, S::Error>>,
81 {
82 ServiceChain {
83 service: Then::new(self.service, service.into_service()),
84 st: PhantomData,
85 }
86 }
87
88 pub fn map<F, Res>(self, f: F) -> ServiceChain<Map<F, S, Res>, St, Req>
94 where
95 Self: Sized,
96 F: Fn(S::Res) -> Res,
97 {
98 ServiceChain {
99 service: Map::new(f, self.service),
100 st: PhantomData,
101 }
102 }
103
104 pub fn map_err<F, Err>(self, f: F) -> ServiceChain<MapErr<F, S, Err>, St, Req>
110 where
111 Self: Sized,
112 F: Fn(S::Error) -> Err,
113 {
114 ServiceChain {
115 service: MapErr::new(f, self.service),
116 st: PhantomData,
117 }
118 }
119
120 pub fn readiness<F>(
122 self,
123 ready: F,
124 ) -> ServiceChain<AndThen<S, FnReadiness<F, S::Error>>, St, Req>
125 where
126 Self: Sized,
127 F: AsyncFn(&St) -> Result<(), S::Error>,
128 {
129 ServiceChain {
130 service: AndThen::new(self.service, FnReadiness::new(ready)),
131 st: PhantomData,
132 }
133 }
134
135 pub fn shutdown<F>(self, sh: F) -> ServiceChain<AndThen<S, FnShutdown<F, S::Error>>, St, Req>
137 where
138 Self: Sized,
139 F: AsyncFnOnce(&St),
140 {
141 ServiceChain {
142 service: AndThen::new(self.service, FnShutdown::new(sh)),
143 st: PhantomData,
144 }
145 }
146
147 pub fn apply_fn<F, In, Out, Err>(
151 self,
152 f: F,
153 ) -> ServiceChain<Apply<S, St, Req, F, In, Out, Err>, St, In>
154 where
155 F: AsyncFn(In, &ApplyCtx<'_, S, St, Req>) -> Result<Out, Err>,
156 Err: From<S::Error>,
157 {
158 crate::apply_fn(self.service, f)
159 }
160}
161
162impl<S: Service<St, Req>, St, Req> Clone for ServiceChain<S, St, Req>
163where
164 S: Clone,
165{
166 fn clone(&self) -> Self {
167 ServiceChain {
168 service: self.service.clone(),
169 st: PhantomData,
170 }
171 }
172}
173
174impl<S: Service<St, Req>, St, Req> fmt::Debug for ServiceChain<S, St, Req>
175where
176 S: 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<S: Service<St, Req>, St, Req> Service<St, Req> for ServiceChain<S, St, Req> {
186 type Res = S::Res;
187 type Error = S::Error;
188
189 #[inline]
190 async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<Self::Res, Self::Error> {
191 ctx.call(&self.service, req).await
192 }
193
194 crate::forward_ready!(St, service);
195 crate::forward_shutdown!(St, service);
196}
197
198impl<Sf: ServiceFactory<St, Req>, St, Req> ServiceChainFactory<Sf, St, Req> {
199 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>(
228 self,
229 f: F,
230 ) -> ServiceChainFactory<ApplyFactory<F, Sf, St, Req, In, Out, Err>, St, In>
231 where
232 F: AsyncFn(In, &ApplyCtx<'_, Sf::Service, St, Req>) -> Result<Out, Err> + Clone,
233 Err: From<Sf::Error>,
234 {
235 crate::apply_fn_factory(self.factory, f)
236 }
237
238 pub fn then<F, U>(self, factory: F) -> ServiceChainFactory<ThenFactory<Sf, U>, St, Req>
245 where
246 Self: Sized,
247 F: IntoServiceFactory<U, St, Result<Sf::Res, Sf::Error>>,
248 U: ServiceFactory<
249 St,
250 Result<Sf::Res, Sf::Error>,
251 Error = Sf::Error,
252 InitError = Sf::InitError,
253 >,
254 {
255 ServiceChainFactory {
256 factory: ThenFactory::new(self.factory, factory.into_factory()),
257 _t: PhantomData,
258 }
259 }
260
261 pub fn map<F, Res>(self, f: F) -> ServiceChainFactory<MapFactory<F, Sf, Res>, St, Req>
264 where
265 Self: Sized,
266 F: Fn(Sf::Res) -> Res + Clone,
267 {
268 ServiceChainFactory {
269 factory: MapFactory::new(f, self.factory),
270 _t: PhantomData,
271 }
272 }
273
274 pub fn map_err<F, E>(self, f: F) -> ServiceChainFactory<MapErrFactory<F, Sf, E>, St, Req>
276 where
277 Self: Sized,
278 F: Fn(Sf::Error) -> E + Clone,
279 {
280 ServiceChainFactory {
281 factory: MapErrFactory::new(f, self.factory),
282 _t: PhantomData,
283 }
284 }
285
286 pub fn map_init_err<F, E>(self, f: F) -> ServiceChainFactory<MapInitErr<F, Sf, E>, St, Req>
288 where
289 Self: Sized,
290 F: Fn(Sf::InitError) -> E + Clone,
291 {
292 ServiceChainFactory {
293 factory: MapInitErr::new(f, self.factory),
294 _t: PhantomData,
295 }
296 }
297
298 pub fn readiness<F>(
300 self,
301 ready: F,
302 ) -> ServiceChainFactory<AndThenFactory<Sf, FnReadiness<F, Sf::Error>>, St, Req>
303 where
304 Self: Sized,
305 F: AsyncFn(&St) -> Result<(), Sf::Error> + Clone,
306 {
307 ServiceChainFactory {
308 factory: AndThenFactory::new(self.factory, FnReadiness::new(ready)),
309 _t: PhantomData,
310 }
311 }
312
313 pub fn shutdown<F>(
315 self,
316 sh: F,
317 ) -> ServiceChainFactory<AndThenFactory<Sf, FnShutdown<F, Sf::Error>>, St, Req>
318 where
319 Self: Sized,
320 F: AsyncFnOnce(&St) + Clone,
321 {
322 ServiceChainFactory {
323 factory: AndThenFactory::new(self.factory, FnShutdown::new(sh)),
324 _t: PhantomData,
325 }
326 }
327
328 pub async fn pipeline(&self, st: St) -> Result<Pipeline<Req, Sf::Res, Sf::Error>, Sf::InitError>
330 where
331 Sf: 'static,
332 St: 'static,
333 Req: 'static,
334 {
335 let svc = self.factory.create(&st).await?;
336 Ok(Pipeline::new(st, svc))
337 }
338}
339
340impl<Sf, St, Req> Clone for ServiceChainFactory<Sf, St, Req>
341where
342 Sf: Clone,
343{
344 fn clone(&self) -> Self {
345 ServiceChainFactory {
346 factory: self.factory.clone(),
347 _t: PhantomData,
348 }
349 }
350}
351
352impl<Sf, St, Req> fmt::Debug for ServiceChainFactory<Sf, St, Req>
353where
354 Sf: fmt::Debug,
355{
356 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
357 f.debug_struct("ServiceChainFactory")
358 .field("factory", &self.factory)
359 .finish()
360 }
361}
362
363impl<Sf: ServiceFactory<St, Req>, St, Req> ServiceFactory<St, Req>
364 for ServiceChainFactory<Sf, St, Req>
365{
366 type Res = Sf::Res;
367 type Error = Sf::Error;
368
369 type Service = Sf::Service;
370 type InitError = Sf::InitError;
371
372 #[inline]
373 async fn create(&self, st: &St) -> Result<Sf::Service, Sf::InitError> {
374 self.factory.create(st).await
375 }
376}