Skip to main content

caldir_core/event/
availability.rs

1use std::fmt;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, serde::Serialize)]
4#[serde(rename_all = "snake_case")]
5pub enum Availability {
6    // Busy (OPAQUE) is the RFC 5545 default — see `Status` for the rationale.
7    #[default]
8    Busy,
9    Free,
10}
11
12impl fmt::Display for Availability {
13    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14        let s = match self {
15            Self::Busy => "busy",
16            Self::Free => "free",
17        };
18        write!(f, "{}", s)
19    }
20}
21
22impl Availability {
23    pub fn as_ics_str(&self) -> &'static str {
24        match self {
25            Self::Busy => "OPAQUE",
26            Self::Free => "TRANSPARENT",
27        }
28    }
29
30    pub fn from_ics_str(s: &str) -> Option<Self> {
31        match s {
32            "OPAQUE" => Some(Self::Busy),
33            "TRANSPARENT" => Some(Self::Free),
34            _ => None,
35        }
36    }
37}
38
39#[cfg(test)]
40mod tests {
41    use super::*;
42
43    #[test]
44    fn maps_to_rfc5545_strings() {
45        assert_eq!(Availability::Busy.as_ics_str(), "OPAQUE");
46        assert_eq!(Availability::Free.as_ics_str(), "TRANSPARENT");
47    }
48
49    #[test]
50    fn parses_each_rfc5545_string() {
51        assert_eq!(
52            Availability::from_ics_str("OPAQUE"),
53            Some(Availability::Busy)
54        );
55        assert_eq!(
56            Availability::from_ics_str("TRANSPARENT"),
57            Some(Availability::Free)
58        );
59    }
60
61    #[test]
62    fn unknown_strings_return_none() {
63        assert_eq!(Availability::from_ics_str("BUSY"), None);
64        assert_eq!(Availability::from_ics_str("opaque"), None);
65        assert_eq!(Availability::from_ics_str(""), None);
66    }
67
68    #[test]
69    fn display_uses_user_facing_label() {
70        assert_eq!(Availability::Busy.to_string(), "busy");
71        assert_eq!(Availability::Free.to_string(), "free");
72    }
73}