titanium_model/
permissions.rs

1//! Discord Permissions
2//!
3//! Permissions in Discord are a way to limit and grant certain abilities to users.
4//! They are represented by a 64-bit integer, serialized as a string.
5
6use bitflags::bitflags;
7use serde::{Deserialize, Deserializer, Serialize, Serializer};
8use std::fmt;
9
10bitflags! {
11    /// Permissions that can be assigned to a Role or User.
12    ///
13    /// See: https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags
14    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
15    pub struct Permissions: u64 {
16        /// Allows creation of instant invites.
17        const CREATE_INSTANT_INVITE = 1 << 0;
18        /// Allows kicking members.
19        const KICK_MEMBERS = 1 << 1;
20        /// Allows banning members.
21        const BAN_MEMBERS = 1 << 2;
22        /// Allows all permissions and bypasses channel permission overwrites.
23        const ADMINISTRATOR = 1 << 3;
24        /// Allows management and editing of channels.
25        const MANAGE_CHANNELS = 1 << 4;
26        /// Allows management and editing of the guild.
27        const MANAGE_GUILD = 1 << 5;
28        /// Allows adding reactions to messages.
29        const ADD_REACTIONS = 1 << 6;
30        /// Allows viewing the audit log.
31        const VIEW_AUDIT_LOG = 1 << 7;
32        /// Allows using priority speaker in a voice channel.
33        const PRIORITY_SPEAKER = 1 << 8;
34        /// Allows the user to go live.
35        const STREAM = 1 << 9;
36        /// Allows viewing guild content (channels, members, etc).
37        const VIEW_CHANNEL = 1 << 10;
38        /// Allows sending messages in a channel.
39        const SEND_MESSAGES = 1 << 11;
40        /// Allows sending TTS messages.
41        const SEND_TTS_MESSAGES = 1 << 12;
42        /// Allows managing messages of others.
43        const MANAGE_MESSAGES = 1 << 13;
44        /// Allows embedding content in messages (e.g. links).
45        const EMBED_LINKS = 1 << 14;
46        /// Allows attaching files.
47        const ATTACH_FILES = 1 << 15;
48        /// Allows reading of message history.
49        const READ_MESSAGE_HISTORY = 1 << 16;
50        /// Allows mentioning @everyone, @here, and all roles.
51        const MENTION_EVERYONE = 1 << 17;
52        /// Allows using external emojis.
53        const USE_EXTERNAL_EMOJIS = 1 << 18;
54        /// Allows viewing guild insights.
55        const VIEW_GUILD_INSIGHTS = 1 << 19;
56        /// Allows connecting to a voice channel.
57        const CONNECT = 1 << 20;
58        /// Allows speaking in a voice channel.
59        const SPEAK = 1 << 21;
60        /// Allows muting members in a voice channel.
61        const MUTE_MEMBERS = 1 << 22;
62        /// Allows deafening members in a voice channel.
63        const DEAFEN_MEMBERS = 1 << 23;
64        /// Allows moving members between voice channels.
65        const MOVE_MEMBERS = 1 << 24;
66        /// Allows using voice-activity-detection.
67        const USE_VAD = 1 << 25;
68        /// Allows changing own nickname.
69        const CHANGE_NICKNAME = 1 << 26;
70        /// Allows managing nicknames of others.
71        const MANAGE_NICKNAMES = 1 << 27;
72        /// Allows managing roles.
73        const MANAGE_ROLES = 1 << 28;
74        /// Allows managing webhooks.
75        const MANAGE_WEBHOOKS = 1 << 29;
76        /// Allows managing emojis and stickers.
77        const MANAGE_EMOJIS_AND_STICKERS = 1 << 30;
78        /// Allows using application commands.
79        const USE_APPLICATION_COMMANDS = 1 << 31;
80        /// Allows requesting to speak in stage channels.
81        const REQUEST_TO_SPEAK = 1 << 32;
82        /// Allows creating, editing, and deleting events.
83        const MANAGE_EVENTS = 1 << 33;
84        /// Allows managing threads.
85        const MANAGE_THREADS = 1 << 34;
86        /// Allows creating public threads.
87        const CREATE_PUBLIC_THREADS = 1 << 35;
88        /// Allows creating private threads.
89        const CREATE_PRIVATE_THREADS = 1 << 36;
90        /// Allows using external stickers.
91        const USE_EXTERNAL_STICKERS = 1 << 37;
92        /// Allows sending messages in threads.
93        const SEND_MESSAGES_IN_THREADS = 1 << 38;
94        /// Allows using embedded activities.
95        const USE_EMBEDDED_ACTIVITIES = 1 << 39;
96        /// Allows timing out users.
97        const MODERATE_MEMBERS = 1 << 40;
98        /// Allows viewing creator monetization analytics.
99        const VIEW_CREATOR_MONETIZATION_ANALYTICS = 1 << 41;
100        /// Allows using soundboard.
101        const USE_SOUNDBOARD = 1 << 42;
102        /// Allows using external sounds.
103        const USE_EXTERNAL_SOUNDS = 1 << 45;
104        /// Allows sending voice messages.
105        const SEND_VOICE_MESSAGES = 1 << 46;
106    }
107}
108
109impl Serialize for Permissions {
110    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
111    where
112        S: Serializer,
113    {
114        // Permissions are serialized as strings
115        serializer.serialize_str(&self.bits().to_string())
116    }
117}
118
119impl<'de> Deserialize<'de> for Permissions {
120    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
121    where
122        D: Deserializer<'de>,
123    {
124        struct PermissionsVisitor;
125
126        impl serde::de::Visitor<'_> for PermissionsVisitor {
127            type Value = Permissions;
128
129            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
130                formatter.write_str("a string or integer representing permissions")
131            }
132
133            fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
134            where
135                E: serde::de::Error,
136            {
137                Ok(Permissions::from_bits_truncate(value))
138            }
139
140            fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
141            where
142                E: serde::de::Error,
143            {
144                value
145                    .parse::<u64>()
146                    .map(Permissions::from_bits_truncate)
147                    .map_err(serde::de::Error::custom)
148            }
149        }
150
151        deserializer.deserialize_any(PermissionsVisitor)
152    }
153}