use std::collections::HashMap;
use std::convert::TryFrom;
use std::fmt;
use serde::de::{Error as DeError, IgnoredAny, MapAccess};
use super::prelude::*;
use super::utils::{emojis, roles, stickers};
use crate::constants::OpCode;
use crate::internal::prelude::*;
use crate::json::prelude::*;
use crate::model::application::command::CommandPermission;
use crate::model::application::interaction::Interaction;
use crate::model::guild::automod::{ActionExecution, Rule};
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct ApplicationCommandPermissionsUpdateEvent {
pub permission: CommandPermission,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct AutoModerationRuleCreateEvent {
pub rule: Rule,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct AutoModerationRuleUpdateEvent {
pub rule: Rule,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct AutoModerationRuleDeleteEvent {
pub rule: Rule,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct AutoModerationActionExecutionEvent {
pub execution: ActionExecution,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct ChannelCreateEvent {
pub channel: Channel,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct ChannelDeleteEvent {
pub channel: Channel,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct ChannelPinsUpdateEvent {
pub guild_id: Option<GuildId>,
pub channel_id: ChannelId,
pub last_pin_timestamp: Option<Timestamp>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct ChannelUpdateEvent {
pub channel: Channel,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct GuildBanAddEvent {
pub guild_id: GuildId,
pub user: User,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct GuildBanRemoveEvent {
pub guild_id: GuildId,
pub user: User,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct GuildCreateEvent {
pub guild: Guild,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct GuildDeleteEvent {
pub guild: UnavailableGuild,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct GuildEmojisUpdateEvent {
#[serde(with = "emojis")]
pub emojis: HashMap<EmojiId, Emoji>,
pub guild_id: GuildId,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct GuildIntegrationsUpdateEvent {
pub guild_id: GuildId,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct GuildMemberAddEvent {
pub member: Member,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct GuildMemberRemoveEvent {
pub guild_id: GuildId,
pub user: User,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct GuildMemberUpdateEvent {
pub guild_id: GuildId,
pub nick: Option<String>,
pub joined_at: Timestamp,
pub roles: Vec<RoleId>,
pub user: User,
pub premium_since: Option<Timestamp>,
#[serde(default)]
pub pending: bool,
#[serde(default)]
pub deaf: bool,
#[serde(default)]
pub mute: bool,
pub avatar: Option<String>,
pub communication_disabled_until: Option<Timestamp>,
}
#[derive(Clone, Debug, Serialize)]
#[non_exhaustive]
pub struct GuildMembersChunkEvent {
pub guild_id: GuildId,
pub members: HashMap<UserId, Member>,
pub chunk_index: u32,
pub chunk_count: u32,
pub nonce: Option<String>,
}
impl<'de> Deserialize<'de> for GuildMembersChunkEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
#[derive(Deserialize)]
#[serde(field_identifier, rename_all = "snake_case")]
enum Field {
GuildId,
ChunkIndex,
ChunkCount,
Members,
Nonce,
Unknown(String),
}
struct GuildMembersChunkVisitor;
impl<'de> Visitor<'de> for GuildMembersChunkVisitor {
type Value = GuildMembersChunkEvent;
fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
formatter.write_str("struct GuildMembersChunkEvent")
}
fn visit_map<A: MapAccess<'de>>(self, mut map: A) -> StdResult<Self::Value, A::Error> {
let mut guild_id = None;
let mut chunk_index = None;
let mut chunk_count = None;
let mut members = None;
let mut nonce = None;
while let Some(key) = map.next_key()? {
match key {
Field::GuildId => {
if guild_id.is_some() {
return Err(DeError::duplicate_field("guild_id"));
}
guild_id = Some(map.next_value()?);
},
Field::ChunkIndex => {
if chunk_index.is_some() {
return Err(DeError::duplicate_field("chunk_index"));
}
chunk_index = Some(map.next_value()?);
},
Field::ChunkCount => {
if chunk_count.is_some() {
return Err(DeError::duplicate_field("chunk_count"));
}
chunk_count = Some(map.next_value()?);
},
Field::Members => {
if members.is_some() {
return Err(DeError::duplicate_field("members"));
}
members = Some(map.next_value::<Vec<InterimMember>>()?);
},
Field::Nonce => {
if nonce.is_some() {
return Err(DeError::duplicate_field("nonce"));
}
nonce = Some(map.next_value()?);
},
Field::Unknown(_) => {
map.next_value::<IgnoredAny>()?;
},
}
}
let guild_id = guild_id.ok_or_else(|| DeError::missing_field("guild_id"))?;
let chunk_index =
chunk_index.ok_or_else(|| DeError::missing_field("chunk_index"))?;
let chunk_count =
chunk_count.ok_or_else(|| DeError::missing_field("chunk_count"))?;
let members = members.ok_or_else(|| DeError::missing_field("members"))?;
let members = members
.into_iter()
.map(|m| {
let mut m = Member::from(m);
m.guild_id = guild_id;
(m.user.id, m)
})
.collect();
Ok(GuildMembersChunkEvent {
guild_id,
members,
chunk_index,
chunk_count,
nonce,
})
}
}
const FIELDS: &[&str] = &["guild_id", "chunk_index", "chunk_count", "members", "nonce"];
deserializer.deserialize_struct("GuildMembersChunkEvent", FIELDS, GuildMembersChunkVisitor)
}
}
#[derive(Clone, Debug, Serialize)]
#[non_exhaustive]
pub struct GuildRoleCreateEvent {
pub role: Role,
}
impl<'de> Deserialize<'de> for GuildRoleCreateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
role: roles::deserialize_event(deserializer)?,
})
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct GuildRoleDeleteEvent {
pub guild_id: GuildId,
pub role_id: RoleId,
}
#[derive(Clone, Debug, Serialize)]
#[non_exhaustive]
pub struct GuildRoleUpdateEvent {
pub role: Role,
}
impl<'de> Deserialize<'de> for GuildRoleUpdateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
role: roles::deserialize_event(deserializer)?,
})
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct GuildStickersUpdateEvent {
#[serde(with = "stickers")]
pub stickers: HashMap<StickerId, Sticker>,
pub guild_id: GuildId,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct InviteCreateEvent {
pub channel_id: ChannelId,
pub code: String,
pub guild_id: Option<GuildId>,
pub inviter: Option<User>,
pub max_age: u64,
pub max_uses: u64,
pub temporary: bool,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct InviteDeleteEvent {
pub channel_id: ChannelId,
pub guild_id: Option<GuildId>,
pub code: String,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct GuildUnavailableEvent {
#[serde(rename = "id")]
pub guild_id: GuildId,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct GuildUpdateEvent {
pub guild: PartialGuild,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct MessageCreateEvent {
pub message: Message,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct MessageDeleteBulkEvent {
pub guild_id: Option<GuildId>,
pub channel_id: ChannelId,
pub ids: Vec<MessageId>,
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct MessageDeleteEvent {
pub guild_id: Option<GuildId>,
pub channel_id: ChannelId,
#[serde(rename = "id")]
pub message_id: MessageId,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct MessageUpdateEvent {
pub id: MessageId,
pub guild_id: Option<GuildId>,
pub channel_id: ChannelId,
pub kind: Option<MessageType>,
pub content: Option<String>,
pub nonce: Option<String>,
pub tts: Option<bool>,
pub pinned: Option<bool>,
pub timestamp: Option<Timestamp>,
pub edited_timestamp: Option<Timestamp>,
pub author: Option<User>,
pub mention_everyone: Option<bool>,
pub mentions: Option<Vec<User>>,
pub mention_roles: Option<Vec<RoleId>>,
pub attachments: Option<Vec<Attachment>>,
pub embeds: Option<Vec<Embed>>,
pub flags: Option<MessageFlags>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct PresenceUpdateEvent {
pub presence: Presence,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct PresencesReplaceEvent {
pub presences: Vec<Presence>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct ReactionAddEvent {
pub reaction: Reaction,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct ReactionRemoveEvent {
pub reaction: Reaction,
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct ReactionRemoveAllEvent {
pub guild_id: Option<GuildId>,
pub channel_id: ChannelId,
pub message_id: MessageId,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct ReadyEvent {
pub ready: Ready,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct ResumedEvent {
#[serde(rename = "_trace")]
pub trace: Vec<Option<String>>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct TypingStartEvent {
pub guild_id: Option<GuildId>,
pub channel_id: ChannelId,
pub timestamp: u64,
pub user_id: UserId,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct UnknownEvent {
pub kind: String,
pub value: Value,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct UserUpdateEvent {
pub current_user: CurrentUser,
}
#[derive(Clone, Deserialize, Serialize)]
#[non_exhaustive]
pub struct VoiceServerUpdateEvent {
pub channel_id: Option<ChannelId>,
pub endpoint: Option<String>,
pub guild_id: Option<GuildId>,
pub token: String,
}
impl fmt::Debug for VoiceServerUpdateEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("VoiceServerUpdateEvent")
.field("channel_id", &self.channel_id)
.field("endpoint", &self.endpoint)
.field("guild_id", &self.guild_id)
.finish()
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct VoiceStateUpdateEvent {
pub voice_state: VoiceState,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct WebhookUpdateEvent {
pub channel_id: ChannelId,
pub guild_id: GuildId,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct InteractionCreateEvent {
pub interaction: Interaction,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct IntegrationCreateEvent {
pub integration: Integration,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct IntegrationUpdateEvent {
pub integration: Integration,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[non_exhaustive]
pub struct IntegrationDeleteEvent {
pub id: IntegrationId,
pub guild_id: GuildId,
pub application_id: Option<ApplicationId>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct StageInstanceCreateEvent {
pub stage_instance: StageInstance,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct StageInstanceUpdateEvent {
pub stage_instance: StageInstance,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct StageInstanceDeleteEvent {
pub stage_instance: StageInstance,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct ThreadCreateEvent {
pub thread: GuildChannel,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct ThreadUpdateEvent {
pub thread: GuildChannel,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct ThreadDeleteEvent {
pub thread: PartialGuildChannel,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct ThreadListSyncEvent {
pub guild_id: GuildId,
#[serde(default)]
pub channels_id: Vec<ChannelId>,
pub threads: Vec<GuildChannel>,
pub members: Vec<ThreadMember>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct ThreadMemberUpdateEvent {
pub member: ThreadMember,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct ThreadMembersUpdateEvent {
pub id: ChannelId,
pub guild_id: GuildId,
pub member_count: u8,
#[serde(default)]
pub added_members: Vec<ThreadMember>,
#[serde(default)]
pub removed_members_ids: Vec<UserId>,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct GuildScheduledEventCreateEvent {
pub event: ScheduledEvent,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct GuildScheduledEventUpdateEvent {
pub event: ScheduledEvent,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(transparent)]
#[non_exhaustive]
pub struct GuildScheduledEventDeleteEvent {
pub event: ScheduledEvent,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct GuildScheduledEventUserAddEvent {
#[serde(rename = "guild_scheduled_event_id")]
scheduled_event_id: ScheduledEventId,
guild_id: GuildId,
user_id: UserId,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct GuildScheduledEventUserRemoveEvent {
#[serde(rename = "guild_scheduled_event_id")]
scheduled_event_id: ScheduledEventId,
guild_id: GuildId,
user_id: UserId,
}
#[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, Serialize)]
#[non_exhaustive]
#[serde(untagged)]
pub enum GatewayEvent {
Dispatch(u64, Event),
Heartbeat(u64),
Reconnect,
InvalidateSession(bool),
Hello(u64),
HeartbeatAck,
}
impl<'de> Deserialize<'de> for GatewayEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
let mut map = JsonMap::deserialize(deserializer)?;
let op = map
.remove("op")
.ok_or_else(|| DeError::custom("expected op"))
.and_then(OpCode::deserialize)
.map_err(DeError::custom)?;
Ok(match op {
OpCode::Event => {
let s = map
.remove("s")
.ok_or_else(|| DeError::custom("expected gateway event sequence"))
.and_then(u64::deserialize)
.map_err(DeError::custom)?;
let kind = map
.remove("t")
.ok_or_else(|| DeError::custom("expected gateway event type"))
.and_then(EventType::deserialize)
.map_err(DeError::custom)?;
let payload = map
.remove("d")
.ok_or_else(|| Error::Decode("expected gateway event d", Value::from(map)))
.map_err(DeError::custom)?;
let x = match deserialize_event_with_type(kind.clone(), payload) {
Ok(x) => x,
Err(why) => {
return Err(DeError::custom(format_args!("event {:?}: {}", kind, why)));
},
};
GatewayEvent::Dispatch(s, x)
},
OpCode::Heartbeat => {
let s = map
.remove("s")
.ok_or_else(|| DeError::custom("Expected heartbeat s"))
.and_then(u64::deserialize)
.map_err(DeError::custom)?;
GatewayEvent::Heartbeat(s)
},
OpCode::Reconnect => GatewayEvent::Reconnect,
OpCode::InvalidSession => {
let resumable = map
.remove("d")
.ok_or_else(|| DeError::custom("expected gateway invalid session d"))
.and_then(bool::deserialize)
.map_err(DeError::custom)?;
GatewayEvent::InvalidateSession(resumable)
},
OpCode::Hello => {
let mut d = map
.remove("d")
.ok_or_else(|| DeError::custom("expected gateway hello d"))
.and_then(JsonMap::deserialize)
.map_err(DeError::custom)?;
let interval = d
.remove("heartbeat_interval")
.ok_or_else(|| DeError::custom("expected gateway hello interval"))
.and_then(u64::deserialize)
.map_err(DeError::custom)?;
GatewayEvent::Hello(interval)
},
OpCode::HeartbeatAck => GatewayEvent::HeartbeatAck,
_ => return Err(DeError::custom("invalid opcode")),
})
}
}
#[allow(clippy::large_enum_variant)]
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
#[serde(untagged)]
pub enum Event {
ApplicationCommandPermissionsUpdate(ApplicationCommandPermissionsUpdateEvent),
AutoModerationRuleCreate(AutoModerationRuleCreateEvent),
AutoModerationRuleUpdate(AutoModerationRuleUpdateEvent),
AutoModerationRuleDelete(AutoModerationRuleDeleteEvent),
AutoModerationActionExecution(AutoModerationActionExecutionEvent),
ChannelCreate(ChannelCreateEvent),
ChannelDelete(ChannelDeleteEvent),
ChannelPinsUpdate(ChannelPinsUpdateEvent),
ChannelUpdate(ChannelUpdateEvent),
GuildBanAdd(GuildBanAddEvent),
GuildBanRemove(GuildBanRemoveEvent),
GuildCreate(GuildCreateEvent),
GuildDelete(GuildDeleteEvent),
GuildEmojisUpdate(GuildEmojisUpdateEvent),
GuildIntegrationsUpdate(GuildIntegrationsUpdateEvent),
GuildMemberAdd(GuildMemberAddEvent),
GuildMemberRemove(GuildMemberRemoveEvent),
GuildMemberUpdate(GuildMemberUpdateEvent),
GuildMembersChunk(GuildMembersChunkEvent),
GuildRoleCreate(GuildRoleCreateEvent),
GuildRoleDelete(GuildRoleDeleteEvent),
GuildRoleUpdate(GuildRoleUpdateEvent),
GuildStickersUpdate(GuildStickersUpdateEvent),
GuildUnavailable(GuildUnavailableEvent),
GuildUpdate(GuildUpdateEvent),
InviteCreate(InviteCreateEvent),
InviteDelete(InviteDeleteEvent),
MessageCreate(MessageCreateEvent),
MessageDelete(MessageDeleteEvent),
MessageDeleteBulk(MessageDeleteBulkEvent),
MessageUpdate(MessageUpdateEvent),
PresenceUpdate(PresenceUpdateEvent),
PresencesReplace(PresencesReplaceEvent),
ReactionAdd(ReactionAddEvent),
ReactionRemove(ReactionRemoveEvent),
ReactionRemoveAll(ReactionRemoveAllEvent),
Ready(ReadyEvent),
Resumed(ResumedEvent),
TypingStart(TypingStartEvent),
UserUpdate(UserUpdateEvent),
VoiceStateUpdate(VoiceStateUpdateEvent),
VoiceServerUpdate(VoiceServerUpdateEvent),
WebhookUpdate(WebhookUpdateEvent),
InteractionCreate(InteractionCreateEvent),
IntegrationCreate(IntegrationCreateEvent),
IntegrationUpdate(IntegrationUpdateEvent),
IntegrationDelete(IntegrationDeleteEvent),
StageInstanceCreate(StageInstanceCreateEvent),
StageInstanceUpdate(StageInstanceUpdateEvent),
StageInstanceDelete(StageInstanceDeleteEvent),
ThreadCreate(ThreadCreateEvent),
ThreadUpdate(ThreadUpdateEvent),
ThreadDelete(ThreadDeleteEvent),
ThreadListSync(ThreadListSyncEvent),
ThreadMemberUpdate(ThreadMemberUpdateEvent),
ThreadMembersUpdate(ThreadMembersUpdateEvent),
GuildScheduledEventCreate(GuildScheduledEventCreateEvent),
GuildScheduledEventUpdate(GuildScheduledEventUpdateEvent),
GuildScheduledEventDelete(GuildScheduledEventDeleteEvent),
GuildScheduledEventUserAdd(GuildScheduledEventUserAddEvent),
GuildScheduledEventUserRemove(GuildScheduledEventUserRemoveEvent),
Unknown(UnknownEvent),
}
#[cfg(feature = "model")]
fn gid_from_channel(c: &Channel) -> RelatedId<GuildId> {
match c {
Channel::Guild(g) => RelatedId::Some(g.guild_id),
_ => RelatedId::None,
}
}
macro_rules! with_related_ids_for_event_types {
($macro:ident) => {
$macro! {
Self::ApplicationCommandPermissionsUpdate, Self::ApplicationCommandPermissionsUpdate(e) => {
user_id: Never,
guild_id: Some(e.permission.guild_id),
channel_id: Never,
message_id: Never,
},
Self::AutoModerationRuleCreate, Self::AutoModerationRuleCreate(e) => {
user_id: Some(e.rule.creator_id),
guild_id: Some(e.rule.guild_id),
channel_id: Never,
message_id: Never,
},
Self::AutoModerationRuleUpdate, Self::AutoModerationRuleUpdate(e) => {
user_id: Some(e.rule.creator_id),
guild_id: Some(e.rule.guild_id),
channel_id: Never,
message_id: Never,
},
Self::AutoModerationRuleDelete, Self::AutoModerationRuleDelete(e) => {
user_id: Some(e.rule.creator_id),
guild_id: Some(e.rule.guild_id),
channel_id: Never,
message_id: Never,
},
Self::AutoModerationActionExecution, Self::AutoModerationActionExecution(e) => {
user_id: Some(e.execution.user_id),
guild_id: Some(e.execution.guild_id),
channel_id: e.execution.channel_id.into(),
message_id: e.execution.message_id.into(),
},
Self::ChannelCreate, Self::ChannelCreate(e) => {
user_id: Never,
guild_id: gid_from_channel(&e.channel),
channel_id: Some(e.channel.id()),
message_id: Never,
},
Self::ChannelDelete, Self::ChannelDelete(e) => {
user_id: Never,
guild_id: gid_from_channel(&e.channel),
channel_id: Some(e.channel.id()),
message_id: Never,
},
Self::ChannelPinsUpdate, Self::ChannelPinsUpdate(e) => {
user_id: Never,
guild_id: e.guild_id.into(),
channel_id: Some(e.channel_id),
message_id: Never,
},
Self::ChannelUpdate, Self::ChannelUpdate(e) => {
user_id: Never,
guild_id: gid_from_channel(&e.channel),
channel_id: Some(e.channel.id()),
message_id: Never,
},
Self::GuildBanAdd, Self::GuildBanAdd(e) => {
user_id: Some(e.user.id),
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildBanRemove, Self::GuildBanRemove(e) => {
user_id: Some(e.user.id),
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildCreate, Self::GuildCreate(e) => {
user_id: Never,
guild_id: Some(e.guild.id),
channel_id: Never,
message_id: Never,
},
Self::GuildDelete, Self::GuildDelete(e) => {
user_id: Never,
guild_id: Some(e.guild.id),
channel_id: Never,
message_id: Never,
},
Self::GuildEmojisUpdate, Self::GuildEmojisUpdate(e) => {
user_id: Never,
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildIntegrationsUpdate, Self::GuildIntegrationsUpdate(e) => {
user_id: Never,
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildMemberAdd, Self::GuildMemberAdd(e) => {
user_id: Some(e.member.user.id),
guild_id: Some(e.member.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildMemberRemove, Self::GuildMemberRemove(e) => {
user_id: Some(e.user.id),
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildMemberUpdate, Self::GuildMemberUpdate(e) => {
user_id: Some(e.user.id),
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildMembersChunk, Self::GuildMembersChunk(e) => {
user_id: Multiple(e.members.keys().copied().collect()),
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildRoleCreate, Self::GuildRoleCreate(e) => {
user_id: Never,
guild_id: Some(e.role.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildRoleDelete, Self::GuildRoleDelete(e) => {
user_id: Never,
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildRoleUpdate, Self::GuildRoleUpdate(e) => {
user_id: Never,
guild_id: Some(e.role.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildScheduledEventCreate, Self::GuildScheduledEventCreate(e) => {
user_id: e.event.creator_id.into(),
guild_id: Some(e.event.guild_id),
channel_id: e.event.channel_id.into(),
message_id: Never,
},
Self::GuildScheduledEventUpdate, Self::GuildScheduledEventUpdate(e) => {
user_id: e.event.creator_id.into(),
guild_id: Some(e.event.guild_id),
channel_id: e.event.channel_id.into(),
message_id: Never,
},
Self::GuildScheduledEventDelete, Self::GuildScheduledEventDelete(e) => {
user_id: e.event.creator_id.into(),
guild_id: Some(e.event.guild_id),
channel_id: e.event.channel_id.into(),
message_id: Never,
},
Self::GuildScheduledEventUserAdd, Self::GuildScheduledEventUserAdd(e) => {
user_id: Some(e.user_id),
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildScheduledEventUserRemove, Self::GuildScheduledEventUserRemove(e) => {
user_id: Some(e.user_id),
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildStickersUpdate, Self::GuildStickersUpdate(e) => {
user_id: Never,
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildUnavailable, Self::GuildUnavailable(e) => {
user_id: Never,
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
Self::GuildUpdate, Self::GuildUpdate(e) => {
user_id: Never,
guild_id: Some(e.guild.id),
channel_id: Never,
message_id: Never,
},
Self::InviteCreate, Self::InviteCreate(e) => {
user_id: e.inviter.as_ref().map(|u| u.id).into(),
guild_id: e.guild_id.into(),
channel_id: Some(e.channel_id),
message_id: Never,
},
Self::InviteDelete, Self::InviteDelete(e) => {
user_id: Never,
guild_id: e.guild_id.into(),
channel_id: Some(e.channel_id),
message_id: Never,
},
Self::MessageCreate, Self::MessageCreate(e) => {
user_id: Some(e.message.author.id),
guild_id: e.message.guild_id.into(),
channel_id: Some(e.message.channel_id),
message_id: Some(e.message.id),
},
Self::MessageDelete, Self::MessageDelete(e) => {
user_id: Never,
guild_id: e.guild_id.into(),
channel_id: Some(e.channel_id),
message_id: Some(e.message_id),
},
Self::MessageDeleteBulk, Self::MessageDeleteBulk(e) => {
user_id: Never,
guild_id: e.guild_id.into(),
channel_id: Some(e.channel_id),
message_id: Multiple(e.ids.clone()),
},
Self::MessageUpdate, Self::MessageUpdate(e) => {
user_id: e.author.as_ref().map(|u| u.id).into(),
guild_id: e.guild_id.into(),
channel_id: Some(e.channel_id),
message_id: Some(e.id),
},
Self::PresenceUpdate, Self::PresenceUpdate(e) => {
user_id: Some(e.presence.user.id),
guild_id: e.presence.guild_id.into(),
channel_id: Never,
message_id: Never,
},
Self::PresencesReplace, Self::PresencesReplace(e) => {
user_id: Multiple(e.presences.iter().map(|p| p.user.id).collect()),
guild_id: Never,
channel_id: Never,
message_id: Never,
},
Self::ReactionAdd, Self::ReactionAdd(e) => {
user_id: e.reaction.user_id.into(),
guild_id: e.reaction.guild_id.into(),
channel_id: Some(e.reaction.channel_id),
message_id: Some(e.reaction.message_id),
},
Self::ReactionRemove, Self::ReactionRemove(e) => {
user_id: e.reaction.user_id.into(),
guild_id: e.reaction.guild_id.into(),
channel_id: Some(e.reaction.channel_id),
message_id: Some(e.reaction.message_id),
},
Self::ReactionRemoveAll, Self::ReactionRemoveAll(e) => {
user_id: Never,
guild_id: e.guild_id.into(),
channel_id: Some(e.channel_id),
message_id: Some(e.message_id),
},
Self::Ready, Self::Ready(e) => {
user_id: Never,
guild_id: Never,
channel_id: Never,
message_id: Never,
},
Self::Resumed, Self::Resumed(e) => {
user_id: Never,
guild_id: Never,
channel_id: Never,
message_id: Never,
},
Self::StageInstanceCreate, Self::StageInstanceCreate(e) => {
user_id: Never,
guild_id: Some(e.stage_instance.guild_id),
channel_id: Some(e.stage_instance.channel_id),
message_id: Never,
},
Self::StageInstanceDelete, Self::StageInstanceDelete(e) => {
user_id: Never,
guild_id: Some(e.stage_instance.guild_id),
channel_id: Some(e.stage_instance.channel_id),
message_id: Never,
},
Self::StageInstanceUpdate, Self::StageInstanceUpdate(e) => {
user_id: Never,
guild_id: Some(e.stage_instance.guild_id),
channel_id: Some(e.stage_instance.channel_id),
message_id: Never,
},
Self::ThreadCreate, Self::ThreadCreate(e) => {
user_id: Never,
guild_id: Some(e.thread.guild_id),
channel_id: Some(e.thread.id),
message_id: Never,
},
Self::ThreadDelete, Self::ThreadDelete(e) => {
user_id: Never,
guild_id: Some(e.thread.guild_id),
channel_id: Some(e.thread.id),
message_id: Never,
},
Self::ThreadListSync, Self::ThreadListSync(e) => {
user_id: Never,
guild_id: Some(e.guild_id),
channel_id: Multiple(e.threads.iter().map(|c| c.id).collect()),
message_id: Never,
},
Self::ThreadMembersUpdate, Self::ThreadMembersUpdate(e) => {
user_id: Multiple(e.added_members
.iter()
.filter_map(|m| m.user_id.as_ref())
.chain(e.removed_members_ids.iter())
.copied()
.collect(),
),
guild_id: Some(e.guild_id),
channel_id: Some(e.id),
message_id: Never,
},
Self::ThreadMemberUpdate, Self::ThreadMemberUpdate(e) => {
user_id: e.member.user_id.into(),
guild_id: Never,
channel_id: e.member.id.into(),
message_id: Never,
},
Self::ThreadUpdate, Self::ThreadUpdate(e) => {
user_id: Never,
guild_id: Some(e.thread.guild_id),
channel_id: Some(e.thread.id),
message_id: Never,
},
Self::TypingStart, Self::TypingStart(e) => {
user_id: Some(e.user_id),
guild_id: e.guild_id.into(),
channel_id: Some(e.channel_id),
message_id: Never,
},
Self::UserUpdate, Self::UserUpdate(e) => {
user_id: Some(e.current_user.id),
guild_id: Never,
channel_id: Never,
message_id: Never,
},
Self::VoiceServerUpdate, Self::VoiceServerUpdate(e) => {
user_id: Never,
guild_id: e.guild_id.into(),
channel_id: e.channel_id.into(),
message_id: Never,
},
Self::VoiceStateUpdate, Self::VoiceStateUpdate(e) => {
user_id: Some(e.voice_state.user_id),
guild_id: e.voice_state.guild_id.into(),
channel_id: Never,
message_id: Never,
},
Self::WebhookUpdate, Self::WebhookUpdate(e) => {
user_id: Never,
guild_id: Some(e.guild_id),
channel_id: Some(e.channel_id),
message_id: Never,
},
Self::InteractionCreate, Self::InteractionCreate(e) => {
user_id: match &e.interaction {
Interaction::Ping(_) => None,
Interaction::ApplicationCommand(i) => Some(i.user.id),
Interaction::MessageComponent(i) => Some(i.user.id),
Interaction::Autocomplete(i) => Some(i.user.id),
Interaction::ModalSubmit(i) => Some(i.user.id),
},
guild_id: match &e.interaction {
Interaction::Ping(_) => None,
Interaction::ApplicationCommand(i) => i.guild_id.into(),
Interaction::MessageComponent(i) => i.guild_id.into(),
Interaction::Autocomplete(i) => i.guild_id.into(),
Interaction::ModalSubmit(i) => i.guild_id.into(),
},
channel_id: match &e.interaction {
Interaction::Ping(_) => None,
Interaction::ApplicationCommand(i) => Some(i.channel_id),
Interaction::MessageComponent(i) => Some(i.channel_id),
Interaction::Autocomplete(i) => Some(i.channel_id),
Interaction::ModalSubmit(i) => Some(i.channel_id),
},
message_id: match &e.interaction {
Interaction::Ping(_) => None,
Interaction::ApplicationCommand(_) => None,
Interaction::MessageComponent(i) => Some(i.message.id),
Interaction::Autocomplete(i) => None,
Interaction::ModalSubmit(i) => i.message.as_ref().map(|m| m.id).into(),
},
},
Self::IntegrationCreate, Self::IntegrationCreate(e) => {
user_id: e.integration.user.as_ref().map(|u| u.id).into(),
guild_id: Some(e.integration.guild_id),
channel_id: Never,
message_id: Never,
},
Self::IntegrationUpdate, Self::IntegrationUpdate(e) => {
user_id: e.integration.user.as_ref().map(|u| u.id).into(),
guild_id: Some(e.integration.guild_id),
channel_id: Never,
message_id: Never,
},
Self::IntegrationDelete, Self::IntegrationDelete(e) => {
user_id: Never,
guild_id: Some(e.guild_id),
channel_id: Never,
message_id: Never,
},
}
};
}
#[cfg(feature = "model")]
macro_rules! define_event_related_id_methods {
($(
$(#[$attr:meta])?
$_:path, $variant:pat => {
user_id: $user_id:expr,
guild_id: $guild_id:expr,
channel_id: $channel_id:expr,
message_id: $message_id:expr,
}
),+ $(,)?) => {
#[must_use]
pub fn user_id(&self) -> RelatedId<UserId> {
use RelatedId::*;
#[allow(unused_variables)]
match self {
Self::Unknown(_) => Never,
$(
$(#[$attr])?
$variant => $user_id
),+
}
}
#[must_use]
pub fn guild_id(&self) -> RelatedId<GuildId> {
use RelatedId::*;
#[allow(unused_variables)]
match self {
Self::Unknown(_) => Never,
$(
$(#[$attr])?
$variant => $guild_id
),+
}
}
#[must_use]
pub fn channel_id(&self) -> RelatedId<ChannelId> {
use RelatedId::*;
#[allow(unused_variables)]
match self {
Self::Unknown(_) => Never,
$(
$(#[$attr])?
$variant => $channel_id
),+
}
}
#[must_use]
pub fn message_id(&self) -> RelatedId<MessageId> {
use RelatedId::*;
#[allow(unused_variables)]
match self {
Self::Unknown(_) => Never,
$(
$(#[$attr])?
$variant => $message_id
),+
}
}
};
}
impl Event {
#[must_use]
pub fn event_type(&self) -> EventType {
match self {
Self::ApplicationCommandPermissionsUpdate(_) => {
EventType::ApplicationCommandPermissionsUpdate
},
Self::AutoModerationRuleCreate(_) => EventType::AutoModerationRuleCreate,
Self::AutoModerationRuleUpdate(_) => EventType::AutoModerationRuleUpdate,
Self::AutoModerationRuleDelete(_) => EventType::AutoModerationRuleDelete,
Self::AutoModerationActionExecution(_) => EventType::AutoModerationActionExecution,
Self::ChannelCreate(_) => EventType::ChannelCreate,
Self::ChannelDelete(_) => EventType::ChannelDelete,
Self::ChannelPinsUpdate(_) => EventType::ChannelPinsUpdate,
Self::ChannelUpdate(_) => EventType::ChannelUpdate,
Self::GuildBanAdd(_) => EventType::GuildBanAdd,
Self::GuildBanRemove(_) => EventType::GuildBanRemove,
Self::GuildCreate(_) => EventType::GuildCreate,
Self::GuildDelete(_) => EventType::GuildDelete,
Self::GuildEmojisUpdate(_) => EventType::GuildEmojisUpdate,
Self::GuildIntegrationsUpdate(_) => EventType::GuildIntegrationsUpdate,
Self::GuildMemberAdd(_) => EventType::GuildMemberAdd,
Self::GuildMemberRemove(_) => EventType::GuildMemberRemove,
Self::GuildMemberUpdate(_) => EventType::GuildMemberUpdate,
Self::GuildMembersChunk(_) => EventType::GuildMembersChunk,
Self::GuildRoleCreate(_) => EventType::GuildRoleCreate,
Self::GuildRoleDelete(_) => EventType::GuildRoleDelete,
Self::GuildRoleUpdate(_) => EventType::GuildRoleUpdate,
Self::GuildStickersUpdate(_) => EventType::GuildStickersUpdate,
Self::GuildUnavailable(_) => EventType::GuildUnavailable,
Self::GuildUpdate(_) => EventType::GuildUpdate,
Self::InviteCreate(_) => EventType::InviteCreate,
Self::InviteDelete(_) => EventType::InviteDelete,
Self::MessageCreate(_) => EventType::MessageCreate,
Self::MessageDelete(_) => EventType::MessageDelete,
Self::MessageDeleteBulk(_) => EventType::MessageDeleteBulk,
Self::MessageUpdate(_) => EventType::MessageUpdate,
Self::PresenceUpdate(_) => EventType::PresenceUpdate,
Self::PresencesReplace(_) => EventType::PresencesReplace,
Self::ReactionAdd(_) => EventType::ReactionAdd,
Self::ReactionRemove(_) => EventType::ReactionRemove,
Self::ReactionRemoveAll(_) => EventType::ReactionRemoveAll,
Self::Ready(_) => EventType::Ready,
Self::Resumed(_) => EventType::Resumed,
Self::TypingStart(_) => EventType::TypingStart,
Self::UserUpdate(_) => EventType::UserUpdate,
Self::VoiceStateUpdate(_) => EventType::VoiceStateUpdate,
Self::VoiceServerUpdate(_) => EventType::VoiceServerUpdate,
Self::WebhookUpdate(_) => EventType::WebhookUpdate,
Self::InteractionCreate(_) => EventType::InteractionCreate,
Self::IntegrationCreate(_) => EventType::IntegrationCreate,
Self::IntegrationUpdate(_) => EventType::IntegrationUpdate,
Self::IntegrationDelete(_) => EventType::IntegrationDelete,
Self::StageInstanceCreate(_) => EventType::StageInstanceCreate,
Self::StageInstanceUpdate(_) => EventType::StageInstanceUpdate,
Self::StageInstanceDelete(_) => EventType::StageInstanceDelete,
Self::ThreadCreate(_) => EventType::ThreadCreate,
Self::ThreadUpdate(_) => EventType::ThreadUpdate,
Self::ThreadDelete(_) => EventType::ThreadDelete,
Self::ThreadListSync(_) => EventType::ThreadListSync,
Self::ThreadMemberUpdate(_) => EventType::ThreadMemberUpdate,
Self::ThreadMembersUpdate(_) => EventType::ThreadMembersUpdate,
Self::GuildScheduledEventCreate(_) => EventType::GuildScheduledEventCreate,
Self::GuildScheduledEventUpdate(_) => EventType::GuildScheduledEventUpdate,
Self::GuildScheduledEventDelete(_) => EventType::GuildScheduledEventDelete,
Self::GuildScheduledEventUserAdd(_) => EventType::GuildScheduledEventUserAdd,
Self::GuildScheduledEventUserRemove(_) => EventType::GuildScheduledEventUserRemove,
Self::Unknown(unknown) => EventType::Other(unknown.kind.clone()),
}
}
#[cfg(feature = "model")]
with_related_ids_for_event_types!(define_event_related_id_methods);
}
pub enum RelatedId<T> {
Never,
None,
Some(T),
Multiple(Vec<T>),
}
impl<T> RelatedId<T> {
pub fn contains(&self, value: &T) -> bool
where
T: std::cmp::PartialEq,
{
match self {
Self::Never | RelatedId::None => false,
Self::Some(id) => id == value,
Self::Multiple(ids) => ids.contains(value),
}
}
}
impl<T> From<Option<T>> for RelatedId<T> {
fn from(value: Option<T>) -> Self {
match value {
None => RelatedId::None,
Some(t) => RelatedId::Some(t),
}
}
}
impl<T> TryFrom<RelatedId<T>> for Option<T> {
type Error = Vec<T>;
fn try_from(value: RelatedId<T>) -> StdResult<Self, Self::Error> {
match value {
RelatedId::Never | RelatedId::None => Ok(None),
RelatedId::Some(t) => Ok(Some(t)),
RelatedId::Multiple(t) => Err(t),
}
}
}
pub fn deserialize_event_with_type(kind: EventType, v: Value) -> Result<Event> {
Ok(match kind {
EventType::ApplicationCommandPermissionsUpdate => {
Event::ApplicationCommandPermissionsUpdate(from_value(v)?)
},
EventType::AutoModerationRuleCreate => Event::AutoModerationRuleCreate(from_value(v)?),
EventType::AutoModerationRuleUpdate => Event::AutoModerationRuleUpdate(from_value(v)?),
EventType::AutoModerationRuleDelete => Event::AutoModerationRuleDelete(from_value(v)?),
EventType::AutoModerationActionExecution => {
Event::AutoModerationActionExecution(from_value(v)?)
},
EventType::ChannelCreate => Event::ChannelCreate(from_value(v)?),
EventType::ChannelDelete => Event::ChannelDelete(from_value(v)?),
EventType::ChannelPinsUpdate => Event::ChannelPinsUpdate(from_value(v)?),
EventType::ChannelUpdate => Event::ChannelUpdate(from_value(v)?),
EventType::GuildBanAdd => Event::GuildBanAdd(from_value(v)?),
EventType::GuildBanRemove => Event::GuildBanRemove(from_value(v)?),
EventType::GuildCreate | EventType::GuildUnavailable => {
if v.get("unavailable").and_then(Value::as_bool).unwrap_or(false) {
Event::GuildUnavailable(from_value(v)?)
} else {
Event::GuildCreate(from_value(v)?)
}
},
EventType::GuildDelete => {
if v.get("unavailable").and_then(Value::as_bool).unwrap_or(false) {
Event::GuildUnavailable(from_value(v)?)
} else {
Event::GuildDelete(from_value(v)?)
}
},
EventType::GuildEmojisUpdate => Event::GuildEmojisUpdate(from_value(v)?),
EventType::GuildIntegrationsUpdate => Event::GuildIntegrationsUpdate(from_value(v)?),
EventType::GuildMemberAdd => Event::GuildMemberAdd(from_value(v)?),
EventType::GuildMemberRemove => Event::GuildMemberRemove(from_value(v)?),
EventType::GuildMemberUpdate => Event::GuildMemberUpdate(from_value(v)?),
EventType::GuildMembersChunk => Event::GuildMembersChunk(from_value(v)?),
EventType::GuildRoleCreate => Event::GuildRoleCreate(from_value(v)?),
EventType::GuildRoleDelete => Event::GuildRoleDelete(from_value(v)?),
EventType::GuildRoleUpdate => Event::GuildRoleUpdate(from_value(v)?),
EventType::GuildStickersUpdate => Event::GuildStickersUpdate(from_value(v)?),
EventType::InviteCreate => Event::InviteCreate(from_value(v)?),
EventType::InviteDelete => Event::InviteDelete(from_value(v)?),
EventType::GuildUpdate => Event::GuildUpdate(from_value(v)?),
EventType::MessageCreate => Event::MessageCreate(from_value(v)?),
EventType::MessageDelete => Event::MessageDelete(from_value(v)?),
EventType::MessageDeleteBulk => Event::MessageDeleteBulk(from_value(v)?),
EventType::ReactionAdd => Event::ReactionAdd(from_value(v)?),
EventType::ReactionRemove => Event::ReactionRemove(from_value(v)?),
EventType::ReactionRemoveAll => Event::ReactionRemoveAll(from_value(v)?),
EventType::MessageUpdate => Event::MessageUpdate(from_value(v)?),
EventType::PresenceUpdate => Event::PresenceUpdate(from_value(v)?),
EventType::PresencesReplace => Event::PresencesReplace(from_value(v)?),
EventType::Ready => Event::Ready(from_value(v)?),
EventType::Resumed => Event::Resumed(from_value(v)?),
EventType::TypingStart => Event::TypingStart(from_value(v)?),
EventType::UserUpdate => Event::UserUpdate(from_value(v)?),
EventType::VoiceServerUpdate => Event::VoiceServerUpdate(from_value(v)?),
EventType::VoiceStateUpdate => Event::VoiceStateUpdate(from_value(v)?),
EventType::WebhookUpdate => Event::WebhookUpdate(from_value(v)?),
EventType::InteractionCreate => Event::InteractionCreate(from_value(v)?),
EventType::IntegrationCreate => Event::IntegrationCreate(from_value(v)?),
EventType::IntegrationUpdate => Event::IntegrationUpdate(from_value(v)?),
EventType::IntegrationDelete => Event::IntegrationDelete(from_value(v)?),
EventType::StageInstanceCreate => Event::StageInstanceCreate(from_value(v)?),
EventType::StageInstanceUpdate => Event::StageInstanceUpdate(from_value(v)?),
EventType::StageInstanceDelete => Event::StageInstanceDelete(from_value(v)?),
EventType::ThreadCreate => Event::ThreadCreate(from_value(v)?),
EventType::ThreadUpdate => Event::ThreadUpdate(from_value(v)?),
EventType::ThreadDelete => Event::ThreadDelete(from_value(v)?),
EventType::ThreadListSync => Event::ThreadListSync(from_value(v)?),
EventType::ThreadMemberUpdate => Event::ThreadMemberUpdate(from_value(v)?),
EventType::ThreadMembersUpdate => Event::ThreadMembersUpdate(from_value(v)?),
EventType::GuildScheduledEventCreate => Event::GuildScheduledEventCreate(from_value(v)?),
EventType::GuildScheduledEventUpdate => Event::GuildScheduledEventUpdate(from_value(v)?),
EventType::GuildScheduledEventDelete => Event::GuildScheduledEventDelete(from_value(v)?),
EventType::GuildScheduledEventUserAdd => Event::GuildScheduledEventUserAdd(from_value(v)?),
EventType::GuildScheduledEventUserRemove => {
Event::GuildScheduledEventUserRemove(from_value(v)?)
},
EventType::Other(kind) => Event::Unknown(UnknownEvent {
kind,
value: v,
}),
})
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[non_exhaustive]
pub enum EventType {
ApplicationCommandPermissionsUpdate,
AutoModerationRuleCreate,
AutoModerationRuleUpdate,
AutoModerationRuleDelete,
AutoModerationActionExecution,
ChannelCreate,
ChannelDelete,
ChannelPinsUpdate,
ChannelUpdate,
GuildBanAdd,
GuildBanRemove,
GuildCreate,
GuildDelete,
GuildEmojisUpdate,
GuildIntegrationsUpdate,
GuildMemberAdd,
GuildMemberRemove,
GuildMemberUpdate,
GuildMembersChunk,
GuildRoleCreate,
GuildRoleDelete,
GuildRoleUpdate,
GuildStickersUpdate,
GuildUnavailable,
GuildUpdate,
InviteCreate,
InviteDelete,
MessageCreate,
MessageDelete,
MessageDeleteBulk,
MessageUpdate,
PresenceUpdate,
PresencesReplace,
ReactionAdd,
ReactionRemove,
ReactionRemoveAll,
Ready,
Resumed,
TypingStart,
UserUpdate,
VoiceStateUpdate,
VoiceServerUpdate,
WebhookUpdate,
InteractionCreate,
IntegrationCreate,
IntegrationUpdate,
IntegrationDelete,
StageInstanceCreate,
StageInstanceUpdate,
StageInstanceDelete,
ThreadCreate,
ThreadUpdate,
ThreadDelete,
ThreadListSync,
ThreadMemberUpdate,
ThreadMembersUpdate,
GuildScheduledEventCreate,
GuildScheduledEventUpdate,
GuildScheduledEventDelete,
GuildScheduledEventUserAdd,
GuildScheduledEventUserRemove,
Other(String),
}
impl From<&Event> for EventType {
fn from(event: &Event) -> EventType {
event.event_type()
}
}
#[derive(Debug, Default)]
pub struct RelatedIdsForEventType {
pub user_id: bool,
pub guild_id: bool,
pub channel_id: bool,
pub message_id: bool,
}
macro_rules! define_related_ids_for_event_type {
(
$(
$(#[$attr:meta])?
$variant:path, $_:pat => { $($input:tt)* }
),+ $(,)?
) => {
#[must_use]
pub fn related_ids(&self) -> RelatedIdsForEventType {
match self {
Self::Other(_) => Default::default(),
$(
$(#[$attr])?
$variant =>
define_related_ids_for_event_type!{ @munch ($($input)*) -> {} }
),+
}
}
};
(@munch ($id:ident: Never, $($next:tt)*) -> {$($output:tt)*}) => {
define_related_ids_for_event_type!{ @munch ($($next)*) -> {$($output)* ($id: false)} }
};
(@munch ($id:ident: $_:expr, $($next:tt)*) -> {$($output:tt)*}) => {
define_related_ids_for_event_type!{ @munch ($($next)*) -> {$($output)* ($id: true)} }
};
(@munch () -> {$(($id:ident: $value:literal))+}) => {
RelatedIdsForEventType {
$(
$id: $value
),+
}
};
}
impl EventType {
const APPLICATION_COMMAND_PERMISSIONS_UPDATE: &'static str =
"APPLICATION_COMMAND_PERMISSIONS_UPDATE";
const AUTO_MODERATION_RULE_CREATE: &'static str = "AUTO_MODERATION_RULE_CREATE";
const AUTO_MODERATION_RULE_UPDATE: &'static str = "AUTO_MODERATION_RULE_UPDATE";
const AUTO_MODERATION_RULE_DELETE: &'static str = "AUTO_MODERATION_RULE_DELETE";
const AUTO_MODERATION_ACTION_EXECUTION: &'static str = "AUTO_MODERATION_ACTION_EXECUTION";
const CHANNEL_CREATE: &'static str = "CHANNEL_CREATE";
const CHANNEL_DELETE: &'static str = "CHANNEL_DELETE";
const CHANNEL_PINS_UPDATE: &'static str = "CHANNEL_PINS_UPDATE";
const CHANNEL_UPDATE: &'static str = "CHANNEL_UPDATE";
const GUILD_BAN_ADD: &'static str = "GUILD_BAN_ADD";
const GUILD_BAN_REMOVE: &'static str = "GUILD_BAN_REMOVE";
const GUILD_CREATE: &'static str = "GUILD_CREATE";
const GUILD_DELETE: &'static str = "GUILD_DELETE";
const GUILD_EMOJIS_UPDATE: &'static str = "GUILD_EMOJIS_UPDATE";
const GUILD_INTEGRATIONS_UPDATE: &'static str = "GUILD_INTEGRATIONS_UPDATE";
const GUILD_MEMBER_ADD: &'static str = "GUILD_MEMBER_ADD";
const GUILD_MEMBER_REMOVE: &'static str = "GUILD_MEMBER_REMOVE";
const GUILD_MEMBER_UPDATE: &'static str = "GUILD_MEMBER_UPDATE";
const GUILD_MEMBERS_CHUNK: &'static str = "GUILD_MEMBERS_CHUNK";
const GUILD_ROLE_CREATE: &'static str = "GUILD_ROLE_CREATE";
const GUILD_ROLE_DELETE: &'static str = "GUILD_ROLE_DELETE";
const GUILD_ROLE_UPDATE: &'static str = "GUILD_ROLE_UPDATE";
const GUILD_STICKERS_UPDATE: &'static str = "GUILD_STICKERS_UPDATE";
const INVITE_CREATE: &'static str = "INVITE_CREATE";
const INVITE_DELETE: &'static str = "INVITE_DELETE";
const GUILD_UPDATE: &'static str = "GUILD_UPDATE";
const MESSAGE_CREATE: &'static str = "MESSAGE_CREATE";
const MESSAGE_DELETE: &'static str = "MESSAGE_DELETE";
const MESSAGE_DELETE_BULK: &'static str = "MESSAGE_DELETE_BULK";
const MESSAGE_REACTION_ADD: &'static str = "MESSAGE_REACTION_ADD";
const MESSAGE_REACTION_REMOVE: &'static str = "MESSAGE_REACTION_REMOVE";
const MESSAGE_REACTION_REMOVE_ALL: &'static str = "MESSAGE_REACTION_REMOVE_ALL";
const MESSAGE_UPDATE: &'static str = "MESSAGE_UPDATE";
const PRESENCE_UPDATE: &'static str = "PRESENCE_UPDATE";
const PRESENCES_REPLACE: &'static str = "PRESENCES_REPLACE";
const READY: &'static str = "READY";
const RESUMED: &'static str = "RESUMED";
const TYPING_START: &'static str = "TYPING_START";
const USER_UPDATE: &'static str = "USER_UPDATE";
const VOICE_SERVER_UPDATE: &'static str = "VOICE_SERVER_UPDATE";
const VOICE_STATE_UPDATE: &'static str = "VOICE_STATE_UPDATE";
const WEBHOOKS_UPDATE: &'static str = "WEBHOOKS_UPDATE";
const INTERACTION_CREATE: &'static str = "INTERACTION_CREATE";
const INTEGRATION_CREATE: &'static str = "INTEGRATION_CREATE";
const INTEGRATION_UPDATE: &'static str = "INTEGRATION_UPDATE";
const INTEGRATION_DELETE: &'static str = "INTEGRATION_DELETE";
const STAGE_INSTANCE_CREATE: &'static str = "STAGE_INSTANCE_CREATE";
const STAGE_INSTANCE_UPDATE: &'static str = "STAGE_INSTANCE_UPDATE";
const STAGE_INSTANCE_DELETE: &'static str = "STAGE_INSTANCE_DELETE";
const THREAD_CREATE: &'static str = "THREAD_CREATE";
const THREAD_UPDATE: &'static str = "THREAD_UPDATE";
const THREAD_DELETE: &'static str = "THREAD_DELETE";
const THREAD_LIST_SYNC: &'static str = "THREAD_LIST_SYNC";
const THREAD_MEMBER_UPDATE: &'static str = "THREAD_MEMBER_UPDATE";
const THREAD_MEMBERS_UPDATE: &'static str = "THREAD_MEMBERS_UPDATE";
const GUILD_SCHEDULED_EVENT_CREATE: &'static str = "GUILD_SCHEDULED_EVENT_CREATE";
const GUILD_SCHEDULED_EVENT_UPDATE: &'static str = "GUILD_SCHEDULED_EVENT_UPDATE";
const GUILD_SCHEDULED_EVENT_DELETE: &'static str = "GUILD_SCHEDULED_EVENT_DELETE";
const GUILD_SCHEDULED_EVENT_USER_ADD: &'static str = "GUILD_SCHEDULED_EVENT_USER_ADD";
const GUILD_SCHEDULED_EVENT_USER_REMOVE: &'static str = "GUILD_SCHEDULED_EVENT_USER_REMOVE";
#[must_use]
pub fn name(&self) -> Option<&str> {
match self {
Self::ApplicationCommandPermissionsUpdate => {
Some(Self::APPLICATION_COMMAND_PERMISSIONS_UPDATE)
},
Self::AutoModerationRuleCreate => Some(Self::AUTO_MODERATION_RULE_CREATE),
Self::AutoModerationRuleUpdate => Some(Self::AUTO_MODERATION_RULE_UPDATE),
Self::AutoModerationRuleDelete => Some(Self::AUTO_MODERATION_RULE_DELETE),
Self::AutoModerationActionExecution => Some(Self::AUTO_MODERATION_ACTION_EXECUTION),
Self::ChannelCreate => Some(Self::CHANNEL_CREATE),
Self::ChannelDelete => Some(Self::CHANNEL_DELETE),
Self::ChannelPinsUpdate => Some(Self::CHANNEL_PINS_UPDATE),
Self::ChannelUpdate => Some(Self::CHANNEL_UPDATE),
Self::GuildBanAdd => Some(Self::GUILD_BAN_ADD),
Self::GuildBanRemove => Some(Self::GUILD_BAN_REMOVE),
Self::GuildCreate => Some(Self::GUILD_CREATE),
Self::GuildDelete => Some(Self::GUILD_DELETE),
Self::GuildEmojisUpdate => Some(Self::GUILD_EMOJIS_UPDATE),
Self::GuildIntegrationsUpdate => Some(Self::GUILD_INTEGRATIONS_UPDATE),
Self::GuildMemberAdd => Some(Self::GUILD_MEMBER_ADD),
Self::GuildMemberRemove => Some(Self::GUILD_MEMBER_REMOVE),
Self::GuildMemberUpdate => Some(Self::GUILD_MEMBER_UPDATE),
Self::GuildMembersChunk => Some(Self::GUILD_MEMBERS_CHUNK),
Self::GuildRoleCreate => Some(Self::GUILD_ROLE_CREATE),
Self::GuildRoleDelete => Some(Self::GUILD_ROLE_DELETE),
Self::GuildRoleUpdate => Some(Self::GUILD_ROLE_UPDATE),
Self::GuildStickersUpdate => Some(Self::GUILD_STICKERS_UPDATE),
Self::InviteCreate => Some(Self::INVITE_CREATE),
Self::InviteDelete => Some(Self::INVITE_DELETE),
Self::GuildUpdate => Some(Self::GUILD_UPDATE),
Self::MessageCreate => Some(Self::MESSAGE_CREATE),
Self::MessageDelete => Some(Self::MESSAGE_DELETE),
Self::MessageDeleteBulk => Some(Self::MESSAGE_DELETE_BULK),
Self::ReactionAdd => Some(Self::MESSAGE_REACTION_ADD),
Self::ReactionRemove => Some(Self::MESSAGE_REACTION_REMOVE),
Self::ReactionRemoveAll => Some(Self::MESSAGE_REACTION_REMOVE_ALL),
Self::MessageUpdate => Some(Self::MESSAGE_UPDATE),
Self::PresenceUpdate => Some(Self::PRESENCE_UPDATE),
Self::PresencesReplace => Some(Self::PRESENCES_REPLACE),
Self::Ready => Some(Self::READY),
Self::Resumed => Some(Self::RESUMED),
Self::TypingStart => Some(Self::TYPING_START),
Self::UserUpdate => Some(Self::USER_UPDATE),
Self::VoiceServerUpdate => Some(Self::VOICE_SERVER_UPDATE),
Self::VoiceStateUpdate => Some(Self::VOICE_STATE_UPDATE),
Self::WebhookUpdate => Some(Self::WEBHOOKS_UPDATE),
Self::InteractionCreate => Some(Self::INTERACTION_CREATE),
Self::IntegrationCreate => Some(Self::INTEGRATION_CREATE),
Self::IntegrationUpdate => Some(Self::INTEGRATION_UPDATE),
Self::IntegrationDelete => Some(Self::INTEGRATION_DELETE),
Self::StageInstanceCreate => Some(Self::STAGE_INSTANCE_CREATE),
Self::StageInstanceUpdate => Some(Self::STAGE_INSTANCE_UPDATE),
Self::StageInstanceDelete => Some(Self::STAGE_INSTANCE_DELETE),
Self::ThreadCreate => Some(Self::THREAD_CREATE),
Self::ThreadUpdate => Some(Self::THREAD_UPDATE),
Self::ThreadDelete => Some(Self::THREAD_DELETE),
Self::ThreadListSync => Some(Self::THREAD_LIST_SYNC),
Self::ThreadMemberUpdate => Some(Self::THREAD_MEMBER_UPDATE),
Self::ThreadMembersUpdate => Some(Self::THREAD_MEMBERS_UPDATE),
Self::GuildScheduledEventCreate => Some(Self::GUILD_SCHEDULED_EVENT_CREATE),
Self::GuildScheduledEventUpdate => Some(Self::GUILD_SCHEDULED_EVENT_UPDATE),
Self::GuildScheduledEventDelete => Some(Self::GUILD_SCHEDULED_EVENT_DELETE),
Self::GuildScheduledEventUserAdd => Some(Self::GUILD_SCHEDULED_EVENT_USER_ADD),
Self::GuildScheduledEventUserRemove => Some(Self::GUILD_SCHEDULED_EVENT_USER_REMOVE),
Self::GuildUnavailable => None,
Self::Other(other) => Some(other),
}
}
with_related_ids_for_event_types!(define_related_ids_for_event_type);
}
impl<'de> Deserialize<'de> for EventType {
fn deserialize<D>(deserializer: D) -> StdResult<Self, D::Error>
where
D: Deserializer<'de>,
{
struct EventTypeVisitor;
impl<'de> Visitor<'de> for EventTypeVisitor {
type Value = EventType;
fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("event type str")
}
fn visit_str<E>(self, v: &str) -> StdResult<Self::Value, E>
where
E: DeError,
{
Ok(match v {
EventType::APPLICATION_COMMAND_PERMISSIONS_UPDATE => {
EventType::ApplicationCommandPermissionsUpdate
},
EventType::AUTO_MODERATION_RULE_CREATE => EventType::AutoModerationRuleCreate,
EventType::AUTO_MODERATION_RULE_UPDATE => EventType::AutoModerationRuleUpdate,
EventType::AUTO_MODERATION_RULE_DELETE => EventType::AutoModerationRuleDelete,
EventType::AUTO_MODERATION_ACTION_EXECUTION => {
EventType::AutoModerationActionExecution
},
EventType::CHANNEL_CREATE => EventType::ChannelCreate,
EventType::CHANNEL_DELETE => EventType::ChannelDelete,
EventType::CHANNEL_PINS_UPDATE => EventType::ChannelPinsUpdate,
EventType::CHANNEL_UPDATE => EventType::ChannelUpdate,
EventType::GUILD_BAN_ADD => EventType::GuildBanAdd,
EventType::GUILD_BAN_REMOVE => EventType::GuildBanRemove,
EventType::GUILD_CREATE => EventType::GuildCreate,
EventType::GUILD_DELETE => EventType::GuildDelete,
EventType::GUILD_EMOJIS_UPDATE => EventType::GuildEmojisUpdate,
EventType::GUILD_INTEGRATIONS_UPDATE => EventType::GuildIntegrationsUpdate,
EventType::GUILD_MEMBER_ADD => EventType::GuildMemberAdd,
EventType::GUILD_MEMBER_REMOVE => EventType::GuildMemberRemove,
EventType::GUILD_MEMBER_UPDATE => EventType::GuildMemberUpdate,
EventType::GUILD_MEMBERS_CHUNK => EventType::GuildMembersChunk,
EventType::GUILD_ROLE_CREATE => EventType::GuildRoleCreate,
EventType::GUILD_ROLE_DELETE => EventType::GuildRoleDelete,
EventType::GUILD_ROLE_UPDATE => EventType::GuildRoleUpdate,
EventType::GUILD_STICKERS_UPDATE => EventType::GuildStickersUpdate,
EventType::INVITE_CREATE => EventType::InviteCreate,
EventType::INVITE_DELETE => EventType::InviteDelete,
EventType::GUILD_UPDATE => EventType::GuildUpdate,
EventType::MESSAGE_CREATE => EventType::MessageCreate,
EventType::MESSAGE_DELETE => EventType::MessageDelete,
EventType::MESSAGE_DELETE_BULK => EventType::MessageDeleteBulk,
EventType::MESSAGE_REACTION_ADD => EventType::ReactionAdd,
EventType::MESSAGE_REACTION_REMOVE => EventType::ReactionRemove,
EventType::MESSAGE_REACTION_REMOVE_ALL => EventType::ReactionRemoveAll,
EventType::MESSAGE_UPDATE => EventType::MessageUpdate,
EventType::PRESENCE_UPDATE => EventType::PresenceUpdate,
EventType::PRESENCES_REPLACE => EventType::PresencesReplace,
EventType::READY => EventType::Ready,
EventType::RESUMED => EventType::Resumed,
EventType::TYPING_START => EventType::TypingStart,
EventType::USER_UPDATE => EventType::UserUpdate,
EventType::VOICE_SERVER_UPDATE => EventType::VoiceServerUpdate,
EventType::VOICE_STATE_UPDATE => EventType::VoiceStateUpdate,
EventType::WEBHOOKS_UPDATE => EventType::WebhookUpdate,
EventType::INTERACTION_CREATE => EventType::InteractionCreate,
EventType::INTEGRATION_CREATE => EventType::IntegrationCreate,
EventType::INTEGRATION_UPDATE => EventType::IntegrationUpdate,
EventType::INTEGRATION_DELETE => EventType::IntegrationDelete,
EventType::STAGE_INSTANCE_CREATE => EventType::StageInstanceCreate,
EventType::STAGE_INSTANCE_UPDATE => EventType::StageInstanceUpdate,
EventType::STAGE_INSTANCE_DELETE => EventType::StageInstanceDelete,
EventType::THREAD_CREATE => EventType::ThreadCreate,
EventType::THREAD_UPDATE => EventType::ThreadUpdate,
EventType::THREAD_DELETE => EventType::ThreadDelete,
EventType::GUILD_SCHEDULED_EVENT_CREATE => EventType::GuildScheduledEventCreate,
EventType::GUILD_SCHEDULED_EVENT_UPDATE => EventType::GuildScheduledEventUpdate,
EventType::GUILD_SCHEDULED_EVENT_DELETE => EventType::GuildScheduledEventDelete,
EventType::GUILD_SCHEDULED_EVENT_USER_ADD => {
EventType::GuildScheduledEventUserAdd
},
EventType::GUILD_SCHEDULED_EVENT_USER_REMOVE => {
EventType::GuildScheduledEventUserRemove
},
other => EventType::Other(other.to_owned()),
})
}
}
deserializer.deserialize_str(EventTypeVisitor)
}
}