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