rustical_dav/
privileges.rs

1use quick_xml::name::Namespace;
2use rustical_xml::{XmlDeserialize, XmlSerialize};
3use std::collections::{HashMap, HashSet};
4
5#[derive(Debug, Clone, XmlSerialize, XmlDeserialize, Eq, Hash, PartialEq)]
6pub enum UserPrivilege {
7    Read,
8    Write,
9    WriteProperties,
10    WriteContent,
11    ReadAcl,
12    ReadCurrentUserPrivilegeSet,
13    WriteAcl,
14    All,
15}
16
17impl XmlSerialize for UserPrivilegeSet {
18    fn serialize<W: std::io::Write>(
19        &self,
20        ns: Option<Namespace>,
21        tag: Option<&[u8]>,
22        namespaces: &HashMap<Namespace, &[u8]>,
23        writer: &mut quick_xml::Writer<W>,
24    ) -> std::io::Result<()> {
25        #[derive(XmlSerialize)]
26        pub struct FakeUserPrivilegeSet {
27            #[xml(rename = b"privilege", flatten)]
28            privileges: Vec<UserPrivilege>,
29        }
30
31        FakeUserPrivilegeSet {
32            privileges: self.privileges.iter().cloned().collect(),
33        }
34        .serialize(ns, tag, namespaces, writer)
35    }
36
37    #[allow(refining_impl_trait)]
38    fn attributes<'a>(&self) -> Option<Vec<quick_xml::events::attributes::Attribute<'a>>> {
39        None
40    }
41}
42
43#[derive(Debug, Clone, Default, PartialEq)]
44pub struct UserPrivilegeSet {
45    privileges: HashSet<UserPrivilege>,
46}
47
48impl UserPrivilegeSet {
49    pub fn has(&self, privilege: &UserPrivilege) -> bool {
50        self.privileges.contains(privilege) || self.privileges.contains(&UserPrivilege::All)
51    }
52
53    pub fn all() -> Self {
54        Self {
55            privileges: HashSet::from([UserPrivilege::All]),
56        }
57    }
58
59    pub fn owner_only(is_owner: bool) -> Self {
60        if is_owner {
61            Self::all()
62        } else {
63            Self::default()
64        }
65    }
66
67    pub fn owner_read(is_owner: bool) -> Self {
68        if is_owner {
69            Self::read_only()
70        } else {
71            Self::default()
72        }
73    }
74
75    pub fn read_only() -> Self {
76        Self {
77            privileges: HashSet::from([
78                UserPrivilege::Read,
79                UserPrivilege::ReadAcl,
80                UserPrivilege::ReadCurrentUserPrivilegeSet,
81            ]),
82        }
83    }
84}
85
86impl<const N: usize> From<[UserPrivilege; N]> for UserPrivilegeSet {
87    fn from(privileges: [UserPrivilege; N]) -> Self {
88        Self {
89            privileges: HashSet::from(privileges),
90        }
91    }
92}