task/
task.rs

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<TaskIdentifierInner> for TaskIdentifier {
34    fn from(value: TaskIdentifierInner) -> Self {
35        Self(value)
36    }
37}
38
39impl From<TaskIdentifier> for TaskIdentifierInner {
40    fn from(value: TaskIdentifier) -> Self {
41        value.0
42    }
43}
44
45impl PartialEq<TaskIdentifierInner> for TaskIdentifier {
46    fn eq(&self, other: &TaskIdentifierInner) -> bool {
47        self.0 == *other
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use super::*;
54    use std::format;
55
56    #[test]
57    fn test_task_identifier_constants() {
58        assert_eq!(TaskIdentifier::MAXIMUM, TaskIdentifierInner::MAX);
59        assert_eq!(TaskIdentifier::MINIMUM, TaskIdentifierInner::MIN);
60    }
61
62    #[test]
63    fn test_task_identifier_new() {
64        let id = TaskIdentifier::new(42);
65        assert_eq!(id.into_inner(), 42);
66    }
67
68    #[test]
69    fn test_task_identifier_into_inner() {
70        let inner_value = 123;
71        let id = TaskIdentifier::new(inner_value);
72        assert_eq!(id.into_inner(), inner_value);
73    }
74
75    #[test]
76    fn test_task_identifier_from_inner_type() {
77        let inner_value = 456;
78        let id: TaskIdentifier = inner_value.into();
79        assert_eq!(id.into_inner(), inner_value);
80    }
81
82    #[test]
83    fn test_task_identifier_into_inner_type() {
84        let id = TaskIdentifier::new(789);
85        let inner_value: TaskIdentifierInner = id.into();
86        assert_eq!(inner_value, 789);
87    }
88
89    #[test]
90    fn test_task_identifier_clone_copy() {
91        let id1 = TaskIdentifier::new(42);
92        let id2 = id1; // Copy
93        let id3 = id1; // Copy (Clone not needed for Copy types)
94
95        assert_eq!(id1.into_inner(), 42);
96        assert_eq!(id2.into_inner(), 42);
97        assert_eq!(id3.into_inner(), 42);
98    }
99
100    #[test]
101    fn test_task_identifier_equality() {
102        let id1 = TaskIdentifier::new(42);
103        let id2 = TaskIdentifier::new(42);
104        let id3 = TaskIdentifier::new(43);
105
106        assert_eq!(id1, id2);
107        assert_ne!(id1, id3);
108    }
109
110    #[test]
111    fn test_task_identifier_equality_with_inner_type() {
112        let id = TaskIdentifier::new(42);
113        let inner_value = 42;
114        let different_value = 43;
115
116        assert_eq!(id, inner_value);
117        assert_ne!(id, different_value);
118    }
119
120    #[test]
121    fn test_task_identifier_ordering() {
122        let id1 = TaskIdentifier::new(10);
123        let id2 = TaskIdentifier::new(20);
124
125        assert!(id1 < id2);
126        assert!(id2 > id1);
127        assert!(id1 <= id2);
128        assert!(id2 >= id1);
129        assert!(id1 <= id1);
130        assert!(id1 >= id1);
131    }
132
133    #[test]
134    fn test_task_identifier_hash_consistency() {
135        use std::collections::HashMap;
136
137        let mut map = HashMap::new();
138        let id = TaskIdentifier::new(42);
139
140        map.insert(id, "test_task");
141        assert_eq!(map.get(&id), Some(&"test_task"));
142    }
143
144    #[test]
145    fn test_task_identifier_debug_format() {
146        let id = TaskIdentifier::new(42);
147        let debug_str = format!("{id:?}");
148        assert!(debug_str.contains("42"));
149    }
150
151    #[test]
152    fn test_edge_cases() {
153        // Test minimum value
154        let min_id = TaskIdentifier::new(TaskIdentifier::MINIMUM);
155        assert_eq!(min_id.into_inner(), TaskIdentifier::MINIMUM);
156
157        // Test maximum value
158        let max_id = TaskIdentifier::new(TaskIdentifier::MAXIMUM);
159        assert_eq!(max_id.into_inner(), TaskIdentifier::MAXIMUM);
160    }
161
162    #[test]
163    fn test_const_constructor() {
164        // Test that the constructor can be used in const context
165        const ID: TaskIdentifier = TaskIdentifier::new(100);
166        assert_eq!(ID.into_inner(), 100);
167    }
168
169    #[test]
170    fn test_const_into_inner() {
171        // Test that into_inner can be used in const context
172        const ID: TaskIdentifier = TaskIdentifier::new(200);
173        const INNER: TaskIdentifierInner = ID.into_inner();
174        assert_eq!(INNER, 200);
175    }
176
177    #[test]
178    fn test_repr_transparent() {
179        // Test that the size is the same as the inner type (due to #[repr(transparent)])
180        assert_eq!(
181            std::mem::size_of::<TaskIdentifier>(),
182            std::mem::size_of::<TaskIdentifierInner>()
183        );
184    }
185
186    #[test]
187    fn test_different_architectures() {
188        // This test verifies the conditional compilation works correctly
189        #[cfg(target_pointer_width = "32")]
190        {
191            assert_eq!(std::mem::size_of::<Task_identifier_inner_type>(), 2); // u16
192        }
193
194        #[cfg(target_pointer_width = "64")]
195        {
196            assert_eq!(std::mem::size_of::<TaskIdentifierInner>(), 4); // u32
197        }
198    }
199
200    #[test]
201    fn test_zero_value() {
202        let zero_id = TaskIdentifier::new(0);
203        assert_eq!(zero_id.into_inner(), 0);
204        assert_eq!(zero_id, 0);
205    }
206
207    #[test]
208    fn test_bidirectional_conversion() {
209        let original_value = 12345;
210        let id = TaskIdentifier::new(original_value);
211        let converted_back: TaskIdentifierInner = id.into();
212        let id_again: TaskIdentifier = converted_back.into();
213
214        assert_eq!(original_value, converted_back);
215        assert_eq!(id, id_again);
216    }
217}