use std::{
cmp::Ordering,
fmt::{Display, Formatter, Result as FmtResult},
str::FromStr,
};
use eyre::{Error, Result, eyre};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)]
pub enum TaskPriority {
#[serde(rename = "p0")]
Highest = 0,
#[serde(rename = "p1")]
High = 1,
#[serde(rename = "p2")]
#[default]
Medium = 2,
#[serde(rename = "p3")]
Low = 3,
#[serde(rename = "p4")]
Lowest = 4,
}
impl Display for TaskPriority {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self {
Self::Highest => write!(f, "p0"),
Self::High => write!(f, "p1"),
Self::Medium => write!(f, "p2"),
Self::Low => write!(f, "p3"),
Self::Lowest => write!(f, "p4"),
}
}
}
impl FromStr for TaskPriority {
type Err = Error;
fn from_str(s: &str) -> Result<Self> {
match s {
"p0" => Ok(Self::Highest),
"p1" => Ok(Self::High),
"p2" => Ok(Self::Medium),
"p3" => Ok(Self::Low),
"p4" => Ok(Self::Lowest),
_ => Err(eyre!("Invalid priority")),
}
}
}
impl Ord for TaskPriority {
fn cmp(&self, other: &Self) -> Ordering {
(other.clone() as u8).cmp(&(self.clone() as u8))
}
}
impl PartialOrd for TaskPriority {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[cfg(test)]
mod tests {
use super::*;
mod display {
use pretty_assertions::assert_eq;
use super::*;
#[test]
fn it_displays_correctly() {
assert_eq!(TaskPriority::Highest.to_string(), "p0");
assert_eq!(TaskPriority::High.to_string(), "p1");
assert_eq!(TaskPriority::Medium.to_string(), "p2");
assert_eq!(TaskPriority::Low.to_string(), "p3");
assert_eq!(TaskPriority::Lowest.to_string(), "p4");
}
}
mod from_str {
use pretty_assertions::assert_eq;
use super::*;
#[test]
fn it_parses_correctly() {
assert_eq!(TaskPriority::from_str("p0").unwrap(), TaskPriority::Highest);
assert_eq!(TaskPriority::from_str("p1").unwrap(), TaskPriority::High);
assert_eq!(TaskPriority::from_str("p2").unwrap(), TaskPriority::Medium);
assert_eq!(TaskPriority::from_str("p3").unwrap(), TaskPriority::Low);
assert_eq!(TaskPriority::from_str("p4").unwrap(), TaskPriority::Lowest);
}
#[test]
fn it_errors_on_invalid_input() {
assert!(TaskPriority::from_str("p5").is_err());
}
}
mod ordering {
use super::*;
#[test]
fn it_orders_correctly() {
assert!(TaskPriority::Highest > TaskPriority::High);
assert!(TaskPriority::High > TaskPriority::Medium);
assert!(TaskPriority::Medium > TaskPriority::Low);
assert!(TaskPriority::Low > TaskPriority::Lowest);
}
}
}