1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
12#[repr(C)]
13pub struct Handle {
14 pub id: u32,
16 pub generation: u32,
19}
20
21impl Handle {
22 #[inline]
24 #[must_use]
25 pub const fn new(id: u32, generation: u32) -> Self {
26 Self { id, generation }
27 }
28
29 #[inline]
31 #[must_use]
32 pub const fn null() -> Self {
33 Self {
34 id: u32::MAX,
35 generation: 0,
36 }
37 }
38
39 #[inline]
41 #[must_use]
42 pub const fn is_null(&self) -> bool {
43 self.id == u32::MAX
44 }
45
46 #[inline]
48 #[must_use]
49 pub const fn to_raw(&self) -> u64 {
50 ((self.generation as u64) << 32) | (self.id as u64)
51 }
52
53 #[inline]
55 #[must_use]
56 pub const fn from_raw(raw: u64) -> Self {
57 Self {
58 id: raw as u32,
59 generation: (raw >> 32) as u32,
60 }
61 }
62}
63
64impl Default for Handle {
65 fn default() -> Self {
66 Self::null()
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_handle_new() {
76 let h = Handle::new(42, 7);
77 assert_eq!(h.id, 42);
78 assert_eq!(h.generation, 7);
79 }
80
81 #[test]
82 fn test_handle_null() {
83 let h = Handle::null();
84 assert!(h.is_null());
85 }
86
87 #[test]
88 fn test_handle_roundtrip() {
89 let h = Handle::new(12345, 67890);
90 let raw = h.to_raw();
91 let h2 = Handle::from_raw(raw);
92 assert_eq!(h, h2);
93 }
94}