1#![deny(clippy::pedantic)]
3#![allow(
4 clippy::cast_possible_truncation,
5 clippy::missing_fields_in_debug,
6 clippy::missing_errors_doc,
7 clippy::missing_panics_doc,
8 clippy::must_use_candidate,
9 clippy::type_complexity,
10 clippy::unused_async,
11 clippy::unused_async_trait_impl
12)]
13use std::rc::Rc;
14
15mod and_then;
16mod apply;
17pub mod boxed;
18pub mod cfg;
19mod chain;
20mod ctx;
21mod fn_ready;
22mod fn_service;
23mod fn_shutdown;
24mod macros;
25mod map;
26mod map_config;
27mod map_err;
28mod map_init_err;
29mod map_state;
30mod middleware;
31pub mod state;
32mod then;
33mod util;
34
35pub mod pipeline;
36mod pl_factory;
37mod pl_inner;
38mod pl_state;
39
40pub use crate::apply::{apply_fn, apply_fn_factory};
41pub use crate::chain::{ServiceChain, ServiceChainFactory, factory, factory_no_st, service};
42pub use crate::ctx::Ctx;
43pub use crate::fn_service::{fn_factory, fn_factory_with_config, fn_service, fn_service_st};
44pub use crate::map_config::{map_config, unit_config};
45pub use crate::map_state::map_state;
46pub use crate::middleware::{Identity, Middleware, Stack, apply, fn_layer};
47pub use crate::pipeline::Pipeline;
48pub use crate::state::{RequestState, State};
49
50#[deprecated]
51pub use crate::chain::svc;
52
53#[allow(unused_variables)]
54pub trait Service<St, Req> {
110 type Res;
112
113 type Error;
115
116 async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<Self::Res, Self::Error>;
123
124 #[inline]
125 async fn ready(&self, ctx: Ctx<'_, Self, St>) -> Result<(), Self::Error> {
134 Ok(())
135 }
136
137 #[inline]
138 async fn shutdown(&self, cfg: Ctx<'_, Self, St>) {}
142
143 #[inline]
144 fn map<F, Res>(self, f: F) -> ServiceChain<dev::Map<F, Self, Res>, St, Req>
152 where
153 Self: Sized,
154 F: Fn(Self::Res) -> Res,
155 {
156 service(dev::Map::new(f, self))
157 }
158
159 #[inline]
160 fn map_err<F, E>(self, f: F) -> ServiceChain<dev::MapErr<F, Self, E>, St, Req>
168 where
169 Self: Sized,
170 F: Fn(Self::Error) -> E,
171 {
172 service(dev::MapErr::new(f, self))
173 }
174
175 #[inline]
176 fn and_then<Next, F>(self, f: F) -> ServiceChain<dev::AndThen<Self, Next>, St, Req>
186 where
187 Self: Sized,
188 Next: Service<St, Self::Res, Error = Self::Error>,
189 F: IntoService<Next, St, Self::Res>,
190 {
191 service(dev::AndThen::new(self, f.into_service()))
192 }
193}
194
195pub trait ServiceFactory<St, Req, Cfg = ()> {
207 type Res;
209
210 type Error;
212
213 type Service: Service<St, Req, Res = Self::Res, Error = Self::Error>;
215
216 type InitError;
218
219 async fn create(&self, cfg: &Cfg) -> Result<Self::Service, Self::InitError>;
221
222 #[inline]
223 async fn pipeline(
225 &self,
226 cfg: &Cfg,
227 ) -> Result<Pipeline<Req, Self::Res, Self::Error>, Self::InitError>
228 where
229 Self: 'static,
230 St: Default + 'static,
231 Req: 'static,
232 Cfg: 'static,
233 {
234 Ok(Pipeline::new(self.create(cfg).await?))
235 }
236
237 #[inline]
238 fn map<F, Res>(self, f: F) -> ServiceChainFactory<dev::MapFactory<F, Self, Res>, St, Req, Cfg>
240 where
241 Self: Sized,
242 F: Fn(Self::Res) -> Res + Clone,
243 {
244 factory(dev::MapFactory::new(f, self))
245 }
246
247 #[inline]
248 fn map_err<F, E>(
251 self,
252 f: F,
253 ) -> ServiceChainFactory<dev::MapErrFactory<F, Self, E>, St, Req, Cfg>
254 where
255 Self: Sized,
256 F: Fn(Self::Error) -> E + Clone,
257 {
258 factory(dev::MapErrFactory::new(f, self))
259 }
260
261 #[inline]
262 fn map_init_err<F, E>(
265 self,
266 f: F,
267 ) -> ServiceChainFactory<dev::MapInitErr<F, Self, E>, St, Req, Cfg>
268 where
269 Self: Sized,
270 F: Fn(Self::InitError) -> E + Clone,
271 {
272 factory(dev::MapInitErr::new(f, self))
273 }
274
275 fn and_then<U, F>(self, f: F) -> ServiceChainFactory<dev::AndThenFactory<Self, U>, St, Req, Cfg>
277 where
278 Self: Sized,
279 U: ServiceFactory<St, Self::Res, Cfg, Error = Self::Error, InitError = Self::InitError>,
280 F: IntoServiceFactory<U, St, Self::Res, Cfg>,
281 {
282 factory(dev::AndThenFactory::new(self, f.into_factory()))
283 }
284
285 fn boxed(
287 self,
288 ) -> boxed::BoxServiceFactory<St, Req, Self::Res, Self::Error, Cfg, Self::InitError>
289 where
290 St: 'static,
291 Req: 'static,
292 Cfg: 'static,
293 Self: Sized + 'static,
294 {
295 boxed::factory(self)
296 }
297}
298
299impl<S, St, Req> Service<St, Req> for &S
300where
301 S: Service<St, Req>,
302{
303 type Res = S::Res;
304 type Error = S::Error;
305
306 #[inline]
307 async fn ready(&self, ctx: Ctx<'_, Self, St>) -> Result<(), S::Error> {
308 ctx.ready(&**self).await
309 }
310
311 #[inline]
312 async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<S::Res, S::Error> {
313 ctx.call_nowait(&**self, req).await
314 }
315
316 #[inline]
317 async fn shutdown(&self, ctx: Ctx<'_, Self, St>) {
318 ctx.shutdown(&**self).await;
319 }
320}
321
322impl<S, St, Req> Service<St, Req> for Box<S>
323where
324 S: Service<St, Req>,
325{
326 type Res = S::Res;
327 type Error = S::Error;
328
329 #[inline]
330 async fn ready(&self, ctx: Ctx<'_, Self, St>) -> Result<(), S::Error> {
331 ctx.ready(&**self).await
332 }
333
334 #[inline]
335 async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<S::Res, S::Error> {
336 ctx.call_nowait(&**self, req).await
337 }
338
339 #[inline]
340 async fn shutdown(&self, ctx: Ctx<'_, Self, St>) {
341 ctx.shutdown(&**self).await;
342 }
343}
344
345impl<S, St, Req> Service<St, Req> for Rc<S>
346where
347 S: Service<St, Req>,
348{
349 type Res = S::Res;
350 type Error = S::Error;
351
352 #[inline]
353 async fn ready(&self, ctx: Ctx<'_, Self, St>) -> Result<(), S::Error> {
354 ctx.ready(&**self).await
355 }
356
357 #[inline]
358 async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<S::Res, S::Error> {
359 ctx.call_nowait(&**self, req).await
360 }
361
362 #[inline]
363 async fn shutdown(&self, ctx: Ctx<'_, Self, St>) {
364 ctx.shutdown(&**self).await;
365 }
366}
367
368impl<Sf, St, Req, Cfg> ServiceFactory<St, Req, Cfg> for Rc<Sf>
369where
370 Sf: ServiceFactory<St, Req, Cfg>,
371{
372 type Res = Sf::Res;
373 type Error = Sf::Error;
374 type Service = Sf::Service;
375 type InitError = Sf::InitError;
376
377 async fn create(&self, cfg: &Cfg) -> Result<Self::Service, Self::InitError> {
378 self.as_ref().create(cfg).await
379 }
380}
381
382pub trait IntoService<S, St, Req>
384where
385 S: Service<St, Req>,
386{
387 fn into_service(self) -> S;
389}
390
391pub trait IntoServiceFactory<Sf, St, Req, Cfg = ()>
393where
394 Sf: ServiceFactory<St, Req, Cfg>,
395{
396 fn into_factory(self) -> Sf;
398}
399
400impl<S, St, Req> IntoService<S, St, Req> for S
401where
402 S: Service<St, Req>,
403{
404 #[inline]
405 fn into_service(self) -> S {
406 self
407 }
408}
409
410impl<Sf, St, Req, Cfg> IntoServiceFactory<Sf, St, Req, Cfg> for Sf
411where
412 Sf: ServiceFactory<St, Req, Cfg>,
413{
414 #[inline]
415 fn into_factory(self) -> Sf {
416 self
417 }
418}
419
420#[inline(always)]
422#[allow(clippy::inline_always)]
423pub fn __assert_svc<St, Req, Res, Err>(
424 s: impl Service<St, Req, Res = Res, Error = Err>,
425) -> impl Service<St, Req, Res = Res, Error = Err> {
426 s
427}
428
429#[inline(always)]
431#[allow(clippy::inline_always)]
432pub fn __assert_factory<Sf, St, Req, Res, Err, InitCfg, InitErr>(f: Sf) -> Sf
433where
434 Sf: ServiceFactory<St, Req, InitCfg, Res = Res, Error = Err, InitError = InitErr>,
435{
436 f
437}
438
439pub mod dev {
440 pub use crate::and_then::{AndThen, AndThenFactory};
441 pub use crate::apply::{Apply, ApplyCtx, ApplyFactory};
442 pub use crate::chain::{ServiceChain, ServiceChainFactory};
443 pub use crate::fn_ready::FnReadiness;
444 pub use crate::fn_service::{
445 FnService, FnServiceConfig, FnServiceFactory, FnServiceNoConfig, FnServiceSt,
446 FnServiceStFactory,
447 };
448 pub use crate::fn_shutdown::FnShutdown;
449 pub use crate::map::{Map, MapFactory};
450 pub use crate::map_config::{MapConfig, UnitConfig};
451 pub use crate::map_err::{MapErr, MapErrFactory};
452 pub use crate::map_init_err::MapInitErr;
453 pub use crate::map_state::MapState;
454 pub use crate::middleware::{ApplyMiddleware, FnMiddleware};
455 pub use crate::then::{Then, ThenFactory};
456}