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(RdiError::ServiceNotFound { ty: type_name, context: 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(RdiError::KeyedServiceNotFound {
129 key: variant.to_string(),
130 ty: type_name,
131 })
132 }
133
134 fn try_get_keyed<T: ?Sized + Sync + Send + 'static>(&self, variant: &str) -> Option<Arc<T>>
136 where
137 Self: Sized,
138 {
139 let type_name = std::any::type_name::<T>();
140 let tid = TypeId::of::<T>();
141 self.get_keyed_by_type_id(tid, variant)
142 .or_else(|| self.get_keyed_any(type_name, variant))
143 .and_then(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
144 }
145
146 fn get_all<T: ?Sized + Sync + Send + 'static>(&self) -> Vec<Arc<T>>
153 where
154 Self: Sized,
155 {
156 self.get_all_any(std::any::type_name::<T>())
157 .into_iter()
158 .filter_map(|a| a.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d)))
159 .collect()
160 }
161
162 fn get_owned_any(&self, _key: &str) -> Option<Arc<dyn Any + Send + Sync>> {
171 None
172 }
173 fn get_keyed_owned_any(
174 &self,
175 _key: &str,
176 _variant: &str,
177 ) -> Option<Arc<dyn Any + Send + Sync>> {
178 None
179 }
180
181 fn get_owned<T: Send + Sync + 'static>(&self) -> Result<T, RdiError>
184 where
185 Self: Sized,
186 {
187 let type_name = std::any::type_name::<T>();
188 let arc_any = self
189 .get_owned_any(type_name)
190 .ok_or(RdiError::ServiceNotFound { ty: type_name, context: None })?;
191 let arc_t: Arc<T> = arc_any
192 .downcast::<Arc<T>>()
193 .ok()
194 .map(|d| Arc::clone(&*d))
195 .ok_or(RdiError::ServiceNotFound { ty: type_name, context: None })?;
196 Arc::try_unwrap(arc_t).map_err(|_| RdiError::OwnedNotSupported(type_name))
197 }
198
199 fn try_get_owned<T: Send + Sync + 'static>(&self) -> Option<T>
201 where
202 Self: Sized,
203 {
204 let arc_any = self.get_owned_any(std::any::type_name::<T>())?;
205 let arc_t: Arc<T> = arc_any.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d))?;
206 Arc::try_unwrap(arc_t).ok()
207 }
208
209 fn get_keyed_owned<T: Send + Sync + 'static>(&self, variant: &str) -> Result<T, RdiError>
212 where
213 Self: Sized,
214 {
215 let type_name = std::any::type_name::<T>();
216 let arc_any = self
217 .get_keyed_owned_any(type_name, variant)
218 .ok_or(RdiError::KeyedServiceNotFound {
219 key: variant.to_string(),
220 ty: type_name,
221 })?;
222 let arc_t: Arc<T> = arc_any
223 .downcast::<Arc<T>>()
224 .ok()
225 .map(|d| Arc::clone(&*d))
226 .ok_or(RdiError::KeyedServiceNotFound {
227 key: variant.to_string(),
228 ty: type_name,
229 })?;
230 Arc::try_unwrap(arc_t).map_err(|_| RdiError::OwnedNotSupported(type_name))
231 }
232
233 fn try_get_keyed_owned<T: Send + Sync + 'static>(&self, variant: &str) -> Option<T>
235 where
236 Self: Sized,
237 {
238 let arc_any = self.get_keyed_owned_any(std::any::type_name::<T>(), variant)?;
239 let arc_t: Arc<T> = arc_any.downcast::<Arc<T>>().ok().map(|d| Arc::clone(&*d))?;
240 Arc::try_unwrap(arc_t).ok()
241 }
242}
243
244pub struct ServiceEntry {
245 pub cache_key: usize,
246 pub key: Option<String>,
247 pub type_name: &'static str, pub factory: ServiceFactory,
249 pub async_factory: Option<AsyncServiceFactory>,
250 pub lifetime: ServiceLifetime,
251}
252
253pub type ServiceFactory =
254 Arc<dyn Fn(&dyn IServiceResolver) -> Arc<dyn Any + Send + Sync> + Send + Sync>;
255
256pub type AsyncServiceFactory = Arc<
263 dyn Fn(Arc<ServiceProvider>) -> Pin<Box<dyn Future<Output = Arc<dyn Any + Send + Sync>> + Send>>
264 + Send
265 + Sync,
266>;