Struct service_async::stack::FactoryStack

source ·
pub struct FactoryStack<C, S> { /* private fields */ }
Expand description

A powerful abstraction for creating complex service chains by managing a stack of service factories.

FactoryStack allows for the composition of multiple FactoryLayers, where each layer can add functionality, modify behavior of inner layers, or transform the service chain.

The FactoryStack works by composing multiple FactoryLayers together. Each layer in the stack wraps the layers below it, creating a nested structure of factories. When you call make or make_async on a FactoryStack, it traverses this structure from the outermost layer to the innermost, creating the complete service chain.

This approach allows users to create complex service factories by chaining multiple factory layers together in an intuitive manner. Each layer can add its own functionality, modify the behavior of inner layers, or even completely transform the service chain.

§Usage

To create a chain of services using FactoryStack:

  1. Start with a FactoryStack initialized with your configuration.
  2. Use the push method to add layers to the stack.
  3. Each layer can modify or enhance the behavior of the inner layers.
  4. Finally, call make or make_async to create the complete service chain.

This system offers a powerful and flexible way to construct and update service chains while managing state and resources efficiently. It allows for modular, reusable pieces of functionality, easy reconfiguration of service chains, and clear separation of concerns between different parts of your service logic.

§Example

use service_async::{layer::FactoryLayer, stack::FactoryStack, MakeService, Service};

struct Config { /* ... */ }
struct ServiceA;
struct ServiceB<T>(T);

impl<C> FactoryLayer<C, ()> for ServiceA {
    type Factory = Self;
    fn layer(&self, _: &C, _: ()) -> Self::Factory { ServiceA }
}

impl<C, T> FactoryLayer<C, T> for ServiceB<T> {
    type Factory = Self;
    fn layer(&self, _: &C, inner: T) -> Self::Factory { ServiceB(inner) }
}

let config = Config { /* ... */ };
let stack = FactoryStack::new(config)
    .push(ServiceA::layer())
    .push(ServiceB::layer());

let service = stack.make().expect("Failed to create service");

This example demonstrates how to create a FactoryStack with two layers (ServiceA and ServiceB) and then use it to create a service.

Implementations§

source§

impl<C> FactoryStack<C, ()>

source

pub const fn new(config: C) -> Self

source§

impl<C, F> FactoryStack<C, F>

source

pub fn replace<NF>(self, factory: NF) -> FactoryStack<C, NF>

Replace inner with a new factory.

source

pub fn push<L>(self, layer: L) -> FactoryStack<C, L::Factory>
where L: FactoryLayer<C, F>,

Push a new factory layer.

source

pub fn into_async(self) -> FactoryStack<C, AsyncMakeServiceWrapper<F>>

Convert the factory to an async factory.

source

pub fn push_map_target<M: Clone>( self, f: M, ) -> FactoryStack<C, MapTargetService<F, M>>

Push a new factory of service to map the request type.

source

pub fn into_boxed_service<Req>( self, ) -> FactoryStack<C, BoxServiceFactory<F, Req>>

Convert the factory to factory of BoxedService. Works for MakeService and AsyncMakeService.

source

pub fn push_boxed_service<Req>( self, ) -> FactoryStack<C, BoxServiceFactory<F, Req>>
where F: MakeService, F::Service: Service<Req>,

👎Deprecated: use into_boxed_service instead

Convert the factory to factory of BoxedService. Works for MakeService and AsyncMakeService.

source

pub fn into_boxed_factory( self, ) -> FactoryStack<C, BoxedMakeService<F::Service, F::Error>>
where F: MakeService + Send + Sync + 'static,

Convert the factory to a fixed type factory(Box dyn). Only works for MakeService.

source

pub fn into_async_boxed_factory( self, ) -> FactoryStack<C, BoxedAsyncMakeService<F::Service, F::Error>>
where F: AsyncMakeService + Send + Sync + 'static, F::Service: 'static,

Convert the factory to a fixed type factory(Box dyn). Only works for AsyncMakeService.

source

pub fn push_boxed_factory( self, ) -> FactoryStack<C, BoxedMakeService<F::Service, F::Error>>
where F: MakeService + Send + Sync + 'static,

👎Deprecated: use into_boxed_factory instead

Convert the factory to a fixed type factory(Box dyn). Only works for MakeService.

source

pub fn into_arc_factory( self, ) -> FactoryStack<C, ArcMakeService<F::Service, F::Error>>
where F: MakeService + Send + Sync + 'static,

Convert the factory to a fixed type factory(Arc dyn). Only works for MakeService.

source

pub fn into_async_arc_factory( self, ) -> FactoryStack<C, Arc<BoxedAsyncMakeService<F::Service, F::Error>>>
where F: AsyncMakeService + Send + Sync + 'static, F::Service: 'static,

Convert the factory to a fixed type factory(Arc Box dyn). Only works for AsyncMakeService.

source

pub fn push_arc_factory( self, ) -> FactoryStack<C, ArcMakeService<F::Service, F::Error>>
where F: MakeService + Send + Sync + 'static,

👎Deprecated: use into_arc_factory instead

Convert the factory to a fixed type factory(Arc dyn). Only works for MakeService.

source

pub fn check_make_svc<R>(self) -> Self
where F: MakeService, F::Service: Service<R>,

Check if the stack is a factory of Service<R>.

source

pub fn check_async_make_svc<R>(self) -> Self
where F: AsyncMakeService, F::Service: Service<R>,

Check if the stack is an async factory of Service<R>.

source

pub fn into_inner(self) -> F

Get the inner factory.

source

pub fn into_parts(self) -> (C, F)

Into config and the factory.

source§

impl<C, F> FactoryStack<C, F>
where F: MakeService,

source

pub fn make(&self) -> Result<F::Service, F::Error>

Make a service.

source§

impl<C, F> FactoryStack<C, F>

source

pub async fn make_async(&self) -> Result<F::Service, F::Error>

Make a service in async.

Auto Trait Implementations§

§

impl<C, S> Freeze for FactoryStack<C, S>
where C: Freeze, S: Freeze,

§

impl<C, S> RefUnwindSafe for FactoryStack<C, S>

§

impl<C, S> Send for FactoryStack<C, S>
where C: Send, S: Send,

§

impl<C, S> Sync for FactoryStack<C, S>
where C: Sync, S: Sync,

§

impl<C, S> Unpin for FactoryStack<C, S>
where C: Unpin, S: Unpin,

§

impl<C, S> UnwindSafe for FactoryStack<C, S>
where C: UnwindSafe, S: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.