1#[cfg(not(feature = "std"))]
2extern crate alloc;
3
4#[cfg(feature = "std")]
5extern crate core;
6
7#[cfg(not(feature = "std"))]
8use alloc::vec::Vec;
9
10use crate::{
11 base_registry::{
12 BaseRegistry,
13 BaseRegistryEntry,
14 },
15 BorrowError,
16 ElementRef,
17 ElementRefMut,
18};
19
20pub type Handle = usize;
25
26#[derive(Default)]
39pub struct Registry<T> {
40 base: BaseRegistry<usize, T, Vec<BaseRegistryEntry<T>>>,
41}
42
43impl<T> Registry<T> {
44 pub fn new() -> Self {
46 Self {
47 base: BaseRegistry::new(),
48 }
49 }
50
51 pub fn with_capacity(size: usize) -> Self {
53 Self {
54 base: BaseRegistry::with_capacity(size),
55 }
56 }
57
58 pub fn is_empty(&self) -> bool {
60 self.base.is_empty()
61 }
62
63 pub fn len(&self) -> usize {
65 self.base.len()
66 }
67
68 pub fn register(&self, value: T) -> Handle {
70 let handle = self.base.len();
71 let (data, borrow_state) = self.base.insert(value);
72 self.base
73 .entries_mut()
74 .push(BaseRegistryEntry::new(data, borrow_state));
75 handle
76 }
77
78 pub fn register_extend<I>(&self, iterable: I) -> (Handle, Handle)
83 where
84 I: IntoIterator<Item = T>,
85 {
86 let data = self.base.insert_extend(iterable);
87 let first = self.base.entries().len();
88 self.base.entries_mut().extend(
89 data.into_iter()
90 .map(|data| BaseRegistryEntry::new(data.0, data.1)),
91 );
92 let next = self.base.len();
93 (first, next)
94 }
95
96 pub fn reserve(&self, additional: usize) {
98 self.base.reserve(additional)
99 }
100
101 pub fn into_vec(self) -> Vec<T> {
105 self.base.into_vec()
106 }
107
108 pub fn iter(&self) -> impl Iterator<Item = Result<ElementRef<T>, BorrowError>> {
111 self.base.entries().iter().map(|entry| entry.borrow())
112 }
113
114 pub fn iter_mut(&mut self) -> impl Iterator<Item = Result<ElementRefMut<T>, BorrowError>> {
117 self.base
118 .entries_mut()
119 .iter_mut()
120 .map(|entry| entry.borrow_mut())
121 }
122
123 pub fn get_unchecked(&self, handle: Handle) -> ElementRef<T> {
127 self.base.borrow(&handle)
128 }
129
130 pub fn get(&self, handle: Handle) -> Result<ElementRef<T>, BorrowError> {
132 self.base.try_borrow(&handle)
133 }
134
135 pub fn get_mut_unchecked(&self, handle: Handle) -> ElementRefMut<T> {
139 self.base.borrow_mut(&handle)
140 }
141
142 pub fn get_mut(&self, handle: Handle) -> Result<ElementRefMut<T>, BorrowError> {
144 self.base.try_borrow_mut(&handle)
145 }
146
147 pub fn safe_to_drop(&mut self) -> bool {
151 self.base.safe_to_drop()
152 }
153}
154
155#[cfg(test)]
156mod registry_test {
157 #[cfg(not(feature = "std"))]
158 extern crate alloc;
159
160 #[cfg(not(feature = "std"))]
161 use alloc::{
162 vec,
163 vec::Vec,
164 };
165 use core::{
166 cell::Cell,
167 mem,
168 };
169
170 use crate::{
171 BorrowError,
172 ElementRef,
173 ElementRefMut,
174 Handle,
175 Registry,
176 };
177
178 struct DropCounter<'c>(&'c Cell<u32>);
180
181 impl<'c> Drop for DropCounter<'c> {
182 fn drop(&mut self) {
183 self.0.set(self.0.get() + 1);
184 }
185 }
186
187 struct Node<'d, T> {
191 parent: Option<Handle>,
192 value: T,
193 #[allow(dead_code)]
194 drop_counter: DropCounter<'d>,
195 }
196
197 impl<'a, 'd, T> Node<'d, T> {
198 pub fn new(parent: Option<Handle>, value: T, drop_counter: DropCounter<'d>) -> Self {
199 Self {
200 parent,
201 value,
202 drop_counter,
203 }
204 }
205 }
206
207 #[test]
208 #[allow(dropping_references)]
209 fn allocates_and_owns_values() {
210 let drop_counter = Cell::new(0);
211 {
212 let registry = Registry::with_capacity(2);
213 assert!(registry.is_empty());
214
215 let mut handle = registry.register(Node::new(None, 1, DropCounter(&drop_counter)));
217 assert_eq!(registry.len(), 1);
218 assert!(!registry.is_empty());
219 handle = registry.register(Node::new(Some(handle), 2, DropCounter(&drop_counter)));
220 assert_eq!(registry.len(), 2);
221 handle = registry.register(Node::new(Some(handle), 3, DropCounter(&drop_counter)));
222 assert_eq!(registry.len(), 3);
223 handle = registry.register(Node::new(Some(handle), 4, DropCounter(&drop_counter)));
224 assert_eq!(registry.len(), 4);
225
226 let node = registry.get(handle).unwrap();
227 assert_eq!(node.value, 4);
228 let node = registry.get(node.parent.unwrap()).unwrap();
229 assert_eq!(node.value, 3);
230 let node = registry.get(node.parent.unwrap()).unwrap();
231 assert_eq!(node.value, 2);
232 let node = registry.get(node.parent.unwrap()).unwrap();
233 assert_eq!(node.value, 1);
234 assert_eq!(node.parent, None);
235 assert_eq!(drop_counter.get(), 0);
236 }
237 assert_eq!(drop_counter.get(), 4);
239 }
240
241 #[test]
242 fn register_extend_allocates_and_returns_handle_range() {
243 let registry = Registry::new();
244 let mut next_handle = 0;
245 for i in 0..15 {
246 let (begin, end) = registry.register_extend(0..i);
247 assert_eq!(begin, next_handle);
248 assert_eq!(end - begin, i);
249 for (j, handle) in (0..i).zip(begin..end) {
250 assert!(registry.get_unchecked(handle).eq(&j));
251 }
252 next_handle = end;
253 }
254 }
255
256 #[test]
257 fn register_extend_allocates_and_owns_values() {
258 let drop_counter = Cell::new(0);
259 {
260 let registry = Registry::with_capacity(2);
261 let iter = (0..100).map(|i| Node::new(None, i, DropCounter(&drop_counter)));
262 let root = registry.register_extend(iter).0;
263 let iter = (0..100).map(|i| Node::new(Some(root), i, DropCounter(&drop_counter)));
264 registry.register_extend(iter);
265 assert_eq!(drop_counter.get(), 0);
266 }
267 assert_eq!(drop_counter.get(), 200);
268 }
269
270 #[test]
271 fn into_vec_reflects_insertion_order() {
272 let registry = Registry::new();
273 for &s in &["a", "b", "c", "d"] {
274 registry.register(s);
275 }
276 let vec = registry.into_vec();
277 assert_eq!(vec, vec!["a", "b", "c", "d"])
278 }
279
280 #[test]
281 fn iter_itereates_in_order() {
282 #[derive(Debug, PartialEq, Eq)]
283 struct NoCopy(usize);
284
285 let registry = Registry::new();
286 for i in 0..10 {
287 registry.register(NoCopy(i));
288 }
289 assert!(registry
290 .iter()
291 .zip((0..10).map(|i| NoCopy(i)))
292 .all(|(a, b)| a.is_ok_and(|a| a.eq(&b))));
293 }
294
295 #[test]
296 fn iter_mut_itereates_in_order() {
297 #[derive(Debug, PartialEq, Eq)]
298 struct NoCopy(usize);
299
300 let mut registry = Registry::new();
301 for i in 0..10 {
302 registry.register(NoCopy(i));
303 }
304 assert!(registry
305 .iter_mut()
306 .zip((0..10).map(|i| NoCopy(i)))
307 .all(|(a, b)| a.is_ok_and(|a| a.eq(&b))));
308 }
309
310 #[test]
311 fn iter_mut_allows_mutable_access() {
312 let mut registry = Registry::new();
313 for i in 0..10 {
314 registry.register(i);
315 }
316 for i in registry.iter_mut() {
317 assert!(i.is_ok());
318 *i.unwrap() += 1;
319 }
320 assert!(registry
321 .iter_mut()
322 .zip(1..11)
323 .all(|(a, b)| a.is_ok_and(|a| a.eq(&b))));
324 }
325
326 #[test]
327 fn handles_valid_with_large_blocks() {
328 let registry = Registry::with_capacity(2);
329 let first_range = registry.register_extend(0..1);
331 let second_range = registry.register_extend(0..100);
332 registry.reserve(1000);
334 let third_range = registry.register_extend(0..500);
336 let fourth_range = registry.register_extend(501..1000);
337
338 assert!((first_range.0..first_range.1)
340 .zip(0..1)
341 .all(|(handle, value)| *registry.get_unchecked(handle) == value));
342 assert!((second_range.0..second_range.1)
343 .zip(0..100)
344 .all(|(handle, value)| *registry.get_unchecked(handle) == value));
345 assert!((third_range.0..third_range.1)
346 .zip(0..500)
347 .all(|(handle, value)| *registry.get_unchecked(handle) == value));
348 assert!((fourth_range.0..fourth_range.1)
349 .zip(501..1000)
350 .all(|(handle, value)| *registry.get_unchecked(handle) == value));
351 }
352
353 #[test]
354 fn tracks_length() {
355 let registry = Registry::with_capacity(16);
356 registry.register_extend(0..4);
357 assert_eq!(registry.len(), 4);
358 registry.register(5);
359 assert_eq!(registry.len(), 5);
360 registry.register(6);
361 assert_eq!(registry.len(), 6);
362 registry.register_extend(0..100);
363 assert_eq!(registry.len(), 106);
364 }
365
366 #[test]
367 fn borrow_out_of_bounds() {
368 let registry = Registry::new();
369 registry.register_extend(0..4);
370 assert_eq!(registry.get(5).err(), Some(BorrowError::OutOfBounds));
371 assert_eq!(registry.get_mut(6).err(), Some(BorrowError::OutOfBounds));
372 }
373
374 #[test]
375 fn counts_immutable_borrws() {
376 let registry = Registry::new();
377 registry.register_extend(1..5);
378 {
379 let borrow_1 = registry.get(1);
380 let borrow_2 = registry.get(1);
381 let borrow_3 = registry.get(1);
382 assert!(borrow_1.as_ref().is_ok_and(|val| val.eq(&2)));
383 assert!(borrow_2.as_ref().is_ok_and(|val| val.eq(&2)));
384 drop(borrow_1);
385 drop(borrow_2);
386 assert_eq!(
387 registry.get_mut(1).err(),
388 Some(BorrowError::AlreadyBorrowed)
389 );
390 assert!(borrow_3.is_ok_and(|val| val.eq(&2)));
391 }
392 assert!(registry.get_mut(1).is_ok_and(|val| val.eq(&2)));
393 }
394
395 #[test]
396 fn only_one_mutable_borrow() {
397 let registry = Registry::new();
398 registry.register_extend(1..5);
399 let mut borrow_1 = registry.get_mut(2);
400 assert!(borrow_1.as_ref().is_ok_and(|val| val.eq(&3)));
401 assert_eq!(
402 registry.get_mut(2).err(),
403 Some(BorrowError::AlreadyBorrowed)
404 );
405 *borrow_1.as_deref_mut().unwrap() *= 2;
406 drop(borrow_1);
407 let borrow_2 = registry.get_mut(2);
408 assert!(borrow_2.as_ref().is_ok_and(|val| val.eq(&6)));
409 }
410
411 #[test]
412 fn borrows_do_not_interfere() {
413 let registry = Registry::new();
414 registry.register_extend(1..5);
415 let borrow_0_1 = registry.get(0);
416 let borrow_1_1 = registry.get_mut(1);
417 let borrow_2_1 = registry.get(2);
418 let borrow_2_2 = registry.get(2);
419 let borrow_3_1 = registry.get_mut(3);
420 assert!(borrow_0_1.as_ref().is_ok_and(|val| val.eq(&1)));
421 assert!(borrow_1_1.as_ref().is_ok_and(|val| val.eq(&2)));
422 assert!(borrow_2_1.as_ref().is_ok_and(|val| val.eq(&3)));
423 assert!(borrow_2_2.as_ref().is_ok_and(|val| val.eq(&3)));
424 assert!(borrow_3_1.as_ref().is_ok_and(|val| val.eq(&4)));
425 }
426
427 #[test]
428 fn immutable_borrow_can_be_cloned() {
429 let registry = Registry::new();
430 registry.register_extend(1..5);
431 let borrow_1 = registry.get_unchecked(0);
432 let borrow_2 = borrow_1.clone();
433 assert!(borrow_1.eq(&1));
434 assert!(borrow_2.eq(&1));
435 drop(borrow_1);
436 assert_eq!(
437 registry.get_mut(0).err(),
438 Some(BorrowError::AlreadyBorrowed)
439 );
440 drop(borrow_2);
441 assert!(registry.get_mut(0).is_ok_and(|val| val.eq(&1)));
442 }
443
444 #[test]
445 fn can_register_with_borrows_out() {
446 let registry = Registry::with_capacity(16);
447 registry.register_extend(1..5);
448 let borrow_1 = registry.get(0);
449 let borrow_2 = registry.get_mut(1);
450 registry.register_extend(5..100);
451 let borrow_3 = registry.get(4);
452 let borrow_4 = registry.get(97);
453 assert!(borrow_1.is_ok_and(|a| a.eq(&1)));
454 assert!(borrow_2.is_ok_and(|a| a.eq(&2)));
455 assert!(borrow_3.is_ok_and(|a| a.eq(&5)));
456 assert!(borrow_4.is_ok_and(|a| a.eq(&98)));
457 }
458
459 #[test]
460 fn borrow_in_iterator_succeeds_with_borrow_out() {
461 let registry = Registry::new();
462 registry.register_extend(1..5);
463 let borrow = registry.get(2);
464 assert_eq!(
465 registry
466 .iter()
467 .map(|result| result.err())
468 .collect::<Vec<Option<BorrowError>>>(),
469 vec![None, None, None, None]
470 );
471 drop(borrow);
472 }
473
474 #[test]
475 fn borrow_in_iterator_fails_with_mutable_borrow_out() {
476 let registry = Registry::new();
477 registry.register_extend(1..5);
478 let borrow = registry.get_mut(2);
479 assert_eq!(
480 registry
481 .iter()
482 .map(|result| result.err())
483 .collect::<Vec<Option<BorrowError>>>(),
484 vec![None, None, Some(BorrowError::AlreadyBorrowed), None]
485 );
486 drop(borrow);
487 }
488
489 #[test]
490 fn safe_to_drop_tracks_borrows() {
491 let mut registry = Registry::new();
492 registry.register_extend(1..5);
493 assert!(registry.safe_to_drop());
494
495 let borrow_1: ElementRef<'_, i32> = unsafe { mem::transmute(registry.get(0)) };
496 let borrow_2: ElementRef<'_, i32> = unsafe { mem::transmute(registry.get(0)) };
497 let borrow_3: ElementRefMut<'_, i32> = unsafe { mem::transmute(registry.get_mut(1)) };
498 assert!(!registry.safe_to_drop());
499
500 assert!(borrow_1.eq(&1));
501 assert!(borrow_2.eq(&1));
502 assert!(borrow_3.eq(&2));
503
504 drop(borrow_1);
505 assert!(!registry.safe_to_drop());
506 drop(borrow_2);
507 assert!(!registry.safe_to_drop());
508 drop(borrow_3);
509 assert!(registry.safe_to_drop());
510 }
511}