serenity/builder/
create_command_permission.rs

1#[cfg(feature = "http")]
2use super::Builder;
3#[cfg(feature = "http")]
4use crate::http::CacheHttp;
5#[cfg(feature = "http")]
6use crate::internal::prelude::*;
7use crate::model::prelude::*;
8
9/// A builder for creating several [`CommandPermission`].
10///
11/// [Discord docs](https://discord.com/developers/docs/interactions/application-commands#edit-application-command-permissions).
12// Cannot be replaced by a simple Vec<CreateCommandPermission> because we need the schema with
13// the `permissions` field, and also to be forward compatible if a new field beyond just
14// `permissions` is added to the HTTP endpoint
15#[derive(Clone, Debug, Default, Serialize)]
16#[must_use]
17pub struct EditCommandPermissions {
18    permissions: Vec<CreateCommandPermission>,
19}
20
21impl EditCommandPermissions {
22    pub fn new(permissions: Vec<CreateCommandPermission>) -> Self {
23        Self {
24            permissions,
25        }
26    }
27}
28
29#[cfg(feature = "http")]
30#[async_trait::async_trait]
31impl Builder for EditCommandPermissions {
32    type Context<'ctx> = (GuildId, CommandId);
33    type Built = CommandPermissions;
34
35    /// Create permissions for a guild application command. These will overwrite any existing
36    /// permissions for that command.
37    ///
38    /// **Note**: The permissions will update instantly.
39    ///
40    /// # Errors
41    ///
42    /// Returns [`Error::Http`] if invalid data is given. See [Discord's docs] for more details.
43    ///
44    /// May also return [`Error::Json`] if there is an error in deserializing the API response.
45    ///
46    /// [Discord's docs]: https://discord.com/developers/docs/interactions/slash-commands
47    #[cfg(feature = "http")]
48    async fn execute(
49        self,
50        cache_http: impl CacheHttp,
51        ctx: Self::Context<'_>,
52    ) -> Result<Self::Built> {
53        cache_http.http().edit_guild_command_permissions(ctx.0, ctx.1, &self).await
54    }
55}
56
57/// A builder for creating an [`CommandPermission`].
58///
59/// [Discord docs](https://discord.com/developers/docs/interactions/application-commands#application-command-permissions-object-application-command-permissions-structure).
60#[derive(Clone, Debug, Serialize)]
61#[must_use]
62pub struct CreateCommandPermission(CommandPermission);
63
64impl CreateCommandPermission {
65    /// Creates a permission overwrite for a specific role
66    pub fn role(id: RoleId, allow: bool) -> Self {
67        Self(CommandPermission {
68            id: id.into(),
69            kind: CommandPermissionType::Role,
70            permission: allow,
71        })
72    }
73
74    /// Creates a permission overwrite for a specific user
75    pub fn user(id: UserId, allow: bool) -> Self {
76        Self(CommandPermission {
77            id: id.into(),
78            kind: CommandPermissionType::User,
79            permission: allow,
80        })
81    }
82
83    /// Creates a permission overwrite for a specific channel
84    pub fn channel(id: ChannelId, allow: bool) -> Self {
85        Self(CommandPermission {
86            id: id.get().into(),
87            kind: CommandPermissionType::Channel,
88            permission: allow,
89        })
90    }
91
92    /// Creates a permission overwrite for a everyone in a guild
93    pub fn everyone(guild_id: GuildId, allow: bool) -> Self {
94        Self(CommandPermission {
95            id: guild_id.get().into(),
96            kind: CommandPermissionType::User,
97            permission: allow,
98        })
99    }
100
101    /// Creates a permission overwrite for all channels in a guild
102    pub fn all_channels(guild_id: GuildId, allow: bool) -> Self {
103        Self(CommandPermission {
104            id: std::num::NonZeroU64::new(guild_id.get() - 1).expect("guild ID was 1").into(),
105            kind: CommandPermissionType::Channel,
106            permission: allow,
107        })
108    }
109}