1#[cfg(feature = "schema")]
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
16#[cfg_attr(feature = "schema", derive(JsonSchema))]
17#[serde(rename_all = "snake_case")]
18pub enum Priority {
19 Critical,
21 High,
23 #[default]
25 Normal,
26 Low,
28}
29
30impl PartialOrd for Priority {
32 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
33 Some(self.cmp(other))
34 }
35}
36
37impl Ord for Priority {
38 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
39 self.weight().cmp(&other.weight())
40 }
41}
42
43impl Priority {
44 pub fn weight(&self) -> u8 {
46 match self {
47 Priority::Critical => 4,
48 Priority::High => 3,
49 Priority::Normal => 2,
50 Priority::Low => 1,
51 }
52 }
53
54 pub fn label(&self) -> &'static str {
56 match self {
57 Priority::Critical => "CRITICAL",
58 Priority::High => "HIGH",
59 Priority::Normal => "NORMAL",
60 Priority::Low => "LOW",
61 }
62 }
63}
64
65#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
70#[cfg_attr(feature = "schema", derive(JsonSchema))]
71#[serde(rename_all = "snake_case")]
72pub enum TaskHealth {
73 OnTrack,
75
76 AtRisk,
78
79 OffTrack,
81}
82
83impl TaskHealth {
84 pub fn label(&self) -> &'static str {
86 match self {
87 TaskHealth::OnTrack => "On Track",
88 TaskHealth::AtRisk => "At Risk",
89 TaskHealth::OffTrack => "Off Track",
90 }
91 }
92
93 pub fn emoji(&self) -> &'static str {
95 match self {
96 TaskHealth::OnTrack => "✅",
97 TaskHealth::AtRisk => "⚠️",
98 TaskHealth::OffTrack => "🚫",
99 }
100 }
101}
102
103#[derive(Debug, Clone, Serialize, Deserialize, Default)]
108#[cfg_attr(feature = "schema", derive(JsonSchema))]
109#[serde(tag = "type", rename_all = "snake_case")]
110pub enum ContextProfile {
111 #[default]
113 Always,
114
115 Conditional {
117 #[serde(default, skip_serializing_if = "Vec::is_empty")]
119 task_types: Vec<String>,
120
121 #[serde(default, skip_serializing_if = "Vec::is_empty")]
123 user_states: Vec<String>,
124
125 #[serde(default, skip_serializing_if = "Option::is_none")]
127 task_health: Option<TaskHealth>,
128 },
129}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134
135 #[test]
136 fn test_priority_ordering() {
137 assert!(Priority::Critical > Priority::High);
138 assert!(Priority::High > Priority::Normal);
139 assert!(Priority::Normal > Priority::Low);
140 }
141
142 #[test]
143 fn test_priority_weight() {
144 assert_eq!(Priority::Critical.weight(), 4);
145 assert_eq!(Priority::High.weight(), 3);
146 assert_eq!(Priority::Normal.weight(), 2);
147 assert_eq!(Priority::Low.weight(), 1);
148 }
149}