Skip to main content

protonmail_client/
flag.rs

1//! IMAP message flags
2//!
3//! Provides a strongly-typed enum for IMAP flags instead of raw
4//! strings. Standard system flags have dedicated variants; arbitrary
5//! keyword flags use the `Keyword` variant.
6
7use std::fmt;
8
9/// An IMAP message flag.
10///
11/// System flags (prefixed with `\` in the IMAP protocol) have
12/// dedicated variants. User-defined keyword flags use [`Flag::Keyword`].
13///
14/// # Examples
15///
16/// ```
17/// use protonmail_client::Flag;
18///
19/// let seen = Flag::Seen;
20/// assert_eq!(seen.as_imap_str(), "\\Seen");
21///
22/// let kw = Flag::Keyword("$Important".to_string());
23/// assert_eq!(kw.as_imap_str(), "$Important");
24/// ```
25#[derive(Debug, Clone, PartialEq, Eq, Hash)]
26pub enum Flag {
27    /// Message has been read (`\Seen`).
28    Seen,
29    /// Message has been answered (`\Answered`).
30    Answered,
31    /// Message is flagged for attention (`\Flagged`).
32    Flagged,
33    /// Message is marked for deletion (`\Deleted`).
34    Deleted,
35    /// Message is a draft (`\Draft`).
36    Draft,
37    /// A user-defined keyword flag (no `\` prefix).
38    Keyword(String),
39}
40
41impl Flag {
42    /// The IMAP wire representation of this flag.
43    ///
44    /// System flags include the leading backslash (e.g. `\Seen`).
45    /// Keyword flags are returned as-is.
46    #[must_use]
47    pub fn as_imap_str(&self) -> &str {
48        match self {
49            Self::Seen => "\\Seen",
50            Self::Answered => "\\Answered",
51            Self::Flagged => "\\Flagged",
52            Self::Deleted => "\\Deleted",
53            Self::Draft => "\\Draft",
54            Self::Keyword(kw) => kw,
55        }
56    }
57}
58
59impl fmt::Display for Flag {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        f.write_str(self.as_imap_str())
62    }
63}
64
65#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn system_flags() {
71        assert_eq!(Flag::Seen.as_imap_str(), "\\Seen");
72        assert_eq!(Flag::Answered.as_imap_str(), "\\Answered");
73        assert_eq!(Flag::Flagged.as_imap_str(), "\\Flagged");
74        assert_eq!(Flag::Deleted.as_imap_str(), "\\Deleted");
75        assert_eq!(Flag::Draft.as_imap_str(), "\\Draft");
76    }
77
78    #[test]
79    fn keyword_flag() {
80        let kw = Flag::Keyword("$Important".to_string());
81        assert_eq!(kw.as_imap_str(), "$Important");
82    }
83
84    #[test]
85    fn display_matches_imap_str() {
86        assert_eq!(format!("{}", Flag::Seen), "\\Seen");
87        assert_eq!(format!("{}", Flag::Keyword("$Junk".to_string())), "$Junk");
88    }
89}