1use crate::collection::{Registration, Source};
2use crate::key::{Key, KeyMap};
3use crate::scope::Scope;
4use crate::sync::ConstructionLock;
5use crate::{Lifetime, ResolveError, Resolver};
6use std::any::Any;
7use std::fmt;
8use std::sync::atomic::{AtomicUsize, Ordering};
9use std::sync::{Arc, OnceLock};
10
11pub(crate) type Erased = Arc<dyn Any + Send + Sync>;
12
13pub(crate) type ConstructFn =
14 Arc<dyn Fn(&Resolver<'_>) -> Result<Erased, ResolveError> + Send + Sync>;
15
16pub(crate) struct Container {
18 registrations: Box<[Registration]>,
19 lookup: KeyMap<Box<[usize]>>,
21 pub(crate) scoped_count: usize,
22 pub(crate) singletons: Slots,
23 pub(crate) construction: ConstructionLock,
24}
25
26impl Container {
27 pub(crate) fn new(mut registrations: Vec<Registration>) -> Self {
28 let (mut singletons, mut scoped) = (0, 0);
31 for registration in &mut registrations {
32 let count = match registration.lifetime {
33 Lifetime::Singleton => &mut singletons,
34 Lifetime::Scoped => &mut scoped,
35 Lifetime::Transient => continue,
36 };
37 registration.slot = *count;
38 *count += 1;
39 }
40
41 let container = Self {
42 lookup: index_by_key(®istrations),
43 registrations: registrations.into_boxed_slice(),
44 scoped_count: scoped,
45 singletons: Slots::new(singletons),
46 construction: ConstructionLock::default(),
47 };
48 for registration in &container.registrations {
49 if let Source::Instance(instance) = ®istration.source {
50 container
51 .singletons
52 .fill(registration.slot, Arc::clone(instance));
53 }
54 }
55 container
56 }
57
58 pub(crate) fn registration(&self, key: Key) -> Option<&Registration> {
60 let &index = self.lookup.get(&key)?.last()?;
61 self.registrations.get(index)
62 }
63
64 pub(crate) fn registrations_of(
65 &self,
66 key: Key,
67 ) -> impl DoubleEndedIterator<Item = &Registration> + ExactSizeIterator {
68 self.lookup
69 .get(&key)
70 .map_or(&[][..], |indices| &indices[..])
71 .iter()
72 .map(|&index| &self.registrations[index])
73 }
74}
75
76pub(crate) fn index_by_key(registrations: &[Registration]) -> KeyMap<Box<[usize]>> {
78 let mut grouped: KeyMap<Vec<usize>> = KeyMap::default();
79 for (index, registration) in registrations.iter().enumerate() {
80 grouped.entry(registration.key).or_default().push(index);
81 }
82 grouped
83 .into_iter()
84 .map(|(key, indices)| (key, indices.into_boxed_slice()))
85 .collect()
86}
87
88pub(crate) struct Slots {
94 slots: Box<[Slot]>,
95 newest: AtomicUsize,
96}
97
98struct Slot {
99 value: OnceLock<Erased>,
100 previous: AtomicUsize,
101}
102
103const NONE: usize = usize::MAX;
104
105impl Slots {
106 pub(crate) fn new(len: usize) -> Self {
107 Self {
108 slots: (0..len)
109 .map(|_| Slot {
110 value: OnceLock::new(),
111 previous: AtomicUsize::new(NONE),
112 })
113 .collect(),
114 newest: AtomicUsize::new(NONE),
115 }
116 }
117
118 pub(crate) fn get(&self, index: usize) -> Option<Erased> {
119 self.slots
120 .get(index)
121 .and_then(|slot| slot.value.get())
122 .map(Arc::clone)
123 }
124
125 pub(crate) fn fill(&self, index: usize, instance: Erased) {
128 if let Some(slot) = self.slots.get(index) {
129 if slot.value.set(instance).is_ok() {
130 let previous = self.newest.swap(index, Ordering::Relaxed);
131 slot.previous.store(previous, Ordering::Relaxed);
132 }
133 }
134 }
135
136 fn release(&mut self) {
137 let mut next = self.newest.swap(NONE, Ordering::Relaxed);
138 while let Some(slot) = self.slots.get_mut(next) {
139 next = *slot.previous.get_mut();
140 drop(slot.value.take());
141 }
142 }
143}
144
145impl Drop for Slots {
146 fn drop(&mut self) {
147 self.release();
148 }
149}
150
151impl Drop for Container {
152 fn drop(&mut self) {
153 self.singletons.release();
154 let registrations = std::mem::take(&mut self.registrations).into_vec();
157 registrations.into_iter().rev().for_each(drop);
158 }
159}
160
161#[derive(Clone)]
163pub struct ServiceProvider {
164 container: Arc<Container>,
165}
166
167impl ServiceProvider {
168 pub(crate) fn new(container: Container) -> Self {
169 Self {
170 container: Arc::new(container),
171 }
172 }
173
174 pub fn resolve<T: ?Sized + Send + Sync + 'static>(&self) -> Result<Arc<T>, ResolveError> {
179 Resolver::root(&self.container).resolve()
180 }
181
182 pub fn resolve_all<T: ?Sized + Send + Sync + 'static>(
184 &self,
185 ) -> Result<Vec<Arc<T>>, ResolveError> {
186 Resolver::root(&self.container).resolve_all()
187 }
188
189 pub fn create_scope(&self) -> Scope {
191 Scope::new(Arc::clone(&self.container))
192 }
193}
194
195impl fmt::Debug for ServiceProvider {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 f.debug_struct("ServiceProvider")
198 .field("registrations", &self.container.registrations)
199 .finish_non_exhaustive()
200 }
201}
202
203#[cfg(test)]
204mod tests {
205 use super::*;
206 use crate::{Dependency, Service, ServiceCollection};
207
208 struct Leaf;
209
210 impl Service for Leaf {
211 fn dependencies() -> Vec<Dependency> {
212 Vec::new()
213 }
214
215 fn construct(_: &Resolver<'_>) -> Result<Self, ResolveError> {
216 Ok(Leaf)
217 }
218 }
219
220 struct Config;
221
222 #[test]
223 fn every_registration_gets_storage() {
224 let mut services = ServiceCollection::new();
225 services
226 .add_scoped::<Leaf>()
227 .add_scoped::<Leaf>()
228 .add_singleton_instance(Config)
229 .add_singleton_with(|_| Ok(Config));
230 let provider = services.build().unwrap();
231 let container = &provider.container;
232
233 assert_eq!(container.scoped_count, 2);
234 assert_eq!(container.singletons.slots.len(), 2);
235 assert_eq!(container.singletons.newest.load(Ordering::Relaxed), 0);
236 }
237}