diff options
| -rw-r--r-- | Cargo.toml | 4 | ||||
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | examples/async-factory/main.rs | 2 | ||||
| -rw-r--r-- | examples/async/animals.rs (renamed from examples/async/animals/mod.rs) | 0 | ||||
| -rw-r--r-- | examples/async/bootstrap.rs | 2 | ||||
| -rw-r--r-- | examples/async/interfaces.rs (renamed from examples/async/interfaces/mod.rs) | 0 | ||||
| -rw-r--r-- | examples/basic/animals.rs (renamed from examples/basic/animals/mod.rs) | 0 | ||||
| -rw-r--r-- | examples/basic/interfaces.rs (renamed from examples/basic/interfaces/mod.rs) | 0 | ||||
| -rw-r--r-- | examples/factory/interfaces.rs (renamed from examples/factory/interfaces/mod.rs) | 0 | ||||
| -rw-r--r-- | examples/generics/interfaces.rs (renamed from examples/generics/interfaces/mod.rs) | 0 | ||||
| -rw-r--r-- | examples/named/interfaces.rs (renamed from examples/named/interfaces/mod.rs) | 0 | ||||
| -rw-r--r-- | examples/with-3rd-party/bootstrap.rs | 2 | ||||
| -rw-r--r-- | examples/with-3rd-party/interfaces.rs (renamed from examples/with-3rd-party/interfaces/mod.rs) | 0 | ||||
| -rw-r--r-- | macros/Cargo.toml | 4 | ||||
| -rw-r--r-- | macros/src/injectable.rs (renamed from macros/src/injectable/mod.rs) | 0 | ||||
| -rw-r--r-- | macros/src/util.rs (renamed from macros/src/util/mod.rs) | 0 | ||||
| -rw-r--r-- | src/castable_function.rs (renamed from src/castable_function/mod.rs) | 0 | ||||
| -rw-r--r-- | src/di_container.rs (renamed from src/di_container/mod.rs) | 0 | ||||
| -rw-r--r-- | src/di_container/asynchronous.rs (renamed from src/di_container/asynchronous/mod.rs) | 78 | ||||
| -rw-r--r-- | src/di_container/asynchronous/binding.rs (renamed from src/di_container/asynchronous/binding/mod.rs) | 0 | ||||
| -rw-r--r-- | src/di_container/asynchronous/binding/builder.rs | 94 | ||||
| -rw-r--r-- | src/di_container/blocking.rs (renamed from src/di_container/blocking/mod.rs) | 48 | ||||
| -rw-r--r-- | src/di_container/blocking/binding.rs (renamed from src/di_container/blocking/binding/mod.rs) | 0 | ||||
| -rw-r--r-- | src/di_container/blocking/binding/builder.rs | 53 | ||||
| -rw-r--r-- | src/errors.rs (renamed from src/errors/mod.rs) | 0 | ||||
| -rw-r--r-- | src/interfaces.rs (renamed from src/interfaces/mod.rs) | 0 | ||||
| -rw-r--r-- | src/lib.rs | 1 | ||||
| -rw-r--r-- | src/private.rs (renamed from src/private/mod.rs) | 0 | ||||
| -rw-r--r-- | src/private/cast.rs (renamed from src/private/cast/mod.rs) | 0 | ||||
| -rw-r--r-- | src/provider.rs (renamed from src/provider/mod.rs) | 0 | ||||
| -rw-r--r-- | src/provider/async.rs | 136 | ||||
| -rw-r--r-- | src/provider/blocking.rs | 74 | ||||
| -rw-r--r-- | src/test_utils.rs | 4 | 
33 files changed, 219 insertions, 290 deletions
@@ -59,3 +59,7 @@ members = [  	"examples/with-3rd-party/third-party-lib",  ] +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = ["cfg(doc_cfg)", "cfg(tarpaulin_include)"] + @@ -15,6 +15,10 @@ versions uses rust-lld. See [Linkme issue #94](https://github.com/dtolnay/linkme  A temporary fix for this is to build with `RUSTFLAGS="-C link-args=-znostart-stop-gc"`  </div> +## Changelog +You can find out what changes have been made in various versions +[here](https://github.com/HampusMat/Syrette/blob/master/CHANGELOG.md). +  ## Namesake  From the [syrette Wikipedia article](https://en.wikipedia.org/wiki/Syrette).  > A syrette is a device for injecting liquid through a needle. @@ -186,9 +190,6 @@ A type or trait that represents a type (itself in the case of it being a type).  **Factory**<br>  A function that creates new instances of a specific type or trait. -**Default factory**<br> -A function that takes no arguments that creates new instances of a specific type or trait. -  ## Rust version requirements  Syrette requires Rust >= 1.62.1 to work. This is mainly due to the dependency on [Linkme](https://crates.io/crates/linkme). diff --git a/examples/async-factory/main.rs b/examples/async-factory/main.rs index 2b796cc..795e50c 100644 --- a/examples/async-factory/main.rs +++ b/examples/async-factory/main.rs @@ -84,7 +84,7 @@ async fn main() -> Result<()>      di_container          .bind::<dyn IPerson>() -        .to_async_default_factory(&|_| { +        .to_async_dynamic_value(&|_| {              Box::new(|| {                  Box::pin(async {                      // Do some time demanding thing... diff --git a/examples/async/animals/mod.rs b/examples/async/animals.rs index 5444978..5444978 100644 --- a/examples/async/animals/mod.rs +++ b/examples/async/animals.rs diff --git a/examples/async/bootstrap.rs b/examples/async/bootstrap.rs index 07e1bf8..5abeac7 100644 --- a/examples/async/bootstrap.rs +++ b/examples/async/bootstrap.rs @@ -20,7 +20,7 @@ pub async fn bootstrap() -> Result<AsyncDIContainer, anyhow::Error>          .in_singleton_scope()          .await?; -    di_container.bind::<dyn ICat>().to_default_factory(&|_| { +    di_container.bind::<dyn ICat>().to_dynamic_value(&|_| {          Box::new(|| {              let cat: TransientPtr<dyn ICat> = TransientPtr::new(Cat::new()); diff --git a/examples/async/interfaces/mod.rs b/examples/async/interfaces.rs index ea0a26d..ea0a26d 100644 --- a/examples/async/interfaces/mod.rs +++ b/examples/async/interfaces.rs diff --git a/examples/basic/animals/mod.rs b/examples/basic/animals.rs index 5444978..5444978 100644 --- a/examples/basic/animals/mod.rs +++ b/examples/basic/animals.rs diff --git a/examples/basic/interfaces/mod.rs b/examples/basic/interfaces.rs index 5444978..5444978 100644 --- a/examples/basic/interfaces/mod.rs +++ b/examples/basic/interfaces.rs diff --git a/examples/factory/interfaces/mod.rs b/examples/factory/interfaces.rs index 2342750..2342750 100644 --- a/examples/factory/interfaces/mod.rs +++ b/examples/factory/interfaces.rs diff --git a/examples/generics/interfaces/mod.rs b/examples/generics/interfaces.rs index 3f31bdf..3f31bdf 100644 --- a/examples/generics/interfaces/mod.rs +++ b/examples/generics/interfaces.rs diff --git a/examples/named/interfaces/mod.rs b/examples/named/interfaces.rs index 6a0108d..6a0108d 100644 --- a/examples/named/interfaces/mod.rs +++ b/examples/named/interfaces.rs diff --git a/examples/with-3rd-party/bootstrap.rs b/examples/with-3rd-party/bootstrap.rs index 26386f5..5d2f713 100644 --- a/examples/with-3rd-party/bootstrap.rs +++ b/examples/with-3rd-party/bootstrap.rs @@ -15,7 +15,7 @@ pub fn bootstrap() -> Result<DIContainer, Box<dyn Error>>      di_container          .bind::<Shuriken>() -        .to_default_factory(&|_| Box::new(|| TransientPtr::new(Shuriken::new())))?; +        .to_dynamic_value(&|_| Box::new(|| TransientPtr::new(Shuriken::new())))?;      Ok(di_container)  } diff --git a/examples/with-3rd-party/interfaces/mod.rs b/examples/with-3rd-party/interfaces.rs index c060c34..c060c34 100644 --- a/examples/with-3rd-party/interfaces/mod.rs +++ b/examples/with-3rd-party/interfaces.rs diff --git a/macros/Cargo.toml b/macros/Cargo.toml index 890c9f3..adf4eda 100644 --- a/macros/Cargo.toml +++ b/macros/Cargo.toml @@ -41,3 +41,7 @@ pretty_assertions = "1.3.0"  syn = { version = "1.0.96", features = ["full", "extra-traits"] }  utility-macros = { git = "https://git.hampusmat.com/utility-macros" } +[lints.rust.unexpected_cfgs] +level = "warn" +check-cfg = ["cfg(doc_cfg)", "cfg(tarpaulin_include)", "cfg(syrette_macros_logging)"] + diff --git a/macros/src/injectable/mod.rs b/macros/src/injectable.rs index 0e6ddfd..0e6ddfd 100644 --- a/macros/src/injectable/mod.rs +++ b/macros/src/injectable.rs diff --git a/macros/src/util/mod.rs b/macros/src/util.rs index 3557896..3557896 100644 --- a/macros/src/util/mod.rs +++ b/macros/src/util.rs diff --git a/src/castable_function/mod.rs b/src/castable_function.rs index 4c2f0db..4c2f0db 100644 --- a/src/castable_function/mod.rs +++ b/src/castable_function.rs diff --git a/src/di_container/mod.rs b/src/di_container.rs index 4e60505..4e60505 100644 --- a/src/di_container/mod.rs +++ b/src/di_container.rs diff --git a/src/di_container/asynchronous/mod.rs b/src/di_container/asynchronous.rs index c993b8b..6cb54f3 100644 --- a/src/di_container/asynchronous/mod.rs +++ b/src/di_container/asynchronous.rs @@ -51,15 +51,17 @@  //! ```  use std::any::type_name; +use crate::castable_function::threadsafe::ThreadsafeCastableFunction;  use crate::di_container::asynchronous::binding::builder::AsyncBindingBuilder;  use crate::di_container::binding_storage::DIContainerBindingStorage;  use crate::di_container::BindingOptions;  use crate::errors::async_di_container::AsyncDIContainerError; +use crate::future::BoxFuture;  use crate::private::cast::arc::CastArc;  use crate::private::cast::boxed::CastBox;  use crate::private::cast::error::CastError; -use crate::provider::r#async::{AsyncProvidable, IAsyncProvider}; -use crate::ptr::SomePtr; +use crate::provider::r#async::{AsyncProvidable, IAsyncProvider, ProvidableFunctionKind}; +use crate::ptr::{SomePtr, TransientPtr};  use crate::util::use_double;  use_double!(crate::dependency_history::DependencyHistory); @@ -347,10 +349,8 @@ impl AsyncDIContainer                  ))              }              #[cfg(feature = "factory")] -            AsyncProvidable::Factory(factory_binding) => { -                use crate::castable_function::threadsafe::ThreadsafeCastableFunction; - -                let factory = factory_binding +            AsyncProvidable::Function(func_bound, ProvidableFunctionKind::UserCalled) => { +                let factory = func_bound                      .as_any()                      .downcast_ref::<ThreadsafeCastableFunction<Interface, Self>>()                      .ok_or_else(|| AsyncDIContainerError::CastFailed { @@ -360,48 +360,42 @@ impl AsyncDIContainer                  Ok(SomePtr::ThreadsafeFactory(factory.call(self).into()))              } -            #[cfg(feature = "factory")] -            AsyncProvidable::DefaultFactory(binding) => { -                use crate::castable_function::threadsafe::ThreadsafeCastableFunction; -                use crate::ptr::TransientPtr; - -                type DefaultFactoryFn<Interface> = ThreadsafeCastableFunction< +            AsyncProvidable::Function(func_bound, ProvidableFunctionKind::Instant) => { +                type Func<Interface> = ThreadsafeCastableFunction<                      dyn Fn() -> TransientPtr<Interface> + Send + Sync,                      AsyncDIContainer,                  >; -                let default_factory = binding +                let dynamic_val_func = func_bound                      .as_any() -                    .downcast_ref::<DefaultFactoryFn<Interface>>() +                    .downcast_ref::<Func<Interface>>()                      .ok_or_else(|| AsyncDIContainerError::CastFailed { -                        interface: type_name::<DefaultFactoryFn<Interface>>(), -                        binding_kind: "default factory", +                        interface: type_name::<Func<Interface>>(), +                        binding_kind: "dynamic value func",                      })?; -                Ok(SomePtr::Transient(default_factory.call(self)())) +                Ok(SomePtr::Transient(dynamic_val_func.call(self)()))              } -            #[cfg(feature = "factory")] -            AsyncProvidable::AsyncDefaultFactory(binding) => { -                use crate::castable_function::threadsafe::ThreadsafeCastableFunction; -                use crate::future::BoxFuture; -                use crate::ptr::TransientPtr; - -                type AsyncDefaultFactoryFn<Interface> = ThreadsafeCastableFunction< -                    dyn Fn<(), Output = BoxFuture<'static, TransientPtr<Interface>>> -                        + Send -                        + Sync, +            AsyncProvidable::Function( +                func_bound, +                ProvidableFunctionKind::AsyncInstant, +            ) => { +                type Func<Interface> = ThreadsafeCastableFunction< +                    dyn Fn() -> BoxFuture<'static, TransientPtr<Interface>> + Send + Sync,                      AsyncDIContainer,                  >; -                let async_default_factory = binding +                let async_dynamic_value_func = func_bound                      .as_any() -                    .downcast_ref::<AsyncDefaultFactoryFn<Interface>>() +                    .downcast_ref::<Func<Interface>>()                      .ok_or_else(|| AsyncDIContainerError::CastFailed { -                        interface: type_name::<AsyncDefaultFactoryFn<Interface>>(), -                        binding_kind: "async default factory", +                        interface: type_name::<Func<Interface>>(), +                        binding_kind: "async dynamic value function",                      })?; -                Ok(SomePtr::Transient(async_default_factory.call(self)().await)) +                Ok(SomePtr::Transient( +                    async_dynamic_value_func.call(self)().await, +                ))              }          }      } @@ -652,7 +646,10 @@ mod tests              }          } +        use std::sync::Arc; +          use crate::castable_function::threadsafe::ThreadsafeCastableFunction; +        use crate::provider::r#async::ProvidableFunctionKind;          type IUserManagerFactory =              dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager> + Send + Sync; @@ -672,10 +669,9 @@ mod tests              };              inner_mock_provider.expect_provide().returning(|_, _| { -                Ok(AsyncProvidable::Factory( -                    crate::ptr::ThreadsafeFactoryPtr::new( -                        ThreadsafeCastableFunction::new(factory_func), -                    ), +                Ok(AsyncProvidable::Function( +                    Arc::new(ThreadsafeCastableFunction::new(factory_func)), +                    ProvidableFunctionKind::UserCalled,                  ))              }); @@ -734,7 +730,10 @@ mod tests              }          } +        use std::sync::Arc; +          use crate::castable_function::threadsafe::ThreadsafeCastableFunction; +        use crate::provider::r#async::ProvidableFunctionKind;          type IUserManagerFactory =              dyn Fn(Vec<i128>) -> TransientPtr<dyn IUserManager> + Send + Sync; @@ -754,10 +753,9 @@ mod tests              };              inner_mock_provider.expect_provide().returning(|_, _| { -                Ok(AsyncProvidable::Factory( -                    crate::ptr::ThreadsafeFactoryPtr::new( -                        ThreadsafeCastableFunction::new(factory_func), -                    ), +                Ok(AsyncProvidable::Function( +                    Arc::new(ThreadsafeCastableFunction::new(factory_func)), +                    ProvidableFunctionKind::UserCalled,                  ))              }); diff --git a/src/di_container/asynchronous/binding/mod.rs b/src/di_container/asynchronous/binding.rs index 6a09bff..6a09bff 100644 --- a/src/di_container/asynchronous/binding/mod.rs +++ b/src/di_container/asynchronous/binding.rs diff --git a/src/di_container/asynchronous/binding/builder.rs b/src/di_container/asynchronous/binding/builder.rs index 8465c9a..db1b576 100644 --- a/src/di_container/asynchronous/binding/builder.rs +++ b/src/di_container/asynchronous/binding/builder.rs @@ -1,13 +1,17 @@  //! Binding builder for types inside of a [`AsyncDIContainer`].  use std::any::type_name;  use std::marker::PhantomData; +use std::sync::Arc; +use crate::castable_function::threadsafe::ThreadsafeCastableFunction;  use crate::di_container::asynchronous::binding::scope_configurator::AsyncBindingScopeConfigurator; -#[cfg(feature = "factory")]  use crate::di_container::asynchronous::binding::when_configurator::AsyncBindingWhenConfigurator;  use crate::di_container::BindingOptions;  use crate::errors::async_di_container::AsyncBindingBuilderError; +use crate::future::BoxFuture;  use crate::interfaces::async_injectable::AsyncInjectable; +use crate::provider::r#async::{AsyncFunctionProvider, ProvidableFunctionKind}; +use crate::ptr::TransientPtr;  use crate::util::use_double;  use_double!(crate::dependency_history::DependencyHistory); @@ -173,8 +177,10 @@ where          Interface: Fn<Args, Output = Return> + Send + Sync,          FactoryFunc: Fn(&AsyncDIContainer) -> BoxFn<Args, Return> + Send + Sync,      { +        use std::sync::Arc; +          use crate::castable_function::threadsafe::ThreadsafeCastableFunction; -        use crate::provider::r#async::AsyncFactoryVariant; +        use crate::provider::r#async::ProvidableFunctionKind;          if self              .di_container @@ -190,9 +196,9 @@ where          self.di_container.set_binding::<Interface>(              BindingOptions::new(), -            Box::new(crate::provider::r#async::AsyncFactoryProvider::new( -                crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), -                AsyncFactoryVariant::Normal, +            Box::new(crate::provider::r#async::AsyncFunctionProvider::new( +                Arc::new(factory_impl), +                ProvidableFunctionKind::UserCalled,              )),          ); @@ -270,9 +276,6 @@ where              + Send              + Sync,      { -        use crate::castable_function::threadsafe::ThreadsafeCastableFunction; -        use crate::provider::r#async::AsyncFactoryVariant; -          if self              .di_container              .has_binding::<Interface>(BindingOptions::new()) @@ -287,17 +290,17 @@ where          self.di_container.set_binding::<Interface>(              BindingOptions::new(), -            Box::new(crate::provider::r#async::AsyncFactoryProvider::new( -                crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), -                AsyncFactoryVariant::Normal, +            Box::new(AsyncFunctionProvider::new( +                Arc::new(factory_impl), +                ProvidableFunctionKind::UserCalled,              )),          );          Ok(AsyncBindingWhenConfigurator::new(self.di_container))      } -    /// Creates a binding of type `Interface` to a factory that takes no arguments -    /// inside of the associated [`AsyncDIContainer`]. +    /// Creates a binding of type `Interface` to a value resolved using the given +    /// function.      ///      /// # Errors      /// Will return Err if the associated [`AsyncDIContainer`] already have a binding @@ -325,7 +328,7 @@ where      /// # {      /// # let mut di_container = AsyncDIContainer::new();      /// # -    /// di_container.bind::<dyn Foo>().to_default_factory(&|_| { +    /// di_container.bind::<dyn Foo>().to_dynamic_value(&|_| {      ///     Box::new(|| {      ///         let bar = TransientPtr::new(Bar {      ///             num: 42, @@ -339,24 +342,20 @@ where      /// # Ok(())      /// # }      /// ``` -    #[cfg(feature = "factory")] -    #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] -    pub fn to_default_factory<Return, FactoryFunc>( +    pub fn to_dynamic_value<Func>(          self, -        factory_func: &'static FactoryFunc, +        func: &'static Func,      ) -> Result<          AsyncBindingWhenConfigurator<'di_container, Interface>,          AsyncBindingBuilderError,      >      where -        Return: 'static + ?Sized, -        FactoryFunc: Fn(&AsyncDIContainer) -> BoxFn<(), crate::ptr::TransientPtr<Return>> +        Func: Fn( +                &AsyncDIContainer, +            ) -> Box<dyn Fn() -> TransientPtr<Interface> + Send + Sync>              + Send              + Sync,      { -        use crate::castable_function::threadsafe::ThreadsafeCastableFunction; -        use crate::provider::r#async::AsyncFactoryVariant; -          if self              .di_container              .has_binding::<Interface>(BindingOptions::new()) @@ -367,21 +366,21 @@ where              )));          } -        let factory_impl = ThreadsafeCastableFunction::new(factory_func); +        let castable_func = ThreadsafeCastableFunction::new(func);          self.di_container.set_binding::<Interface>(              BindingOptions::new(), -            Box::new(crate::provider::r#async::AsyncFactoryProvider::new( -                crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), -                AsyncFactoryVariant::Default, +            Box::new(AsyncFunctionProvider::new( +                Arc::new(castable_func), +                ProvidableFunctionKind::Instant,              )),          );          Ok(AsyncBindingWhenConfigurator::new(self.di_container))      } -    /// Creates a binding of factory type `Interface` to a async factory inside of the -    /// associated [`AsyncDIContainer`]. +    /// Creates a binding of type `Interface` to a value resolved using the given +    /// async function.      ///      /// # Errors      /// Will return Err if the associated [`AsyncDIContainer`] already have a binding @@ -412,7 +411,7 @@ where      /// #      /// di_container      ///     .bind::<dyn Foo>() -    ///     .to_async_default_factory(&|_| { +    ///     .to_async_dynamic_value(&|_| {      ///         Box::new(|| {      ///             Box::pin(async {      ///                 let bar = TransientPtr::new(Bar { @@ -430,24 +429,21 @@ where      /// # Ok(())      /// # }      /// ``` -    #[cfg(feature = "factory")] -    #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] -    pub fn to_async_default_factory<Return, FactoryFunc>( +    pub fn to_async_dynamic_value<Func>(          self, -        factory_func: &'static FactoryFunc, +        func: &'static Func,      ) -> Result<          AsyncBindingWhenConfigurator<'di_container, Interface>,          AsyncBindingBuilderError,      >      where -        Return: 'static + ?Sized, -        FactoryFunc: Fn(&AsyncDIContainer) -> BoxFn<(), crate::future::BoxFuture<'static, Return>> -            + Send +        Func: Fn( +                &AsyncDIContainer, +            ) -> Box< +                dyn Fn() -> BoxFuture<'static, TransientPtr<Interface>> + Send + Sync, +            > + Send              + Sync,      { -        use crate::castable_function::threadsafe::ThreadsafeCastableFunction; -        use crate::provider::r#async::AsyncFactoryVariant; -          if self              .di_container              .has_binding::<Interface>(BindingOptions::new()) @@ -458,13 +454,13 @@ where              )));          } -        let factory_impl = ThreadsafeCastableFunction::new(factory_func); +        let castable_func = ThreadsafeCastableFunction::new(func);          self.di_container.set_binding::<Interface>(              BindingOptions::new(), -            Box::new(crate::provider::r#async::AsyncFactoryProvider::new( -                crate::ptr::ThreadsafeFactoryPtr::new(factory_impl), -                AsyncFactoryVariant::AsyncDefault, +            Box::new(AsyncFunctionProvider::new( +                Arc::new(castable_func), +                ProvidableFunctionKind::AsyncInstant,              )),          ); @@ -599,8 +595,7 @@ mod tests      }      #[tokio::test] -    #[cfg(feature = "factory")] -    async fn can_bind_to_default_factory() +    async fn can_bind_to_dynamic_value()      {          use crate::ptr::TransientPtr; @@ -625,7 +620,7 @@ mod tests              );          binding_builder -            .to_default_factory(&|_| { +            .to_dynamic_value(&|_| {                  Box::new(|| {                      let user_manager: TransientPtr<dyn subjects_async::IUserManager> =                          TransientPtr::new(subjects_async::UserManager::new()); @@ -637,8 +632,7 @@ mod tests      }      #[tokio::test] -    #[cfg(feature = "factory")] -    async fn can_bind_to_async_default_factory() +    async fn can_bind_to_async_dynamic_value()      {          use crate::ptr::TransientPtr;          use crate::test_utils::async_closure; @@ -664,7 +658,7 @@ mod tests              );          binding_builder -            .to_async_default_factory(&|_| { +            .to_async_dynamic_value(&|_| {                  async_closure!(|| {                      let user_manager: TransientPtr<dyn subjects_async::IUserManager> =                          TransientPtr::new(subjects_async::UserManager::new()); diff --git a/src/di_container/blocking/mod.rs b/src/di_container/blocking.rs index d8b0d59..0c464df 100644 --- a/src/di_container/blocking/mod.rs +++ b/src/di_container/blocking.rs @@ -51,14 +51,15 @@  //! ```  use std::any::type_name; +use crate::castable_function::CastableFunction;  use crate::di_container::binding_storage::DIContainerBindingStorage;  use crate::di_container::blocking::binding::builder::BindingBuilder;  use crate::di_container::BindingOptions;  use crate::errors::di_container::DIContainerError;  use crate::private::cast::boxed::CastBox;  use crate::private::cast::rc::CastRc; -use crate::provider::blocking::{IProvider, Providable}; -use crate::ptr::SomePtr; +use crate::provider::blocking::{IProvider, Providable, ProvidableFunctionKind}; +use crate::ptr::{SomePtr, TransientPtr};  use crate::util::use_double;  use_double!(crate::dependency_history::DependencyHistory); @@ -284,10 +285,8 @@ impl DIContainer                  })?,              )),              #[cfg(feature = "factory")] -            Providable::Factory(factory_binding) => { -                use crate::castable_function::CastableFunction; - -                let factory = factory_binding +            Providable::Function(func_bound, ProvidableFunctionKind::UserCalled) => { +                let factory = func_bound                      .as_any()                      .downcast_ref::<CastableFunction<Interface, Self>>()                      .ok_or_else(|| DIContainerError::CastFailed { @@ -297,23 +296,19 @@ impl DIContainer                  Ok(SomePtr::Factory(factory.call(self).into()))              } -            #[cfg(feature = "factory")] -            Providable::DefaultFactory(factory_binding) => { -                use crate::castable_function::CastableFunction; -                use crate::ptr::TransientPtr; - -                type DefaultFactoryFn<Interface> = +            Providable::Function(func_bound, ProvidableFunctionKind::Instant) => { +                type Func<Interface> =                      CastableFunction<dyn Fn() -> TransientPtr<Interface>, DIContainer>; -                let default_factory = factory_binding +                let dynamic_val_func = func_bound                      .as_any() -                    .downcast_ref::<DefaultFactoryFn<Interface>>() +                    .downcast_ref::<Func<Interface>>()                      .ok_or_else(|| DIContainerError::CastFailed {                          interface: type_name::<Interface>(), -                        binding_kind: "default factory", +                        binding_kind: "dynamic value function",                      })?; -                Ok(SomePtr::Transient(default_factory.call(self)())) +                Ok(SomePtr::Transient(dynamic_val_func.call(self)()))              }          }      } @@ -517,7 +512,10 @@ mod tests      #[cfg(feature = "factory")]      fn can_get_factory()      { +        use std::rc::Rc; +          use crate::castable_function::CastableFunction; +        use crate::provider::blocking::ProvidableFunctionKind;          use crate::ptr::FactoryPtr;          trait IUserManager @@ -572,9 +570,10 @@ mod tests          let mut mock_provider = MockIProvider::new();          mock_provider.expect_provide().returning_st(|_, _| { -            Ok(Providable::Factory(FactoryPtr::new(CastableFunction::new( -                factory_func, -            )))) +            Ok(Providable::Function( +                Rc::new(CastableFunction::new(factory_func)), +                ProvidableFunctionKind::UserCalled, +            ))          });          di_container @@ -592,8 +591,10 @@ mod tests      #[cfg(feature = "factory")]      fn can_get_factory_named()      { +        use std::rc::Rc; +          use crate::castable_function::CastableFunction; -        use crate::ptr::FactoryPtr; +        use crate::provider::blocking::ProvidableFunctionKind;          trait IUserManager          { @@ -647,9 +648,10 @@ mod tests          let mut mock_provider = MockIProvider::new();          mock_provider.expect_provide().returning_st(|_, _| { -            Ok(Providable::Factory(FactoryPtr::new(CastableFunction::new( -                factory_func, -            )))) +            Ok(Providable::Function( +                Rc::new(CastableFunction::new(factory_func)), +                ProvidableFunctionKind::UserCalled, +            ))          });          di_container.binding_storage.set::<IUserManagerFactory>( diff --git a/src/di_container/blocking/binding/mod.rs b/src/di_container/blocking/binding.rs index 6a09bff..6a09bff 100644 --- a/src/di_container/blocking/binding/mod.rs +++ b/src/di_container/blocking/binding.rs diff --git a/src/di_container/blocking/binding/builder.rs b/src/di_container/blocking/binding/builder.rs index ead1a54..596a2aa 100644 --- a/src/di_container/blocking/binding/builder.rs +++ b/src/di_container/blocking/binding/builder.rs @@ -1,13 +1,16 @@  //! Binding builder for types inside of a [`DIContainer`].  use std::any::type_name;  use std::marker::PhantomData; +use std::rc::Rc; +use crate::castable_function::CastableFunction;  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::BindingOptions;  use crate::errors::di_container::BindingBuilderError;  use crate::interfaces::injectable::Injectable; +use crate::provider::blocking::{FunctionProvider, ProvidableFunctionKind}; +use crate::ptr::TransientPtr;  use crate::util::use_double;  use_double!(crate::dependency_history::DependencyHistory); @@ -181,8 +184,6 @@ where          Interface: Fn<Args, Output = crate::ptr::TransientPtr<Return>>,          Func: Fn(&DIContainer) -> Box<Interface>,      { -        use crate::castable_function::CastableFunction; -          if self              .di_container              .has_binding::<Interface>(BindingOptions::new()) @@ -196,17 +197,17 @@ where          self.di_container.set_binding::<Interface>(              BindingOptions::new(), -            Box::new(crate::provider::blocking::FactoryProvider::new( -                crate::ptr::FactoryPtr::new(factory_impl), -                false, +            Box::new(FunctionProvider::new( +                Rc::new(factory_impl), +                ProvidableFunctionKind::UserCalled,              )),          );          Ok(BindingWhenConfigurator::new(self.di_container))      } -    /// Creates a binding of type `Interface` to a factory that takes no arguments -    /// inside of the associated [`DIContainer`]. +    /// Creates a binding of type `Interface` to a value resolved using the given +    /// function.      ///      /// # Errors      /// Will return Err if the associated [`DIContainer`] already have a binding for @@ -244,33 +245,20 @@ where      /// # {      /// # let mut di_container = DIContainer::new();      /// # -    /// di_container.bind::<dyn IBuffer>().to_default_factory(&|_| { -    ///     Box::new(|| { -    ///         let buffer = TransientPtr::new(Buffer::<BUFFER_SIZE>::new()); -    /// -    ///         buffer as TransientPtr<dyn IBuffer> -    ///     }) +    /// di_container.bind::<dyn IBuffer>().to_dynamic_value(&|_| { +    ///     Box::new(|| TransientPtr::new(Buffer::<BUFFER_SIZE>::new()))      /// });      /// #      /// # Ok(())      /// # }      /// ``` -    #[cfg(feature = "factory")] -    #[cfg_attr(doc_cfg, doc(cfg(feature = "factory")))] -    pub fn to_default_factory<Return, FactoryFunc>( +    pub fn to_dynamic_value<Func>(          self, -        factory_func: &'static FactoryFunc, +        func: &'static Func,      ) -> Result<BindingWhenConfigurator<'di_container, Interface>, BindingBuilderError>      where -        Return: 'static + ?Sized, -        FactoryFunc: Fn( -            &DIContainer, -        ) -> crate::ptr::TransientPtr< -            dyn Fn<(), Output = crate::ptr::TransientPtr<Return>>, -        >, +        Func: Fn(&DIContainer) -> TransientPtr<dyn Fn() -> TransientPtr<Interface>>,      { -        use crate::castable_function::CastableFunction; -          if self              .di_container              .has_binding::<Interface>(BindingOptions::new()) @@ -280,13 +268,13 @@ where              >()));          } -        let factory_impl = CastableFunction::new(factory_func); +        let castable_func = CastableFunction::new(func);          self.di_container.set_binding::<Interface>(              BindingOptions::new(), -            Box::new(crate::provider::blocking::FactoryProvider::new( -                crate::ptr::FactoryPtr::new(factory_impl), -                true, +            Box::new(FunctionProvider::new( +                Rc::new(castable_func), +                ProvidableFunctionKind::Instant,              )),          ); @@ -370,8 +358,7 @@ mod tests      }      #[test] -    #[cfg(feature = "factory")] -    fn can_bind_to_default_factory() +    fn can_bind_to_dynamic_value()      {          use crate::ptr::TransientPtr; @@ -395,7 +382,7 @@ mod tests          );          binding_builder -            .to_default_factory(&|_| { +            .to_dynamic_value(&|_| {                  Box::new(move || {                      let user_manager: TransientPtr<dyn subjects::IUserManager> =                          TransientPtr::new(subjects::UserManager::new()); diff --git a/src/errors/mod.rs b/src/errors.rs index 7eb10bd..7eb10bd 100644 --- a/src/errors/mod.rs +++ b/src/errors.rs diff --git a/src/interfaces/mod.rs b/src/interfaces.rs index e7068ad..e7068ad 100644 --- a/src/interfaces/mod.rs +++ b/src/interfaces.rs @@ -110,7 +110,6 @@ pub mod private;  mod provider;  mod util; -#[cfg(feature = "factory")]  mod castable_function;  #[cfg(test)] diff --git a/src/private/mod.rs b/src/private.rs index 9b03ce8..9b03ce8 100644 --- a/src/private/mod.rs +++ b/src/private.rs diff --git a/src/private/cast/mod.rs b/src/private/cast.rs index ddff2a4..ddff2a4 100644 --- a/src/private/cast/mod.rs +++ b/src/private/cast.rs diff --git a/src/provider/mod.rs b/src/provider.rs index 7fb96bb..7fb96bb 100644 --- a/src/provider/mod.rs +++ b/src/provider.rs diff --git a/src/provider/async.rs b/src/provider/async.rs index 68eed87..787ef06 100644 --- a/src/provider/async.rs +++ b/src/provider/async.rs @@ -1,7 +1,9 @@  use std::marker::PhantomData; +use std::sync::Arc;  use async_trait::async_trait; +use crate::castable_function::threadsafe::AnyThreadsafeCastableFunction;  use crate::errors::injectable::InjectableError;  use crate::interfaces::async_injectable::AsyncInjectable;  use crate::ptr::{ThreadsafeSingletonPtr, TransientPtr}; @@ -14,24 +16,19 @@ pub enum AsyncProvidable<DIContainerT>  {      Transient(TransientPtr<dyn AsyncInjectable<DIContainerT>>),      Singleton(ThreadsafeSingletonPtr<dyn AsyncInjectable<DIContainerT>>), -    #[cfg(feature = "factory")] -    Factory( -        crate::ptr::ThreadsafeFactoryPtr< -            dyn crate::castable_function::threadsafe::AnyThreadsafeCastableFunction, -        >, -    ), -    #[cfg(feature = "factory")] -    DefaultFactory( -        crate::ptr::ThreadsafeFactoryPtr< -            dyn crate::castable_function::threadsafe::AnyThreadsafeCastableFunction, -        >, +    Function( +        Arc<dyn crate::castable_function::threadsafe::AnyThreadsafeCastableFunction>, +        ProvidableFunctionKind,      ), +} + +#[derive(Debug, Clone, Copy)] +pub enum ProvidableFunctionKind +{      #[cfg(feature = "factory")] -    AsyncDefaultFactory( -        crate::ptr::ThreadsafeFactoryPtr< -            dyn crate::castable_function::threadsafe::AnyThreadsafeCastableFunction, -        >, -    ), +    UserCalled, +    Instant, +    AsyncInstant,  }  #[async_trait] @@ -176,41 +173,28 @@ where      }  } -#[cfg(feature = "factory")] -#[derive(Clone, Copy)] -pub enum AsyncFactoryVariant -{ -    Normal, -    Default, -    AsyncDefault, -} - -#[cfg(feature = "factory")] -pub struct AsyncFactoryProvider +pub struct AsyncFunctionProvider  { -    factory: crate::ptr::ThreadsafeFactoryPtr< -        dyn crate::castable_function::threadsafe::AnyThreadsafeCastableFunction, -    >, -    variant: AsyncFactoryVariant, +    function: Arc<dyn AnyThreadsafeCastableFunction>, +    providable_func_kind: ProvidableFunctionKind,  } -#[cfg(feature = "factory")] -impl AsyncFactoryProvider +impl AsyncFunctionProvider  {      pub fn new( -        factory: crate::ptr::ThreadsafeFactoryPtr< -            dyn crate::castable_function::threadsafe::AnyThreadsafeCastableFunction, -        >, -        variant: AsyncFactoryVariant, +        function: Arc<dyn AnyThreadsafeCastableFunction>, +        providable_func_kind: ProvidableFunctionKind,      ) -> Self      { -        Self { factory, variant } +        Self { +            function, +            providable_func_kind, +        }      }  } -#[cfg(feature = "factory")]  #[async_trait] -impl<DIContainerT> IAsyncProvider<DIContainerT> for AsyncFactoryProvider +impl<DIContainerT> IAsyncProvider<DIContainerT> for AsyncFunctionProvider  where      DIContainerT: Send + Sync,  { @@ -220,15 +204,10 @@ where          _dependency_history: DependencyHistory,      ) -> Result<AsyncProvidable<DIContainerT>, InjectableError>      { -        Ok(match self.variant { -            AsyncFactoryVariant::Normal => AsyncProvidable::Factory(self.factory.clone()), -            AsyncFactoryVariant::Default => { -                AsyncProvidable::DefaultFactory(self.factory.clone()) -            } -            AsyncFactoryVariant::AsyncDefault => { -                AsyncProvidable::AsyncDefaultFactory(self.factory.clone()) -            } -        }) +        Ok(AsyncProvidable::Function( +            self.function.clone(), +            self.providable_func_kind, +        ))      }      fn do_clone(&self) -> Box<dyn IAsyncProvider<DIContainerT>> @@ -237,14 +216,13 @@ where      }  } -#[cfg(feature = "factory")] -impl Clone for AsyncFactoryProvider +impl Clone for AsyncFunctionProvider  {      fn clone(&self) -> Self      {          Self { -            factory: self.factory.clone(), -            variant: self.variant, +            function: self.function.clone(), +            providable_func_kind: self.providable_func_kind,          }      }  } @@ -304,14 +282,13 @@ mod tests      }      #[tokio::test] -    #[cfg(feature = "factory")] -    async fn async_factory_provider_works() +    async fn function_provider_works()      {          use std::any::Any; +        use std::sync::Arc;          use crate::castable_function::threadsafe::AnyThreadsafeCastableFunction;          use crate::castable_function::AnyCastableFunction; -        use crate::ptr::ThreadsafeFactoryPtr;          #[derive(Debug)]          struct FooFactory; @@ -326,54 +303,25 @@ mod tests          impl AnyThreadsafeCastableFunction for FooFactory {} -        let factory_provider = AsyncFactoryProvider::new( -            ThreadsafeFactoryPtr::new(FooFactory), -            AsyncFactoryVariant::Normal, -        ); - -        let default_factory_provider = AsyncFactoryProvider::new( -            ThreadsafeFactoryPtr::new(FooFactory), -            AsyncFactoryVariant::Default, -        ); - -        let async_default_factory_provider = AsyncFactoryProvider::new( -            ThreadsafeFactoryPtr::new(FooFactory), -            AsyncFactoryVariant::AsyncDefault, +        let instant_func_provider = AsyncFunctionProvider::new( +            Arc::new(FooFactory), +            ProvidableFunctionKind::Instant,          );          let di_container = MockAsyncDIContainer::new();          assert!(              matches!( -                factory_provider -                    .provide(&di_container, MockDependencyHistory::new()) -                    .await -                    .unwrap(), -                AsyncProvidable::Factory(_) -            ), -            "The provided type is not a factory" -        ); - -        assert!( -            matches!( -                default_factory_provider -                    .provide(&di_container, MockDependencyHistory::new()) -                    .await -                    .unwrap(), -                AsyncProvidable::DefaultFactory(_) -            ), -            "The provided type is not a default factory" -        ); - -        assert!( -            matches!( -                async_default_factory_provider +                instant_func_provider                      .provide(&di_container, MockDependencyHistory::new())                      .await                      .unwrap(), -                AsyncProvidable::AsyncDefaultFactory(_) +                AsyncProvidable::Function(_, ProvidableFunctionKind::Instant)              ), -            "The provided type is not a async default factory" +            concat!( +                "The provided type is not a AsyncProvidable::Function of kind ", +                "ProvidableFunctionKind::Instant" +            )          );      }  } diff --git a/src/provider/blocking.rs b/src/provider/blocking.rs index 6475dc7..6b22ad0 100644 --- a/src/provider/blocking.rs +++ b/src/provider/blocking.rs @@ -1,5 +1,7 @@  use std::marker::PhantomData; +use std::rc::Rc; +use crate::castable_function::AnyCastableFunction;  use crate::errors::injectable::InjectableError;  use crate::interfaces::injectable::Injectable;  use crate::ptr::{SingletonPtr, TransientPtr}; @@ -12,12 +14,15 @@ pub enum Providable<DIContainerType>  {      Transient(TransientPtr<dyn Injectable<DIContainerType>>),      Singleton(SingletonPtr<dyn Injectable<DIContainerType>>), +    Function(Rc<dyn AnyCastableFunction>, ProvidableFunctionKind), +} + +#[derive(Debug, Clone, Copy)] +pub enum ProvidableFunctionKind +{      #[cfg(feature = "factory")] -    Factory(crate::ptr::FactoryPtr<dyn crate::castable_function::AnyCastableFunction>), -    #[cfg(feature = "factory")] -    DefaultFactory( -        crate::ptr::FactoryPtr<dyn crate::castable_function::AnyCastableFunction>, -    ), +    UserCalled, +    Instant,  }  #[cfg_attr(test, mockall::automock)] @@ -107,32 +112,27 @@ where      }  } -#[cfg(feature = "factory")] -pub struct FactoryProvider +pub struct FunctionProvider  { -    factory: crate::ptr::FactoryPtr<dyn crate::castable_function::AnyCastableFunction>, -    is_default_factory: bool, +    function: Rc<dyn AnyCastableFunction>, +    providable_func_kind: ProvidableFunctionKind,  } -#[cfg(feature = "factory")] -impl FactoryProvider +impl FunctionProvider  {      pub fn new( -        factory: crate::ptr::FactoryPtr< -            dyn crate::castable_function::AnyCastableFunction, -        >, -        is_default_factory: bool, +        function: Rc<dyn AnyCastableFunction>, +        providable_func_kind: ProvidableFunctionKind,      ) -> Self      {          Self { -            factory, -            is_default_factory, +            function, +            providable_func_kind,          }      }  } -#[cfg(feature = "factory")] -impl<DIContainerType> IProvider<DIContainerType> for FactoryProvider +impl<DIContainerType> IProvider<DIContainerType> for FunctionProvider  {      fn provide(          &self, @@ -140,11 +140,10 @@ impl<DIContainerType> IProvider<DIContainerType> for FactoryProvider          _dependency_history: DependencyHistory,      ) -> Result<Providable<DIContainerType>, InjectableError>      { -        Ok(if self.is_default_factory { -            Providable::DefaultFactory(self.factory.clone()) -        } else { -            Providable::Factory(self.factory.clone()) -        }) +        Ok(Providable::Function( +            self.function.clone(), +            self.providable_func_kind, +        ))      }  } @@ -197,13 +196,12 @@ mod tests      }      #[test] -    #[cfg(feature = "factory")] -    fn factory_provider_works() +    fn function_provider_works()      {          use std::any::Any; +        use std::rc::Rc;          use crate::castable_function::AnyCastableFunction; -        use crate::ptr::FactoryPtr;          #[derive(Debug)]          struct FooFactory; @@ -216,27 +214,21 @@ mod tests              }          } -        let factory_provider = FactoryProvider::new(FactoryPtr::new(FooFactory), false); -        let default_factory_provider = -            FactoryProvider::new(FactoryPtr::new(FooFactory), true); +        let instant_func_provider = +            FunctionProvider::new(Rc::new(FooFactory), ProvidableFunctionKind::Instant);          let di_container = MockDIContainer::new();          assert!(              matches!( -                factory_provider.provide(&di_container, MockDependencyHistory::new()), -                Ok(Providable::Factory(_)) -            ), -            "The provided type is not a factory" -        ); - -        assert!( -            matches!( -                default_factory_provider +                instant_func_provider                      .provide(&di_container, MockDependencyHistory::new()), -                Ok(Providable::DefaultFactory(_)) +                Ok(Providable::Function(_, ProvidableFunctionKind::Instant))              ), -            "The provided type is not a default factory" +            concat!( +                "The provided type is not a Providable::Function of kind ", +                "ProvidableFunctionKind::Instant" +            )          );      }  } diff --git a/src/test_utils.rs b/src/test_utils.rs index 491e9b4..176ffa9 100644 --- a/src/test_utils.rs +++ b/src/test_utils.rs @@ -301,7 +301,7 @@ pub mod mocks      }  } -#[cfg(all(feature = "async", feature = "factory"))] +#[cfg(all(feature = "async"))]  macro_rules! async_closure {      (|$($args: ident),*| { $($inner: stmt);* }) => {          Box::new(|$($args),*| { @@ -315,5 +315,5 @@ macro_rules! async_closure {      };  } -#[cfg(all(feature = "async", feature = "factory"))] +#[cfg(all(feature = "async"))]  pub(crate) use async_closure;  | 
