1use int_enum::IntEnum;
7use serde_repr::*;
8use strum_macros::EnumIter;
9use strum_macros::EnumString;
10
11#[allow(non_camel_case_types)]
13#[derive(
14 Serialize_repr,
15 Deserialize_repr,
16 Clone,
17 Copy,
18 Debug,
19 Default,
20 Eq,
21 PartialEq,
22 EnumIter,
23 EnumString,
24 IntEnum,
25 strum_macros::Display,
26)]
27#[repr(u8)]
28pub enum SystemdUnitActiveState {
29 #[default]
30 unknown = 0,
31 active = 1,
32 reloading = 2,
33 inactive = 3,
34 failed = 4,
35 activating = 5,
36 deactivating = 6,
37}
38
39#[allow(non_camel_case_types)]
41#[derive(
42 Serialize_repr,
43 Deserialize_repr,
44 Clone,
45 Copy,
46 Debug,
47 Default,
48 Eq,
49 PartialEq,
50 EnumIter,
51 EnumString,
52 IntEnum,
53 strum_macros::Display,
54)]
55#[repr(u8)]
56pub enum SystemdUnitLoadState {
57 #[default]
58 unknown = 0,
59 loaded = 1,
60 error = 2,
61 masked = 3,
62 not_found = 4,
63}
64
65pub fn is_unit_unhealthy(
69 active_state: SystemdUnitActiveState,
70 load_state: SystemdUnitLoadState,
71) -> bool {
72 match load_state {
73 SystemdUnitLoadState::loaded => !matches!(active_state, SystemdUnitActiveState::active),
75 SystemdUnitLoadState::masked => false,
78 _ => true,
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86 use std::str::FromStr;
87 use strum::IntoEnumIterator;
88
89 #[test]
90 fn test_is_unit_unhealthy() {
91 assert!(!is_unit_unhealthy(
93 SystemdUnitActiveState::active,
94 SystemdUnitLoadState::loaded
95 ));
96 assert!(is_unit_unhealthy(
98 SystemdUnitActiveState::activating,
99 SystemdUnitLoadState::loaded
100 ));
101 assert!(!is_unit_unhealthy(
103 SystemdUnitActiveState::activating,
104 SystemdUnitLoadState::masked
105 ));
106 assert!(is_unit_unhealthy(
108 SystemdUnitActiveState::deactivating,
109 SystemdUnitLoadState::not_found
110 ));
111 assert!(is_unit_unhealthy(
112 SystemdUnitActiveState::active,
114 SystemdUnitLoadState::error,
115 ));
116 }
117
118 #[test]
119 fn test_iterators() {
120 assert!(SystemdUnitActiveState::iter().collect::<Vec<_>>().len() > 0);
121 assert!(SystemdUnitLoadState::iter().collect::<Vec<_>>().len() > 0);
122 }
123
124 #[test]
125 fn test_active_state_from_str() {
126 assert_eq!(
127 SystemdUnitActiveState::from_str("active").unwrap(),
128 SystemdUnitActiveState::active
129 );
130 assert_eq!(
131 SystemdUnitActiveState::from_str("reloading").unwrap(),
132 SystemdUnitActiveState::reloading
133 );
134 assert_eq!(
135 SystemdUnitActiveState::from_str("inactive").unwrap(),
136 SystemdUnitActiveState::inactive
137 );
138 assert_eq!(
139 SystemdUnitActiveState::from_str("failed").unwrap(),
140 SystemdUnitActiveState::failed
141 );
142 assert_eq!(
143 SystemdUnitActiveState::from_str("activating").unwrap(),
144 SystemdUnitActiveState::activating
145 );
146 assert_eq!(
147 SystemdUnitActiveState::from_str("deactivating").unwrap(),
148 SystemdUnitActiveState::deactivating
149 );
150 assert_eq!(
151 SystemdUnitActiveState::from_str("unknown").unwrap(),
152 SystemdUnitActiveState::unknown
153 );
154 }
155
156 #[test]
157 fn test_active_state_from_str_invalid() {
158 assert!(SystemdUnitActiveState::from_str("invalid").is_err());
159 assert!(SystemdUnitActiveState::from_str("").is_err());
160 assert!(SystemdUnitActiveState::from_str("ACTIVE").is_err());
161 }
162
163 #[test]
164 fn test_load_state_from_str() {
165 assert_eq!(
166 SystemdUnitLoadState::from_str("loaded").unwrap(),
167 SystemdUnitLoadState::loaded
168 );
169 assert_eq!(
170 SystemdUnitLoadState::from_str("error").unwrap(),
171 SystemdUnitLoadState::error
172 );
173 assert_eq!(
174 SystemdUnitLoadState::from_str("masked").unwrap(),
175 SystemdUnitLoadState::masked
176 );
177 assert_eq!(
178 SystemdUnitLoadState::from_str("not_found").unwrap(),
179 SystemdUnitLoadState::not_found
180 );
181 assert_eq!(
182 SystemdUnitLoadState::from_str("unknown").unwrap(),
183 SystemdUnitLoadState::unknown
184 );
185 }
186
187 #[test]
188 fn test_load_state_from_str_invalid() {
189 assert!(SystemdUnitLoadState::from_str("invalid").is_err());
190 assert!(SystemdUnitLoadState::from_str("").is_err());
191 assert!(SystemdUnitLoadState::from_str("LOADED").is_err());
192 }
193
194 #[test]
195 fn test_active_state_display() {
196 assert_eq!(format!("{}", SystemdUnitActiveState::active), "active");
197 assert_eq!(
198 format!("{}", SystemdUnitActiveState::reloading),
199 "reloading"
200 );
201 assert_eq!(format!("{}", SystemdUnitActiveState::inactive), "inactive");
202 assert_eq!(format!("{}", SystemdUnitActiveState::failed), "failed");
203 assert_eq!(
204 format!("{}", SystemdUnitActiveState::activating),
205 "activating"
206 );
207 assert_eq!(
208 format!("{}", SystemdUnitActiveState::deactivating),
209 "deactivating"
210 );
211 assert_eq!(format!("{}", SystemdUnitActiveState::unknown), "unknown");
212 }
213
214 #[test]
215 fn test_load_state_display() {
216 assert_eq!(format!("{}", SystemdUnitLoadState::loaded), "loaded");
217 assert_eq!(format!("{}", SystemdUnitLoadState::error), "error");
218 assert_eq!(format!("{}", SystemdUnitLoadState::masked), "masked");
219 assert_eq!(format!("{}", SystemdUnitLoadState::not_found), "not_found");
220 assert_eq!(format!("{}", SystemdUnitLoadState::unknown), "unknown");
221 }
222
223 #[test]
224 fn test_active_state_default() {
225 let state: SystemdUnitActiveState = Default::default();
226 assert_eq!(state, SystemdUnitActiveState::unknown);
227 }
228
229 #[test]
230 fn test_load_state_default() {
231 let state: SystemdUnitLoadState = Default::default();
232 assert_eq!(state, SystemdUnitLoadState::unknown);
233 }
234
235 #[test]
236 fn test_active_state_clone() {
237 let state = SystemdUnitActiveState::active;
238 let cloned = state.clone();
239 assert_eq!(state, cloned);
240 }
241
242 #[test]
243 fn test_load_state_clone() {
244 let state = SystemdUnitLoadState::loaded;
245 let cloned = state.clone();
246 assert_eq!(state, cloned);
247 }
248
249 #[test]
250 fn test_active_state_debug() {
251 let state = SystemdUnitActiveState::active;
252 let debug_str = format!("{:?}", state);
253 assert!(debug_str.contains("active"));
254 }
255
256 #[test]
257 fn test_load_state_debug() {
258 let state = SystemdUnitLoadState::loaded;
259 let debug_str = format!("{:?}", state);
260 assert!(debug_str.contains("loaded"));
261 }
262
263 #[test]
264 fn test_active_state_equality() {
265 assert_eq!(
266 SystemdUnitActiveState::active,
267 SystemdUnitActiveState::active
268 );
269 assert_ne!(
270 SystemdUnitActiveState::active,
271 SystemdUnitActiveState::inactive
272 );
273 }
274
275 #[test]
276 fn test_load_state_equality() {
277 assert_eq!(SystemdUnitLoadState::loaded, SystemdUnitLoadState::loaded);
278 assert_ne!(SystemdUnitLoadState::loaded, SystemdUnitLoadState::masked);
279 }
280
281 #[test]
282 fn test_active_state_int_enum() {
283 assert_eq!(SystemdUnitActiveState::unknown as u8, 0);
284 assert_eq!(SystemdUnitActiveState::active as u8, 1);
285 assert_eq!(SystemdUnitActiveState::reloading as u8, 2);
286 assert_eq!(SystemdUnitActiveState::inactive as u8, 3);
287 assert_eq!(SystemdUnitActiveState::failed as u8, 4);
288 assert_eq!(SystemdUnitActiveState::activating as u8, 5);
289 assert_eq!(SystemdUnitActiveState::deactivating as u8, 6);
290 }
291
292 #[test]
293 fn test_load_state_int_enum() {
294 assert_eq!(SystemdUnitLoadState::unknown as u8, 0);
295 assert_eq!(SystemdUnitLoadState::loaded as u8, 1);
296 assert_eq!(SystemdUnitLoadState::error as u8, 2);
297 assert_eq!(SystemdUnitLoadState::masked as u8, 3);
298 assert_eq!(SystemdUnitLoadState::not_found as u8, 4);
299 }
300
301 #[test]
302 fn test_active_state_from_int() {
303 assert_eq!(
304 SystemdUnitActiveState::try_from(0).unwrap(),
305 SystemdUnitActiveState::unknown
306 );
307 assert_eq!(
308 SystemdUnitActiveState::try_from(1).unwrap(),
309 SystemdUnitActiveState::active
310 );
311 assert_eq!(
312 SystemdUnitActiveState::try_from(2).unwrap(),
313 SystemdUnitActiveState::reloading
314 );
315 assert_eq!(
316 SystemdUnitActiveState::try_from(3).unwrap(),
317 SystemdUnitActiveState::inactive
318 );
319 assert_eq!(
320 SystemdUnitActiveState::try_from(4).unwrap(),
321 SystemdUnitActiveState::failed
322 );
323 assert_eq!(
324 SystemdUnitActiveState::try_from(5).unwrap(),
325 SystemdUnitActiveState::activating
326 );
327 assert_eq!(
328 SystemdUnitActiveState::try_from(6).unwrap(),
329 SystemdUnitActiveState::deactivating
330 );
331 }
332
333 #[test]
334 fn test_load_state_from_int() {
335 assert_eq!(
336 SystemdUnitLoadState::try_from(0).unwrap(),
337 SystemdUnitLoadState::unknown
338 );
339 assert_eq!(
340 SystemdUnitLoadState::try_from(1).unwrap(),
341 SystemdUnitLoadState::loaded
342 );
343 assert_eq!(
344 SystemdUnitLoadState::try_from(2).unwrap(),
345 SystemdUnitLoadState::error
346 );
347 assert_eq!(
348 SystemdUnitLoadState::try_from(3).unwrap(),
349 SystemdUnitLoadState::masked
350 );
351 assert_eq!(
352 SystemdUnitLoadState::try_from(4).unwrap(),
353 SystemdUnitLoadState::not_found
354 );
355 }
356
357 #[test]
358 fn test_active_state_from_int_invalid() {
359 assert!(SystemdUnitActiveState::try_from(255).is_err());
360 assert!(SystemdUnitActiveState::try_from(100).is_err());
361 }
362
363 #[test]
364 fn test_load_state_from_int_invalid() {
365 assert!(SystemdUnitLoadState::try_from(255).is_err());
366 assert!(SystemdUnitLoadState::try_from(100).is_err());
367 }
368
369 #[test]
370 fn test_is_unit_unhealthy_all_combinations() {
371 assert!(!is_unit_unhealthy(
373 SystemdUnitActiveState::active,
374 SystemdUnitLoadState::loaded
375 ));
376 assert!(is_unit_unhealthy(
377 SystemdUnitActiveState::reloading,
378 SystemdUnitLoadState::loaded
379 ));
380 assert!(is_unit_unhealthy(
381 SystemdUnitActiveState::inactive,
382 SystemdUnitLoadState::loaded
383 ));
384 assert!(is_unit_unhealthy(
385 SystemdUnitActiveState::failed,
386 SystemdUnitLoadState::loaded
387 ));
388 assert!(is_unit_unhealthy(
389 SystemdUnitActiveState::activating,
390 SystemdUnitLoadState::loaded
391 ));
392 assert!(is_unit_unhealthy(
393 SystemdUnitActiveState::deactivating,
394 SystemdUnitLoadState::loaded
395 ));
396 assert!(is_unit_unhealthy(
397 SystemdUnitActiveState::unknown,
398 SystemdUnitLoadState::loaded
399 ));
400
401 assert!(!is_unit_unhealthy(
403 SystemdUnitActiveState::active,
404 SystemdUnitLoadState::masked
405 ));
406 assert!(!is_unit_unhealthy(
407 SystemdUnitActiveState::reloading,
408 SystemdUnitLoadState::masked
409 ));
410 assert!(!is_unit_unhealthy(
411 SystemdUnitActiveState::inactive,
412 SystemdUnitLoadState::masked
413 ));
414 assert!(!is_unit_unhealthy(
415 SystemdUnitActiveState::failed,
416 SystemdUnitLoadState::masked
417 ));
418 assert!(!is_unit_unhealthy(
419 SystemdUnitActiveState::activating,
420 SystemdUnitLoadState::masked
421 ));
422 assert!(!is_unit_unhealthy(
423 SystemdUnitActiveState::deactivating,
424 SystemdUnitLoadState::masked
425 ));
426 assert!(!is_unit_unhealthy(
427 SystemdUnitActiveState::unknown,
428 SystemdUnitLoadState::masked
429 ));
430
431 assert!(is_unit_unhealthy(
433 SystemdUnitActiveState::active,
434 SystemdUnitLoadState::error
435 ));
436 assert!(is_unit_unhealthy(
437 SystemdUnitActiveState::reloading,
438 SystemdUnitLoadState::error
439 ));
440 assert!(is_unit_unhealthy(
441 SystemdUnitActiveState::inactive,
442 SystemdUnitLoadState::error
443 ));
444 assert!(is_unit_unhealthy(
445 SystemdUnitActiveState::failed,
446 SystemdUnitLoadState::error
447 ));
448 assert!(is_unit_unhealthy(
449 SystemdUnitActiveState::activating,
450 SystemdUnitLoadState::error
451 ));
452 assert!(is_unit_unhealthy(
453 SystemdUnitActiveState::deactivating,
454 SystemdUnitLoadState::error
455 ));
456 assert!(is_unit_unhealthy(
457 SystemdUnitActiveState::unknown,
458 SystemdUnitLoadState::error
459 ));
460
461 assert!(is_unit_unhealthy(
463 SystemdUnitActiveState::active,
464 SystemdUnitLoadState::not_found
465 ));
466 assert!(is_unit_unhealthy(
467 SystemdUnitActiveState::reloading,
468 SystemdUnitLoadState::not_found
469 ));
470 assert!(is_unit_unhealthy(
471 SystemdUnitActiveState::inactive,
472 SystemdUnitLoadState::not_found
473 ));
474 assert!(is_unit_unhealthy(
475 SystemdUnitActiveState::failed,
476 SystemdUnitLoadState::not_found
477 ));
478 assert!(is_unit_unhealthy(
479 SystemdUnitActiveState::activating,
480 SystemdUnitLoadState::not_found
481 ));
482 assert!(is_unit_unhealthy(
483 SystemdUnitActiveState::deactivating,
484 SystemdUnitLoadState::not_found
485 ));
486 assert!(is_unit_unhealthy(
487 SystemdUnitActiveState::unknown,
488 SystemdUnitLoadState::not_found
489 ));
490
491 assert!(is_unit_unhealthy(
493 SystemdUnitActiveState::active,
494 SystemdUnitLoadState::unknown
495 ));
496 assert!(is_unit_unhealthy(
497 SystemdUnitActiveState::reloading,
498 SystemdUnitLoadState::unknown
499 ));
500 assert!(is_unit_unhealthy(
501 SystemdUnitActiveState::inactive,
502 SystemdUnitLoadState::unknown
503 ));
504 assert!(is_unit_unhealthy(
505 SystemdUnitActiveState::failed,
506 SystemdUnitLoadState::unknown
507 ));
508 assert!(is_unit_unhealthy(
509 SystemdUnitActiveState::activating,
510 SystemdUnitLoadState::unknown
511 ));
512 assert!(is_unit_unhealthy(
513 SystemdUnitActiveState::deactivating,
514 SystemdUnitLoadState::unknown
515 ));
516 assert!(is_unit_unhealthy(
517 SystemdUnitActiveState::unknown,
518 SystemdUnitLoadState::unknown
519 ));
520 }
521
522 #[test]
523 fn test_active_state_serialization() {
524 let state = SystemdUnitActiveState::active;
525 let serialized = serde_json::to_string(&state).unwrap();
526 assert_eq!(serialized, "1");
527
528 let deserialized: SystemdUnitActiveState = serde_json::from_str(&serialized).unwrap();
529 assert_eq!(deserialized, state);
530 }
531
532 #[test]
533 fn test_load_state_serialization() {
534 let state = SystemdUnitLoadState::loaded;
535 let serialized = serde_json::to_string(&state).unwrap();
536 assert_eq!(serialized, "1");
537
538 let deserialized: SystemdUnitLoadState = serde_json::from_str(&serialized).unwrap();
539 assert_eq!(deserialized, state);
540 }
541
542 #[test]
543 fn test_active_state_all_variants_serialization() {
544 for state in SystemdUnitActiveState::iter() {
545 let serialized = serde_json::to_string(&state).unwrap();
546 let deserialized: SystemdUnitActiveState = serde_json::from_str(&serialized).unwrap();
547 assert_eq!(deserialized, state);
548 }
549 }
550
551 #[test]
552 fn test_load_state_all_variants_serialization() {
553 for state in SystemdUnitLoadState::iter() {
554 let serialized = serde_json::to_string(&state).unwrap();
555 let deserialized: SystemdUnitLoadState = serde_json::from_str(&serialized).unwrap();
556 assert_eq!(deserialized, state);
557 }
558 }
559}