#![deny(clippy::pedantic)]
#![allow(
clippy::cast_possible_truncation,
clippy::missing_fields_in_debug,
clippy::missing_errors_doc,
clippy::missing_panics_doc,
clippy::must_use_candidate,
clippy::type_complexity,
clippy::unused_async,
clippy::unused_async_trait_impl
)]
use std::rc::Rc;
mod and_then;
mod apply;
pub mod boxed;
pub mod cfg;
mod chain;
mod ctx;
mod fn_ready;
mod fn_service;
mod fn_shutdown;
mod macros;
mod map;
mod map_config;
mod map_err;
mod map_init_err;
mod map_state;
mod middleware;
pub mod state;
mod then;
mod util;
pub mod pipeline;
mod pl_factory;
mod pl_inner;
mod pl_state;
pub use crate::apply::{apply_fn, apply_fn_factory};
pub use crate::chain::{ServiceChain, ServiceChainFactory, factory, factory_no_st, service};
pub use crate::ctx::Ctx;
pub use crate::fn_service::{fn_factory, fn_factory_with_config, fn_service, fn_service_st};
pub use crate::map_config::{map_config, unit_config};
pub use crate::map_state::map_state;
pub use crate::middleware::{Identity, Middleware, Stack, apply, fn_layer};
pub use crate::pipeline::Pipeline;
pub use crate::state::{RequestState, State};
#[deprecated]
pub use crate::chain::svc;
#[allow(unused_variables)]
pub trait Service<St, Req> {
type Res;
type Error;
async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<Self::Res, Self::Error>;
#[inline]
async fn ready(&self, ctx: Ctx<'_, Self, St>) -> Result<(), Self::Error> {
Ok(())
}
#[inline]
async fn shutdown(&self, cfg: Ctx<'_, Self, St>) {}
#[inline]
fn map<F, Res>(self, f: F) -> ServiceChain<dev::Map<F, Self, Res>, St, Req>
where
Self: Sized,
F: Fn(Self::Res) -> Res,
{
service(dev::Map::new(f, self))
}
#[inline]
fn map_err<F, E>(self, f: F) -> ServiceChain<dev::MapErr<F, Self, E>, St, Req>
where
Self: Sized,
F: Fn(Self::Error) -> E,
{
service(dev::MapErr::new(f, self))
}
#[inline]
fn and_then<Next, F>(self, f: F) -> ServiceChain<dev::AndThen<Self, Next>, St, Req>
where
Self: Sized,
Next: Service<St, Self::Res, Error = Self::Error>,
F: IntoService<Next, St, Self::Res>,
{
service(dev::AndThen::new(self, f.into_service()))
}
}
pub trait ServiceFactory<St, Req, Cfg = ()> {
type Res;
type Error;
type Service: Service<St, Req, Res = Self::Res, Error = Self::Error>;
type InitError;
async fn create(&self, cfg: &Cfg) -> Result<Self::Service, Self::InitError>;
#[inline]
async fn pipeline(
&self,
cfg: &Cfg,
) -> Result<Pipeline<Req, Self::Res, Self::Error>, Self::InitError>
where
Self: 'static,
St: Default + 'static,
Req: 'static,
Cfg: 'static,
{
Ok(Pipeline::new(self.create(cfg).await?))
}
#[inline]
fn map<F, Res>(self, f: F) -> ServiceChainFactory<dev::MapFactory<F, Self, Res>, St, Req, Cfg>
where
Self: Sized,
F: Fn(Self::Res) -> Res + Clone,
{
factory(dev::MapFactory::new(f, self))
}
#[inline]
fn map_err<F, E>(
self,
f: F,
) -> ServiceChainFactory<dev::MapErrFactory<F, Self, E>, St, Req, Cfg>
where
Self: Sized,
F: Fn(Self::Error) -> E + Clone,
{
factory(dev::MapErrFactory::new(f, self))
}
#[inline]
fn map_init_err<F, E>(
self,
f: F,
) -> ServiceChainFactory<dev::MapInitErr<F, Self, E>, St, Req, Cfg>
where
Self: Sized,
F: Fn(Self::InitError) -> E + Clone,
{
factory(dev::MapInitErr::new(f, self))
}
fn and_then<U, F>(self, f: F) -> ServiceChainFactory<dev::AndThenFactory<Self, U>, St, Req, Cfg>
where
Self: Sized,
U: ServiceFactory<St, Self::Res, Cfg, Error = Self::Error, InitError = Self::InitError>,
F: IntoServiceFactory<U, St, Self::Res, Cfg>,
{
factory(dev::AndThenFactory::new(self, f.into_factory()))
}
fn boxed(
self,
) -> boxed::BoxServiceFactory<St, Req, Self::Res, Self::Error, Cfg, Self::InitError>
where
St: 'static,
Req: 'static,
Cfg: 'static,
Self: Sized + 'static,
{
boxed::factory(self)
}
}
impl<S, St, Req> Service<St, Req> for &S
where
S: Service<St, Req>,
{
type Res = S::Res;
type Error = S::Error;
#[inline]
async fn ready(&self, ctx: Ctx<'_, Self, St>) -> Result<(), S::Error> {
ctx.ready(&**self).await
}
#[inline]
async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<S::Res, S::Error> {
ctx.call_nowait(&**self, req).await
}
#[inline]
async fn shutdown(&self, ctx: Ctx<'_, Self, St>) {
ctx.shutdown(&**self).await;
}
}
impl<S, St, Req> Service<St, Req> for Box<S>
where
S: Service<St, Req>,
{
type Res = S::Res;
type Error = S::Error;
#[inline]
async fn ready(&self, ctx: Ctx<'_, Self, St>) -> Result<(), S::Error> {
ctx.ready(&**self).await
}
#[inline]
async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<S::Res, S::Error> {
ctx.call_nowait(&**self, req).await
}
#[inline]
async fn shutdown(&self, ctx: Ctx<'_, Self, St>) {
ctx.shutdown(&**self).await;
}
}
impl<S, St, Req> Service<St, Req> for Rc<S>
where
S: Service<St, Req>,
{
type Res = S::Res;
type Error = S::Error;
#[inline]
async fn ready(&self, ctx: Ctx<'_, Self, St>) -> Result<(), S::Error> {
ctx.ready(&**self).await
}
#[inline]
async fn call(&self, req: Req, ctx: Ctx<'_, Self, St>) -> Result<S::Res, S::Error> {
ctx.call_nowait(&**self, req).await
}
#[inline]
async fn shutdown(&self, ctx: Ctx<'_, Self, St>) {
ctx.shutdown(&**self).await;
}
}
impl<Sf, St, Req, Cfg> ServiceFactory<St, Req, Cfg> for Rc<Sf>
where
Sf: ServiceFactory<St, Req, Cfg>,
{
type Res = Sf::Res;
type Error = Sf::Error;
type Service = Sf::Service;
type InitError = Sf::InitError;
async fn create(&self, cfg: &Cfg) -> Result<Self::Service, Self::InitError> {
self.as_ref().create(cfg).await
}
}
pub trait IntoService<S, St, Req>
where
S: Service<St, Req>,
{
fn into_service(self) -> S;
}
pub trait IntoServiceFactory<Sf, St, Req, Cfg = ()>
where
Sf: ServiceFactory<St, Req, Cfg>,
{
fn into_factory(self) -> Sf;
}
impl<S, St, Req> IntoService<S, St, Req> for S
where
S: Service<St, Req>,
{
#[inline]
fn into_service(self) -> S {
self
}
}
impl<Sf, St, Req, Cfg> IntoServiceFactory<Sf, St, Req, Cfg> for Sf
where
Sf: ServiceFactory<St, Req, Cfg>,
{
#[inline]
fn into_factory(self) -> Sf {
self
}
}
#[inline(always)]
#[allow(clippy::inline_always)]
pub fn __assert_svc<St, Req, Res, Err>(
s: impl Service<St, Req, Res = Res, Error = Err>,
) -> impl Service<St, Req, Res = Res, Error = Err> {
s
}
#[inline(always)]
#[allow(clippy::inline_always)]
pub fn __assert_factory<Sf, St, Req, Res, Err, InitCfg, InitErr>(f: Sf) -> Sf
where
Sf: ServiceFactory<St, Req, InitCfg, Res = Res, Error = Err, InitError = InitErr>,
{
f
}
pub mod dev {
pub use crate::and_then::{AndThen, AndThenFactory};
pub use crate::apply::{Apply, ApplyCtx, ApplyFactory};
pub use crate::chain::{ServiceChain, ServiceChainFactory};
pub use crate::fn_ready::FnReadiness;
pub use crate::fn_service::{
FnService, FnServiceConfig, FnServiceFactory, FnServiceNoConfig, FnServiceSt,
FnServiceStFactory,
};
pub use crate::fn_shutdown::FnShutdown;
pub use crate::map::{Map, MapFactory};
pub use crate::map_config::{MapConfig, UnitConfig};
pub use crate::map_err::{MapErr, MapErrFactory};
pub use crate::map_init_err::MapInitErr;
pub use crate::map_state::MapState;
pub use crate::middleware::{ApplyMiddleware, FnMiddleware};
pub use crate::then::{Then, ThenFactory};
}