sayiir_core/priority.rs
1//! Task priority levels for execution ordering.
2//!
3//! Priority determines the order in which tasks are picked up by workers.
4//! Lower numeric values indicate higher priority. The default is [`Normal`](Priority::Normal) (3).
5
6use serde::{Deserialize, Serialize};
7
8/// Execution priority for a task.
9///
10/// Lower numeric values are executed first. Workers use this value
11/// (combined with aging) to decide which available task to claim next.
12///
13/// # Examples
14///
15/// ```
16/// use sayiir_core::priority::Priority;
17///
18/// assert_eq!(Priority::default(), Priority::Normal);
19/// assert_eq!(Priority::Critical.as_u8(), 1);
20/// assert!(Priority::Critical < Priority::Low);
21/// ```
22#[repr(u8)]
23#[derive(
24 Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize,
25)]
26pub enum Priority {
27 /// Highest priority (1). Use sparingly for time-critical work.
28 Critical = 1,
29 /// High priority (2).
30 High = 2,
31 /// Default priority (3).
32 #[default]
33 Normal = 3,
34 /// Low priority (4). Background work.
35 Low = 4,
36 /// Lowest priority (5). Best-effort, may be starved without aging.
37 Minimal = 5,
38}
39
40impl Priority {
41 /// Convert a `u8` to a `Priority`, returning `None` for out-of-range values.
42 #[must_use]
43 pub fn from_u8(value: u8) -> Option<Self> {
44 match value {
45 1 => Some(Self::Critical),
46 2 => Some(Self::High),
47 3 => Some(Self::Normal),
48 4 => Some(Self::Low),
49 5 => Some(Self::Minimal),
50 _ => None,
51 }
52 }
53
54 /// Return the numeric value of this priority (1–5).
55 #[must_use]
56 pub fn as_u8(self) -> u8 {
57 self as u8
58 }
59}
60
61#[cfg(test)]
62#[allow(clippy::unwrap_used)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn default_is_normal() {
68 assert_eq!(Priority::default(), Priority::Normal);
69 assert_eq!(Priority::default().as_u8(), 3);
70 }
71
72 #[test]
73 fn round_trip() {
74 for v in 1..=5 {
75 let p = Priority::from_u8(v).unwrap();
76 assert_eq!(p.as_u8(), v);
77 }
78 }
79
80 #[test]
81 fn out_of_range() {
82 assert!(Priority::from_u8(0).is_none());
83 assert!(Priority::from_u8(6).is_none());
84 }
85
86 #[test]
87 fn ordering() {
88 assert!(Priority::Critical < Priority::High);
89 assert!(Priority::High < Priority::Normal);
90 assert!(Priority::Normal < Priority::Low);
91 assert!(Priority::Low < Priority::Minimal);
92 }
93}