1use std::num::NonZero;
2
3use crate::Error;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11pub struct Id(NonZero<u32>);
12
13impl std::fmt::Display for Id {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 write!(f, "{}", self.0.get())
16 }
17}
18
19pub(crate) struct NonZeroSlab<T>(slab::Slab<T>);
24
25impl<T> NonZeroSlab<T> {
26 pub fn insert(&mut self, value: T) -> Id {
27 let id = self.0.insert(value) + 1;
28 let id = u32::try_from(id).expect("u32 overflow");
29 Id(unsafe { NonZero::new_unchecked(id) })
30 }
31
32 pub fn get(&self, id: Id) -> Option<&T> {
33 let id = (id.0.get() - 1) as usize;
34 self.0.get(id)
35 }
36
37 pub fn get_mut(&mut self, id: Id) -> Option<&mut T> {
38 let id = (id.0.get() - 1) as usize;
39 self.0.get_mut(id)
40 }
41
42 pub fn remove(&mut self, id: Id) -> Option<T> {
43 let id = (id.0.get() - 1) as usize;
44 self.0.try_remove(id)
45 }
46}
47
48impl TryFrom<i32> for Id {
49 type Error = Error;
50
51 fn try_from(value: i32) -> Result<Self, Self::Error> {
52 Self::try_from(u32::try_from(value).map_err(|_| Error::InvalidId)?)
53 }
54}
55
56impl TryFrom<u32> for Id {
57 type Error = Error;
58
59 fn try_from(value: u32) -> Result<Self, Self::Error> {
60 NonZero::try_from(value).map(Id).map_err(|_| Error::InvalidId)
61 }
62}
63
64impl From<Id> for u32 {
65 fn from(value: Id) -> Self {
66 value.0.get()
67 }
68}
69
70impl TryFrom<Id> for i32 {
71 type Error = Error;
72
73 fn try_from(value: Id) -> Result<Self, Self::Error> {
74 i32::try_from(u32::from(value)).map_err(|_| Error::InvalidId)
75 }
76}
77
78impl<T> Default for NonZeroSlab<T> {
79 fn default() -> Self {
80 Self(slab::Slab::new())
81 }
82}