1use core::fmt::Display;
2
3#[cfg(target_pointer_width = "32")]
4pub type TaskIdentifierInner = u16;
5#[cfg(target_pointer_width = "64")]
6pub type TaskIdentifierInner = u32;
7
8#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq, PartialOrd, Ord)]
9#[repr(transparent)]
10pub struct TaskIdentifier(TaskIdentifierInner);
11
12impl TaskIdentifier {
13 pub const MAXIMUM: TaskIdentifierInner = TaskIdentifierInner::MAX;
14 pub const MINIMUM: TaskIdentifierInner = TaskIdentifierInner::MIN;
15}
16
17impl Display for TaskIdentifier {
18 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
19 write!(f, "{}", self.0)
20 }
21}
22
23impl TaskIdentifier {
24 pub const fn new(identifier: TaskIdentifierInner) -> Self {
25 Self(identifier)
26 }
27
28 pub const fn into_inner(self) -> TaskIdentifierInner {
29 self.0
30 }
31}
32
33impl From<usize> for TaskIdentifier {
34 fn from(value: usize) -> Self {
35 Self(value as TaskIdentifierInner)
36 }
37}
38
39impl From<TaskIdentifier> for usize {
40 fn from(value: TaskIdentifier) -> Self {
41 value.0 as usize
42 }
43}
44
45impl From<TaskIdentifierInner> for TaskIdentifier {
46 fn from(value: TaskIdentifierInner) -> Self {
47 Self(value)
48 }
49}
50
51impl From<TaskIdentifier> for TaskIdentifierInner {
52 fn from(value: TaskIdentifier) -> Self {
53 value.0
54 }
55}
56
57impl PartialEq<TaskIdentifierInner> for TaskIdentifier {
58 fn eq(&self, other: &TaskIdentifierInner) -> bool {
59 self.0 == *other
60 }
61}
62
63#[cfg(test)]
64mod tests {
65 use super::*;
66 use std::format;
67
68 #[test]
69 fn test_task_identifier_constants() {
70 assert_eq!(TaskIdentifier::MAXIMUM, TaskIdentifierInner::MAX);
71 assert_eq!(TaskIdentifier::MINIMUM, TaskIdentifierInner::MIN);
72 }
73
74 #[test]
75 fn test_task_identifier_new() {
76 let id = TaskIdentifier::new(42);
77 assert_eq!(id.into_inner(), 42);
78 }
79
80 #[test]
81 fn test_task_identifier_into_inner() {
82 let inner_value = 123;
83 let id = TaskIdentifier::new(inner_value);
84 assert_eq!(id.into_inner(), inner_value);
85 }
86
87 #[test]
88 fn test_task_identifier_from_inner_type() {
89 let inner_value = 456;
90 let id: TaskIdentifier = inner_value.into();
91 assert_eq!(id.into_inner(), inner_value);
92 }
93
94 #[test]
95 fn test_task_identifier_into_inner_type() {
96 let id = TaskIdentifier::new(789);
97 let inner_value: TaskIdentifierInner = id.into();
98 assert_eq!(inner_value, 789);
99 }
100
101 #[test]
102 fn test_task_identifier_clone_copy() {
103 let id1 = TaskIdentifier::new(42);
104 let id2 = id1; let id3 = id1; assert_eq!(id1.into_inner(), 42);
108 assert_eq!(id2.into_inner(), 42);
109 assert_eq!(id3.into_inner(), 42);
110 }
111
112 #[test]
113 fn test_task_identifier_equality() {
114 let id1 = TaskIdentifier::new(42);
115 let id2 = TaskIdentifier::new(42);
116 let id3 = TaskIdentifier::new(43);
117
118 assert_eq!(id1, id2);
119 assert_ne!(id1, id3);
120 }
121
122 #[test]
123 fn test_task_identifier_equality_with_inner_type() {
124 let id = TaskIdentifier::new(42);
125 let inner_value = 42;
126 let different_value = 43;
127
128 assert_eq!(id, inner_value);
129 assert_ne!(id, different_value);
130 }
131
132 #[test]
133 fn test_task_identifier_ordering() {
134 let id1 = TaskIdentifier::new(10);
135 let id2 = TaskIdentifier::new(20);
136
137 assert!(id1 < id2);
138 assert!(id2 > id1);
139 assert!(id1 <= id2);
140 assert!(id2 >= id1);
141 assert!(id1 <= id1);
142 assert!(id1 >= id1);
143 }
144
145 #[test]
146 fn test_task_identifier_hash_consistency() {
147 use std::collections::HashMap;
148
149 let mut map = HashMap::new();
150 let id = TaskIdentifier::new(42);
151
152 map.insert(id, "test_task");
153 assert_eq!(map.get(&id), Some(&"test_task"));
154 }
155
156 #[test]
157 fn test_task_identifier_debug_format() {
158 let id = TaskIdentifier::new(42);
159 let debug_str = format!("{id:?}");
160 assert!(debug_str.contains("42"));
161 }
162
163 #[test]
164 fn test_edge_cases() {
165 let min_id = TaskIdentifier::new(TaskIdentifier::MINIMUM);
167 assert_eq!(min_id.into_inner(), TaskIdentifier::MINIMUM);
168
169 let max_id = TaskIdentifier::new(TaskIdentifier::MAXIMUM);
171 assert_eq!(max_id.into_inner(), TaskIdentifier::MAXIMUM);
172 }
173
174 #[test]
175 fn test_const_constructor() {
176 const ID: TaskIdentifier = TaskIdentifier::new(100);
178 assert_eq!(ID.into_inner(), 100);
179 }
180
181 #[test]
182 fn test_const_into_inner() {
183 const ID: TaskIdentifier = TaskIdentifier::new(200);
185 const INNER: TaskIdentifierInner = ID.into_inner();
186 assert_eq!(INNER, 200);
187 }
188
189 #[test]
190 fn test_repr_transparent() {
191 assert_eq!(
193 std::mem::size_of::<TaskIdentifier>(),
194 std::mem::size_of::<TaskIdentifierInner>()
195 );
196 }
197
198 #[test]
199 fn test_different_architectures() {
200 #[cfg(target_pointer_width = "32")]
202 {
203 assert_eq!(std::mem::size_of::<Task_identifier_inner_type>(), 2); }
205
206 #[cfg(target_pointer_width = "64")]
207 {
208 assert_eq!(std::mem::size_of::<TaskIdentifierInner>(), 4); }
210 }
211
212 #[test]
213 fn test_zero_value() {
214 let zero_id = TaskIdentifier::new(0);
215 assert_eq!(zero_id.into_inner(), 0);
216 assert_eq!(zero_id, 0);
217 }
218
219 #[test]
220 fn test_bidirectional_conversion() {
221 let original_value = 12345;
222 let id = TaskIdentifier::new(original_value);
223 let converted_back: TaskIdentifierInner = id.into();
224 let id_again: TaskIdentifier = converted_back.into();
225
226 assert_eq!(original_value, converted_back);
227 assert_eq!(id, id_again);
228 }
229}