1use crate::error::RdiError;
2use crate::provider::ServiceProvider;
3use std::any::{Any, TypeId};
4use std::collections::HashMap;
5use std::future::Future;
6use std::pin::Pin;
7use std::sync::Arc;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15pub enum ServiceLifetime {
16 Transient,
17 Scoped,
18 Singleton,
19}
20
21#[derive(Clone)]
26pub struct ServiceDescriptor {
27 pub type_id: TypeId,
28 pub type_name: &'static str,
29 pub key: Option<String>,
30 pub factory: ServiceFactory,
31 pub async_factory: Option<AsyncServiceFactory>,
32 pub lifetime: ServiceLifetime,
33}
34
35pub type ServiceStore = HashMap<TypeId, Vec<ServiceEntry>>;
39
40pub trait IServiceResolver: Send + Sync {
44 fn get_any(&self, key: &str) -> Option<Arc<dyn Any + Send + Sync>>;
45 fn get_keyed_any(&self, key: &str, variant: &str) -> Option<Arc<dyn Any + Send + Sync>>;
46
47 fn get_by_type_id(&self, _tid: TypeId) -> Option<Arc<dyn Any + Send + Sync>> {
52 None
53 }
54 fn get_keyed_by_type_id(
56 &self,
57 _tid: TypeId,
58 _key: &str,
59 ) -> Option<Arc<dyn Any + Send + Sync>> {
60 None
61 }
62
63 fn get_all_any(&self, _key: &str) -> Vec<Arc<dyn Any + Send + Sync>> {
72 Vec::new()
73 }
74
75 fn provider_arc(&self) -> Option<Arc<ServiceProvider>> {
86 None
87 }
88
89 fn get<T: ?Sized + Sync + Send + 'static>(&self) -> Result<Arc<T>, RdiError>
95 where
96 Self: Sized,
97 {
98 let type_name = std::any::type_name::<T>();
99 let tid = TypeId::of::<T>();
100 self.get_by_type_id(tid)
101 .or_else(|| self.get_any(type_name))
102 .and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
103 .ok_or_else(|| RdiError::not_found(type_name, None))
104 }
105
106 fn try_get<T: ?Sized + Sync + Send + 'static>(&self) -> Option<Arc<T>>
108 where
109 Self: Sized,
110 {
111 let type_name = std::any::type_name::<T>();
112 let tid = TypeId::of::<T>();
113 self.get_by_type_id(tid)
114 .or_else(|| self.get_any(type_name))
115 .and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
116 }
117
118 fn get_keyed<T: ?Sized + Sync + Send + 'static>(&self, variant: &str) -> Result<Arc<T>, RdiError>
120 where
121 Self: Sized,
122 {
123 let type_name = std::any::type_name::<T>();
124 let tid = TypeId::of::<T>();
125 self.get_keyed_by_type_id(tid, variant)
126 .or_else(|| self.get_keyed_any(type_name, variant))
127 .and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
128 .ok_or_else(|| RdiError::keyed_not_found(type_name, variant, None))
129 }
130
131 fn try_get_keyed<T: ?Sized + Sync + Send + 'static>(&self, variant: &str) -> Option<Arc<T>>
133 where
134 Self: Sized,
135 {
136 let type_name = std::any::type_name::<T>();
137 let tid = TypeId::of::<T>();
138 self.get_keyed_by_type_id(tid, variant)
139 .or_else(|| self.get_keyed_any(type_name, variant))
140 .and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
141 }
142
143 fn get_all<T: ?Sized + Sync + Send + 'static>(&self) -> Vec<Arc<T>>
150 where
151 Self: Sized,
152 {
153 self.get_all_any(std::any::type_name::<T>())
154 .into_iter()
155 .filter_map(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
156 .collect()
157 }
158
159 fn get_owned_any(&self, _key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
168 None
169 }
170 fn get_keyed_owned_any(
171 &self,
172 _key: &str,
173 _variant: &str,
174 ) -> Option<Arc<dyn Any + Send + Sync>> {
175 None
176 }
177
178 fn get_owned<T: Send + Sync + 'static>(&self) -> Result<T, RdiError>
181 where
182 Self: Sized,
183 {
184 let type_name = std::any::type_name::<T>();
185 let arc_any = self
186 .get_owned_any(type_name)
187 .ok_or_else(|| RdiError::not_found(type_name, None))?;
188 let arc_t: Arc<T> = arc_any
189 .downcast::<Arc<T>>()
190 .ok()
191 .map(|d| Arc::clone(&*d))
192 .ok_or_else(|| RdiError::not_found(type_name, None))?;
193 Arc::try_unwrap(arc_t).map_err(|_| RdiError::OwnedNotSupported(type_name))
194 }
195
196 fn try_get_owned<T: Send + Sync + 'static>(&self) -> Option<T>
198 where
199 Self: Sized,
200 {
201 let arc_any = self.get_owned_any(std::any::type_name::<T>())?;
202 let arc_t: Arc<T> = arc_any.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d))?;
203 Arc::try_unwrap(arc_t).ok()
204 }
205
206 fn get_keyed_owned<T: Send + Sync + 'static>(&self, variant: &str) -> Result<T, RdiError>
209 where
210 Self: Sized,
211 {
212 let type_name = std::any::type_name::<T>();
213 let arc_any = self
214 .get_keyed_owned_any(type_name, variant)
215 .ok_or_else(|| RdiError::keyed_not_found(type_name, variant, None))?;
216 let arc_t: Arc<T> = arc_any
217 .downcast::<Arc<T>>()
218 .ok()
219 .map(|d| Arc::clone(&*d))
220 .ok_or_else(|| RdiError::keyed_not_found(type_name, variant, None))?;
221 Arc::try_unwrap(arc_t).map_err(|_| RdiError::OwnedNotSupported(type_name))
222 }
223
224 fn try_get_keyed_owned<T: Send + Sync + 'static>(&self, variant: &str) -> Option<T>
226 where
227 Self: Sized,
228 {
229 let arc_any = self.get_keyed_owned_any(std::any::type_name::<T>(), variant)?;
230 let arc_t: Arc<T> = arc_any.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d))?;
231 Arc::try_unwrap(arc_t).ok()
232 }
233}
234
235pub struct ServiceEntry {
236 pub cache_key: usize,
237 pub key: Option<String>,
238 pub type_name: &'static str, pub factory: ServiceFactory,
240 pub async_factory: Option<AsyncServiceFactory>,
241 pub lifetime: ServiceLifetime,
242}
243
244pub type ServiceFactory =
245 Arc<dyn Fn(&dyn IServiceResolver) -> Arc<dyn Any + Send + Sync> + Send + Sync>;
246
247pub type AsyncServiceFactory = Arc<
254 dyn Fn(Arc<ServiceProvider>) -> Pin<Box<dyn Future<Output = Arc<dyn Any + Send + Sync>> + Send>>
255 + Send
256 + Sync,
257>;