diff options
author | HampusM <hampus@hampusmat.com> | 2023-10-04 12:51:06 +0200 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2023-10-04 12:52:22 +0200 |
commit | 0f2756536e8fc311119da2af5b4dcc33f41bec6e (patch) | |
tree | 0964efe0eaf855017c67fae52da8672a47becc65 /src/castable_factory | |
parent | c936439bfac9e35958f685a52abb51d781e70a7c (diff) |
refactor!: remove factory & declare_default_factory macros
BREAKING CHANGE: The factory and the declare_default_factory macros have been removed. They are no longer needed to use factories
Diffstat (limited to 'src/castable_factory')
-rw-r--r-- | src/castable_factory/mod.rs | 88 | ||||
-rw-r--r-- | src/castable_factory/threadsafe.rs | 99 |
2 files changed, 187 insertions, 0 deletions
diff --git a/src/castable_factory/mod.rs b/src/castable_factory/mod.rs new file mode 100644 index 0000000..196dc14 --- /dev/null +++ b/src/castable_factory/mod.rs @@ -0,0 +1,88 @@ +use std::any::{type_name, Any}; +use std::fmt::Debug; + +use crate::any_factory::AnyFactory; +use crate::ptr::TransientPtr; + +#[cfg(feature = "async")] +pub mod threadsafe; + +pub struct CastableFactory<ReturnInterface, DIContainerT> +where + ReturnInterface: 'static + ?Sized, + DIContainerT: 'static, +{ + func: &'static dyn Fn(&DIContainerT) -> TransientPtr<ReturnInterface>, +} + +impl<ReturnInterface, DIContainerT> CastableFactory<ReturnInterface, DIContainerT> +where + ReturnInterface: 'static + ?Sized, +{ + pub fn new( + func: &'static dyn Fn(&DIContainerT) -> TransientPtr<ReturnInterface>, + ) -> Self + { + Self { func } + } + + pub fn call(&self, di_container: &DIContainerT) -> TransientPtr<ReturnInterface> + { + (self.func)(di_container) + } +} + +impl<ReturnInterface, DIContainerT> AnyFactory + for CastableFactory<ReturnInterface, DIContainerT> +where + ReturnInterface: 'static + ?Sized, + DIContainerT: 'static, +{ + fn as_any(&self) -> &dyn Any + { + self + } +} + +impl<ReturnInterface, DIContainerT> Debug + for CastableFactory<ReturnInterface, DIContainerT> +where + ReturnInterface: 'static + ?Sized, +{ + #[cfg(not(tarpaulin_include))] + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result + { + let ret = type_name::<TransientPtr<ReturnInterface>>(); + + formatter.write_fmt(format_args!( + "CastableFactory (&DIContainer) -> {ret} {{ ... }}" + )) + } +} + +#[cfg(test)] +mod tests +{ + use super::*; + use crate::di_container::blocking::MockDIContainer; + + #[derive(Debug, PartialEq, Eq)] + struct Bacon + { + heal_amount: u32, + } + + #[test] + fn can_call() + { + let castable_factory = CastableFactory::new(&|_: &MockDIContainer| { + TransientPtr::new(Bacon { heal_amount: 27 }) + }); + + let mock_di_container = MockDIContainer::new(); + + let output = castable_factory.call(&mock_di_container); + + assert_eq!(output, TransientPtr::new(Bacon { heal_amount: 27 })); + } +} diff --git a/src/castable_factory/threadsafe.rs b/src/castable_factory/threadsafe.rs new file mode 100644 index 0000000..5935d75 --- /dev/null +++ b/src/castable_factory/threadsafe.rs @@ -0,0 +1,99 @@ +use std::any::{type_name, Any}; +use std::fmt::Debug; + +use crate::any_factory::{AnyFactory, AnyThreadsafeFactory}; +use crate::ptr::TransientPtr; + +pub struct ThreadsafeCastableFactory<ReturnInterface, DIContainerT> +where + DIContainerT: 'static, + ReturnInterface: 'static + ?Sized, +{ + func: &'static (dyn Fn(&DIContainerT) -> TransientPtr<ReturnInterface> + Send + Sync), +} + +impl<ReturnInterface, DIContainerT> + ThreadsafeCastableFactory<ReturnInterface, DIContainerT> +where + DIContainerT: 'static, + ReturnInterface: 'static + ?Sized, +{ + pub fn new( + func: &'static (dyn Fn(&DIContainerT) -> TransientPtr<ReturnInterface> + + Send + + Sync), + ) -> Self + { + Self { func } + } + + pub fn call(&self, di_container: &DIContainerT) -> TransientPtr<ReturnInterface> + { + (self.func)(di_container) + } +} + +impl<ReturnInterface, DIContainerT> AnyFactory + for ThreadsafeCastableFactory<ReturnInterface, DIContainerT> +where + DIContainerT: 'static, + ReturnInterface: 'static + ?Sized, +{ + fn as_any(&self) -> &dyn Any + { + self + } +} + +impl<ReturnInterface, DIContainerT> AnyThreadsafeFactory + for ThreadsafeCastableFactory<ReturnInterface, DIContainerT> +where + DIContainerT: 'static, + ReturnInterface: 'static + ?Sized, +{ +} + +impl<ReturnInterface, DIContainerT> Debug + for ThreadsafeCastableFactory<ReturnInterface, DIContainerT> +where + DIContainerT: 'static, + ReturnInterface: 'static + ?Sized, +{ + #[cfg(not(tarpaulin_include))] + fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result + { + let ret = type_name::<TransientPtr<ReturnInterface>>(); + + formatter.write_fmt(format_args!( + "ThreadsafeCastableFactory (&AsyncDIContainer) -> {ret} {{ ... }}", + )) + } +} + +#[cfg(test)] +mod tests +{ + use super::*; + use crate::di_container::asynchronous::MockAsyncDIContainer; + + #[derive(Debug, PartialEq, Eq)] + struct Bacon + { + heal_amount: u32, + } + + #[test] + fn can_call() + { + let castable_factory = + ThreadsafeCastableFactory::new(&|_: &MockAsyncDIContainer| { + TransientPtr::new(Bacon { heal_amount: 27 }) + }); + + let mock_di_container = MockAsyncDIContainer::new(); + + let output = castable_factory.call(&mock_di_container); + + assert_eq!(output, TransientPtr::new(Bacon { heal_amount: 27 })); + } +} |