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: Send + Sync + 'static>(pub Arc<T>);
22pub struct DIK<T: Send + Sync + 'static, K: 'static>(pub Arc<T>, std::marker::PhantomData<K>);
23
24#[derive(Clone)]
25pub enum Service {
26 Singleton(Arc<dyn Any + Send + Sync>),
27 Transient(Arc<dyn Fn() -> Arc<dyn Any + Send + Sync> + Send + Sync>),
28 Scoped(Arc<dyn Fn() -> Arc<dyn Any + Send + Sync> + Send + Sync>),
29}
30
31#[derive(Clone)]
32pub struct ServiceCollection {
33 collection: HashMap<(TypeId, Option<TypeId>), Service>,
34}
35
36impl ServiceCollection {
37 pub fn new() -> Self {
38 Self {
39 collection: HashMap::new(),
40 }
41 }
42
43 pub fn add_singleton<T: Send + Sync + 'static>(
44 &self,
45 service: T,
46 ) -> Result<(), ServiceAlreadyExistsError> {
47 self.add_internal::<T>(Service::Singleton(Arc::new(service)), None)
48 }
49 pub fn add_singleton_keyed<T: Send + Sync + 'static>(
50 &self,
51 service: T,
52 key: TypeId,
53 ) -> Result<(), ServiceAlreadyExistsError> {
54 self.add_internal::<T>(Service::Singleton(Arc::new(service)), Some(key))
55 }
56
57 fn add_internal<T: Send + Sync + 'static>(
58 &self,
59 service: Service,
60 key: Option<TypeId>,
61 ) -> Result<(), ServiceAlreadyExistsError> {
62 let tid = (TypeId::of::<T>(), key);
63 if self.collection.contains_sync(&tid) {
64 return Err(ServiceAlreadyExistsError);
65 }
66 self.collection.insert_sync(tid, service);
67 Ok(())
68 }
69
70 pub fn add_transient<T: Send + Sync + 'static, F>(
71 &self,
72 service_factory: F,
73 ) -> Result<(), ServiceAlreadyExistsError>
74 where
75 F: Fn() -> T + Send + Sync + 'static,
76 {
77 self.add_internal::<T>(
78 Service::Transient(Arc::new(move || Arc::new(service_factory()))),
79 None,
80 )
81 }
82 pub fn add_transient_keyed<T: Send + Sync + 'static, F>(
83 &self,
84 service_factory: F,
85 key: TypeId,
86 ) -> Result<(), ServiceAlreadyExistsError>
87 where
88 F: Fn() -> T + Send + Sync + 'static,
89 {
90 self.add_internal::<T>(
91 Service::Transient(Arc::new(move || Arc::new(service_factory()))),
92 Some(key),
93 )
94 }
95
96 pub fn add_scoped<T: Send + Sync + 'static, F>(
97 &self,
98 service_factory: F,
99 ) -> Result<(), ServiceAlreadyExistsError>
100 where
101 F: Fn() -> T + Send + Sync + 'static,
102 {
103 self.add_internal::<T>(
104 Service::Scoped(Arc::new(move || Arc::new(service_factory()))),
105 None,
106 )
107 }
108 pub fn add_scoped_keyed<T: Send + Sync + 'static, F>(
109 &self,
110 service_factory: F,
111 key: TypeId,
112 ) -> Result<(), ServiceAlreadyExistsError>
113 where
114 F: Fn() -> T + Send + Sync + 'static,
115 {
116 self.add_internal::<T>(
117 Service::Scoped(Arc::new(move || Arc::new(service_factory()))),
118 Some(key),
119 )
120 }
121
122 pub fn create_scope(&self) -> Arc<Scope> {
123 let scope: Scope = HashMap::new();
124 self.collection.iter_sync(|k, v| {
125 let Service::Scoped(_) = v else {
126 return true;
127 };
128 scope.insert_sync(k.clone(), OnceLock::new());
129 true
130 });
131 Arc::new(scope)
132 }
133
134 fn di_internal<T: Send + Sync + 'static>(
135 &self,
136 key: Option<TypeId>,
137 scope: Option<Arc<Arc<dyn ScopeProvider>>>,
138 ) -> Result<Arc<T>, ServiceNotFoundError> {
139 let tid = (TypeId::of::<T>(), key);
140 if let Some(s) = self.collection.read_sync(&tid, |_, s| match s {
141 Service::Singleton(service) if let Ok(res) = service.clone().downcast() => Ok(res),
142 Service::Transient(factory) if let Ok(res) = factory.clone()().downcast() => Ok(res),
143 Service::Scoped(factory) => {
144 let scope = scope
145 .unwrap_or_else(|| get_default_scope_full())
146 .provide_scope()?;
147 let Some(res) = scope.get_sync(&tid) else {
148 return Err(ServiceNotFoundError);
149 };
150 res.get_or_init(|| factory.clone()())
151 .clone()
152 .downcast()
153 .map_err(|_| ServiceNotFoundError)
154 },
155 _ => Err(ServiceNotFoundError),
156 }) {
157 return s;
158 } else {
159 Err(ServiceNotFoundError)
160 }
161 }
162
163 pub fn di<T: Send + Sync + 'static>(&self) -> Result<Arc<T>, ServiceNotFoundError> {
164 self.di_internal(None, None)
165 }
166
167 pub fn dik<T: Send + Sync + 'static, K: 'static>(
168 &self,
169 ) -> Result<Arc<T>, ServiceNotFoundError> {
170 self.di_internal(Some(TypeId::of::<K>()), None)
171 }
172
173 pub fn dis<T: Send + Sync + 'static>(
174 &self,
175 scope: Arc<Arc<dyn ScopeProvider>>,
176 ) -> Result<Arc<T>, ServiceNotFoundError> {
177 self.di_internal(None, Some(scope))
178 }
179 pub fn disk<T: Send + Sync + 'static, K: 'static>(
180 &self,
181 scope: Arc<Arc<dyn ScopeProvider>>,
182 ) -> Result<Arc<T>, ServiceNotFoundError> {
183 self.di_internal(Some(TypeId::of::<K>()), Some(scope))
184 }
185}
186
187static SERVICE_PROVIDER: ArcSwapOption<ServiceCollection> = ArcSwapOption::const_empty();
188
189pub fn sp() -> Option<Arc<ServiceCollection>> {
190 SERVICE_PROVIDER.load_full()
191}
192
193pub fn spp() -> Arc<ServiceCollection> {
194 sp().expect("ServiceProvider not yet initialized")
195}
196
197pub fn set_sp(sp: ServiceCollection) -> Option<Arc<ServiceCollection>> {
198 set_sp_arc(Arc::new(sp))
199}
200pub fn set_sp_arc(sp: Arc<ServiceCollection>) -> Option<Arc<ServiceCollection>> {
201 SERVICE_PROVIDER.swap(Some(sp))
202}