revolt_permissions/models/
mod.rs

1mod channel;
2mod server;
3mod user;
4
5pub use channel::*;
6use revolt_result::{create_error, Result};
7pub use server::*;
8pub use user::*;
9
10/// Holds a permission value to manipulate.
11#[derive(Clone, Debug)]
12pub struct PermissionValue(u64);
13
14impl PermissionValue {
15    /// Apply a given override to this value
16    pub fn apply(&mut self, v: Override) {
17        self.allow(v.allow);
18        self.revoke(v.deny);
19    }
20
21    /// Allow given permissions
22    pub fn allow(&mut self, v: u64) {
23        self.0 |= v;
24    }
25
26    /// Revoke given permissions
27    pub fn revoke(&mut self, v: u64) {
28        self.0 &= !v;
29    }
30
31    /// Revoke all permissions
32    pub fn revoke_all(&mut self) {
33        self.0 = 0;
34    }
35
36    /// Restrict to given permissions
37    pub fn restrict(&mut self, v: u64) {
38        self.0 &= v;
39    }
40
41    /// Check whether certain a permission has been granted
42    pub fn has(&self, v: u64) -> bool {
43        (self.0 & v) == v
44    }
45
46    /// Check whether certain a user permission has been granted
47    pub fn has_user_permission(&self, permission: UserPermission) -> bool {
48        self.has(permission as u64)
49    }
50
51    /// Check whether certain a channel permission has been granted
52    pub fn has_channel_permission(&self, permission: ChannelPermission) -> bool {
53        self.has(permission as u64)
54    }
55
56    /// Throw if missing user permission
57    pub fn throw_if_lacking_user_permission(&self, permission: UserPermission) -> Result<()> {
58        if self.has_user_permission(permission) {
59            Ok(())
60        } else {
61            Err(create_error!(MissingPermission {
62                permission: permission.to_string()
63            }))
64        }
65    }
66
67    /// Throw if missing channel permission
68    pub fn throw_if_lacking_channel_permission(&self, permission: ChannelPermission) -> Result<()> {
69        if self.has_channel_permission(permission) {
70            Ok(())
71        } else {
72            Err(create_error!(MissingPermission {
73                permission: permission.to_string()
74            }))
75        }
76    }
77
78    /// Throw an error if we cannot grant permissions on either allows or denies
79    /// going from the previous given value to the next given value.
80    ///
81    /// We need to check any:
82    /// - allows added (permissions now granted)
83    /// - denies removed (permissions now neutral or granted)
84    pub async fn throw_permission_override<C>(
85        &self,
86        current_value: C,
87        next_value: &Override,
88    ) -> Result<()>
89    where
90        C: Into<Option<Override>>,
91    {
92        let current_value = current_value.into();
93
94        if let Some(current_value) = current_value {
95            if !self.has(!current_value.allows() & next_value.allows())
96                || !self.has(current_value.denies() & !next_value.denies())
97            {
98                return Err(create_error!(CannotGiveMissingPermissions));
99            }
100        } else if !self.has(next_value.allows()) {
101            return Err(create_error!(CannotGiveMissingPermissions));
102        }
103
104        Ok(())
105    }
106}
107
108impl From<i64> for PermissionValue {
109    fn from(v: i64) -> Self {
110        Self(v as u64)
111    }
112}
113
114impl From<u64> for PermissionValue {
115    fn from(v: u64) -> Self {
116        Self(v)
117    }
118}
119
120impl From<PermissionValue> for u64 {
121    fn from(v: PermissionValue) -> Self {
122        v.0
123    }
124}
125
126impl From<ChannelPermission> for PermissionValue {
127    fn from(v: ChannelPermission) -> Self {
128        (v as u64).into()
129    }
130}