task/
error.rs

1use core::{fmt, num::NonZeroU32};
2
3pub type Result<T> = core::result::Result<T, Error>;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6#[repr(u8)]
7pub enum Error {
8    InvalidTaskIdentifier = 1,
9    InvalidSpawnerIdentifier,
10    ThreadNotRegistered,
11    ThreadAlreadyRegistered,
12    FailedToCreateThread,
13    NoThreadForTask,
14    FailedToSpawnThread,
15    InvalidEnvironmentVariable,
16    TooManyTasks,
17    TooManySpawners,
18    AlreadyInitialized,
19    AlreadySet,
20    NotInitialized,
21    NoSpawnerAvailable,
22}
23
24impl fmt::Display for Error {
25    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
26        write!(f, "{self:?}")
27    }
28}
29
30impl core::error::Error for Error {}
31
32impl From<Error> for NonZeroU32 {
33    fn from(error: Error) -> Self {
34        unsafe { NonZeroU32::new_unchecked(error as u32) }
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::*;
41    use std::format;
42    use std::string::{String, ToString};
43    use std::vec;
44
45    #[test]
46    fn test_error_type_display() {
47        let error = Error::InvalidTaskIdentifier;
48        let display_string = format!("{error}");
49        assert_eq!(display_string, "InvalidTaskIdentifier");
50
51        let error = Error::TooManyTasks;
52        let display_string = format!("{error}");
53        assert_eq!(display_string, "TooManyTasks");
54    }
55
56    #[test]
57    fn test_error_type_debug() {
58        let error = Error::InvalidSpawnerIdentifier;
59        let debug_string = format!("{error:?}");
60        assert_eq!(debug_string, "InvalidSpawnerIdentifier");
61
62        let error = Error::ThreadNotRegistered;
63        let debug_string = format!("{error:?}");
64        assert_eq!(debug_string, "ThreadNotRegistered");
65    }
66
67    #[test]
68    fn test_error_type_clone() {
69        let error1 = Error::FailedToCreateThread;
70        let error2 = error1.clone();
71
72        assert_eq!(format!("{error1:?}"), format!("{:?}", error2));
73    }
74
75    #[test]
76    fn test_all_error_variants() {
77        let errors = vec![
78            Error::InvalidTaskIdentifier,
79            Error::InvalidSpawnerIdentifier,
80            Error::ThreadNotRegistered,
81            Error::ThreadAlreadyRegistered,
82            Error::FailedToCreateThread,
83            Error::NoThreadForTask,
84            Error::FailedToSpawnThread,
85            Error::InvalidEnvironmentVariable,
86            Error::TooManyTasks,
87            Error::TooManySpawners,
88            Error::AlreadyInitialized,
89            Error::AlreadySet,
90            Error::NotInitialized,
91            Error::NoSpawnerAvailable,
92        ];
93
94        // Test that all variants can be created and formatted
95        for error in errors {
96            let debug_str = format!("{error:?}");
97            let display_str = format!("{error}");
98
99            assert!(!debug_str.is_empty());
100            assert!(!display_str.is_empty());
101            assert_eq!(debug_str, display_str);
102        }
103    }
104
105    #[test]
106    fn test_error_to_nonzero_u32_conversion() {
107        let errors_and_expected_values = vec![
108            (Error::InvalidTaskIdentifier, 1u32),
109            (Error::InvalidSpawnerIdentifier, 2u32),
110            (Error::ThreadNotRegistered, 3u32),
111            (Error::ThreadAlreadyRegistered, 4u32),
112            (Error::FailedToCreateThread, 5u32),
113            (Error::NoThreadForTask, 6u32),
114            (Error::FailedToSpawnThread, 7u32),
115            (Error::InvalidEnvironmentVariable, 8u32),
116            (Error::TooManyTasks, 9u32),
117            (Error::TooManySpawners, 10u32),
118            (Error::AlreadyInitialized, 11u32),
119            (Error::AlreadySet, 12u32),
120            (Error::NotInitialized, 13u32),
121            (Error::NoSpawnerAvailable, 14u32),
122        ];
123
124        for (error, expected_value) in errors_and_expected_values {
125            let non_zero: NonZeroU32 = error.into();
126            assert_eq!(non_zero.get(), expected_value);
127        }
128    }
129
130    #[test]
131    fn test_result_type_ok() {
132        let result: Result<i32> = Ok(42);
133        assert!(result.is_ok());
134        if let Ok(value) = result {
135            assert_eq!(value, 42);
136        }
137    }
138
139    #[test]
140    fn test_result_type_err() {
141        let result: Result<i32> = Err(Error::InvalidTaskIdentifier);
142        assert!(result.is_err());
143
144        if let Err(error) = result {
145            assert_eq!(format!("{error:?}"), "InvalidTaskIdentifier");
146        }
147    }
148
149    #[test]
150    fn test_error_in_result_chain() {
151        fn might_fail(should_fail: bool) -> Result<String> {
152            if should_fail {
153                Err(Error::TooManyTasks)
154            } else {
155                Ok("Success".to_string())
156            }
157        }
158
159        let success_result = might_fail(false);
160        assert!(success_result.is_ok());
161        if let Ok(value) = success_result {
162            assert_eq!(value, "Success");
163        }
164
165        let failure_result = might_fail(true);
166        assert!(failure_result.is_err());
167
168        if let Err(error) = failure_result {
169            assert_eq!(format!("{error:?}"), "TooManyTasks");
170        }
171    }
172
173    #[test]
174    fn test_error_propagation() {
175        fn inner_function() -> Result<i32> {
176            Err(Error::NotInitialized)
177        }
178
179        fn outer_function() -> Result<String> {
180            let _value = inner_function()?;
181            Ok("This won't be reached".to_string())
182        }
183
184        let result = outer_function();
185        assert!(result.is_err());
186
187        if let Err(error) = result {
188            assert_eq!(format!("{error:?}"), "NotInitialized");
189        }
190    }
191
192    #[test]
193    fn test_error_size() {
194        // Ensure the error type has a reasonable size
195        assert!(std::mem::size_of::<Error>() <= 8);
196    }
197
198    #[test]
199    fn test_specific_error_scenarios() {
200        // Test environment variable error specifically
201        let env_error = Error::InvalidEnvironmentVariable;
202        let display_str = format!("{env_error}");
203        let non_zero: NonZeroU32 = env_error.into();
204        assert_eq!(non_zero.get(), 8u32);
205        assert_eq!(display_str, "InvalidEnvironmentVariable");
206
207        // Test task-related errors
208        let task_error = Error::InvalidTaskIdentifier;
209        assert_eq!(format!("{task_error}"), "InvalidTaskIdentifier");
210
211        let spawner_error = Error::InvalidSpawnerIdentifier;
212        assert_eq!(format!("{spawner_error}"), "InvalidSpawnerIdentifier");
213    }
214}