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