aboutsummaryrefslogtreecommitdiff
path: root/src/provider
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2022-08-29 20:52:56 +0200
committerHampusM <hampus@hampusmat.com>2022-08-29 21:01:32 +0200
commit080cc42bb1da09059dbc35049a7ded0649961e0c (patch)
tree307ee564124373616022c1ba2b4d5af80845cd92 /src/provider
parent6e31d8f9e46fece348f329763b39b9c6f2741c07 (diff)
feat: implement async functionality
Diffstat (limited to 'src/provider')
-rw-r--r--src/provider/async.rs135
-rw-r--r--src/provider/blocking.rs122
-rw-r--r--src/provider/mod.rs4
3 files changed, 261 insertions, 0 deletions
diff --git a/src/provider/async.rs b/src/provider/async.rs
new file mode 100644
index 0000000..93ae03a
--- /dev/null
+++ b/src/provider/async.rs
@@ -0,0 +1,135 @@
+#![allow(clippy::module_name_repetitions)]
+use std::marker::PhantomData;
+
+use async_trait::async_trait;
+
+use crate::async_di_container::AsyncDIContainer;
+use crate::errors::injectable::InjectableError;
+use crate::interfaces::async_injectable::AsyncInjectable;
+use crate::ptr::{ThreadsafeSingletonPtr, TransientPtr};
+
+#[derive(strum_macros::Display, Debug)]
+pub enum AsyncProvidable
+{
+ Transient(TransientPtr<dyn AsyncInjectable>),
+ Singleton(ThreadsafeSingletonPtr<dyn AsyncInjectable>),
+ #[cfg(feature = "factory")]
+ Factory(
+ crate::ptr::ThreadsafeFactoryPtr<
+ dyn crate::interfaces::any_factory::AnyThreadsafeFactory,
+ >,
+ ),
+}
+
+#[async_trait]
+pub trait IAsyncProvider: Send + Sync
+{
+ async fn provide(
+ &self,
+ di_container: &AsyncDIContainer,
+ dependency_history: Vec<&'static str>,
+ ) -> Result<AsyncProvidable, InjectableError>;
+}
+
+pub struct AsyncTransientTypeProvider<InjectableType>
+where
+ InjectableType: AsyncInjectable,
+{
+ injectable_phantom: PhantomData<InjectableType>,
+}
+
+impl<InjectableType> AsyncTransientTypeProvider<InjectableType>
+where
+ InjectableType: AsyncInjectable,
+{
+ pub fn new() -> Self
+ {
+ Self {
+ injectable_phantom: PhantomData,
+ }
+ }
+}
+
+#[async_trait]
+impl<InjectableType> IAsyncProvider for AsyncTransientTypeProvider<InjectableType>
+where
+ InjectableType: AsyncInjectable,
+{
+ async fn provide(
+ &self,
+ di_container: &AsyncDIContainer,
+ dependency_history: Vec<&'static str>,
+ ) -> Result<AsyncProvidable, InjectableError>
+ {
+ Ok(AsyncProvidable::Transient(
+ InjectableType::resolve(di_container, dependency_history).await?,
+ ))
+ }
+}
+
+pub struct AsyncSingletonProvider<InjectableType>
+where
+ InjectableType: AsyncInjectable,
+{
+ singleton: ThreadsafeSingletonPtr<InjectableType>,
+}
+
+impl<InjectableType> AsyncSingletonProvider<InjectableType>
+where
+ InjectableType: AsyncInjectable,
+{
+ pub fn new(singleton: ThreadsafeSingletonPtr<InjectableType>) -> Self
+ {
+ Self { singleton }
+ }
+}
+
+#[async_trait]
+impl<InjectableType> IAsyncProvider for AsyncSingletonProvider<InjectableType>
+where
+ InjectableType: AsyncInjectable,
+{
+ async fn provide(
+ &self,
+ _di_container: &AsyncDIContainer,
+ _dependency_history: Vec<&'static str>,
+ ) -> Result<AsyncProvidable, InjectableError>
+ {
+ Ok(AsyncProvidable::Singleton(self.singleton.clone()))
+ }
+}
+
+#[cfg(feature = "factory")]
+pub struct AsyncFactoryProvider
+{
+ factory: crate::ptr::ThreadsafeFactoryPtr<
+ dyn crate::interfaces::any_factory::AnyThreadsafeFactory,
+ >,
+}
+
+#[cfg(feature = "factory")]
+impl AsyncFactoryProvider
+{
+ pub fn new(
+ factory: crate::ptr::ThreadsafeFactoryPtr<
+ dyn crate::interfaces::any_factory::AnyThreadsafeFactory,
+ >,
+ ) -> Self
+ {
+ Self { factory }
+ }
+}
+
+#[cfg(feature = "factory")]
+#[async_trait]
+impl IAsyncProvider for AsyncFactoryProvider
+{
+ async fn provide(
+ &self,
+ _di_container: &AsyncDIContainer,
+ _dependency_history: Vec<&'static str>,
+ ) -> Result<AsyncProvidable, InjectableError>
+ {
+ Ok(AsyncProvidable::Factory(self.factory.clone()))
+ }
+}
diff --git a/src/provider/blocking.rs b/src/provider/blocking.rs
new file mode 100644
index 0000000..13674b9
--- /dev/null
+++ b/src/provider/blocking.rs
@@ -0,0 +1,122 @@
+#![allow(clippy::module_name_repetitions)]
+use std::marker::PhantomData;
+
+use crate::errors::injectable::InjectableError;
+use crate::interfaces::injectable::Injectable;
+use crate::ptr::{SingletonPtr, TransientPtr};
+use crate::DIContainer;
+
+#[derive(strum_macros::Display, Debug)]
+pub enum Providable
+{
+ Transient(TransientPtr<dyn Injectable>),
+ Singleton(SingletonPtr<dyn Injectable>),
+ #[cfg(feature = "factory")]
+ Factory(crate::ptr::FactoryPtr<dyn crate::interfaces::any_factory::AnyFactory>),
+}
+
+pub trait IProvider
+{
+ fn provide(
+ &self,
+ di_container: &DIContainer,
+ dependency_history: Vec<&'static str>,
+ ) -> Result<Providable, InjectableError>;
+}
+
+pub struct TransientTypeProvider<InjectableType>
+where
+ InjectableType: Injectable,
+{
+ injectable_phantom: PhantomData<InjectableType>,
+}
+
+impl<InjectableType> TransientTypeProvider<InjectableType>
+where
+ InjectableType: Injectable,
+{
+ pub fn new() -> Self
+ {
+ Self {
+ injectable_phantom: PhantomData,
+ }
+ }
+}
+
+impl<InjectableType> IProvider for TransientTypeProvider<InjectableType>
+where
+ InjectableType: Injectable,
+{
+ fn provide(
+ &self,
+ di_container: &DIContainer,
+ dependency_history: Vec<&'static str>,
+ ) -> Result<Providable, InjectableError>
+ {
+ Ok(Providable::Transient(InjectableType::resolve(
+ di_container,
+ dependency_history,
+ )?))
+ }
+}
+
+pub struct SingletonProvider<InjectableType>
+where
+ InjectableType: Injectable,
+{
+ singleton: SingletonPtr<InjectableType>,
+}
+
+impl<InjectableType> SingletonProvider<InjectableType>
+where
+ InjectableType: Injectable,
+{
+ pub fn new(singleton: SingletonPtr<InjectableType>) -> Self
+ {
+ Self { singleton }
+ }
+}
+
+impl<InjectableType> IProvider for SingletonProvider<InjectableType>
+where
+ InjectableType: Injectable,
+{
+ fn provide(
+ &self,
+ _di_container: &DIContainer,
+ _dependency_history: Vec<&'static str>,
+ ) -> Result<Providable, InjectableError>
+ {
+ Ok(Providable::Singleton(self.singleton.clone()))
+ }
+}
+
+#[cfg(feature = "factory")]
+pub struct FactoryProvider
+{
+ factory: crate::ptr::FactoryPtr<dyn crate::interfaces::any_factory::AnyFactory>,
+}
+
+#[cfg(feature = "factory")]
+impl FactoryProvider
+{
+ pub fn new(
+ factory: crate::ptr::FactoryPtr<dyn crate::interfaces::any_factory::AnyFactory>,
+ ) -> Self
+ {
+ Self { factory }
+ }
+}
+
+#[cfg(feature = "factory")]
+impl IProvider for FactoryProvider
+{
+ fn provide(
+ &self,
+ _di_container: &DIContainer,
+ _dependency_history: Vec<&'static str>,
+ ) -> Result<Providable, InjectableError>
+ {
+ Ok(Providable::Factory(self.factory.clone()))
+ }
+}
diff --git a/src/provider/mod.rs b/src/provider/mod.rs
new file mode 100644
index 0000000..7fb96bb
--- /dev/null
+++ b/src/provider/mod.rs
@@ -0,0 +1,4 @@
+pub mod blocking;
+
+#[cfg(feature = "async")]
+pub mod r#async;