aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2023-09-14 19:41:56 +0200
committerHampusM <hampus@hampusmat.com>2023-09-14 21:17:37 +0200
commit9bed6b4d2772fd020ea9eb6eaaba4ca014d96f94 (patch)
treedff0d7768f4a56c9d75e4a6c89974891373e997b
parent9a7cf8cfd376da09c982606aa79f253319dfe382 (diff)
refactor!: remove blocking DI container interface
BREAKING CHANGE: IDIContainer have been removed and multiple structs no longer take a DI container generic parameter
-rw-r--r--examples/basic/main.rs1
-rw-r--r--examples/factory/main.rs2
-rw-r--r--examples/generics/main.rs2
-rw-r--r--examples/named/main.rs1
-rw-r--r--examples/with-3rd-party/main.rs2
-rw-r--r--macros/src/injectable/implementation.rs3
-rw-r--r--src/di_container/blocking/binding/builder.rs92
-rw-r--r--src/di_container/blocking/binding/scope_configurator.rs68
-rw-r--r--src/di_container/blocking/binding/when_configurator.rs35
-rw-r--r--src/di_container/blocking/mod.rs318
-rw-r--r--src/di_container/blocking/prelude.rs2
-rw-r--r--src/interfaces/injectable.rs11
-rw-r--r--src/lib.rs1
-rw-r--r--src/provider/blocking.rs37
-rw-r--r--src/test_utils.rs124
15 files changed, 259 insertions, 440 deletions
diff --git a/examples/basic/main.rs b/examples/basic/main.rs
index 7b129e9..dbc9215 100644
--- a/examples/basic/main.rs
+++ b/examples/basic/main.rs
@@ -11,7 +11,6 @@ mod interfaces;
use bootstrap::bootstrap;
use interfaces::dog::IDog;
use interfaces::human::IHuman;
-use syrette::di_container::blocking::prelude::*;
fn main() -> Result<(), Box<dyn Error>>
{
diff --git a/examples/factory/main.rs b/examples/factory/main.rs
index d428717..2c18829 100644
--- a/examples/factory/main.rs
+++ b/examples/factory/main.rs
@@ -9,8 +9,6 @@ mod user_manager;
use std::error::Error;
-use syrette::di_container::blocking::prelude::*;
-
use crate::bootstrap::bootstrap;
use crate::interfaces::user_manager::IUserManager;
diff --git a/examples/generics/main.rs b/examples/generics/main.rs
index 7910cad..e54b168 100644
--- a/examples/generics/main.rs
+++ b/examples/generics/main.rs
@@ -4,8 +4,6 @@ mod printer;
use std::error::Error;
-use syrette::di_container::blocking::prelude::*;
-
use crate::bootstrap::bootstrap;
use crate::interfaces::printer::IPrinter;
diff --git a/examples/named/main.rs b/examples/named/main.rs
index e7cccd0..5411a12 100644
--- a/examples/named/main.rs
+++ b/examples/named/main.rs
@@ -9,7 +9,6 @@ mod ninja;
mod shuriken;
use anyhow::Result;
-use syrette::di_container::blocking::prelude::*;
use crate::bootstrap::bootstrap;
use crate::interfaces::ninja::INinja;
diff --git a/examples/with-3rd-party/main.rs b/examples/with-3rd-party/main.rs
index 520038e..e9f8c89 100644
--- a/examples/with-3rd-party/main.rs
+++ b/examples/with-3rd-party/main.rs
@@ -8,8 +8,6 @@ mod ninja;
use std::error::Error;
-use syrette::di_container::blocking::prelude::*;
-
use crate::bootstrap::bootstrap;
use crate::interfaces::ninja::INinja;
diff --git a/macros/src/injectable/implementation.rs b/macros/src/injectable/implementation.rs
index 9e97f45..1efd1fa 100644
--- a/macros/src/injectable/implementation.rs
+++ b/macros/src/injectable/implementation.rs
@@ -289,7 +289,7 @@ impl<Dep: IDependency> InjectableImpl<Dep>
quote! {
#maybe_doc_hidden
impl #generics syrette::interfaces::injectable::Injectable<
- syrette::di_container::blocking::DIContainer,
+ ::syrette::di_container::blocking::DIContainer
> for #self_type
{
fn resolve(
@@ -303,7 +303,6 @@ impl<Dep: IDependency> InjectableImpl<Dep>
{
use std::any::type_name;
- use syrette::di_container::blocking::IDIContainer;
use syrette::errors::injectable::InjectableError;
let self_type_name = type_name::<#self_type>();
diff --git a/src/di_container/blocking/binding/builder.rs b/src/di_container/blocking/binding/builder.rs
index bfc9e4e..64e787e 100644
--- a/src/di_container/blocking/binding/builder.rs
+++ b/src/di_container/blocking/binding/builder.rs
@@ -1,6 +1,4 @@
-//! Binding builder for types inside of a [`IDIContainer`].
-//!
-//! [`IDIContainer`]: crate::di_container::blocking::IDIContainer
+//! Binding builder for types inside of a [`DIContainer`].
use std::any::type_name;
use std::marker::PhantomData;
use std::rc::Rc;
@@ -8,36 +6,32 @@ use std::rc::Rc;
use crate::di_container::blocking::binding::scope_configurator::BindingScopeConfigurator;
#[cfg(feature = "factory")]
use crate::di_container::blocking::binding::when_configurator::BindingWhenConfigurator;
-use crate::di_container::blocking::IDIContainer;
use crate::di_container::BindingOptions;
use crate::errors::di_container::BindingBuilderError;
use crate::interfaces::injectable::Injectable;
use crate::util::use_double;
use_double!(crate::dependency_history::DependencyHistory);
+use_double!(crate::di_container::blocking::DIContainer);
-/// Binding builder for type `Interface` inside a [`IDIContainer`].
-///
-/// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
+/// Binding builder for type `Interface` inside a [`DIContainer`].
#[must_use = "No binding will be created if you don't use the binding builder"]
-pub struct BindingBuilder<Interface, DIContainerType>
+pub struct BindingBuilder<Interface>
where
Interface: 'static + ?Sized,
- DIContainerType: IDIContainer,
{
- di_container: Rc<DIContainerType>,
+ di_container: Rc<DIContainer>,
dependency_history_factory: fn() -> DependencyHistory,
interface_phantom: PhantomData<Interface>,
}
-impl<Interface, DIContainerType> BindingBuilder<Interface, DIContainerType>
+impl<Interface> BindingBuilder<Interface>
where
Interface: 'static + ?Sized,
- DIContainerType: IDIContainer,
{
pub(crate) fn new(
- di_container: Rc<DIContainerType>,
+ di_container: Rc<DIContainer>,
dependency_history_factory: fn() -> DependencyHistory,
) -> Self
{
@@ -49,13 +43,13 @@ where
}
/// Creates a binding of type `Interface` to type `Implementation` inside of the
- /// associated [`IDIContainer`].
+ /// associated [`DIContainer`].
///
/// The scope of the binding is transient. But that can be changed by using the
/// returned [`BindingScopeConfigurator`]
///
/// # Errors
- /// Will return Err if the associated [`IDIContainer`] already have a binding for
+ /// Will return Err if the associated [`DIContainer`] already have a binding for
/// the interface.
///
/// # Examples
@@ -63,7 +57,6 @@ where
/// # use std::error::Error;
/// #
/// # use syrette::{DIContainer, injectable};
- /// # use syrette::di_container::blocking::IDIContainer;
/// #
/// # trait Foo {}
/// #
@@ -88,16 +81,11 @@ where
/// # Ok(())
/// # }
/// ```
- ///
- /// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
pub fn to<Implementation>(
self,
- ) -> Result<
- BindingScopeConfigurator<Interface, Implementation, DIContainerType>,
- BindingBuilderError,
- >
+ ) -> Result<BindingScopeConfigurator<Interface, Implementation>, BindingBuilderError>
where
- Implementation: Injectable<DIContainerType>,
+ Implementation: Injectable<DIContainer>,
{
if self
.di_container
@@ -119,10 +107,10 @@ where
}
/// Creates a binding of factory type `Interface` to a factory inside of the
- /// associated [`IDIContainer`].
+ /// associated [`DIContainer`].
///
/// # Errors
- /// Will return Err if the associated [`IDIContainer`] already have a binding for
+ /// Will return Err if the associated [`DIContainer`] already have a binding for
/// the interface.
///
/// # Examples
@@ -131,7 +119,6 @@ where
/// #
/// # use syrette::{DIContainer, factory};
/// # use syrette::ptr::TransientPtr;
- /// # use syrette::di_container::blocking::IDIContainer;
/// #
/// # trait ICustomerID {}
/// # trait ICustomer {}
@@ -182,19 +169,17 @@ where
/// # Ok(())
/// # }
/// ```
- ///
- /// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
#[cfg(feature = "factory")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))]
pub fn to_factory<Args, Return, Func>(
self,
factory_func: &'static Func,
- ) -> Result<BindingWhenConfigurator<Interface, DIContainerType>, BindingBuilderError>
+ ) -> Result<BindingWhenConfigurator<Interface>, BindingBuilderError>
where
Args: std::marker::Tuple + 'static,
Return: 'static + ?Sized,
Interface: Fn<Args, Output = crate::ptr::TransientPtr<Return>>,
- Func: Fn<(std::rc::Rc<DIContainerType>,), Output = Box<Interface>>,
+ Func: Fn<(std::rc::Rc<DIContainer>,), Output = Box<Interface>>,
{
use crate::private::castable_factory::blocking::CastableFactory;
@@ -221,10 +206,10 @@ where
}
/// Creates a binding of type `Interface` to a factory that takes no arguments
- /// inside of the associated [`IDIContainer`].
+ /// inside of the associated [`DIContainer`].
///
/// # Errors
- /// Will return Err if the associated [`IDIContainer`] already have a binding for
+ /// Will return Err if the associated [`DIContainer`] already have a binding for
/// the interface.
///
/// # Examples
@@ -233,7 +218,6 @@ where
/// #
/// # use syrette::{DIContainer, factory};
/// # use syrette::ptr::TransientPtr;
- /// # use syrette::di_container::blocking::IDIContainer;
/// #
/// # trait IBuffer {}
/// #
@@ -271,18 +255,16 @@ where
/// # Ok(())
/// # }
/// ```
- ///
- /// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
#[cfg(feature = "factory")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))]
pub fn to_default_factory<Return, FactoryFunc>(
self,
factory_func: &'static FactoryFunc,
- ) -> Result<BindingWhenConfigurator<Interface, DIContainerType>, BindingBuilderError>
+ ) -> Result<BindingWhenConfigurator<Interface>, BindingBuilderError>
where
Return: 'static + ?Sized,
FactoryFunc: Fn<
- (Rc<DIContainerType>,),
+ (Rc<DIContainer>,),
Output = crate::ptr::TransientPtr<
dyn Fn<(), Output = crate::ptr::TransientPtr<Return>>,
>,
@@ -322,12 +304,13 @@ mod tests
use super::*;
use crate::dependency_history::MockDependencyHistory;
- use crate::test_utils::{mocks, subjects};
+ use crate::di_container::blocking::MockDIContainer;
+ use crate::test_utils::subjects;
#[test]
fn can_bind_to() -> Result<(), Box<dyn Error>>
{
- let mut mock_di_container = mocks::blocking_di_container::MockDIContainer::new();
+ let mut mock_di_container = MockDIContainer::new();
mock_di_container
.expect_has_binding::<dyn subjects::INumber>()
@@ -341,11 +324,10 @@ mod tests
.return_once(|_options, _provider| ())
.once();
- let binding_builder =
- BindingBuilder::<
- dyn subjects::INumber,
- mocks::blocking_di_container::MockDIContainer,
- >::new(Rc::new(mock_di_container), MockDependencyHistory::new);
+ let binding_builder = BindingBuilder::<dyn subjects::INumber>::new(
+ Rc::new(mock_di_container),
+ MockDependencyHistory::new,
+ );
binding_builder.to::<subjects::Number>()?;
@@ -364,7 +346,7 @@ mod tests
type IUserManagerFactory =
dyn Fn(i32, String) -> TransientPtr<dyn subjects::IUserManager>;
- let mut mock_di_container = mocks::blocking_di_container::MockDIContainer::new();
+ let mut mock_di_container = MockDIContainer::new();
mock_di_container
.expect_has_binding::<IUserManagerFactory>()
@@ -378,11 +360,10 @@ mod tests
.return_once(|_, _provider| ())
.once();
- let binding_builder =
- BindingBuilder::<
- IUserManagerFactory,
- mocks::blocking_di_container::MockDIContainer,
- >::new(Rc::new(mock_di_container), MockDependencyHistory::new);
+ let binding_builder = BindingBuilder::<IUserManagerFactory>::new(
+ Rc::new(mock_di_container),
+ MockDependencyHistory::new,
+ );
binding_builder.to_factory(&|_| {
Box::new(move |_num, _text| {
@@ -407,7 +388,7 @@ mod tests
declare_default_factory!(dyn subjects::IUserManager);
- let mut mock_di_container = mocks::blocking_di_container::MockDIContainer::new();
+ let mut mock_di_container = MockDIContainer::new();
mock_di_container
.expect_has_binding::<dyn subjects::IUserManager>()
@@ -421,11 +402,10 @@ mod tests
.return_once(|_, _provider| ())
.once();
- let binding_builder =
- BindingBuilder::<
- dyn subjects::IUserManager,
- mocks::blocking_di_container::MockDIContainer,
- >::new(Rc::new(mock_di_container), MockDependencyHistory::new);
+ let binding_builder = BindingBuilder::<dyn subjects::IUserManager>::new(
+ Rc::new(mock_di_container),
+ MockDependencyHistory::new,
+ );
binding_builder.to_default_factory(&|_| {
Box::new(move || {
diff --git a/src/di_container/blocking/binding/scope_configurator.rs b/src/di_container/blocking/binding/scope_configurator.rs
index 0fcdfdf..be469ba 100644
--- a/src/di_container/blocking/binding/scope_configurator.rs
+++ b/src/di_container/blocking/binding/scope_configurator.rs
@@ -1,11 +1,8 @@
-//! Scope configurator for a binding for types inside of a [`IDIContainer`].
-//!
-//! [`IDIContainer`]: crate::di_container::blocking::IDIContainer
+//! Scope configurator for a binding for types inside of a [`DIContainer`].
use std::marker::PhantomData;
use std::rc::Rc;
use crate::di_container::blocking::binding::when_configurator::BindingWhenConfigurator;
-use crate::di_container::blocking::IDIContainer;
use crate::di_container::BindingOptions;
use crate::errors::di_container::BindingScopeConfiguratorError;
use crate::interfaces::injectable::Injectable;
@@ -14,32 +11,28 @@ use crate::ptr::SingletonPtr;
use crate::util::use_double;
use_double!(crate::dependency_history::DependencyHistory);
+use_double!(crate::di_container::blocking::DIContainer);
-/// Scope configurator for a binding for type `Interface` inside a [`IDIContainer`].
-///
-/// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
-pub struct BindingScopeConfigurator<Interface, Implementation, DIContainerType>
+/// Scope configurator for a binding for type `Interface` inside a [`DIContainer`].
+pub struct BindingScopeConfigurator<Interface, Implementation>
where
Interface: 'static + ?Sized,
- Implementation: Injectable<DIContainerType>,
- DIContainerType: IDIContainer,
+ Implementation: Injectable<DIContainer>,
{
- di_container: Rc<DIContainerType>,
+ di_container: Rc<DIContainer>,
dependency_history_factory: fn() -> DependencyHistory,
interface_phantom: PhantomData<Interface>,
implementation_phantom: PhantomData<Implementation>,
}
-impl<Interface, Implementation, DIContainerType>
- BindingScopeConfigurator<Interface, Implementation, DIContainerType>
+impl<Interface, Implementation> BindingScopeConfigurator<Interface, Implementation>
where
Interface: 'static + ?Sized,
- Implementation: Injectable<DIContainerType>,
- DIContainerType: IDIContainer,
+ Implementation: Injectable<DIContainer>,
{
pub(crate) fn new(
- di_container: Rc<DIContainerType>,
+ di_container: Rc<DIContainer>,
dependency_history_factory: fn() -> DependencyHistory,
) -> Self
{
@@ -55,8 +48,7 @@ where
///
/// This is the default.
#[allow(clippy::must_use_candidate)]
- pub fn in_transient_scope(self)
- -> BindingWhenConfigurator<Interface, DIContainerType>
+ pub fn in_transient_scope(self) -> BindingWhenConfigurator<Interface>
{
self.set_in_transient_scope();
@@ -69,10 +61,7 @@ where
/// Will return Err if resolving the implementation fails.
pub fn in_singleton_scope(
self,
- ) -> Result<
- BindingWhenConfigurator<Interface, DIContainerType>,
- BindingScopeConfiguratorError,
- >
+ ) -> Result<BindingWhenConfigurator<Interface>, BindingScopeConfiguratorError>
{
let singleton: SingletonPtr<Implementation> = SingletonPtr::from(
Implementation::resolve(
@@ -94,7 +83,7 @@ where
{
self.di_container.set_binding::<Interface>(
BindingOptions::new(),
- Box::new(TransientTypeProvider::<Implementation, DIContainerType>::new()),
+ Box::new(TransientTypeProvider::<Implementation, DIContainer>::new()),
);
}
}
@@ -104,12 +93,13 @@ mod tests
{
use super::*;
use crate::dependency_history::MockDependencyHistory;
- use crate::test_utils::{mocks, subjects};
+ use crate::di_container::blocking::MockDIContainer;
+ use crate::test_utils::subjects;
#[test]
fn in_transient_scope_works()
{
- let mut di_container_mock = mocks::blocking_di_container::MockDIContainer::new();
+ let mut di_container_mock = MockDIContainer::new();
di_container_mock
.expect_set_binding::<dyn subjects::IUserManager>()
@@ -117,12 +107,13 @@ mod tests
.return_once(|_name, _provider| ())
.once();
- let binding_scope_configurator =
- BindingScopeConfigurator::<
- dyn subjects::IUserManager,
- subjects::UserManager,
- mocks::blocking_di_container::MockDIContainer,
- >::new(Rc::new(di_container_mock), MockDependencyHistory::new);
+ let binding_scope_configurator = BindingScopeConfigurator::<
+ dyn subjects::IUserManager,
+ subjects::UserManager,
+ >::new(
+ Rc::new(di_container_mock),
+ MockDependencyHistory::new,
+ );
binding_scope_configurator.in_transient_scope();
}
@@ -130,7 +121,7 @@ mod tests
#[test]
fn in_singleton_scope_works()
{
- let mut di_container_mock = mocks::blocking_di_container::MockDIContainer::new();
+ let mut di_container_mock = MockDIContainer::new();
di_container_mock
.expect_set_binding::<dyn subjects::IUserManager>()
@@ -138,12 +129,13 @@ mod tests
.return_once(|_name, _provider| ())
.once();
- let binding_scope_configurator =
- BindingScopeConfigurator::<
- dyn subjects::IUserManager,
- subjects::UserManager,
- mocks::blocking_di_container::MockDIContainer,
- >::new(Rc::new(di_container_mock), MockDependencyHistory::new);
+ let binding_scope_configurator = BindingScopeConfigurator::<
+ dyn subjects::IUserManager,
+ subjects::UserManager,
+ >::new(
+ Rc::new(di_container_mock),
+ MockDependencyHistory::new,
+ );
assert!(binding_scope_configurator.in_singleton_scope().is_ok());
}
diff --git a/src/di_container/blocking/binding/when_configurator.rs b/src/di_container/blocking/binding/when_configurator.rs
index 52b23ff..3d267b2 100644
--- a/src/di_container/blocking/binding/when_configurator.rs
+++ b/src/di_container/blocking/binding/when_configurator.rs
@@ -1,33 +1,29 @@
-//! When configurator for a binding for types inside of a [`IDIContainer`].
-//!
-//! [`IDIContainer`]: crate::di_container::blocking::IDIContainer
+//! When configurator for a binding for types inside of a [`DIContainer`].
use std::any::type_name;
use std::marker::PhantomData;
use std::rc::Rc;
-use crate::di_container::blocking::IDIContainer;
use crate::di_container::BindingOptions;
use crate::errors::di_container::BindingWhenConfiguratorError;
+use crate::util::use_double;
-/// When configurator for a binding for type `Interface` inside a [`IDIContainer`].
-///
-/// [`IDIContainer`]: crate::di_container::blocking::IDIContainer
-pub struct BindingWhenConfigurator<Interface, DIContainerType>
+use_double!(crate::di_container::blocking::DIContainer);
+
+/// When configurator for a binding for type `Interface` inside a [`DIContainer`].
+pub struct BindingWhenConfigurator<Interface>
where
Interface: 'static + ?Sized,
- DIContainerType: IDIContainer,
{
- di_container: Rc<DIContainerType>,
+ di_container: Rc<DIContainer>,
interface_phantom: PhantomData<Interface>,
}
-impl<Interface, DIContainerType> BindingWhenConfigurator<Interface, DIContainerType>
+impl<Interface> BindingWhenConfigurator<Interface>
where
Interface: 'static + ?Sized,
- DIContainerType: IDIContainer,
{
- pub(crate) fn new(di_container: Rc<DIContainerType>) -> Self
+ pub(crate) fn new(di_container: Rc<DIContainer>) -> Self
{
Self {
di_container,
@@ -70,13 +66,14 @@ mod tests
use mockall::predicate::eq;
use super::*;
+ use crate::di_container::blocking::MockDIContainer;
use crate::provider::blocking::MockIProvider;
- use crate::test_utils::{mocks, subjects};
+ use crate::test_utils::subjects;
#[test]
fn when_named_works()
{
- let mut di_container_mock = mocks::blocking_di_container::MockDIContainer::new();
+ let mut di_container_mock = MockDIContainer::new();
di_container_mock
.expect_remove_binding::<dyn subjects::INumber>()
@@ -90,10 +87,10 @@ mod tests
.return_once(|_name, _provider| ())
.once();
- let binding_when_configurator = BindingWhenConfigurator::<
- dyn subjects::INumber,
- mocks::blocking_di_container::MockDIContainer,
- >::new(Rc::new(di_container_mock));
+ let binding_when_configurator =
+ BindingWhenConfigurator::<dyn subjects::INumber>::new(Rc::new(
+ di_container_mock,
+ ));
assert!(binding_when_configurator.when_named("cool").is_ok());
}
diff --git a/src/di_container/blocking/mod.rs b/src/di_container/blocking/mod.rs
index 27ea0fb..169abd2 100644
--- a/src/di_container/blocking/mod.rs
+++ b/src/di_container/blocking/mod.rs
@@ -5,7 +5,6 @@
//! use std::collections::HashMap;
//! use std::error::Error;
//!
-//! use syrette::di_container::blocking::IDIContainer;
//! use syrette::{injectable, DIContainer};
//!
//! trait IDatabaseService
@@ -69,15 +68,45 @@ use_double!(crate::dependency_history::DependencyHistory);
pub mod binding;
pub mod prelude;
-/// Blocking dependency injection container interface.
-///
-/// **This trait is sealed and cannot be implemented for types outside this crate.**
-pub trait IDIContainer: Sized + 'static + details::DIContainerInternals
+#[cfg(not(test))]
+pub(crate) type BindingOptionsWithLt<'a> = BindingOptions<'a>;
+
+#[cfg(test)]
+pub(crate) type BindingOptionsWithLt = BindingOptions<'static>;
+
+/// Blocking dependency injection container.
+pub struct DIContainer
+{
+ binding_storage: RefCell<DIContainerBindingStorage<dyn IProvider<Self>>>,
+}
+
+impl DIContainer
+{
+ /// Returns a new `DIContainer`.
+ #[must_use]
+ pub fn new() -> Rc<Self>
+ {
+ Rc::new(Self {
+ binding_storage: RefCell::new(DIContainerBindingStorage::new()),
+ })
+ }
+}
+
+#[cfg_attr(test, mockall::automock)]
+impl DIContainer
{
/// Returns a new [`BindingBuilder`] for the given interface.
- fn bind<Interface>(self: &mut Rc<Self>) -> BindingBuilder<Interface, Self>
+ #[allow(clippy::missing_panics_doc)]
+ pub fn bind<Interface>(self: &mut Rc<Self>) -> BindingBuilder<Interface>
where
- Interface: 'static + ?Sized;
+ Interface: 'static + ?Sized,
+ {
+ #[cfg(test)]
+ panic!("Nope");
+
+ #[cfg(not(test))]
+ BindingBuilder::new(self.clone(), DependencyHistory::new)
+ }
/// Returns the type bound with `Interface`.
///
@@ -86,9 +115,12 @@ pub trait IDIContainer: Sized + 'static + details::DIContainerInternals
/// - No binding for `Interface` exists
/// - Resolving the binding for `Interface` fails
/// - Casting the binding for `Interface` fails
- fn get<Interface>(self: &Rc<Self>) -> Result<SomePtr<Interface>, DIContainerError>
+ pub fn get<Interface>(self: &Rc<Self>) -> Result<SomePtr<Interface>, DIContainerError>
where
- Interface: 'static + ?Sized;
+ Interface: 'static + ?Sized,
+ {
+ self.get_bound::<Interface>(DependencyHistory::new(), BindingOptions::new())
+ }
/// Returns the type bound with `Interface` and the specified name.
///
@@ -97,12 +129,18 @@ pub trait IDIContainer: Sized + 'static + details::DIContainerInternals
/// - No binding for `Interface` with name `name` exists
/// - Resolving the binding for `Interface` fails
/// - Casting the binding for `Interface` fails
- fn get_named<Interface>(
+ pub fn get_named<Interface>(
self: &Rc<Self>,
name: &'static str,
) -> Result<SomePtr<Interface>, DIContainerError>
where
- Interface: 'static + ?Sized;
+ Interface: 'static + ?Sized,
+ {
+ self.get_bound::<Interface>(
+ DependencyHistory::new(),
+ BindingOptions::new().name(name),
+ )
+ }
/// Returns the type bound with `Interface` where the binding has the specified
/// options.
@@ -118,7 +156,6 @@ pub trait IDIContainer: Sized + 'static + details::DIContainerInternals
/// # Examples
/// ```no_run
/// # use syrette::di_container::blocking::DIContainer;
- /// # use syrette::di_container::blocking::IDIContainer;
/// # use syrette::dependency_history::DependencyHistory;
/// # use syrette::di_container::BindingOptions;
/// #
@@ -140,132 +177,17 @@ pub trait IDIContainer: Sized + 'static + details::DIContainerInternals
/// # Ok(())
/// # }
/// ```
- fn get_bound<Interface>(
+ pub fn get_bound<Interface>(
self: &Rc<Self>,
dependency_history: DependencyHistory,
binding_options: BindingOptionsWithLt,
) -> Result<SomePtr<Interface>, DIContainerError>
where
- Interface: 'static + ?Sized;
-}
-
-#[cfg(not(test))]
-pub(crate) type BindingOptionsWithLt<'a> = BindingOptions<'a>;
-
-#[cfg(test)]
-pub(crate) type BindingOptionsWithLt = BindingOptions<'static>;
-
-/// Blocking dependency injection container.
-pub struct DIContainer
-{
- binding_storage: RefCell<DIContainerBindingStorage<dyn IProvider<Self>>>,
-}
-
-impl DIContainer
-{
- /// Returns a new `DIContainer`.
- #[must_use]
- pub fn new() -> Rc<Self>
- {
- Rc::new(Self {
- binding_storage: RefCell::new(DIContainerBindingStorage::new()),
- })
- }
-}
-
-impl IDIContainer for DIContainer
-{
- fn bind<Interface>(self: &mut Rc<Self>) -> BindingBuilder<Interface, Self>
- where
- Interface: 'static + ?Sized,
- {
- BindingBuilder::new(self.clone(), DependencyHistory::new)
- }
-
- fn get<Interface>(self: &Rc<Self>) -> Result<SomePtr<Interface>, DIContainerError>
- where
- Interface: 'static + ?Sized,
- {
- self.get_bound::<Interface>(DependencyHistory::new(), BindingOptions::new())
- }
-
- fn get_named<Interface>(
- self: &Rc<Self>,
- name: &'static str,
- ) -> Result<SomePtr<Interface>, DIContainerError>
- where
- Interface: 'static + ?Sized,
- {
- self.get_bound::<Interface>(
- DependencyHistory::new(),
- BindingOptions::new().name(name),
- )
- }
-
- fn get_bound<Interface>(
- self: &Rc<Self>,
- dependency_history: DependencyHistory,
- binding_options: BindingOptions,
- ) -> Result<SomePtr<Interface>, DIContainerError>
- where
Interface: 'static + ?Sized,
{
let binding_providable = self
.get_binding_providable::<Interface>(binding_options, dependency_history)?;
- #[cfg(feature = "factory")]
- return self.handle_binding_providable(binding_providable);
-
- #[cfg(not(feature = "factory"))]
- Self::handle_binding_providable(binding_providable)
- }
-}
-
-impl details::DIContainerInternals for DIContainer
-{
- fn has_binding<Interface>(self: &Rc<Self>, binding_options: BindingOptions) -> bool
- where
- Interface: ?Sized + 'static,
- {
- self.binding_storage
- .borrow()
- .has::<Interface>(binding_options)
- }
-
- fn set_binding<Interface>(
- self: &Rc<Self>,
- binding_options: BindingOptions<'static>,
- provider: Box<dyn IProvider<Self>>,
- ) where
- Interface: 'static + ?Sized,
- {
- self.binding_storage
- .borrow_mut()
- .set::<Interface>(binding_options, provider);
- }
-
- fn remove_binding<Interface>(
- self: &Rc<Self>,
- binding_options: BindingOptions<'static>,
- ) -> Option<Box<dyn IProvider<Self>>>
- where
- Interface: 'static + ?Sized,
- {
- self.binding_storage
- .borrow_mut()
- .remove::<Interface>(binding_options)
- }
-}
-
-impl DIContainer
-{
- fn handle_binding_providable<Interface>(
- #[cfg(feature = "factory")] self: &Rc<Self>,
- binding_providable: Providable<Self>,
- ) -> Result<SomePtr<Interface>, DIContainerError>
- where
- Interface: 'static + ?Sized,
- {
match binding_providable {
Providable::Transient(transient_binding) => Ok(SomePtr::Transient(
transient_binding.cast::<Interface>().map_err(|_| {
@@ -318,7 +240,7 @@ impl DIContainer
fn get_binding_providable<Interface>(
self: &Rc<Self>,
- binding_options: BindingOptions,
+ binding_options: BindingOptionsWithLt,
dependency_history: DependencyHistory,
) -> Result<Providable<Self>, DIContainerError>
where
@@ -344,38 +266,41 @@ impl DIContainer
interface: type_name::<Interface>(),
})
}
-}
-pub(crate) mod details
-{
- use std::rc::Rc;
+ fn has_binding<Interface>(
+ self: &Rc<Self>,
+ binding_options: BindingOptionsWithLt,
+ ) -> bool
+ where
+ Interface: ?Sized + 'static,
+ {
+ self.binding_storage
+ .borrow()
+ .has::<Interface>(binding_options)
+ }
- use crate::di_container::blocking::BindingOptionsWithLt;
- use crate::di_container::BindingOptions;
- use crate::provider::blocking::IProvider;
+ fn set_binding<Interface>(
+ self: &Rc<Self>,
+ binding_options: BindingOptions<'static>,
+ provider: Box<dyn IProvider<Self>>,
+ ) where
+ Interface: 'static + ?Sized,
+ {
+ self.binding_storage
+ .borrow_mut()
+ .set::<Interface>(binding_options, provider);
+ }
- pub trait DIContainerInternals
+ fn remove_binding<Interface>(
+ self: &Rc<Self>,
+ binding_options: BindingOptions<'static>,
+ ) -> Option<Box<dyn IProvider<Self>>>
+ where
+ Interface: 'static + ?Sized,
{
- fn has_binding<Interface>(
- self: &Rc<Self>,
- binding_options: BindingOptionsWithLt,
- ) -> bool
- where
- Interface: ?Sized + 'static;
-
- fn set_binding<Interface>(
- self: &Rc<Self>,
- binding_options: BindingOptions<'static>,
- provider: Box<dyn IProvider<Self>>,
- ) where
- Interface: 'static + ?Sized;
-
- fn remove_binding<Interface>(
- self: &Rc<Self>,
- binding_options: BindingOptions<'static>,
- ) -> Option<Box<dyn IProvider<Self>>>
- where
- Interface: 'static + ?Sized;
+ self.binding_storage
+ .borrow_mut()
+ .remove::<Interface>(binding_options)
}
}
@@ -385,15 +310,16 @@ mod tests
use std::error::Error;
use super::*;
+ use crate::provider::blocking::MockIProvider;
use crate::ptr::{SingletonPtr, TransientPtr};
- use crate::test_utils::{mocks, subjects};
+ use crate::test_utils::subjects;
#[test]
fn can_get() -> Result<(), Box<dyn Error>>
{
let di_container = DIContainer::new();
- let mut mock_provider = mocks::blocking_provider::MockProvider::new();
+ let mut mock_provider = MockIProvider::new();
mock_provider.expect_provide().returning(|_, _| {
Ok(Providable::Transient(TransientPtr::new(
@@ -421,7 +347,7 @@ mod tests
{
let di_container = DIContainer::new();
- let mut mock_provider = mocks::blocking_provider::MockProvider::new();
+ let mut mock_provider = MockIProvider::new();
mock_provider.expect_provide().returning(|_, _| {
Ok(Providable::Transient(TransientPtr::new(
@@ -449,7 +375,7 @@ mod tests
{
let di_container = DIContainer::new();
- let mut mock_provider = mocks::blocking_provider::MockProvider::new();
+ let mut mock_provider = MockIProvider::new();
let mut singleton = SingletonPtr::new(subjects::Number::new());
@@ -481,7 +407,7 @@ mod tests
{
let di_container = DIContainer::new();
- let mut mock_provider = mocks::blocking_provider::MockProvider::new();
+ let mut mock_provider = MockIProvider::new();
let mut singleton = SingletonPtr::new(subjects::Number::new());
@@ -574,7 +500,7 @@ mod tests
})
};
- let mut mock_provider = mocks::blocking_provider::MockProvider::new();
+ let mut mock_provider = MockIProvider::new();
mock_provider.expect_provide().returning_st(|_, _| {
Ok(Providable::Factory(FactoryPtr::new(CastableFactory::new(
@@ -652,7 +578,7 @@ mod tests
})
};
- let mut mock_provider = mocks::blocking_provider::MockProvider::new();
+ let mut mock_provider = MockIProvider::new();
mock_provider.expect_provide().returning_st(|_, _| {
Ok(Providable::Factory(FactoryPtr::new(CastableFactory::new(
@@ -674,4 +600,68 @@ mod tests
Ok(())
}
+
+ #[test]
+ fn has_binding_works()
+ {
+ let di_container = DIContainer::new();
+
+ // No binding is present yet
+ assert!(!di_container.has_binding::<subjects::Ninja>(BindingOptions::new()));
+
+ di_container
+ .binding_storage
+ .borrow_mut()
+ .set::<subjects::Ninja>(
+ BindingOptions::new(),
+ Box::new(MockIProvider::new()),
+ );
+
+ assert!(di_container.has_binding::<subjects::Ninja>(BindingOptions::new()));
+ }
+
+ #[test]
+ fn set_binding_works()
+ {
+ let di_container = DIContainer::new();
+
+ di_container.set_binding::<subjects::Ninja>(
+ BindingOptions::new(),
+ Box::new(MockIProvider::new()),
+ );
+
+ assert!(di_container
+ .binding_storage
+ .borrow_mut()
+ .has::<subjects::Ninja>(BindingOptions::new()));
+ }
+
+ #[test]
+ fn remove_binding_works()
+ {
+ let di_container = DIContainer::new();
+
+ di_container
+ .binding_storage
+ .borrow_mut()
+ .set::<subjects::Ninja>(
+ BindingOptions::new(),
+ Box::new(MockIProvider::new()),
+ );
+
+ assert!(
+ // Formatting is weird without this comment
+ di_container
+ .remove_binding::<subjects::Ninja>(BindingOptions::new())
+ .is_some()
+ );
+
+ assert!(
+ // Formatting is weird without this comment
+ !di_container
+ .binding_storage
+ .borrow_mut()
+ .has::<subjects::Ninja>(BindingOptions::new())
+ );
+ }
}
diff --git a/src/di_container/blocking/prelude.rs b/src/di_container/blocking/prelude.rs
index 82db5e3..216be4b 100644
--- a/src/di_container/blocking/prelude.rs
+++ b/src/di_container/blocking/prelude.rs
@@ -1,2 +1,2 @@
//! Commonly used types.
-pub use crate::di_container::blocking::{DIContainer, IDIContainer};
+pub use crate::di_container::blocking::DIContainer;
diff --git a/src/interfaces/injectable.rs b/src/interfaces/injectable.rs
index 2622320..458b167 100644
--- a/src/interfaces/injectable.rs
+++ b/src/interfaces/injectable.rs
@@ -2,7 +2,6 @@
use std::fmt::Debug;
use std::rc::Rc;
-use crate::di_container::blocking::IDIContainer;
use crate::errors::injectable::InjectableError;
use crate::private::cast::CastFrom;
use crate::ptr::TransientPtr;
@@ -11,25 +10,21 @@ use crate::util::use_double;
use_double!(crate::dependency_history::DependencyHistory);
/// Interface for structs that can be injected into or be injected to.
-pub trait Injectable<DIContainerType>: CastFrom
-where
- DIContainerType: IDIContainer,
+pub trait Injectable<DIContainerT>: CastFrom
{
/// Resolves the dependencies of the injectable.
///
/// # Errors
/// Will return `Err` if resolving the dependencies fails.
fn resolve(
- di_container: &Rc<DIContainerType>,
+ di_container: &Rc<DIContainerT>,
dependency_history: DependencyHistory,
) -> Result<TransientPtr<Self>, InjectableError>
where
Self: Sized;
}
-impl<DIContainerType> Debug for dyn Injectable<DIContainerType>
-where
- DIContainerType: IDIContainer,
+impl<DIContainerT> Debug for dyn Injectable<DIContainerT>
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result
{
diff --git a/src/lib.rs b/src/lib.rs
index 40bf6e6..fd8d0d7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -131,7 +131,6 @@ mod test_utils;
/// # Examples
/// ```
/// # use syrette::{di_container_bind, DIContainer, injectable};
-/// # use syrette::di_container::blocking::IDIContainer;
/// #
/// # trait INinja {}
/// #
diff --git a/src/provider/blocking.rs b/src/provider/blocking.rs
index bc9134d..c719f59 100644
--- a/src/provider/blocking.rs
+++ b/src/provider/blocking.rs
@@ -1,7 +1,6 @@
use std::marker::PhantomData;
use std::rc::Rc;
-use crate::di_container::blocking::IDIContainer;
use crate::errors::injectable::InjectableError;
use crate::interfaces::injectable::Injectable;
use crate::ptr::{SingletonPtr, TransientPtr};
@@ -11,8 +10,6 @@ use_double!(crate::dependency_history::DependencyHistory);
#[derive(strum_macros::Display, Debug)]
pub enum Providable<DIContainerType>
-where
- DIContainerType: IDIContainer,
{
Transient(TransientPtr<dyn Injectable<DIContainerType>>),
Singleton(SingletonPtr<dyn Injectable<DIContainerType>>),
@@ -22,10 +19,8 @@ where
DefaultFactory(crate::ptr::FactoryPtr<dyn crate::private::any_factory::AnyFactory>),
}
-#[cfg_attr(test, mockall::automock, allow(dead_code))]
+#[cfg_attr(test, mockall::automock)]
pub trait IProvider<DIContainerType>
-where
- DIContainerType: IDIContainer,
{
fn provide(
&self,
@@ -37,7 +32,6 @@ where
pub struct TransientTypeProvider<InjectableType, DIContainerType>
where
InjectableType: Injectable<DIContainerType>,
- DIContainerType: IDIContainer,
{
injectable_phantom: PhantomData<InjectableType>,
di_container_phantom: PhantomData<DIContainerType>,
@@ -47,7 +41,6 @@ impl<InjectableType, DIContainerType>
TransientTypeProvider<InjectableType, DIContainerType>
where
InjectableType: Injectable<DIContainerType>,
- DIContainerType: IDIContainer,
{
pub fn new() -> Self
{
@@ -62,7 +55,6 @@ impl<InjectableType, DIContainerType> IProvider<DIContainerType>
for TransientTypeProvider<InjectableType, DIContainerType>
where
InjectableType: Injectable<DIContainerType>,
- DIContainerType: IDIContainer,
{
fn provide(
&self,
@@ -80,7 +72,6 @@ where
pub struct SingletonProvider<InjectableType, DIContainerType>
where
InjectableType: Injectable<DIContainerType>,
- DIContainerType: IDIContainer,
{
singleton: SingletonPtr<InjectableType>,
@@ -90,7 +81,6 @@ where
impl<InjectableType, DIContainerType> SingletonProvider<InjectableType, DIContainerType>
where
InjectableType: Injectable<DIContainerType>,
- DIContainerType: IDIContainer,
{
pub fn new(singleton: SingletonPtr<InjectableType>) -> Self
{
@@ -105,7 +95,6 @@ impl<InjectableType, DIContainerType> IProvider<DIContainerType>
for SingletonProvider<InjectableType, DIContainerType>
where
InjectableType: Injectable<DIContainerType>,
- DIContainerType: IDIContainer,
{
fn provide(
&self,
@@ -141,8 +130,6 @@ impl FactoryProvider
#[cfg(feature = "factory")]
impl<DIContainerType> IProvider<DIContainerType> for FactoryProvider
-where
- DIContainerType: IDIContainer,
{
fn provide(
&self,
@@ -165,17 +152,16 @@ mod tests
use super::*;
use crate::dependency_history::MockDependencyHistory;
- use crate::test_utils::{mocks, subjects};
+ use crate::di_container::blocking::MockDIContainer;
+ use crate::test_utils::subjects;
#[test]
fn transient_type_provider_works() -> Result<(), Box<dyn Error>>
{
- let transient_type_provider = TransientTypeProvider::<
- subjects::UserManager,
- mocks::blocking_di_container::MockDIContainer,
- >::new();
+ let transient_type_provider =
+ TransientTypeProvider::<subjects::UserManager, MockDIContainer>::new();
- let di_container = mocks::blocking_di_container::MockDIContainer::new();
+ let di_container = MockDIContainer::new();
let dependency_history_mock = MockDependencyHistory::new();
@@ -195,12 +181,11 @@ mod tests
fn singleton_provider_works() -> Result<(), Box<dyn Error>>
{
let singleton_provider =
- SingletonProvider::<
- subjects::UserManager,
- mocks::blocking_di_container::MockDIContainer,
- >::new(SingletonPtr::new(subjects::UserManager {}));
+ SingletonProvider::<subjects::UserManager, MockDIContainer>::new(
+ SingletonPtr::new(subjects::UserManager {}),
+ );
- let di_container = mocks::blocking_di_container::MockDIContainer::new();
+ let di_container = MockDIContainer::new();
assert!(
matches!(
@@ -230,7 +215,7 @@ mod tests
let default_factory_provider =
FactoryProvider::new(FactoryPtr::new(FooFactory), true);
- let di_container = Rc::new(mocks::blocking_di_container::MockDIContainer::new());
+ let di_container = Rc::new(MockDIContainer::new());
assert!(
matches!(
diff --git a/src/test_utils.rs b/src/test_utils.rs
index a304a71..95b7ce1 100644
--- a/src/test_utils.rs
+++ b/src/test_utils.rs
@@ -7,7 +7,6 @@ pub mod subjects
use syrette_macros::declare_interface;
- use crate::di_container::blocking::IDIContainer;
use crate::interfaces::injectable::Injectable;
use crate::private::cast::CastFromArc;
use crate::ptr::TransientPtr;
@@ -49,12 +48,10 @@ pub mod subjects
declare_interface!(UserManager -> IUserManager);
- impl<DIContainerType> Injectable<DIContainerType> for UserManager
- where
- DIContainerType: IDIContainer,
+ impl<DIContainerT> Injectable<DIContainerT> for UserManager
{
fn resolve(
- _di_container: &Rc<DIContainerType>,
+ _di_container: &Rc<DIContainerT>,
_dependency_history: DependencyHistory,
) -> Result<TransientPtr<Self>, crate::errors::injectable::InjectableError>
where
@@ -115,12 +112,10 @@ pub mod subjects
declare_interface!(Number -> INumber);
- impl<DIContainerType> Injectable<DIContainerType> for Number
- where
- DIContainerType: IDIContainer,
+ impl<DIContainerT> Injectable<DIContainerT> for Number
{
fn resolve(
- _di_container: &Rc<DIContainerType>,
+ _di_container: &Rc<DIContainerT>,
_dependency_history: DependencyHistory,
) -> Result<TransientPtr<Self>, crate::errors::injectable::InjectableError>
where
@@ -279,87 +274,13 @@ pub mod mocks
#![allow(clippy::ref_option_ref)] // Caused by Mockall
#![allow(dead_code)] // Not all mock functions may be used
- use mockall::mock;
-
- pub mod blocking_di_container
- {
- use std::rc::Rc;
-
- use super::*;
- use crate::di_container::blocking::binding::builder::BindingBuilder;
- use crate::di_container::blocking::details::DIContainerInternals;
- use crate::di_container::blocking::{BindingOptionsWithLt, IDIContainer};
- use crate::di_container::BindingOptions;
- use crate::errors::di_container::DIContainerError;
- use crate::provider::blocking::IProvider;
- use crate::ptr::SomePtr;
- use crate::util::use_double;
-
- use_double!(crate::dependency_history::DependencyHistory);
-
- mock! {
- pub DIContainer {}
-
- impl IDIContainer for DIContainer
- {
- fn bind<Interface>(self: &mut Rc<Self>) -> BindingBuilder<Interface, Self>
- where
- Interface: 'static + ?Sized;
-
- fn get<Interface>(self: &Rc<Self>) -> Result<SomePtr<Interface>, DIContainerError>
- where
- Interface: 'static + ?Sized;
-
- fn get_named<Interface>(
- self: &Rc<Self>,
- name: &'static str,
- ) -> Result<SomePtr<Interface>, DIContainerError>
- where
- Interface: 'static + ?Sized;
-
- #[doc(hidden)]
- fn get_bound<'opts, Interface>(
- self: &Rc<Self>,
- dependency_history: DependencyHistory,
- binding_options: BindingOptionsWithLt,
- ) -> Result<SomePtr<Interface>, DIContainerError>
- where
- Interface: 'static + ?Sized;
- }
-
- impl DIContainerInternals for DIContainer
- {
- fn has_binding<Interface>(
- self: &Rc<Self>,
- binding_options: BindingOptionsWithLt
- ) -> bool
- where
- Interface: ?Sized + 'static;
-
- #[doc(hidden)]
- fn set_binding<Interface>(
- self: &Rc<Self>,
- binding_options: BindingOptions<'static>,
- provider: Box<dyn IProvider<Self>>,
- ) where
- Interface: 'static + ?Sized;
-
- fn remove_binding<Interface>(
- self: &Rc<Self>,
- binding_options: BindingOptions<'static>,
- ) -> Option<Box<dyn IProvider<Self>>>
- where
- Interface: 'static + ?Sized;
- }
- }
- }
-
#[cfg(feature = "async")]
pub mod async_di_container
{
use std::sync::Arc;
- use super::*;
+ use mockall::mock;
+
use crate::di_container::asynchronous::binding::builder::AsyncBindingBuilder;
use crate::di_container::asynchronous::details::DIContainerInternals;
use crate::di_container::asynchronous::IAsyncDIContainer;
@@ -438,8 +359,8 @@ pub mod mocks
use std::sync::Arc;
use async_trait::async_trait;
+ use mockall::mock;
- use super::*;
use crate::di_container::asynchronous::IAsyncDIContainer;
use crate::errors::injectable::InjectableError;
use crate::provider::r#async::{AsyncProvidable, IAsyncProvider};
@@ -468,37 +389,6 @@ pub mod mocks
}
}
}
-
- pub mod blocking_provider
- {
- use std::rc::Rc;
-
- use super::*;
- use crate::di_container::blocking::IDIContainer;
- use crate::errors::injectable::InjectableError;
- use crate::provider::blocking::{IProvider, Providable};
- use crate::util::use_double;
-
- use_double!(crate::dependency_history::DependencyHistory);
-
- mock! {
- pub Provider<DIContainerType>
- where
- DIContainerType: IDIContainer
- {}
-
- impl<DIContainerType> IProvider<DIContainerType> for Provider<DIContainerType>
- where
- DIContainerType: IDIContainer,
- {
- fn provide(
- &self,
- di_container: &Rc<DIContainerType>,
- dependency_history: DependencyHistory,
- ) -> Result<Providable<DIContainerType>, InjectableError>;
- }
- }
- }
}
#[cfg(all(feature = "async", feature = "factory"))]