1use core::ops::{Add, AddAssign};
2
3pub type UserIdentifierInner = u16;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
6#[repr(transparent)]
7pub struct UserIdentifier(UserIdentifierInner);
8
9impl UserIdentifier {
10 pub const ROOT: Self = Self::new(0);
11
12 pub const MINIMUM: Self = Self::new(1);
13 pub const MAXIMUM: Self = Self::new(UserIdentifierInner::MAX);
14
15 pub const fn new(identifier: UserIdentifierInner) -> Self {
16 Self(identifier)
17 }
18
19 pub const fn as_u16(self) -> UserIdentifierInner {
20 self.0
21 }
22}
23
24impl AddAssign<UserIdentifierInner> for UserIdentifier {
25 fn add_assign(&mut self, other: UserIdentifierInner) {
26 self.0 += other;
27 }
28}
29
30impl Add<UserIdentifierInner> for UserIdentifier {
31 type Output = Self;
32
33 fn add(self, other: UserIdentifierInner) -> Self {
34 Self::new(self.0 + other)
35 }
36}
37
38impl From<UserIdentifierInner> for UserIdentifier {
39 fn from(value: UserIdentifierInner) -> Self {
40 UserIdentifier::new(value)
41 }
42}
43impl From<UserIdentifier> for UserIdentifierInner {
44 fn from(value: UserIdentifier) -> Self {
45 value.as_u16()
46 }
47}
48
49pub type GroupIdentifierInner = u16;
50
51#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
52#[repr(transparent)]
53pub struct GroupIdentifier(GroupIdentifierInner);
54
55impl GroupIdentifier {
56 pub const ROOT: Self = Self::new(0);
57
58 pub const MINIMUM: Self = Self::new(1);
59 pub const MAXIMUM: Self = Self::new(GroupIdentifierInner::MAX);
60
61 pub const fn new(identifier: GroupIdentifierInner) -> Self {
62 Self(identifier)
63 }
64
65 pub const fn as_u16(self) -> GroupIdentifierInner {
66 self.0
67 }
68}
69
70impl From<GroupIdentifierInner> for GroupIdentifier {
71 fn from(value: GroupIdentifierInner) -> Self {
72 GroupIdentifier::new(value)
73 }
74}
75impl From<GroupIdentifier> for GroupIdentifierInner {
76 fn from(value: GroupIdentifier) -> Self {
77 value.as_u16()
78 }
79}
80
81impl AddAssign<GroupIdentifierInner> for GroupIdentifier {
82 fn add_assign(&mut self, other: GroupIdentifierInner) {
83 self.0 += other;
84 }
85}
86
87impl Add<GroupIdentifierInner> for GroupIdentifier {
88 type Output = Self;
89
90 fn add(self, other: GroupIdentifierInner) -> Self {
91 Self::new(self.0 + other)
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 use alloc::{collections::BTreeMap, format};
100
101 #[test]
102 fn test_user_identifier_constants() {
103 assert_eq!(UserIdentifier::ROOT.as_u16(), 0);
104 assert_eq!(UserIdentifier::MINIMUM.as_u16(), 1);
105 assert_eq!(UserIdentifier::MAXIMUM.as_u16(), u16::MAX);
106 }
107
108 #[test]
109 fn test_user_identifier_new() {
110 let id = UserIdentifier::new(42);
111 assert_eq!(id.as_u16(), 42);
112 }
113
114 #[test]
115 fn test_user_identifier_as_u16() {
116 let id = UserIdentifier::new(123);
117 assert_eq!(id.as_u16(), 123);
118 }
119
120 #[test]
121 fn test_user_identifier_add_assign() {
122 let mut id = UserIdentifier::new(10);
123 id += 5;
124 assert_eq!(id.as_u16(), 15);
125 }
126
127 #[test]
128 fn test_user_identifier_add() {
129 let id1 = UserIdentifier::new(10);
130 let id2 = id1 + 5;
131 assert_eq!(id1.as_u16(), 10); assert_eq!(id2.as_u16(), 15);
133 }
134
135 #[test]
136 fn test_user_identifier_from_u16() {
137 let id: UserIdentifier = 42u16.into();
138 assert_eq!(id.as_u16(), 42);
139 }
140
141 #[test]
142 fn test_user_identifier_to_u16() {
143 let id = UserIdentifier::new(42);
144 let value: u16 = id.into();
145 assert_eq!(value, 42);
146 }
147
148 #[test]
149 fn test_user_identifier_clone_copy() {
150 let id1 = UserIdentifier::new(42);
151 let id2 = id1; let id3 = id1; assert_eq!(id1.as_u16(), 42);
155 assert_eq!(id2.as_u16(), 42);
156 assert_eq!(id3.as_u16(), 42);
157 }
158
159 #[test]
160 fn test_user_identifier_equality() {
161 let id1 = UserIdentifier::new(42);
162 let id2 = UserIdentifier::new(42);
163 let id3 = UserIdentifier::new(43);
164
165 assert_eq!(id1, id2);
166 assert_ne!(id1, id3);
167 }
168
169 #[test]
170 fn test_user_identifier_ordering() {
171 let id1 = UserIdentifier::new(10);
172 let id2 = UserIdentifier::new(20);
173
174 assert!(id1 < id2);
175 assert!(id2 > id1);
176 assert!(id1 <= id2);
177 assert!(id2 >= id1);
178 assert!(id1 <= id1);
179 assert!(id1 >= id1);
180 }
181
182 #[test]
183 fn test_group_identifier_constants() {
184 assert_eq!(GroupIdentifier::ROOT.as_u16(), 0);
185 assert_eq!(GroupIdentifier::MINIMUM.as_u16(), 1);
186 assert_eq!(GroupIdentifier::MAXIMUM.as_u16(), u16::MAX);
187 }
188
189 #[test]
190 fn test_group_identifier_new() {
191 let id = GroupIdentifier::new(42);
192 assert_eq!(id.as_u16(), 42);
193 }
194
195 #[test]
196 fn test_group_identifier_as_u16() {
197 let id = GroupIdentifier::new(123);
198 assert_eq!(id.as_u16(), 123);
199 }
200
201 #[test]
202 fn test_group_identifier_add_assign() {
203 let mut id = GroupIdentifier::new(10);
204 id += 5;
205 assert_eq!(id.as_u16(), 15);
206 }
207
208 #[test]
209 fn test_group_identifier_add() {
210 let id1 = GroupIdentifier::new(10);
211 let id2 = id1 + 5;
212 assert_eq!(id1.as_u16(), 10); assert_eq!(id2.as_u16(), 15);
214 }
215
216 #[test]
217 fn test_group_identifier_from_u16() {
218 let id: GroupIdentifier = 42u16.into();
219 assert_eq!(id.as_u16(), 42);
220 }
221
222 #[test]
223 fn test_group_identifier_to_u16() {
224 let id = GroupIdentifier::new(42);
225 let value: u16 = id.into();
226 assert_eq!(value, 42);
227 }
228
229 #[test]
230 fn test_group_identifier_clone_copy() {
231 let id1 = GroupIdentifier::new(42);
232 let id2 = id1; let id3 = id1; assert_eq!(id1.as_u16(), 42);
236 assert_eq!(id2.as_u16(), 42);
237 assert_eq!(id3.as_u16(), 42);
238 }
239
240 #[test]
241 fn test_group_identifier_equality() {
242 let id1 = GroupIdentifier::new(42);
243 let id2 = GroupIdentifier::new(42);
244 let id3 = GroupIdentifier::new(43);
245
246 assert_eq!(id1, id2);
247 assert_ne!(id1, id3);
248 }
249
250 #[test]
251 fn test_group_identifier_ordering() {
252 let id1 = GroupIdentifier::new(10);
253 let id2 = GroupIdentifier::new(20);
254
255 assert!(id1 < id2);
256 assert!(id2 > id1);
257 assert!(id1 <= id2);
258 assert!(id2 >= id1);
259 assert!(id1 <= id1);
260 assert!(id1 >= id1);
261 }
262
263 #[test]
264 fn test_edge_cases_user_identifier() {
265 let min_id = UserIdentifier::new(0);
267 assert_eq!(min_id.as_u16(), 0);
268
269 let max_id = UserIdentifier::new(u16::MAX);
271 assert_eq!(max_id.as_u16(), u16::MAX);
272
273 let near_max = UserIdentifier::new(u16::MAX - 1);
275 let result = near_max + 1;
276 assert_eq!(result.as_u16(), u16::MAX);
277 }
278
279 #[test]
280 fn test_edge_cases_group_identifier() {
281 let min_id = GroupIdentifier::new(0);
283 assert_eq!(min_id.as_u16(), 0);
284
285 let max_id = GroupIdentifier::new(u16::MAX);
287 assert_eq!(max_id.as_u16(), u16::MAX);
288
289 let near_max = GroupIdentifier::new(u16::MAX - 1);
291 let result = near_max + 1;
292 assert_eq!(result.as_u16(), u16::MAX);
293 }
294
295 #[test]
296 fn test_hash_consistency() {
297 let mut user_map = BTreeMap::new();
298 let mut group_map = BTreeMap::new();
299
300 let user_id = UserIdentifier::new(42);
301 let group_id = GroupIdentifier::new(42);
302
303 user_map.insert(user_id, "test_user");
304 group_map.insert(group_id, "test_group");
305
306 assert_eq!(user_map.get(&user_id), Some(&"test_user"));
307 assert_eq!(group_map.get(&group_id), Some(&"test_group"));
308 }
309
310 #[test]
311 fn test_debug_format() {
312 let user_id = UserIdentifier::new(42);
313 let group_id = GroupIdentifier::new(42);
314
315 let user_debug = format!("{user_id:?}");
316 let group_debug = format!("{group_id:?}");
317
318 assert!(user_debug.contains("42"));
319 assert!(group_debug.contains("42"));
320 }
321}