serenity/model/
permissions.rs

1//! A set of permissions for a role or user. These can be assigned directly to a role or as a
2//! channel's permission overrides.
3//!
4//! For convenience, methods for each permission are available, which can be used to test if the
5//! set of permissions contains a single permission. This can simplify code and reduce a potential
6//! import.
7//!
8//! Additionally, presets equivalent to the official client's `@everyone` role presets are
9//! available. These are [`PRESET_GENERAL`], [`PRESET_TEXT`], and [`PRESET_VOICE`].
10//!
11//! Permissions follow a hierarchy:
12//! - An account can grant roles to users that are of a lower position than its highest role;
13//! - An account can edit roles lesser than its highest role, but can only grant permissions they
14//!   have;
15//! - An account can move only roles lesser than its highest role;
16//! - An account can only kick/ban accounts with a lesser role than its top role.
17//!
18//! **Note**: The following permissions require the owner account (e.g. the owner of a bot) to use
19//! two-factor authentication in the case that a guild has guild-wide 2FA enabled:
20//! - [Administrator]
21//! - [Ban Members]
22//! - [Kick Members]
23//! - [Manage Channels]
24//! - [Manage Guild]
25//! - [Manage Messages]
26//! - [Manage Roles]
27//! - [Manage Webhooks]
28//!
29//! [Administrator]: Permissions::ADMINISTRATOR
30//! [Ban Members]: Permissions::BAN_MEMBERS
31//! [Kick Members]: Permissions::KICK_MEMBERS
32//! [Manage Channels]: Permissions::MANAGE_CHANNELS
33//! [Manage Guild]: Permissions::MANAGE_GUILD
34//! [Manage Messages]: Permissions::MANAGE_MESSAGES
35//! [Manage Roles]: Permissions::MANAGE_ROLES
36//! [Manage Webhooks]: Permissions::MANAGE_WEBHOOKS
37
38#[cfg(feature = "model")]
39use std::fmt;
40
41use serde::de::{Deserialize, Deserializer};
42use serde::ser::{Serialize, Serializer};
43
44use super::utils::StrOrInt;
45
46/// This macro generates the [`Permissions::get_permission_names`] method.
47///
48/// It is invoked by passing the names of all methods used to check for permissions along with
49/// their names displayed inside Discord.
50///
51/// ## Examples
52///
53/// Using this macro
54///
55/// ```ignore
56/// generate_get_permission_names! {
57///     add_reactions: "Add Reactions",
58///     administrator: "Administrator"
59/// };
60/// ```
61///
62/// Generates this implementation:
63///
64/// ```ignore
65/// impl Permissions {
66///     fn get_permission_names(self) -> Vec<&'static str> {
67///         let mut names = Vec::new();
68///
69///         if self.add_reactions() {
70///             names.push("Add Reactions");
71///         }
72///         if self.administrator() {
73///             names.push("Administrator");
74///         }
75///
76///         names
77///     }
78/// }
79/// ```
80#[cfg(feature = "model")]
81macro_rules! generate_get_permission_names {
82    {$ ($perm:ident: $name:expr),*} => {
83        impl Permissions {
84            /// Returns a list of names of all contained permissions.
85            #[must_use]
86            pub fn get_permission_names(self) -> Vec<&'static str> {
87                let mut names = Vec::new();
88
89                $(
90                    if self.$perm() {
91                        names.push($name);
92                    }
93                )*
94
95                names
96            }
97        }
98    }
99}
100
101/// Returns a set of permissions with the original @everyone permissions set to true.
102///
103/// This includes the following permissions:
104/// - [Add Reactions]
105/// - [Attach Files]
106/// - [Change Nickname]
107/// - [Connect]
108/// - [Create Instant Invite]
109/// - [Embed Links]
110/// - [Mention Everyone]
111/// - [Read Message History]
112/// - [View Channel]
113/// - [Send Messages]
114/// - [Send TTS Messages]
115/// - [Speak]
116/// - [Use External Emojis]
117/// - [Use VAD]
118///
119/// **Note**: The [Send TTS Messages] permission is set to `true`. Consider setting this to
120/// `false`, via:
121///
122/// ```rust
123/// use serenity::model::permissions::{self, Permissions};
124///
125/// permissions::PRESET_GENERAL.toggle(Permissions::SEND_TTS_MESSAGES);
126/// ```
127///
128/// [Add Reactions]: Permissions::ADD_REACTIONS
129/// [Attach Files]: Permissions::ATTACH_FILES
130/// [Change Nickname]: Permissions::CHANGE_NICKNAME
131/// [Connect]: Permissions::CONNECT
132/// [Create Instant Invite]: Permissions::CREATE_INSTANT_INVITE
133/// [Embed Links]: Permissions::EMBED_LINKS
134/// [Mention Everyone]: Permissions::MENTION_EVERYONE
135/// [Read Message History]: Permissions::READ_MESSAGE_HISTORY
136/// [View Channel]: Permissions::VIEW_CHANNEL
137/// [Send Messages]: Permissions::SEND_MESSAGES
138/// [Send TTS Messages]: Permissions::SEND_TTS_MESSAGES
139/// [Speak]: Permissions::SPEAK
140/// [Use External Emojis]: Permissions::USE_EXTERNAL_EMOJIS
141/// [Use VAD]: Permissions::USE_VAD
142pub const PRESET_GENERAL: Permissions = Permissions::from_bits_truncate(
143    Permissions::ADD_REACTIONS.bits()
144        | Permissions::ATTACH_FILES.bits()
145        | Permissions::CHANGE_NICKNAME.bits()
146        | Permissions::CONNECT.bits()
147        | Permissions::CREATE_INSTANT_INVITE.bits()
148        | Permissions::EMBED_LINKS.bits()
149        | Permissions::MENTION_EVERYONE.bits()
150        | Permissions::READ_MESSAGE_HISTORY.bits()
151        | Permissions::VIEW_CHANNEL.bits()
152        | Permissions::SEND_MESSAGES.bits()
153        | Permissions::SEND_TTS_MESSAGES.bits()
154        | Permissions::SPEAK.bits()
155        | Permissions::USE_EXTERNAL_EMOJIS.bits()
156        | Permissions::USE_VAD.bits(),
157);
158
159/// Returns a set of text-only permissions with the original `@everyone` permissions set to true.
160///
161/// This includes the text permissions that are in [`PRESET_GENERAL`]:
162/// - [Add Reactions]
163/// - [Attach Files]
164/// - [Change Nickname]
165/// - [Create Instant Invite]
166/// - [Embed Links]
167/// - [Mention Everyone]
168/// - [Read Message History]
169/// - [View Channel]
170/// - [Send Messages]
171/// - [Send TTS Messages]
172/// - [Use External Emojis]
173///
174/// [Add Reactions]: Permissions::ADD_REACTIONS
175/// [Attach Files]: Permissions::ATTACH_FILES
176/// [Change Nickname]: Permissions::CHANGE_NICKNAME
177/// [Create Instant Invite]: Permissions::CREATE_INSTANT_INVITE
178/// [Embed Links]: Permissions::EMBED_LINKS
179/// [Mention Everyone]: Permissions::MENTION_EVERYONE
180/// [Read Message History]: Permissions::READ_MESSAGE_HISTORY
181/// [View Channel]: Permissions::VIEW_CHANNEL
182/// [Send Messages]: Permissions::SEND_MESSAGES
183/// [Send TTS Messages]: Permissions::SEND_TTS_MESSAGES
184/// [Use External Emojis]: Permissions::USE_EXTERNAL_EMOJIS
185pub const PRESET_TEXT: Permissions = Permissions::from_bits_truncate(
186    Permissions::ADD_REACTIONS.bits()
187        | Permissions::ATTACH_FILES.bits()
188        | Permissions::CHANGE_NICKNAME.bits()
189        | Permissions::CREATE_INSTANT_INVITE.bits()
190        | Permissions::EMBED_LINKS.bits()
191        | Permissions::MENTION_EVERYONE.bits()
192        | Permissions::READ_MESSAGE_HISTORY.bits()
193        | Permissions::VIEW_CHANNEL.bits()
194        | Permissions::SEND_MESSAGES.bits()
195        | Permissions::SEND_TTS_MESSAGES.bits()
196        | Permissions::USE_EXTERNAL_EMOJIS.bits(),
197);
198
199/// Returns a set of voice-only permissions with the original `@everyone` permissions set to true.
200///
201/// This includes the voice permissions that are in [`PRESET_GENERAL`]:
202/// - [Connect]
203/// - [Speak]
204/// - [Use VAD]
205///
206/// [Connect]: Permissions::CONNECT
207/// [Speak]: Permissions::SPEAK
208/// [Use VAD]: Permissions::USE_VAD
209pub const PRESET_VOICE: Permissions = Permissions::from_bits_truncate(
210    Permissions::CONNECT.bits() | Permissions::SPEAK.bits() | Permissions::USE_VAD.bits(),
211);
212
213/// A set of permissions that can be assigned to [`User`]s and [`Role`]s via
214/// [`PermissionOverwrite`]s, roles globally in a [`Guild`], and to [`GuildChannel`]s.
215///
216/// [Discord docs](https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags).
217///
218/// [`Guild`]: super::guild::Guild
219/// [`GuildChannel`]: super::channel::GuildChannel
220/// [`PermissionOverwrite`]: super::channel::PermissionOverwrite
221/// [`Role`]: super::guild::Role
222/// [`User`]: super::user::User
223#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
224#[derive(Copy, Clone, Default, Debug, Eq, Hash, PartialEq)]
225#[repr(packed)]
226pub struct Permissions(u64);
227
228bitflags::bitflags! {
229    impl Permissions: u64 {
230        /// Allows for the creation of [`RichInvite`]s.
231        ///
232        /// [`RichInvite`]: super::invite::RichInvite
233        const CREATE_INSTANT_INVITE = 1 << 0;
234        /// Allows for the kicking of guild [member]s.
235        ///
236        /// [member]: super::guild::Member
237        const KICK_MEMBERS = 1 << 1;
238        /// Allows the banning of guild [member]s.
239        ///
240        /// [member]: super::guild::Member
241        const BAN_MEMBERS = 1 << 2;
242        /// Allows all permissions, bypassing channel [permission overwrite]s.
243        ///
244        /// [permission overwrite]: super::channel::PermissionOverwrite
245        const ADMINISTRATOR = 1 << 3;
246        /// Allows management and editing of guild [channel]s.
247        ///
248        /// [channel]: super::channel::GuildChannel
249        const MANAGE_CHANNELS = 1 << 4;
250        /// Allows management and editing of the [guild].
251        ///
252        /// [guild]: super::guild::Guild
253        const MANAGE_GUILD = 1 << 5;
254        /// [`Member`]s with this permission can add new [`Reaction`]s to a [`Message`]. Members
255        /// can still react using reactions already added to messages without this permission.
256        ///
257        /// [`Member`]: super::guild::Member
258        /// [`Message`]: super::channel::Message
259        /// [`Reaction`]: super::channel::Reaction
260        const ADD_REACTIONS = 1 << 6;
261        /// Allows viewing a guild's audit logs.
262        const VIEW_AUDIT_LOG = 1 << 7;
263        /// Allows the use of priority speaking in voice channels.
264        const PRIORITY_SPEAKER = 1 << 8;
265        /// Allows the user to go live.
266        const STREAM = 1 << 9;
267        /// Allows guild members to view a channel, which includes reading messages in text
268        /// channels and joining voice channels.
269        const VIEW_CHANNEL = 1 << 10;
270        /// Allows sending messages in a guild channel.
271        const SEND_MESSAGES = 1 << 11;
272        /// Allows the sending of text-to-speech messages in a channel.
273        const SEND_TTS_MESSAGES = 1 << 12;
274        /// Allows the deleting of other messages in a guild channel.
275        ///
276        /// **Note**: This does not allow the editing of other messages.
277        const MANAGE_MESSAGES = 1 << 13;
278        /// Allows links from this user - or users of this role - to be embedded, with potential
279        /// data such as a thumbnail, description, and page name.
280        const EMBED_LINKS = 1 << 14;
281        /// Allows uploading of files.
282        const ATTACH_FILES = 1 << 15;
283        /// Allows the reading of a channel's message history.
284        const READ_MESSAGE_HISTORY = 1 << 16;
285        /// Allows the usage of the `@everyone` mention, which will notify all users in a channel.
286        /// The `@here` mention will also be available, and can be used to mention all non-offline
287        /// users.
288        ///
289        /// **Note**: You probably want this to be disabled for most roles and users.
290        const MENTION_EVERYONE = 1 << 17;
291        /// Allows the usage of custom emojis from other guilds.
292        ///
293        /// This does not dictate whether custom emojis in this guild can be used in other guilds.
294        const USE_EXTERNAL_EMOJIS = 1 << 18;
295        /// Allows for viewing guild insights.
296        const VIEW_GUILD_INSIGHTS = 1 << 19;
297        /// Allows the joining of a voice channel.
298        const CONNECT = 1 << 20;
299        /// Allows the user to speak in a voice channel.
300        const SPEAK = 1 << 21;
301        /// Allows the muting of members in a voice channel.
302        const MUTE_MEMBERS = 1 << 22;
303        /// Allows the deafening of members in a voice channel.
304        const DEAFEN_MEMBERS = 1 << 23;
305        /// Allows the moving of members from one voice channel to another.
306        const MOVE_MEMBERS = 1 << 24;
307        /// Allows the usage of voice-activity-detection in a [voice] channel.
308        ///
309        /// If this is disabled, then [`Member`]s must use push-to-talk.
310        ///
311        /// [`Member`]: super::guild::Member
312        /// [voice]: super::channel::ChannelType::Voice
313        const USE_VAD = 1 << 25;
314        /// Allows members to change their own nickname in the guild.
315        const CHANGE_NICKNAME = 1 << 26;
316        /// Allows members to change other members' nicknames.
317        const MANAGE_NICKNAMES = 1 << 27;
318        /// Allows management and editing of roles below their own.
319        const MANAGE_ROLES = 1 << 28;
320        /// Allows management of webhooks.
321        const MANAGE_WEBHOOKS = 1 << 29;
322        /// Allows for editing and deleting emojis, stickers, and soundboard sounds created by all
323        /// users.
324        const MANAGE_GUILD_EXPRESSIONS = 1 << 30;
325        #[deprecated = "use `Permissions::MANAGE_GUILD_EXPRESSIONS` instead"]
326        const MANAGE_EMOJIS_AND_STICKERS = 1 << 30;
327        /// Allows members to use application commands, including slash commands and context menu
328        /// commands.
329        const USE_APPLICATION_COMMANDS = 1 << 31;
330        /// Allows for requesting to speak in stage channels.
331        const REQUEST_TO_SPEAK = 1 << 32;
332        /// Allows for editing, and deleting scheduled events created by all users.
333        const MANAGE_EVENTS = 1 << 33;
334        /// Allows for deleting and archiving threads, and viewing all private threads.
335        const MANAGE_THREADS = 1 << 34;
336        /// Allows for creating threads.
337        const CREATE_PUBLIC_THREADS = 1 << 35;
338        /// Allows for creating private threads.
339        const CREATE_PRIVATE_THREADS = 1 << 36;
340        /// Allows the usage of custom stickers from other servers.
341        const USE_EXTERNAL_STICKERS = 1 << 37;
342        /// Allows for sending messages in threads
343        const SEND_MESSAGES_IN_THREADS = 1 << 38;
344        /// Allows for launching activities in a voice channel
345        const USE_EMBEDDED_ACTIVITIES = 1 << 39;
346        /// Allows for timing out users to prevent them from sending or reacting to messages in
347        /// chat and threads, and from speaking in voice and stage channels.
348        const MODERATE_MEMBERS = 1 << 40;
349        /// Allows for viewing role subscription insights.
350        const VIEW_CREATOR_MONETIZATION_ANALYTICS = 1 << 41;
351        /// Allows for using soundboard in a voice channel.
352        const USE_SOUNDBOARD = 1 << 42;
353        /// Allows for creating emojis, stickers, and soundboard sounds, and editing and deleting
354        /// those created by the current user.
355        const CREATE_GUILD_EXPRESSIONS = 1 << 43;
356        /// Allows for creating scheduled events, and editing and deleting those created by the
357        /// current user.
358        const CREATE_EVENTS = 1 << 44;
359        /// Allows the usage of custom soundboard sounds from other servers.
360        const USE_EXTERNAL_SOUNDS = 1 << 45;
361        /// Allows sending voice messages.
362        const SEND_VOICE_MESSAGES = 1 << 46;
363        /// Allows setting the status of a voice channel.
364        const SET_VOICE_CHANNEL_STATUS = 1 << 48;
365        /// Allows attaching polls to message sends.
366        const SEND_POLLS = 1 << 49;
367        /// Allows user-installed apps to send public responses.
368        const USE_EXTERNAL_APPS = 1 << 50;
369    }
370}
371
372#[cfg(feature = "model")]
373generate_get_permission_names! {
374    add_reactions: "Add Reactions",
375    administrator: "Administrator",
376    attach_files: "Attach Files",
377    ban_members: "Ban Members",
378    change_nickname: "Change Nickname",
379    connect: "Connect",
380    create_events: "Create Events",
381    create_guild_expressions: "Create Guild Expressions",
382    create_instant_invite: "Create Instant Invite",
383    create_private_threads: "Create Private Threads",
384    create_public_threads: "Create Public Threads",
385    deafen_members: "Deafen Members",
386    embed_links: "Embed Links",
387    external_emojis: "Use External Emojis",
388    kick_members: "Kick Members",
389    manage_channels: "Manage Channels",
390    manage_events: "Manage Events",
391    manage_guild: "Manage Guilds",
392    manage_guild_expressions: "Manage Guild Expressions",
393    manage_messages: "Manage Messages",
394    manage_nicknames: "Manage Nicknames",
395    manage_roles: "Manage Roles",
396    manage_threads: "Manage Threads",
397    manage_webhooks: "Manage Webhooks",
398    mention_everyone: "Mention Everyone",
399    moderate_members: "Moderate Members",
400    move_members: "Move Members",
401    mute_members: "Mute Members",
402    priority_speaker: "Priority Speaker",
403    read_message_history: "Read Message History",
404    request_to_speak: "Request To Speak",
405    send_messages: "Send Messages",
406    send_messages_in_threads: "Send Messages in Threads",
407    send_tts_messages: "Send TTS Messages",
408    speak: "Speak",
409    stream: "Stream",
410    use_commands: "Use Application Commands",
411    use_embedded_activities: "Use Embedded Activities",
412    use_external_emojis: "Use External Emojis",
413    use_external_stickers: "Use External Stickers",
414    use_vad: "Use Voice Activity",
415    view_audit_log: "View Audit Log",
416    view_channel: "View Channel",
417    view_guild_insights: "View Guild Insights"
418}
419
420/// TODO: use a macro to shorten this entire file lol
421#[cfg(feature = "model")]
422impl Permissions {
423    #[must_use]
424    pub fn dm_permissions() -> Self {
425        Self::ADD_REACTIONS
426            | Self::STREAM
427            | Self::VIEW_CHANNEL
428            | Self::SEND_MESSAGES
429            | Self::SEND_TTS_MESSAGES
430            | Self::EMBED_LINKS
431            | Self::ATTACH_FILES
432            | Self::READ_MESSAGE_HISTORY
433            | Self::MENTION_EVERYONE
434            | Self::USE_EXTERNAL_EMOJIS
435            | Self::CONNECT
436            | Self::SPEAK
437            | Self::USE_VAD
438            | Self::USE_APPLICATION_COMMANDS
439            | Self::USE_EXTERNAL_STICKERS
440            | Self::SEND_VOICE_MESSAGES
441            | Self::SEND_POLLS
442            | Self::USE_EXTERNAL_APPS
443    }
444
445    /// Shorthand for checking that the set of permissions contains the [Add Reactions] permission.
446    ///
447    /// [Add Reactions]: Self::ADD_REACTIONS
448    #[must_use]
449    pub const fn add_reactions(self) -> bool {
450        self.contains(Self::ADD_REACTIONS)
451    }
452
453    /// Shorthand for checking that the set of permissions contains the [Administrator] permission.
454    ///
455    /// [Administrator]: Self::ADMINISTRATOR
456    #[must_use]
457    pub const fn administrator(self) -> bool {
458        self.contains(Self::ADMINISTRATOR)
459    }
460
461    /// Shorthand for checking that the set of permissions contains the [Attach Files] permission.
462    ///
463    /// [Attach Files]: Self::ATTACH_FILES
464    #[must_use]
465    pub const fn attach_files(self) -> bool {
466        self.contains(Self::ATTACH_FILES)
467    }
468
469    /// Shorthand for checking that the set of permissions contains the [Ban Members] permission.
470    ///
471    /// [Ban Members]: Self::BAN_MEMBERS
472    #[must_use]
473    pub const fn ban_members(self) -> bool {
474        self.contains(Self::BAN_MEMBERS)
475    }
476
477    /// Shorthand for checking that the set of permissions contains the [Change Nickname]
478    /// permission.
479    ///
480    /// [Change Nickname]: Self::CHANGE_NICKNAME
481    #[must_use]
482    pub const fn change_nickname(self) -> bool {
483        self.contains(Self::CHANGE_NICKNAME)
484    }
485
486    /// Shorthand for checking that the set of permissions contains the [Connect] permission.
487    ///
488    /// [Connect]: Self::CONNECT
489    #[must_use]
490    pub const fn connect(self) -> bool {
491        self.contains(Self::CONNECT)
492    }
493
494    /// Shorthand for checking that the set of permissions contains the [Create Events] permission.
495    ///
496    /// [Create Events]: Self::CREATE_EVENTS
497    #[must_use]
498    pub const fn create_events(self) -> bool {
499        self.contains(Self::CREATE_EVENTS)
500    }
501
502    /// Shorthand for checking that the set of permissions contains the [Create Guild Expressions]
503    /// permission.
504    ///
505    /// [Create Guild Expressions]: Self::CREATE_GUILD_EXPRESSIONS
506    #[must_use]
507    pub const fn create_guild_expressions(self) -> bool {
508        self.contains(Self::CREATE_GUILD_EXPRESSIONS)
509    }
510
511    /// Shorthand for checking that the set of permissions contains the [View Audit Log]
512    /// permission.
513    ///
514    /// [View Audit Log]: Self::VIEW_AUDIT_LOG
515    #[must_use]
516    pub const fn view_audit_log(self) -> bool {
517        self.contains(Self::VIEW_AUDIT_LOG)
518    }
519
520    /// Shorthand for checking that the set of permissions contains the [View Channel] permission.
521    ///
522    /// [View Channel]: Self::VIEW_CHANNEL
523    #[must_use]
524    pub const fn view_channel(self) -> bool {
525        self.contains(Self::VIEW_CHANNEL)
526    }
527
528    /// Shorthand for checking that the set of permissions contains the [View Guild Insights]
529    /// permission.
530    ///
531    /// [View Guild Insights]: Self::VIEW_GUILD_INSIGHTS
532    #[must_use]
533    pub const fn view_guild_insights(self) -> bool {
534        self.contains(Self::VIEW_GUILD_INSIGHTS)
535    }
536
537    /// Shorthand for checking that the set of permission contains the [Priority Speaker]
538    /// permission.
539    ///
540    /// [Priority Speaker]: Self::PRIORITY_SPEAKER
541    #[must_use]
542    pub const fn priority_speaker(self) -> bool {
543        self.contains(Self::PRIORITY_SPEAKER)
544    }
545
546    /// Shorthand for checking that the set of permission contains the [Stream] permission.
547    ///
548    /// [Stream]: Self::STREAM
549    #[must_use]
550    pub const fn stream(self) -> bool {
551        self.contains(Self::STREAM)
552    }
553
554    /// Shorthand for checking that the set of permissions contains the [Create Instant Invite]
555    /// permission.
556    ///
557    /// [Create Instant Invite]: Self::CREATE_INSTANT_INVITE
558    #[must_use]
559    pub const fn create_instant_invite(self) -> bool {
560        self.contains(Self::CREATE_INSTANT_INVITE)
561    }
562
563    /// Shorthand for checking that the set of permissions contains the [Create Private Threads]
564    /// permission.
565    ///
566    /// [Create Private Threads]: Self::CREATE_PRIVATE_THREADS
567    #[must_use]
568    pub const fn create_private_threads(self) -> bool {
569        self.contains(Self::CREATE_PRIVATE_THREADS)
570    }
571
572    /// Shorthand for checking that the set of permissions contains the [Create Public Threads]
573    /// permission.
574    ///
575    /// [Create Public Threads]: Self::CREATE_PUBLIC_THREADS
576    #[must_use]
577    pub const fn create_public_threads(self) -> bool {
578        self.contains(Self::CREATE_PUBLIC_THREADS)
579    }
580
581    /// Shorthand for checking that the set of permissions contains the [Deafen Members]
582    /// permission.
583    ///
584    /// [Deafen Members]: Self::DEAFEN_MEMBERS
585    #[must_use]
586    pub const fn deafen_members(self) -> bool {
587        self.contains(Self::DEAFEN_MEMBERS)
588    }
589
590    /// Shorthand for checking that the set of permissions contains the [Embed Links] permission.
591    ///
592    /// [Embed Links]: Self::EMBED_LINKS
593    #[must_use]
594    pub const fn embed_links(self) -> bool {
595        self.contains(Self::EMBED_LINKS)
596    }
597
598    /// Shorthand for checking that the set of permissions contains the [Use External Emojis]
599    /// permission.
600    ///
601    /// [Use External Emojis]: Self::USE_EXTERNAL_EMOJIS
602    #[must_use]
603    pub const fn external_emojis(self) -> bool {
604        self.contains(Self::USE_EXTERNAL_EMOJIS)
605    }
606
607    /// Shorthand for checking that the set of permissions contains the [Kick Members] permission.
608    ///
609    /// [Kick Members]: Self::KICK_MEMBERS
610    #[must_use]
611    pub const fn kick_members(self) -> bool {
612        self.contains(Self::KICK_MEMBERS)
613    }
614
615    /// Shorthand for checking that the set of permissions contains the [Manage Channels]
616    /// permission.
617    ///
618    /// [Manage Channels]: Self::MANAGE_CHANNELS
619    #[must_use]
620    pub const fn manage_channels(self) -> bool {
621        self.contains(Self::MANAGE_CHANNELS)
622    }
623
624    #[deprecated = "use `manage_guild_expressions` instead"]
625    #[must_use]
626    pub const fn manage_emojis_and_stickers(self) -> bool {
627        #[allow(deprecated)]
628        self.contains(Self::MANAGE_EMOJIS_AND_STICKERS)
629    }
630
631    /// Shorthand for checking that the set of permissions contains the [Manage Events] permission.
632    ///
633    /// [Manage Events]: Self::MANAGE_EVENTS
634    #[must_use]
635    pub fn manage_events(self) -> bool {
636        self.contains(Self::MANAGE_EVENTS)
637    }
638
639    /// Shorthand for checking that the set of permissions contains the [Manage Guild] permission.
640    ///
641    /// [Manage Guild]: Self::MANAGE_GUILD
642    #[must_use]
643    pub const fn manage_guild(self) -> bool {
644        self.contains(Self::MANAGE_GUILD)
645    }
646
647    /// Shorthand for checking that the set of permissions contains the [Manage Guild Expressions]
648    /// permission.
649    ///
650    /// [Manage Guild Expressions]: Self::MANAGE_GUILD_EXPRESSIONS
651    #[must_use]
652    pub const fn manage_guild_expressions(self) -> bool {
653        self.contains(Self::MANAGE_GUILD_EXPRESSIONS)
654    }
655
656    /// Shorthand for checking that the set of permissions contains the [Manage Messages]
657    /// permission.
658    ///
659    /// [Manage Messages]: Self::MANAGE_MESSAGES
660    #[must_use]
661    pub const fn manage_messages(self) -> bool {
662        self.contains(Self::MANAGE_MESSAGES)
663    }
664
665    /// Shorthand for checking that the set of permissions contains the [Manage Nicknames]
666    /// permission.
667    ///
668    /// [Manage Nicknames]: Self::MANAGE_NICKNAMES
669    #[must_use]
670    pub const fn manage_nicknames(self) -> bool {
671        self.contains(Self::MANAGE_NICKNAMES)
672    }
673
674    /// Shorthand for checking that the set of permissions contains the [Manage Roles] permission.
675    ///
676    /// [Manage Roles]: Self::MANAGE_ROLES
677    #[must_use]
678    pub const fn manage_roles(self) -> bool {
679        self.contains(Self::MANAGE_ROLES)
680    }
681
682    /// Shorthand for checking that the set of permissions contains the [Manage Threads]
683    /// permission.
684    ///
685    /// [Manage Threads]: Self::MANAGE_THREADS
686    #[must_use]
687    pub const fn manage_threads(self) -> bool {
688        self.contains(Self::MANAGE_THREADS)
689    }
690
691    /// Shorthand for checking that the set of permissions contains the [Manage Webhooks]
692    /// permission.
693    ///
694    /// [Manage Webhooks]: Self::MANAGE_WEBHOOKS
695    #[must_use]
696    pub const fn manage_webhooks(self) -> bool {
697        self.contains(Self::MANAGE_WEBHOOKS)
698    }
699
700    /// Shorthand for checking that the set of permissions contains the [Mention Everyone]
701    /// permission.
702    ///
703    /// [Mention Everyone]: Self::MENTION_EVERYONE
704    #[must_use]
705    pub const fn mention_everyone(self) -> bool {
706        self.contains(Self::MENTION_EVERYONE)
707    }
708
709    /// Shorthand for checking that the set of permissions contains the [Moderate Members]
710    /// permission.
711    ///
712    /// [Moderate Members]: Self::MODERATE_MEMBERS
713    #[must_use]
714    pub const fn moderate_members(self) -> bool {
715        self.contains(Self::MODERATE_MEMBERS)
716    }
717
718    /// Shorthand for checking that the set of permissions contains the [Move Members] permission.
719    ///
720    /// [Move Members]: Self::MOVE_MEMBERS
721    #[must_use]
722    pub const fn move_members(self) -> bool {
723        self.contains(Self::MOVE_MEMBERS)
724    }
725
726    /// Shorthand for checking that the set of permissions contains the [Mute Members] permission.
727    ///
728    /// [Mute Members]: Self::MUTE_MEMBERS
729    #[must_use]
730    pub const fn mute_members(self) -> bool {
731        self.contains(Self::MUTE_MEMBERS)
732    }
733
734    /// Shorthand for checking that the set of permissions contains the [Read Message History]
735    /// permission.
736    ///
737    /// [Read Message History]: Self::READ_MESSAGE_HISTORY
738    #[must_use]
739    pub const fn read_message_history(self) -> bool {
740        self.contains(Self::READ_MESSAGE_HISTORY)
741    }
742
743    /// Shorthand for checking that the set of permissions contains the [Send Messages] permission.
744    ///
745    /// [Send Messages]: Self::SEND_MESSAGES
746    #[must_use]
747    pub const fn send_messages(self) -> bool {
748        self.contains(Self::SEND_MESSAGES)
749    }
750
751    /// Shorthand for checking that the set of permissions contains the [Send Messages in Threads]
752    /// permission.
753    ///
754    /// [Send Messages in Threads]: Self::SEND_MESSAGES_IN_THREADS
755    #[must_use]
756    pub const fn send_messages_in_threads(self) -> bool {
757        self.contains(Self::SEND_MESSAGES_IN_THREADS)
758    }
759
760    /// Shorthand for checking that the set of permissions contains the [Send TTS Messages]
761    /// permission.
762    ///
763    /// [Send TTS Messages]: Self::SEND_TTS_MESSAGES
764    #[must_use]
765    pub const fn send_tts_messages(self) -> bool {
766        self.contains(Self::SEND_TTS_MESSAGES)
767    }
768
769    /// Shorthand for checking that the set of permissions contains the [Speak] permission.
770    ///
771    /// [Speak]: Self::SPEAK
772    #[must_use]
773    pub const fn speak(self) -> bool {
774        self.contains(Self::SPEAK)
775    }
776
777    /// Shorthand for checking that the set of permissions contains the [Request To Speak]
778    /// permission.
779    ///
780    /// [Request To Speak]: Self::REQUEST_TO_SPEAK
781    #[must_use]
782    pub const fn request_to_speak(self) -> bool {
783        self.contains(Self::REQUEST_TO_SPEAK)
784    }
785
786    /// Shorthand for checking that the set of permissions contains the [Use Embedded Activities]
787    /// permission.
788    ///
789    /// [Use Embedded Activities]: Self::USE_EMBEDDED_ACTIVITIES
790    #[must_use]
791    pub const fn use_embedded_activities(self) -> bool {
792        self.contains(Self::USE_EMBEDDED_ACTIVITIES)
793    }
794
795    /// Shorthand for checking that the set of permissions contains the [Use External Emojis]
796    /// permission.
797    ///
798    /// [Use External Emojis]: Self::USE_EXTERNAL_EMOJIS
799    #[must_use]
800    pub const fn use_external_emojis(self) -> bool {
801        self.contains(Self::USE_EXTERNAL_EMOJIS)
802    }
803
804    /// Shorthand for checking that the set of permissions contains the [Use External Stickers]
805    /// permission.
806    ///
807    /// [Use External Stickers]: Self::USE_EXTERNAL_STICKERS
808    #[must_use]
809    pub const fn use_external_stickers(self) -> bool {
810        self.contains(Self::USE_EXTERNAL_STICKERS)
811    }
812
813    /// Shorthand for checking that the set of permissions contains the [Use Application Commands]
814    /// permission.
815    ///
816    /// [Use Application Commands]: Self::USE_APPLICATION_COMMANDS
817    #[must_use]
818    pub const fn use_commands(self) -> bool {
819        self.contains(Self::USE_APPLICATION_COMMANDS)
820    }
821
822    /// Shorthand for checking that the set of permissions contains the [Use VAD] permission.
823    ///
824    /// [Use VAD]: Self::USE_VAD
825    #[must_use]
826    pub const fn use_vad(self) -> bool {
827        self.contains(Self::USE_VAD)
828    }
829
830    /// Shorthand for checking that the set of permissions contains the [Send Polls] permission.
831    ///
832    /// [Send Polls]: Self::SEND_POLLS
833    #[must_use]
834    pub const fn send_polls(self) -> bool {
835        self.contains(Self::SEND_POLLS)
836    }
837    /// Shorthand for checking that the set of permissions contains the [Use External Apps]
838    /// permission.
839    ///
840    /// [Use External Apps]: Self::USE_EXTERNAL_APPS
841    #[must_use]
842    pub const fn use_external_apps(self) -> bool {
843        self.contains(Self::USE_EXTERNAL_APPS)
844    }
845}
846
847// Manual impl needed because Permissions are usually sent as a stringified integer,
848// but audit log changes are sent as an int, which is probably a problem.
849impl<'de> Deserialize<'de> for Permissions {
850    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
851        let val = StrOrInt::deserialize(deserializer)?;
852        let val = val.parse().map_err(serde::de::Error::custom)?;
853
854        Ok(Permissions::from_bits_truncate(val))
855    }
856}
857
858impl Serialize for Permissions {
859    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
860        serializer.collect_str(&self.bits())
861    }
862}
863
864#[cfg(feature = "model")]
865impl fmt::Display for Permissions {
866    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
867        let names = self.get_permission_names();
868
869        let total = names.len();
870        for (i, &name) in names.iter().enumerate() {
871            if i > 0 && i != total - 1 {
872                f.write_str(", ")?;
873            }
874
875            if total > 1 && i == total - 1 {
876                f.write_str(" and ")?;
877            }
878
879            f.write_str(name)?;
880        }
881
882        Ok(())
883    }
884}
885
886#[cfg(test)]
887mod tests {
888    use super::*;
889    use crate::json::{assert_json, json};
890
891    #[test]
892    fn permissions_serde() {
893        let value = Permissions::MANAGE_GUILD | Permissions::MANAGE_ROLES;
894        assert_json(&value, json!("268435488"));
895    }
896}