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