anthill_di/
service_mapping_builder.rs

1use std::marker::Unsize;
2use std::{sync::Arc, marker::PhantomData, any::TypeId};
3
4use crate::LifeCycle;
5use crate::types::TypeInfo;
6use crate::{core_context::CoreContext, types::{MapComponentError, MapComponentResult}};
7
8pub struct ServiceMappingBuilder<TComponent: Sync + Send + 'static> {
9    core_context: Arc<CoreContext>,
10    pd: PhantomData<TComponent>
11}
12
13/// Map registered component to service
14impl<TComponent: Sync + Send + 'static> ServiceMappingBuilder<TComponent> {
15    pub (crate) fn new(core_context: Arc<CoreContext>) -> Self {
16        Self {
17            core_context,
18            pd: PhantomData,
19        }
20    }
21
22    /// Map component as service
23    /// 
24    ///# Example
25    ///---
26    /// ```ignore
27    /// struct SomeComponent {}
28    /// 
29    /// let root_context = DependencyContext::new_root();
30    /// root_context.register_type::<SomeComponent>(LifeCycle::Transient).await
31    ///     .unwrap()
32    ///     .map_as::<dyn SomeService>().await
33    ///     .unwrap();
34    /// ```
35    #[cfg(feature = "async-mode")]
36    pub async fn map_as<TService: ?Sized + Sync + Send + 'static>(self) -> MapComponentResult<Self> where TComponent: Unsize<TService> {
37        let component_id = TypeId::of::<TComponent>();
38
39        let components_read_guard = self.core_context.components.read().await;
40        let component = components_read_guard.get(&component_id);
41
42        if component.is_none() {
43            return Err(MapComponentError::ComponentNotFound{
44                component_type_info: TypeInfo::from_type::<TComponent>(),
45                service_type_info: TypeInfo::from_type::<TService>(),
46            });
47        }
48
49        let component = component.unwrap();
50
51        match component.life_cycle_type {
52            LifeCycle::Transient => self.core_context.cycled_component_service_collection.write().await.add_mapping_as_transient::<TComponent, TService>(),
53            LifeCycle::Singleton => self.core_context.cycled_component_service_collection.write().await.add_mapping_as_singleton::<TComponent, TService>(),
54            LifeCycle::ContextDependent =>  self.core_context.cycled_component_service_collection.write().await.add_mapping_as_context_dependent::<TComponent, TService>()
55        };
56
57        drop(components_read_guard);
58
59        Ok(self)
60    }
61
62    /// Map component as service (blocking version)
63    /// 
64    ///# Example
65    ///---
66    /// ```ignore
67    /// struct SomeComponent {}
68    /// 
69    /// let root_context = DependencyContext::new_root();
70    /// root_context.register_type::<SomeComponent>(LifeCycle::Transient)
71    ///     .unwrap()
72    ///     .blocking_map_as::<dyn SomeService>()
73    ///     .unwrap();
74    /// ```
75    #[cfg(feature = "blocking")]
76    pub fn blocking_map_as<TService: ?Sized + Sync + Send + 'static>(self) -> MapComponentResult<Self> where TComponent: Unsize<TService> {
77        std::thread::spawn(move || {
78            let component_id = TypeId::of::<TComponent>();
79
80            let components_read_guard = self.core_context.components.blocking_read();
81            let component = components_read_guard.get(&component_id);
82
83            if component.is_none() {
84                return Err(MapComponentError::ComponentNotFound{
85                    component_type_info: TypeInfo::from_type::<TComponent>(),
86                    service_type_info: TypeInfo::from_type::<TService>(),
87                });
88            }
89
90            let component = component.unwrap();
91
92            match component.life_cycle_type {
93                LifeCycle::Transient => self.core_context.cycled_component_service_collection.blocking_write().add_mapping_as_transient::<TComponent, TService>(),
94                LifeCycle::Singleton => self.core_context.cycled_component_service_collection.blocking_write().add_mapping_as_singleton::<TComponent, TService>(),
95                LifeCycle::ContextDependent =>  self.core_context.cycled_component_service_collection.blocking_write().add_mapping_as_context_dependent::<TComponent, TService>()
96            };
97
98            drop(components_read_guard);
99
100            Ok(self)
101        }).join().unwrap()
102    }
103
104    /// Map component as service
105    /// 
106    ///# Example
107    ///---
108    /// ```ignore
109    /// struct SomeComponent {}
110    /// 
111    /// let root_context = DependencyContext::new_root();
112    /// root_context.register_type::<SomeComponent>(LifeCycle::Transient)
113    ///     .unwrap()
114    ///     .map_as::<dyn SomeService>()
115    ///     .unwrap();
116    /// ```
117    #[cfg(not(feature = "async-mode"))]
118    pub fn map_as<TService: ?Sized + Sync + Send + 'static>(self) -> MapComponentResult<Self> where TComponent: Unsize<TService> {
119        let component_id = TypeId::of::<TComponent>();
120
121        let components_read_guard = self.core_context.components.read().unwrap();
122        let component = components_read_guard.get(&component_id);
123
124        if component.is_none() {
125            return Err(MapComponentError::ComponentNotFound{
126                component_type_info: TypeInfo::from_type::<TComponent>(),
127                service_type_info: TypeInfo::from_type::<TService>(),
128            });
129        }
130
131        let component = component.unwrap();
132
133        match component.life_cycle_type {
134            LifeCycle::Transient => self.core_context.cycled_component_service_collection.write().unwrap().add_mapping_as_transient::<TComponent, TService>(),
135            LifeCycle::Singleton => self.core_context.cycled_component_service_collection.write().unwrap().add_mapping_as_singleton::<TComponent, TService>(),
136            LifeCycle::ContextDependent =>  self.core_context.cycled_component_service_collection.write().unwrap().add_mapping_as_context_dependent::<TComponent, TService>()
137        };
138
139        drop(components_read_guard);
140
141        Ok(self)
142    }
143}