service_async/layer.rs
1use std::marker::PhantomData;
2
3use crate::AsyncMakeServiceWrapper;
4
5/// A trait for creating layered factory wrappers, enabling complex service compositions.
6///
7/// `FactoryLayer` defines how to wrap one factory with another, creating a new composite factory.
8/// This allows for the creation of reusable, modular pieces of functionality that can be easily combined.
9///
10/// Unlike Tower's `Layer` which creates a `Service` wrapping an inner `Service`,
11/// `FactoryLayer` creates a `Factory` wrapping an inner `Factory`, which can then be used
12/// to create the entire `Service` chain.
13pub trait FactoryLayer<C, F> {
14 /// The type of factory this layer produces.
15 type Factory;
16
17 /// Creates a new factory wrapper.
18 ///
19 /// This method defines how the layer transforms the inner factory into a new factory.
20 fn layer(&self, config: &C, inner: F) -> Self::Factory;
21}
22
23/// Creates a `FactoryLayer` from a closure, simplifying the creation of custom layers.
24///
25/// This function allows for easy creation of `FactoryLayer` implementations without
26/// explicitly defining new structs.
27pub const fn layer_fn<C, FN>(f: FN) -> LayerFn<C, FN> {
28 LayerFn {
29 f,
30 marker: PhantomData,
31 }
32}
33
34/// A struct that wraps a closure to implement `FactoryLayer`.
35///
36/// `LayerFn` allows closures to be used as `FactoryLayer`s, providing a flexible way
37/// to create custom layers.
38pub struct LayerFn<C, FN> {
39 f: FN,
40 marker: PhantomData<fn(C)>,
41}
42
43impl<C, F, FN, O> FactoryLayer<C, F> for LayerFn<C, FN>
44where
45 FN: Fn(&C, F) -> O,
46{
47 type Factory = O;
48
49 #[inline]
50 fn layer(&self, config: &C, inner: F) -> Self::Factory {
51 (self.f)(config, inner)
52 }
53}
54
55pub struct LayerAsync;
56
57impl<C, F> FactoryLayer<C, F> for LayerAsync {
58 type Factory = AsyncMakeServiceWrapper<F>;
59
60 #[inline]
61 fn layer(&self, _config: &C, inner: F) -> Self::Factory {
62 AsyncMakeServiceWrapper(inner)
63 }
64}