pub mod application_command;
pub mod autocomplete;
pub mod message_component;
pub mod modal;
pub mod ping;
use serde::de::{Deserialize, Deserializer, Error as DeError};
use serde::ser::{Serialize, Serializer};
use self::application_command::ApplicationCommandInteraction;
use self::autocomplete::AutocompleteInteraction;
use self::message_component::MessageComponentInteraction;
use self::modal::ModalSubmitInteraction;
use self::ping::PingInteraction;
use crate::json::{from_value, JsonMap, Value};
use crate::model::id::{ApplicationId, InteractionId};
use crate::model::user::User;
use crate::model::Permissions;
#[derive(Clone, Debug)]
pub enum Interaction {
Ping(PingInteraction),
ApplicationCommand(ApplicationCommandInteraction),
MessageComponent(MessageComponentInteraction),
Autocomplete(AutocompleteInteraction),
ModalSubmit(ModalSubmitInteraction),
}
impl Interaction {
#[must_use]
pub fn id(&self) -> InteractionId {
match self {
Self::Ping(i) => i.id,
Self::ApplicationCommand(i) => i.id,
Self::MessageComponent(i) => i.id,
Self::Autocomplete(i) => i.id,
Self::ModalSubmit(i) => i.id,
}
}
#[must_use]
pub fn kind(&self) -> InteractionType {
match self {
Self::Ping(_) => InteractionType::Ping,
Self::ApplicationCommand(_) => InteractionType::ApplicationCommand,
Self::MessageComponent(_) => InteractionType::MessageComponent,
Self::Autocomplete(_) => InteractionType::Autocomplete,
Self::ModalSubmit(_) => InteractionType::ModalSubmit,
}
}
#[must_use]
pub fn app_permissions(&self) -> Option<Permissions> {
match self {
Self::Ping(_) => None,
Self::ApplicationCommand(i) => i.app_permissions,
Self::MessageComponent(i) => i.app_permissions,
Self::Autocomplete(i) => i.app_permissions,
Self::ModalSubmit(i) => i.app_permissions,
}
}
#[must_use]
pub fn application_id(&self) -> ApplicationId {
match self {
Self::Ping(i) => i.application_id,
Self::ApplicationCommand(i) => i.application_id,
Self::MessageComponent(i) => i.application_id,
Self::Autocomplete(i) => i.application_id,
Self::ModalSubmit(i) => i.application_id,
}
}
#[must_use]
pub fn token(&self) -> &str {
match self {
Self::Ping(ref i) => i.token.as_str(),
Self::ApplicationCommand(i) => i.token.as_str(),
Self::MessageComponent(i) => i.token.as_str(),
Self::Autocomplete(i) => i.token.as_str(),
Self::ModalSubmit(i) => i.token.as_str(),
}
}
#[must_use]
pub fn guild_locale(&self) -> Option<&str> {
match self {
Self::Ping(i) => i.guild_locale.as_deref(),
Self::ApplicationCommand(i) => i.guild_locale.as_deref(),
Self::MessageComponent(i) => i.guild_locale.as_deref(),
Self::Autocomplete(i) => i.guild_locale.as_deref(),
Self::ModalSubmit(i) => i.guild_locale.as_deref(),
}
}
#[must_use]
pub fn ping(self) -> Option<PingInteraction> {
match self {
Self::Ping(i) => Some(i),
_ => None,
}
}
#[must_use]
pub fn application_command(self) -> Option<ApplicationCommandInteraction> {
match self {
Self::ApplicationCommand(i) => Some(i),
_ => None,
}
}
#[must_use]
pub fn message_component(self) -> Option<MessageComponentInteraction> {
match self {
Self::MessageComponent(i) => Some(i),
_ => None,
}
}
#[must_use]
pub fn autocomplete(self) -> Option<AutocompleteInteraction> {
match self {
Self::Autocomplete(i) => Some(i),
_ => None,
}
}
#[must_use]
pub fn modal_submit(self) -> Option<ModalSubmitInteraction> {
match self {
Self::ModalSubmit(i) => Some(i),
_ => None,
}
}
}
impl<'de> Deserialize<'de> for Interaction {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
let map = JsonMap::deserialize(deserializer)?;
let kind = map
.get("type")
.ok_or_else(|| DeError::custom("expected type"))
.and_then(InteractionType::deserialize)
.map_err(DeError::custom)?;
match kind {
InteractionType::Ping => from_value::<PingInteraction>(Value::from(map))
.map(Interaction::Ping)
.map_err(DeError::custom),
InteractionType::ApplicationCommand => {
from_value::<ApplicationCommandInteraction>(Value::from(map))
.map(Interaction::ApplicationCommand)
.map_err(DeError::custom)
},
InteractionType::MessageComponent => {
from_value::<MessageComponentInteraction>(Value::from(map))
.map(Interaction::MessageComponent)
.map_err(DeError::custom)
},
InteractionType::Autocomplete => {
from_value::<AutocompleteInteraction>(Value::from(map))
.map(Interaction::Autocomplete)
.map_err(DeError::custom)
},
InteractionType::ModalSubmit => from_value::<ModalSubmitInteraction>(Value::from(map))
.map(Interaction::ModalSubmit)
.map_err(DeError::custom),
InteractionType::Unknown => Err(DeError::custom("Unknown interaction type")),
}
}
}
impl Serialize for Interaction {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
match self {
Self::Ping(i) => PingInteraction::serialize(i, serializer),
Self::ApplicationCommand(i) => ApplicationCommandInteraction::serialize(i, serializer),
Self::MessageComponent(i) => MessageComponentInteraction::serialize(i, serializer),
Self::Autocomplete(i) => AutocompleteInteraction::serialize(i, serializer),
Self::ModalSubmit(i) => ModalSubmitInteraction::serialize(i, serializer),
}
}
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
#[non_exhaustive]
#[repr(u8)]
pub enum InteractionType {
Ping = 1,
ApplicationCommand = 2,
MessageComponent = 3,
Autocomplete = 4,
ModalSubmit = 5,
Unknown = !0,
}
enum_number!(InteractionType {
Ping,
MessageComponent,
ApplicationCommand,
Autocomplete,
ModalSubmit
});
bitflags! {
#[derive(Default)]
pub struct MessageFlags: u64 {
const SUPPRESS_EMBEDS = 1 << 2;
const EPHEMERAL = 1 << 6;
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct MessageInteraction {
pub id: InteractionId,
#[serde(rename = "type")]
pub kind: InteractionType,
pub name: String,
pub user: User,
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq, PartialOrd, Ord)]
#[non_exhaustive]
#[repr(u8)]
pub enum InteractionResponseType {
Pong = 1,
ChannelMessageWithSource = 4,
DeferredChannelMessageWithSource = 5,
DeferredUpdateMessage = 6,
UpdateMessage = 7,
Autocomplete = 8,
Modal = 9,
}