use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub enum TodoPriority {
Low,
Medium,
High,
Critical,
}
impl TodoPriority {
pub fn from_tag(tag: &str) -> Self {
match tag.to_uppercase().as_str() {
"BUG" | "FIXME" | "ERROR" => TodoPriority::Critical,
"HACK" | "WARN" | "WARNING" | "FIX" => TodoPriority::High,
"TODO" | "WIP" | "MAYBE" => TodoPriority::Medium,
"NOTE" | "XXX" | "INFO" | "DOCS" | "PERF" | "TEST" | "IDEA" => TodoPriority::Low,
_ => TodoPriority::Medium,
}
}
pub fn display_name(&self) -> &'static str {
match self {
TodoPriority::Critical => "Critical",
TodoPriority::High => "High",
TodoPriority::Medium => "Medium",
TodoPriority::Low => "Low",
}
}
}
impl std::fmt::Display for TodoPriority {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.display_name())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn from_tag_maps_critical_tags() {
for tag in ["BUG", "FIXME", "ERROR"] {
assert_eq!(TodoPriority::from_tag(tag), TodoPriority::Critical);
}
}
#[test]
fn from_tag_maps_high_tags() {
for tag in ["HACK", "WARN", "WARNING", "FIX"] {
assert_eq!(TodoPriority::from_tag(tag), TodoPriority::High);
}
}
#[test]
fn from_tag_maps_medium_tags() {
for tag in ["TODO", "WIP", "MAYBE"] {
assert_eq!(TodoPriority::from_tag(tag), TodoPriority::Medium);
}
}
#[test]
fn from_tag_maps_low_tags() {
for tag in ["NOTE", "XXX", "INFO", "DOCS", "PERF", "TEST", "IDEA"] {
assert_eq!(TodoPriority::from_tag(tag), TodoPriority::Low);
}
}
#[test]
fn from_tag_is_case_insensitive() {
assert_eq!(TodoPriority::from_tag("bug"), TodoPriority::Critical);
assert_eq!(TodoPriority::from_tag("Fixme"), TodoPriority::Critical);
}
#[test]
fn from_tag_defaults_unknown_to_medium() {
assert_eq!(TodoPriority::from_tag("CUSTOM"), TodoPriority::Medium);
}
#[test]
fn display_name_matches_variant() {
assert_eq!(TodoPriority::Critical.display_name(), "Critical");
assert_eq!(TodoPriority::High.display_name(), "High");
assert_eq!(TodoPriority::Medium.display_name(), "Medium");
assert_eq!(TodoPriority::Low.display_name(), "Low");
}
#[test]
fn display_uses_display_name() {
assert_eq!(TodoPriority::Critical.to_string(), "Critical");
assert_eq!(format!("{}", TodoPriority::Low), "Low");
}
#[test]
fn ordering_ranks_by_severity() {
assert!(TodoPriority::Low < TodoPriority::Medium);
assert!(TodoPriority::Medium < TodoPriority::High);
assert!(TodoPriority::High < TodoPriority::Critical);
}
}