use crate::channel::ChannelType;
use serde::{Deserialize, Serialize};
use serde_repr::{Deserialize_repr, Serialize_repr};
use std::{
cmp::Eq,
collections::HashMap,
ops::{Range, RangeInclusive},
};
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct CommandOption {
#[serde(skip_serializing_if = "Option::is_none")]
pub autocomplete: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub channel_types: Option<Vec<ChannelType>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub choices: Option<Vec<CommandOptionChoice>>,
pub description: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub description_localizations: Option<HashMap<String, String>>,
#[serde(rename = "type")]
pub kind: CommandOptionType,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_length: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
pub max_value: Option<CommandOptionValue>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_length: Option<u16>,
#[serde(skip_serializing_if = "Option::is_none")]
pub min_value: Option<CommandOptionValue>,
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name_localizations: Option<HashMap<String, String>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub options: Option<Vec<CommandOption>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub required: Option<bool>,
}
impl CommandOption {
pub const STRING_LENGTH_RANGE: RangeInclusive<u16> = 0..=6000;
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct CommandOptionChoice {
pub name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub name_localizations: Option<HashMap<String, String>>,
pub value: CommandOptionChoiceValue,
}
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
#[serde(untagged)]
pub enum CommandOptionChoiceValue {
String(String),
Integer(i64),
Number(f64),
}
#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Serialize)]
#[serde(untagged)]
pub enum CommandOptionValue {
Integer(i64),
Number(f64),
}
impl CommandOptionValue {
pub const INTEGER_RANGE: Range<i64> =
-(2_i64.pow(f64::MANTISSA_DIGITS) - 1)..(2_i64.pow(f64::MANTISSA_DIGITS));
#[allow(clippy::cast_precision_loss)]
pub const NUMBER_RANGE: RangeInclusive<f64> =
(Self::INTEGER_RANGE.start as f64)..=((Self::INTEGER_RANGE.end - 1) as f64);
}
#[derive(Clone, Copy, Debug, Deserialize_repr, Eq, Hash, PartialEq, Serialize_repr)]
#[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,
}
impl CommandOptionType {
pub const fn kind(self) -> &'static str {
match self {
CommandOptionType::SubCommand => "SubCommand",
CommandOptionType::SubCommandGroup => "SubCommandGroup",
CommandOptionType::String => "String",
CommandOptionType::Integer => "Integer",
CommandOptionType::Boolean => "Boolean",
CommandOptionType::User => "User",
CommandOptionType::Channel => "Channel",
CommandOptionType::Role => "Role",
CommandOptionType::Mentionable => "Mentionable",
CommandOptionType::Number => "Number",
CommandOptionType::Attachment => "Attachment",
}
}
}