diff options
| author | HampusM <hampus@hampusmat.com> | 2023-09-14 19:41:56 +0200 | 
|---|---|---|
| committer | HampusM <hampus@hampusmat.com> | 2023-09-14 21:17:37 +0200 | 
| commit | 9bed6b4d2772fd020ea9eb6eaaba4ca014d96f94 (patch) | |
| tree | dff0d7768f4a56c9d75e4a6c89974891373e997b | |
| parent | 9a7cf8cfd376da09c982606aa79f253319dfe382 (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.rs | 1 | ||||
| -rw-r--r-- | examples/factory/main.rs | 2 | ||||
| -rw-r--r-- | examples/generics/main.rs | 2 | ||||
| -rw-r--r-- | examples/named/main.rs | 1 | ||||
| -rw-r--r-- | examples/with-3rd-party/main.rs | 2 | ||||
| -rw-r--r-- | macros/src/injectable/implementation.rs | 3 | ||||
| -rw-r--r-- | src/di_container/blocking/binding/builder.rs | 92 | ||||
| -rw-r--r-- | src/di_container/blocking/binding/scope_configurator.rs | 68 | ||||
| -rw-r--r-- | src/di_container/blocking/binding/when_configurator.rs | 35 | ||||
| -rw-r--r-- | src/di_container/blocking/mod.rs | 318 | ||||
| -rw-r--r-- | src/di_container/blocking/prelude.rs | 2 | ||||
| -rw-r--r-- | src/interfaces/injectable.rs | 11 | ||||
| -rw-r--r-- | src/lib.rs | 1 | ||||
| -rw-r--r-- | src/provider/blocking.rs | 37 | ||||
| -rw-r--r-- | src/test_utils.rs | 124 | 
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      { @@ -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"))] | 
