use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[cfg(feature = "http")]
use crate::builder::{CreateApplicationCommand, CreateApplicationCommands};
#[cfg(feature = "http")]
use crate::http::Http;
#[cfg(feature = "http")]
use crate::internal::prelude::*;
use crate::json::Value;
#[cfg(feature = "http")]
use crate::json::{self, JsonMap};
use crate::model::channel::ChannelType;
use crate::model::id::{
ApplicationId,
CommandId,
CommandPermissionId,
CommandVersionId,
GuildId,
RoleId,
UserId,
};
use crate::model::Permissions;
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct Command {
pub id: CommandId,
#[serde(rename = "type")]
pub kind: CommandType,
pub application_id: ApplicationId,
pub guild_id: Option<GuildId>,
pub name: String,
pub name_localized: Option<String>,
pub name_localizations: Option<HashMap<String, String>>,
pub description: String,
pub description_localized: Option<String>,
pub description_localizations: Option<HashMap<String, String>>,
#[serde(default)]
pub options: Vec<CommandOption>,
pub default_member_permissions: Option<Permissions>,
#[serde(default)]
pub dm_permission: Option<bool>,
#[serde(default = "default_permission_value")]
#[deprecated(note = "replaced by `default_member_permissions`")]
pub default_permission: bool,
pub version: CommandVersionId,
}
fn default_permission_value() -> bool {
true
}
#[cfg(feature = "http")]
impl Command {
pub async fn create_global_application_command<F>(
http: impl AsRef<Http>,
f: F,
) -> Result<Command>
where
F: FnOnce(&mut CreateApplicationCommand) -> &mut CreateApplicationCommand,
{
let map = Command::build_application_command(f);
http.as_ref().create_global_application_command(&Value::from(map)).await
}
pub async fn set_global_application_commands<F>(
http: impl AsRef<Http>,
f: F,
) -> Result<Vec<Command>>
where
F: FnOnce(&mut CreateApplicationCommands) -> &mut CreateApplicationCommands,
{
let mut array = CreateApplicationCommands::default();
f(&mut array);
http.as_ref().create_global_application_commands(&Value::from(array.0)).await
}
pub async fn edit_global_application_command<F>(
http: impl AsRef<Http>,
command_id: CommandId,
f: F,
) -> Result<Command>
where
F: FnOnce(&mut CreateApplicationCommand) -> &mut CreateApplicationCommand,
{
let map = Command::build_application_command(f);
http.as_ref().edit_global_application_command(command_id.into(), &Value::from(map)).await
}
pub async fn get_global_application_commands(http: impl AsRef<Http>) -> Result<Vec<Command>> {
http.as_ref().get_global_application_commands().await
}
pub async fn get_global_application_command(
http: impl AsRef<Http>,
command_id: CommandId,
) -> Result<Command> {
http.as_ref().get_global_application_command(command_id.into()).await
}
pub async fn delete_global_application_command(
http: impl AsRef<Http>,
command_id: CommandId,
) -> Result<()> {
http.as_ref().delete_global_application_command(command_id.into()).await
}
}
#[cfg(feature = "http")]
impl Command {
#[inline]
pub(crate) fn build_application_command<F>(f: F) -> JsonMap
where
F: FnOnce(&mut CreateApplicationCommand) -> &mut CreateApplicationCommand,
{
let mut create_application_command = CreateApplicationCommand::default();
f(&mut create_application_command);
json::hashmap_to_json_map(create_application_command.0)
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
#[non_exhaustive]
#[repr(u8)]
pub enum CommandType {
ChatInput = 1,
User = 2,
Message = 3,
Unknown = !0,
}
enum_number!(CommandType {
ChatInput,
User,
Message
});
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct CommandOption {
#[serde(rename = "type")]
pub kind: CommandOptionType,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name_localizations: Option<std::collections::HashMap<String, String>>,
pub description: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description_localizations: Option<std::collections::HashMap<String, String>>,
#[serde(default)]
pub required: bool,
#[serde(default)]
pub choices: Vec<CommandOptionChoice>,
#[serde(default)]
pub options: Vec<CommandOption>,
#[serde(default)]
pub channel_types: Vec<ChannelType>,
#[serde(default)]
pub min_value: Option<serde_json::Number>,
#[serde(default)]
pub max_value: Option<serde_json::Number>,
#[serde(default)]
pub min_length: Option<u16>,
#[serde(default)]
pub max_length: Option<u16>,
#[serde(default)]
pub autocomplete: bool,
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
#[non_exhaustive]
#[repr(u8)]
pub enum CommandOptionType {
SubCommand = 1,
SubCommandGroup = 2,
String = 3,
Integer = 4,
Boolean = 5,
User = 6,
Channel = 7,
Role = 8,
Mentionable = 9,
Number = 10,
Attachment = 11,
Unknown = !0,
}
enum_number!(CommandOptionType {
SubCommand,
SubCommandGroup,
String,
Integer,
Boolean,
User,
Channel,
Role,
Mentionable,
Number,
Attachment
});
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct CommandOptionChoice {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name_localizations: Option<std::collections::HashMap<String, String>>,
pub value: Value,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct CommandPermission {
pub id: CommandId,
pub application_id: ApplicationId,
pub guild_id: GuildId,
pub permissions: Vec<CommandPermissionData>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct CommandPermissionData {
pub id: CommandPermissionId,
#[serde(rename = "type")]
pub kind: CommandPermissionType,
pub permission: bool,
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
#[non_exhaustive]
#[repr(u8)]
pub enum CommandPermissionType {
Role = 1,
User = 2,
Channel = 3,
Unknown = !0,
}
enum_number!(CommandPermissionType {
Role,
User,
Channel,
});
impl CommandPermissionId {
#[must_use]
pub fn to_user_id(self) -> UserId {
self.0.into()
}
#[must_use]
pub fn to_role_id(self) -> RoleId {
self.0.into()
}
}
impl From<RoleId> for CommandPermissionId {
fn from(id: RoleId) -> Self {
Self(id.0)
}
}
impl<'a> From<&'a RoleId> for CommandPermissionId {
fn from(id: &RoleId) -> Self {
Self(id.0)
}
}
impl From<UserId> for CommandPermissionId {
fn from(id: UserId) -> Self {
Self(id.0)
}
}
impl<'a> From<&'a UserId> for CommandPermissionId {
fn from(id: &UserId) -> Self {
Self(id.0)
}
}
impl From<CommandPermissionId> for RoleId {
fn from(id: CommandPermissionId) -> Self {
Self(id.0)
}
}
impl From<CommandPermissionId> for UserId {
fn from(id: CommandPermissionId) -> Self {
Self(id.0)
}
}