intid_allocator/
unique.rs1use crate::IdExhaustedError;
2use core::cell::Cell;
3use intid::{uint, IntegerIdCounter};
4
5#[cfg(feature = "atomic")]
6pub mod atomic;
7
8#[derive(Clone, Debug)]
15pub struct UniqueIdAllocator<T: IntegerIdCounter> {
16 next_id: Cell<Option<T>>,
17}
18impl<T: IntegerIdCounter> Default for UniqueIdAllocator<T> {
19 fn default() -> Self {
20 Self::new()
21 }
22}
23impl<T: IntegerIdCounter> UniqueIdAllocator<T> {
24 #[inline]
27 pub fn max_used_id(&self) -> Option<T> {
28 self.next_id
29 .get()
30 .and_then(|id| IntegerIdCounter::checked_sub(id, uint::one()))
31 }
32
33 #[inline]
38 pub const fn new() -> Self {
39 Self::with_start(T::START)
40 }
41
42 #[inline]
45 pub const fn with_start(start: T) -> Self {
46 UniqueIdAllocator {
47 next_id: Cell::new(Some(start)),
48 }
49 }
50
51 #[inline]
56 #[track_caller]
57 pub fn alloc(&self) -> T {
58 match self.try_alloc() {
59 Ok(id) => id,
60 Err(e) => e.panic(),
61 }
62 }
63
64 #[inline]
67 pub fn try_alloc(&self) -> Result<T, IdExhaustedError<T>> {
68 let old_id = self.next_id.get().ok_or_else(IdExhaustedError::new)?;
69 self.next_id
70 .set(IntegerIdCounter::checked_add(old_id, intid::uint::one()));
71 Ok(old_id)
72 }
73
74 #[inline]
77 pub fn reset(&mut self) {
78 self.next_id.set(Some(T::START))
79 }
80}