use std::sync::Arc;
use super::{
boxed::BoxServiceFactory, layer::FactoryLayer, ArcMakeService, BoxedMakeService, MakeService,
MapTargetService, Service,
};
pub struct FactoryStack<C, S> {
config: C,
inner: S,
}
impl<C> FactoryStack<C, ()> {
pub const fn new(config: C) -> Self {
FactoryStack { config, inner: () }
}
}
impl<C, F> FactoryStack<C, F> {
#[inline]
pub fn replace<NF>(self, factory: NF) -> FactoryStack<C, NF> {
FactoryStack {
config: self.config,
inner: factory,
}
}
#[inline]
pub fn push<L>(self, layer: L) -> FactoryStack<C, L::Factory>
where
L: FactoryLayer<C, F>,
{
let inner = layer.layer(&self.config, self.inner);
FactoryStack {
config: self.config,
inner,
}
}
#[inline]
pub fn push_map_target<M: Clone>(self, f: M) -> FactoryStack<C, MapTargetService<F, M>> {
FactoryStack {
config: self.config,
inner: MapTargetService {
f,
inner: self.inner,
},
}
}
#[inline]
pub fn push_boxed_service<Req>(self) -> FactoryStack<C, BoxServiceFactory<F, Req>>
where
F: MakeService,
F::Service: Service<Req>,
{
FactoryStack {
config: self.config,
inner: BoxServiceFactory::new(self.inner),
}
}
#[inline]
pub fn push_boxed_factory(self) -> FactoryStack<C, BoxedMakeService<F::Service, F::Error>>
where
F: MakeService + Send + Sync + 'static,
{
FactoryStack {
config: self.config,
inner: Box::new(self.inner),
}
}
#[inline]
pub fn push_arc_factory(self) -> FactoryStack<C, ArcMakeService<F::Service, F::Error>>
where
F: MakeService + Send + Sync + 'static,
{
FactoryStack {
config: self.config,
inner: Arc::new(self.inner),
}
}
#[inline]
pub fn check_make_svc<R>(self) -> Self
where
F: MakeService,
F::Service: Service<R>,
{
self
}
#[inline]
pub fn into_inner(self) -> F {
self.inner
}
#[inline]
pub fn into_parts(self) -> (C, F) {
(self.config, self.inner)
}
}
impl<C, F> FactoryStack<C, F>
where
F: MakeService,
{
#[inline]
pub fn make(&self) -> Result<F::Service, F::Error> {
self.inner.make()
}
}