reifydb_core/util/ioc/
mod.rs1mod resolve_arc;
5mod resolve_rc;
6
7use std::{
8 any::{Any, TypeId, type_name},
9 collections::HashMap,
10 sync::{Arc, RwLock},
11};
12
13use reifydb_type::{Result, diagnostic::internal, error};
14#[allow(unused_imports)]
15pub use resolve_arc::LazyResolveArc;
16pub use resolve_rc::LazyResolveRc;
17
18struct BoxedValue {
19 value: Box<dyn Any + Send + Sync>,
20}
21
22impl BoxedValue {
23 fn new<T: Clone + Any + Send + Sync + 'static>(value: T) -> Self {
24 Self {
25 value: Box::new(value),
26 }
27 }
28
29 fn value<T: Clone + Any + Send + Sync + 'static>(&self) -> Option<T> {
30 self.value.downcast_ref::<T>().cloned()
31 }
32}
33
34pub struct IocContainer {
36 dependencies: Arc<RwLock<HashMap<TypeId, BoxedValue>>>,
37}
38
39impl IocContainer {
40 pub fn new() -> Self {
41 Self {
42 dependencies: Arc::new(RwLock::new(HashMap::new())),
43 }
44 }
45
46 pub fn register<T: Clone + Any + Send + Sync + 'static>(self, service: T) -> Self {
47 self.dependencies.write().unwrap().insert(TypeId::of::<T>(), BoxedValue::new(service));
48 self
49 }
50
51 pub fn resolve<T: Clone + Any + Send + Sync + 'static>(&self) -> Result<T> {
52 self.dependencies
53 .read()
54 .unwrap()
55 .get(&TypeId::of::<T>())
56 .and_then(|boxed| boxed.value::<T>())
57 .ok_or_else(|| {
58 error!(internal(format!("Type {} not registered in IoC container", type_name::<T>())))
59 })
60 }
61}
62
63impl Clone for IocContainer {
64 fn clone(&self) -> Self {
65 Self {
66 dependencies: self.dependencies.clone(),
67 }
68 }
69}
70
71impl Default for IocContainer {
72 fn default() -> Self {
73 Self::new()
74 }
75}