Skip to main content

caldir_core/event/
status.rs

1use std::fmt;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize)]
4#[serde(rename_all = "snake_case")]
5pub enum Status {
6    // CONFIRMED is the RFC 5545 default — an event with no STATUS line is
7    // semantically confirmed, so absence and "confirmed" must round-trip the
8    // same way.
9    #[default]
10    Confirmed,
11    Tentative,
12    Cancelled,
13}
14
15impl fmt::Display for Status {
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        let s = match self {
18            Self::Confirmed => "confirmed",
19            Self::Tentative => "tentative",
20            Self::Cancelled => "cancelled",
21        };
22        write!(f, "{}", s)
23    }
24}
25
26impl Status {
27    pub fn as_ics_str(&self) -> &'static str {
28        match self {
29            Self::Confirmed => "CONFIRMED",
30            Self::Tentative => "TENTATIVE",
31            Self::Cancelled => "CANCELLED",
32        }
33    }
34
35    pub fn from_ics_str(s: &str) -> Option<Self> {
36        match s {
37            "CONFIRMED" => Some(Self::Confirmed),
38            "TENTATIVE" => Some(Self::Tentative),
39            "CANCELLED" => Some(Self::Cancelled),
40            _ => None,
41        }
42    }
43}
44
45#[cfg(test)]
46mod tests {
47    use super::*;
48
49    #[test]
50    fn maps_to_rfc5545_strings() {
51        assert_eq!(Status::Confirmed.as_ics_str(), "CONFIRMED");
52        assert_eq!(Status::Tentative.as_ics_str(), "TENTATIVE");
53        assert_eq!(Status::Cancelled.as_ics_str(), "CANCELLED");
54    }
55
56    #[test]
57    fn parses_each_rfc5545_string() {
58        assert_eq!(Status::from_ics_str("CONFIRMED"), Some(Status::Confirmed));
59        assert_eq!(Status::from_ics_str("TENTATIVE"), Some(Status::Tentative));
60        assert_eq!(Status::from_ics_str("CANCELLED"), Some(Status::Cancelled));
61    }
62
63    #[test]
64    fn unknown_strings_return_none() {
65        assert_eq!(Status::from_ics_str("DRAFT"), None);
66        assert_eq!(Status::from_ics_str("confirmed"), None);
67        assert_eq!(Status::from_ics_str(""), None);
68    }
69
70    #[test]
71    fn display_uses_lowercase_label() {
72        assert_eq!(Status::Confirmed.to_string(), "confirmed");
73        assert_eq!(Status::Tentative.to_string(), "tentative");
74        assert_eq!(Status::Cancelled.to_string(), "cancelled");
75    }
76}