From 080cc42bb1da09059dbc35049a7ded0649961e0c Mon Sep 17 00:00:00 2001 From: HampusM Date: Mon, 29 Aug 2022 20:52:56 +0200 Subject: feat: implement async functionality --- src/provider/async.rs | 135 +++++++++++++++++++++++++++++++++++++++++++++++ src/provider/blocking.rs | 122 ++++++++++++++++++++++++++++++++++++++++++ src/provider/mod.rs | 4 ++ 3 files changed, 261 insertions(+) create mode 100644 src/provider/async.rs create mode 100644 src/provider/blocking.rs create mode 100644 src/provider/mod.rs (limited to 'src/provider') 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), + Singleton(ThreadsafeSingletonPtr), + #[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; +} + +pub struct AsyncTransientTypeProvider +where + InjectableType: AsyncInjectable, +{ + injectable_phantom: PhantomData, +} + +impl AsyncTransientTypeProvider +where + InjectableType: AsyncInjectable, +{ + pub fn new() -> Self + { + Self { + injectable_phantom: PhantomData, + } + } +} + +#[async_trait] +impl IAsyncProvider for AsyncTransientTypeProvider +where + InjectableType: AsyncInjectable, +{ + async fn provide( + &self, + di_container: &AsyncDIContainer, + dependency_history: Vec<&'static str>, + ) -> Result + { + Ok(AsyncProvidable::Transient( + InjectableType::resolve(di_container, dependency_history).await?, + )) + } +} + +pub struct AsyncSingletonProvider +where + InjectableType: AsyncInjectable, +{ + singleton: ThreadsafeSingletonPtr, +} + +impl AsyncSingletonProvider +where + InjectableType: AsyncInjectable, +{ + pub fn new(singleton: ThreadsafeSingletonPtr) -> Self + { + Self { singleton } + } +} + +#[async_trait] +impl IAsyncProvider for AsyncSingletonProvider +where + InjectableType: AsyncInjectable, +{ + async fn provide( + &self, + _di_container: &AsyncDIContainer, + _dependency_history: Vec<&'static str>, + ) -> Result + { + 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 + { + 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), + Singleton(SingletonPtr), + #[cfg(feature = "factory")] + Factory(crate::ptr::FactoryPtr), +} + +pub trait IProvider +{ + fn provide( + &self, + di_container: &DIContainer, + dependency_history: Vec<&'static str>, + ) -> Result; +} + +pub struct TransientTypeProvider +where + InjectableType: Injectable, +{ + injectable_phantom: PhantomData, +} + +impl TransientTypeProvider +where + InjectableType: Injectable, +{ + pub fn new() -> Self + { + Self { + injectable_phantom: PhantomData, + } + } +} + +impl IProvider for TransientTypeProvider +where + InjectableType: Injectable, +{ + fn provide( + &self, + di_container: &DIContainer, + dependency_history: Vec<&'static str>, + ) -> Result + { + Ok(Providable::Transient(InjectableType::resolve( + di_container, + dependency_history, + )?)) + } +} + +pub struct SingletonProvider +where + InjectableType: Injectable, +{ + singleton: SingletonPtr, +} + +impl SingletonProvider +where + InjectableType: Injectable, +{ + pub fn new(singleton: SingletonPtr) -> Self + { + Self { singleton } + } +} + +impl IProvider for SingletonProvider +where + InjectableType: Injectable, +{ + fn provide( + &self, + _di_container: &DIContainer, + _dependency_history: Vec<&'static str>, + ) -> Result + { + Ok(Providable::Singleton(self.singleton.clone())) + } +} + +#[cfg(feature = "factory")] +pub struct FactoryProvider +{ + factory: crate::ptr::FactoryPtr, +} + +#[cfg(feature = "factory")] +impl FactoryProvider +{ + pub fn new( + factory: crate::ptr::FactoryPtr, + ) -> Self + { + Self { factory } + } +} + +#[cfg(feature = "factory")] +impl IProvider for FactoryProvider +{ + fn provide( + &self, + _di_container: &DIContainer, + _dependency_history: Vec<&'static str>, + ) -> Result + { + 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; -- cgit v1.2.3-18-g5258