Skip to main content

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<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; // Copy
105        let id3 = id1; // Copy (Clone not needed for Copy types)
106
107        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        // Test minimum value
166        let min_id = TaskIdentifier::new(TaskIdentifier::MINIMUM);
167        assert_eq!(min_id.into_inner(), TaskIdentifier::MINIMUM);
168
169        // Test maximum value
170        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        // Test that the constructor can be used in const context
177        const ID: TaskIdentifier = TaskIdentifier::new(100);
178        assert_eq!(ID.into_inner(), 100);
179    }
180
181    #[test]
182    fn test_const_into_inner() {
183        // Test that into_inner can be used in const context
184        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        // Test that the size is the same as the inner type (due to #[repr(transparent)])
192        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        // This test verifies the conditional compilation works correctly
201        #[cfg(target_pointer_width = "32")]
202        {
203            assert_eq!(std::mem::size_of::<Task_identifier_inner_type>(), 2); // u16
204        }
205
206        #[cfg(target_pointer_width = "64")]
207        {
208            assert_eq!(std::mem::size_of::<TaskIdentifierInner>(), 4); // u32
209        }
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}