1use std::num::NonZeroU32;
2use std::num::NonZeroU64;
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5#[repr(C)]
6pub struct SlotId {
7 id_raw: NonZeroU64,
8}
9
10#[derive(Clone, Copy, Debug, PartialEq, Eq)]
11#[repr(transparent)]
12pub struct SlotGen(NonZeroU32);
13
14impl SlotGen {
15 pub const MIN: Self = Self(NonZeroU32::MIN);
16
17 #[must_use]
18 pub const fn new(raw: u32) -> Option<Self> {
19 match NonZeroU32::new(raw) {
20 Some(raw) => Some(Self(raw)),
21 None => None,
22 }
23 }
24
25 pub const fn get(self) -> u32 {
26 self.0.get()
27 }
28
29 #[must_use]
30 pub const fn checked_add(self, other: u32) -> Option<Self> {
31 match self.0.checked_add(other) {
32 Some(raw) => Some(Self(raw)),
33 None => None,
34 }
35 }
36}
37
38impl SlotId {
39 #[must_use]
40 pub const fn from_parts(slot: u32, generation: SlotGen) -> Self {
41 let raw = ((generation.get() as u64) << 32) | (slot as u64);
42 Self {
45 id_raw: unsafe { NonZeroU64::new_unchecked(raw) },
46 }
47 }
48
49 pub const fn slot(self) -> u32 {
50 self.id_raw.get() as u32
51 }
52
53 pub const fn generation(self) -> SlotGen {
54 SlotGen(unsafe { NonZeroU32::new_unchecked((self.id_raw.get() >> 32) as u32) })
56 }
57}