1#[cfg(feature = "axum")]
2pub mod axum;
3pub mod error;
4#[cfg(feature = "jav")]
5pub mod jav;
6pub mod scope;
7
8use std::{
9 any::{Any, TypeId},
10 sync::{Arc, OnceLock},
11};
12
13use arc_swap::ArcSwapOption;
14use scc::HashMap;
15
16use crate::{
17 error::{ServiceAlreadyExistsError, ServiceNotFoundError},
18 scope::{Scope, ScopeProvider, get_default_scope_full},
19};
20
21pub struct DI<T: ?Sized + Send + Sync + 'static>(pub Arc<T>);
22pub struct DIK<T: ?Sized + Send + Sync + 'static, K: 'static>(
23 pub Arc<T>,
24 pub std::marker::PhantomData<K>,
25);
26
27#[derive(Clone)]
28pub enum Service {
29 Singleton(Arc<dyn Any + Send + Sync>),
30 Transient(Arc<dyn Fn() -> Arc<dyn Any + Send + Sync> + Send + Sync>),
31 Scoped(Arc<dyn Fn() -> Arc<dyn Any + Send + Sync> + Send + Sync>),
32}
33
34#[derive(Clone)]
35pub struct ServiceCollection {
36 collection: HashMap<(TypeId, Option<TypeId>), Service>,
37}
38
39impl ServiceCollection {
40 pub fn new() -> Self {
41 Self {
42 collection: HashMap::new(),
43 }
44 }
45
46 pub fn add_singleton<T: Send + Sync + 'static>(
47 &self,
48 service: T,
49 ) -> Result<(), ServiceAlreadyExistsError> {
50 self.add_internal::<T>(Service::Singleton(Arc::new(Arc::new(service))), None)
51 }
52
53 pub fn add_singleton_keyed<T: Send + Sync + 'static>(
54 &self,
55 service: T,
56 key: TypeId,
57 ) -> Result<(), ServiceAlreadyExistsError> {
58 self.add_internal::<T>(Service::Singleton(Arc::new(Arc::new(service))), Some(key))
59 }
60
61 pub fn add_singleton_trait<Trait: ?Sized + Send + Sync + 'static>(
62 &self,
63 service: Arc<Trait>,
64 ) -> Result<(), ServiceAlreadyExistsError> {
65 self.add_internal::<Trait>(Service::Singleton(Arc::new(service)), None)
66 }
67
68 pub fn add_singleton_trait_keyed<Trait: ?Sized + Send + Sync + 'static>(
69 &self,
70 service: Arc<Trait>,
71 key: TypeId,
72 ) -> Result<(), ServiceAlreadyExistsError> {
73 self.add_internal::<Trait>(Service::Singleton(Arc::new(service)), Some(key))
74 }
75
76 fn add_internal<T: ?Sized + Send + Sync + 'static>(
77 &self,
78 service: Service,
79 key: Option<TypeId>,
80 ) -> Result<(), ServiceAlreadyExistsError> {
81 let tid = (TypeId::of::<T>(), key);
82 if self.collection.contains_sync(&tid) {
83 return Err(ServiceAlreadyExistsError);
84 }
85 let _ = self.collection.insert_sync(tid, service);
86 Ok(())
87 }
88
89 pub fn add_transient<T: Send + Sync + 'static, F>(
90 &self,
91 service_factory: F,
92 ) -> Result<(), ServiceAlreadyExistsError>
93 where
94 F: Fn() -> T + Send + Sync + 'static,
95 {
96 self.add_internal::<T>(
97 Service::Transient(Arc::new(move || Arc::new(Arc::new(service_factory())))),
98 None,
99 )
100 }
101 pub fn add_transient_keyed<T: Send + Sync + 'static, F>(
102 &self,
103 service_factory: F,
104 key: TypeId,
105 ) -> Result<(), ServiceAlreadyExistsError>
106 where
107 F: Fn() -> T + Send + Sync + 'static,
108 {
109 self.add_internal::<T>(
110 Service::Transient(Arc::new(move || Arc::new(Arc::new(service_factory())))),
111 Some(key),
112 )
113 }
114
115 pub fn add_transient_trait<Trait: ?Sized + Send + Sync + 'static, F>(
116 &self,
117 service_factory: F,
118 ) -> Result<(), ServiceAlreadyExistsError>
119 where
120 F: Fn() -> Arc<Trait> + Send + Sync + 'static,
121 {
122 self.add_internal::<Trait>(
123 Service::Transient(Arc::new(move || Arc::new(service_factory()))),
124 None,
125 )
126 }
127
128 pub fn add_transient_trait_keyed<Trait: ?Sized + Send + Sync + 'static, F>(
129 &self,
130 service_factory: F,
131 key: TypeId,
132 ) -> Result<(), ServiceAlreadyExistsError>
133 where
134 F: Fn() -> Arc<Trait> + Send + Sync + 'static,
135 {
136 self.add_internal::<Trait>(
137 Service::Transient(Arc::new(move || Arc::new(service_factory()))),
138 Some(key),
139 )
140 }
141
142 pub fn add_scoped<T: Send + Sync + 'static, F>(
143 &self,
144 service_factory: F,
145 ) -> Result<(), ServiceAlreadyExistsError>
146 where
147 F: Fn() -> T + Send + Sync + 'static,
148 {
149 self.add_internal::<T>(
150 Service::Scoped(Arc::new(move || Arc::new(Arc::new(service_factory())))),
151 None,
152 )
153 }
154 pub fn add_scoped_keyed<T: Send + Sync + 'static, F>(
155 &self,
156 service_factory: F,
157 key: TypeId,
158 ) -> Result<(), ServiceAlreadyExistsError>
159 where
160 F: Fn() -> T + Send + Sync + 'static,
161 {
162 self.add_internal::<T>(
163 Service::Scoped(Arc::new(move || Arc::new(Arc::new(service_factory())))),
164 Some(key),
165 )
166 }
167
168 pub fn add_scoped_trait<Trait: ?Sized + Send + Sync + 'static, F>(
169 &self,
170 service_factory: F,
171 ) -> Result<(), ServiceAlreadyExistsError>
172 where
173 F: Fn() -> Arc<Trait> + Send + Sync + 'static,
174 {
175 self.add_internal::<Trait>(
176 Service::Scoped(Arc::new(move || Arc::new(service_factory()))),
177 None,
178 )
179 }
180
181 pub fn add_scoped_trait_keyed<Trait: ?Sized + Send + Sync + 'static, F>(
182 &self,
183 service_factory: F,
184 key: TypeId,
185 ) -> Result<(), ServiceAlreadyExistsError>
186 where
187 F: Fn() -> Arc<Trait> + Send + Sync + 'static,
188 {
189 self.add_internal::<Trait>(
190 Service::Scoped(Arc::new(move || Arc::new(service_factory()))),
191 Some(key),
192 )
193 }
194
195 pub fn create_scope(&self) -> Arc<Scope> {
196 let scope: Scope = HashMap::new();
197 self.collection.iter_sync(|k, v| {
198 let Service::Scoped(_) = v else {
199 return true;
200 };
201 let _ = scope.insert_sync(k.clone(), OnceLock::new());
202 true
203 });
204 Arc::new(scope)
205 }
206
207 fn di_internal<T: ?Sized + Send + Sync + 'static>(
208 &self,
209 key: Option<TypeId>,
210 scope: Option<Arc<Arc<dyn ScopeProvider>>>,
211 ) -> Result<Arc<T>, ServiceNotFoundError> {
212 let tid = (TypeId::of::<T>(), key);
213 if let Some(s) = self.collection.read_sync(&tid, |_, s| match s {
214 Service::Singleton(service) if let Ok(res) = service.clone().downcast::<Arc<T>>() => {
215 Ok((*res).clone())
216 },
217 Service::Transient(factory) => {
218 let instance = factory.clone()();
219 if let Ok(res) = instance.downcast::<Arc<T>>() {
220 Ok((*res).clone())
221 } else {
222 Err(ServiceNotFoundError)
223 }
224 },
225 Service::Scoped(factory) => {
226 let scope = scope
227 .unwrap_or_else(|| get_default_scope_full())
228 .provide_scope()?;
229 let Some(res) = scope.get_sync(&tid) else {
230 return Err(ServiceNotFoundError);
231 };
232 let instance = res.get_or_init(|| factory.clone()()).clone();
233 if let Ok(res) = instance.downcast::<Arc<T>>() {
234 Ok((*res).clone())
235 } else {
236 Err(ServiceNotFoundError)
237 }
238 },
239 _ => Err(ServiceNotFoundError),
240 }) {
241 return s;
242 } else {
243 Err(ServiceNotFoundError)
244 }
245 }
246
247 pub fn dir<T: ?Sized + Send + Sync + 'static>(&self) -> Result<Arc<T>, ServiceNotFoundError> {
248 self.di_internal(None, None)
249 }
250
251 pub fn dikr<T: ?Sized + Send + Sync + 'static, K: 'static>(
252 &self,
253 ) -> Result<Arc<T>, ServiceNotFoundError> {
254 self.di_internal(Some(TypeId::of::<K>()), None)
255 }
256
257 pub fn disr<T: ?Sized + Send + Sync + 'static>(
258 &self,
259 scope: Arc<Arc<dyn ScopeProvider>>,
260 ) -> Result<Arc<T>, ServiceNotFoundError> {
261 self.di_internal(None, Some(scope))
262 }
263 pub fn diskr<T: ?Sized + Send + Sync + 'static, K: 'static>(
264 &self,
265 scope: Arc<Arc<dyn ScopeProvider>>,
266 ) -> Result<Arc<T>, ServiceNotFoundError> {
267 self.di_internal(Some(TypeId::of::<K>()), Some(scope))
268 }
269
270 pub fn di<T: ?Sized + Send + Sync + 'static>(&self) -> Arc<T> {
271 self.di_internal(None, None)
272 .expect("Failed to find service")
273 }
274
275 pub fn dik<T: ?Sized + Send + Sync + 'static, K: 'static>(&self) -> Arc<T> {
276 self.di_internal(Some(TypeId::of::<K>()), None)
277 .expect("Failed to find service")
278 }
279
280 pub fn dis<T: ?Sized + Send + Sync + 'static>(
281 &self,
282 scope: Arc<Arc<dyn ScopeProvider>>,
283 ) -> Arc<T> {
284 self.di_internal(None, Some(scope))
285 .expect("Failed to find service")
286 }
287 pub fn disk<T: ?Sized + Send + Sync + 'static, K: 'static>(
288 &self,
289 scope: Arc<Arc<dyn ScopeProvider>>,
290 ) -> Arc<T> {
291 self.di_internal(Some(TypeId::of::<K>()), Some(scope))
292 .expect("Failed to find service")
293 }
294}
295
296static SERVICE_PROVIDER: ArcSwapOption<ServiceCollection> = ArcSwapOption::const_empty();
297
298pub fn spo() -> Option<Arc<ServiceCollection>> {
299 SERVICE_PROVIDER.load_full()
300}
301
302pub fn sp() -> Arc<ServiceCollection> {
303 spo().expect("ServiceProvider not yet initialized")
304}
305
306pub fn set_sp(sp: ServiceCollection) -> Option<Arc<ServiceCollection>> {
307 set_sp_arc(Arc::new(sp))
308}
309pub fn set_sp_arc(sp: Arc<ServiceCollection>) -> Option<Arc<ServiceCollection>> {
310 SERVICE_PROVIDER.swap(Some(sp))
311}
312
313pub fn init_sp() {
314 set_sp(ServiceCollection::new());
315}