imap_proto/types/
acls.rs

1use super::to_owned_cow;
2
3use std::borrow::Cow;
4
5// IMAP4 ACL Extension 4313/2086
6
7#[derive(Debug, Eq, PartialEq)]
8pub struct Acl<'a> {
9    pub mailbox: Cow<'a, str>,
10    pub acls: Vec<AclEntry<'a>>,
11}
12
13impl<'a> Acl<'a> {
14    pub fn into_owned(self) -> Acl<'static> {
15        Acl {
16            mailbox: to_owned_cow(self.mailbox),
17            acls: self.acls.into_iter().map(AclEntry::into_owned).collect(),
18        }
19    }
20}
21
22#[derive(Debug, Eq, PartialEq)]
23pub struct AclEntry<'a> {
24    pub identifier: Cow<'a, str>,
25    pub rights: Vec<AclRight>,
26}
27
28impl<'a> AclEntry<'a> {
29    pub fn into_owned(self) -> AclEntry<'static> {
30        AclEntry {
31            identifier: to_owned_cow(self.identifier),
32            rights: self.rights,
33        }
34    }
35}
36
37#[derive(Debug, Eq, PartialEq)]
38pub struct ListRights<'a> {
39    pub mailbox: Cow<'a, str>,
40    pub identifier: Cow<'a, str>,
41    pub required: Vec<AclRight>,
42    pub optional: Vec<AclRight>,
43}
44
45impl<'a> ListRights<'a> {
46    pub fn into_owned(self) -> ListRights<'static> {
47        ListRights {
48            mailbox: to_owned_cow(self.mailbox),
49            identifier: to_owned_cow(self.identifier),
50            required: self.required,
51            optional: self.optional,
52        }
53    }
54}
55
56#[derive(Debug, Eq, PartialEq)]
57pub struct MyRights<'a> {
58    pub mailbox: Cow<'a, str>,
59    pub rights: Vec<AclRight>,
60}
61
62impl<'a> MyRights<'a> {
63    pub fn into_owned(self) -> MyRights<'static> {
64        MyRights {
65            mailbox: to_owned_cow(self.mailbox),
66            rights: self.rights,
67        }
68    }
69}
70
71#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
72pub enum AclRight {
73    /// l - lookup (mailbox is visible to LIST/LSUB commands, SUBSCRIBE
74    /// mailbox)
75    Lookup,
76    /// r - read (SELECT the mailbox, perform STATUS)
77    Read,
78    /// s - keep seen/unseen information across sessions (set or clear
79    /// \SEEN flag via STORE, also set \SEEN during APPEND/COPY/
80    /// FETCH BODY[...])
81    Seen,
82    /// w - write (set or clear flags other than \SEEN and \DELETED via
83    /// STORE, also set them during APPEND/COPY)
84    Write,
85    /// i - insert (perform APPEND, COPY into mailbox)
86    Insert,
87    /// p - post (send mail to submission address for mailbox,
88    /// not enforced by IMAP4 itself)
89    Post,
90    /// k - create mailboxes (CREATE new sub-mailboxes in any
91    /// implementation-defined hierarchy, parent mailbox for the new
92    /// mailbox name in RENAME)
93    CreateMailbox,
94    /// x - delete mailbox (DELETE mailbox, old mailbox name in RENAME)
95    DeleteMailbox,
96    /// t - delete messages (set or clear \DELETED flag via STORE, set
97    /// \DELETED flag during APPEND/COPY)
98    DeleteMessage,
99    /// e - perform EXPUNGE and expunge as a part of CLOSE
100    Expunge,
101    /// a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS)
102    Administer,
103    /// n - ability to write .shared annotations values
104    /// From RFC 5257
105    Annotation,
106    /// c - old (deprecated) create. Do not use. Read RFC 4314 for more information.
107    OldCreate,
108    /// d - old (deprecated) delete. Do not use. Read RFC 4314 for more information.
109    OldDelete,
110    /// A custom right
111    Custom(char),
112}
113
114impl From<char> for AclRight {
115    fn from(c: char) -> Self {
116        match c {
117            'l' => AclRight::Lookup,
118            'r' => AclRight::Read,
119            's' => AclRight::Seen,
120            'w' => AclRight::Write,
121            'i' => AclRight::Insert,
122            'p' => AclRight::Post,
123            'k' => AclRight::CreateMailbox,
124            'x' => AclRight::DeleteMailbox,
125            't' => AclRight::DeleteMessage,
126            'e' => AclRight::Expunge,
127            'a' => AclRight::Administer,
128            'n' => AclRight::Annotation,
129            'c' => AclRight::OldCreate,
130            'd' => AclRight::OldDelete,
131            _ => AclRight::Custom(c),
132        }
133    }
134}
135
136impl From<AclRight> for char {
137    fn from(right: AclRight) -> Self {
138        match right {
139            AclRight::Lookup => 'l',
140            AclRight::Read => 'r',
141            AclRight::Seen => 's',
142            AclRight::Write => 'w',
143            AclRight::Insert => 'i',
144            AclRight::Post => 'p',
145            AclRight::CreateMailbox => 'k',
146            AclRight::DeleteMailbox => 'x',
147            AclRight::DeleteMessage => 't',
148            AclRight::Expunge => 'e',
149            AclRight::Administer => 'a',
150            AclRight::Annotation => 'n',
151            AclRight::OldCreate => 'c',
152            AclRight::OldDelete => 'd',
153            AclRight::Custom(c) => c,
154        }
155    }
156}
157
158#[cfg(test)]
159mod tests {
160    use super::*;
161
162    #[test]
163    fn test_char_to_acl_right() {
164        assert_eq!(Into::<AclRight>::into('l'), AclRight::Lookup);
165        assert_eq!(Into::<AclRight>::into('c'), AclRight::OldCreate);
166        assert_eq!(Into::<AclRight>::into('k'), AclRight::CreateMailbox);
167        assert_eq!(Into::<AclRight>::into('0'), AclRight::Custom('0'));
168    }
169
170    #[test]
171    fn test_acl_right_to_char() {
172        assert_eq!(Into::<char>::into(AclRight::Lookup), 'l');
173        assert_eq!(Into::<char>::into(AclRight::OldCreate), 'c');
174        assert_eq!(Into::<char>::into(AclRight::CreateMailbox), 'k');
175        assert_eq!(Into::<char>::into(AclRight::Custom('0')), '0');
176    }
177}