Skip to main content

discordrs/model/
permissions.rs

1use std::fmt::Formatter;
2
3use serde::de::{self, Visitor};
4use serde::{Deserialize, Deserializer, Serialize, Serializer};
5
6#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
7/// Typed Discord API object for `PermissionsBitField`.
8pub struct PermissionsBitField(pub u64);
9
10impl PermissionsBitField {
11    pub fn bits(self) -> u64 {
12        self.0
13    }
14
15    pub fn contains(self, permission: u64) -> bool {
16        self.0 & permission == permission
17    }
18
19    pub fn insert(&mut self, permission: u64) {
20        self.0 |= permission;
21    }
22
23    pub fn remove(&mut self, permission: u64) {
24        self.0 &= !permission;
25    }
26}
27
28impl Serialize for PermissionsBitField {
29    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
30    where
31        S: Serializer,
32    {
33        serializer.serialize_str(&self.0.to_string())
34    }
35}
36
37impl<'de> Deserialize<'de> for PermissionsBitField {
38    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
39    where
40        D: Deserializer<'de>,
41    {
42        struct PermissionsVisitor;
43
44        impl<'de> Visitor<'de> for PermissionsVisitor {
45            type Value = PermissionsBitField;
46
47            fn expecting(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
48                formatter.write_str("a Discord permission bitfield encoded as a string or integer")
49            }
50
51            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
52            where
53                E: de::Error,
54            {
55                Ok(PermissionsBitField(value))
56            }
57
58            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
59            where
60                E: de::Error,
61            {
62                value
63                    .parse()
64                    .map(PermissionsBitField)
65                    .map_err(|error| E::custom(format!("invalid permission bitfield: {error}")))
66            }
67
68            fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
69            where
70                E: de::Error,
71            {
72                self.visit_str(&value)
73            }
74        }
75
76        deserializer.deserialize_any(PermissionsVisitor)
77    }
78}