use chrono::{DateTime, Utc};
use serde::de::Error as DeError;
use serde::ser::{
Serialize,
SerializeSeq,
Serializer
};
use std::{
collections::HashMap,
fmt
};
use super::utils::{deserialize_emojis, deserialize_u64};
use super::prelude::*;
use crate::constants::{OpCode, VoiceOpCode};
use crate::internal::prelude::*;
#[cfg(feature = "cache")]
use crate::cache::{Cache, CacheUpdate};
#[cfg(feature = "cache")]
use std::mem;
#[cfg(feature = "cache")]
use async_trait::async_trait;
#[derive(Clone, Debug)]
pub struct ChannelCreateEvent {
pub channel: Channel,
pub(crate) _nonexhaustive: (),
}
impl<'de> Deserialize<'de> for ChannelCreateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
channel: Channel::deserialize(deserializer)?,
_nonexhaustive: (),
})
}
}
impl Serialize for ChannelCreateEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
Channel::serialize(&self.channel, serializer)
}
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for ChannelCreateEvent {
type Output = Channel;
async fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
match self.channel {
Channel::Guild(ref channel) => {
let (guild_id, channel_id) = (channel.guild_id, channel.id);
let old_channel = cache
.guilds
.write().await
.get_mut(&guild_id)
.and_then(|g| g.channels.insert(channel_id, channel.clone()))
.map(Channel::Guild);
cache
.channels
.write().await
.insert(channel_id, channel.clone());
old_channel
},
Channel::Private(ref mut channel) => {
if let Some(channel) = cache.private_channels.read().await.get(&channel.id) {
return Some(Channel::Private(channel.clone()));
}
let id = {
let user_id = {
cache.update_user_entry(&channel.recipient).await;
channel.recipient.id
};
if let Some(u) = cache.users.read().await.get(&user_id) {
channel.recipient = u.clone();
}
channel.id
};
cache
.private_channels
.write()
.await
.insert(id, channel.clone())
.map(Channel::Private)
},
Channel::Category(ref category) => {
cache
.categories
.write()
.await
.insert(category.id, category.clone())
.map(Channel::Category)
},
}
}
}
#[derive(Clone, Debug)]
pub struct ChannelDeleteEvent {
pub channel: Channel,
pub(crate) _nonexhaustive: (),
}
#[cfg(all(feature = "cache", feature = "model"))]
#[async_trait]
impl CacheUpdate for ChannelDeleteEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
match self.channel {
Channel::Guild(ref channel) => {
let (guild_id, channel_id) = (channel.guild_id, channel.id);
cache
.channels
.write()
.await
.remove(&channel_id);
cache
.guilds
.write()
.await
.get_mut(&guild_id)
.map(|g| g.channels.remove(&channel_id));
},
Channel::Category(ref category) => {
let channel_id = category.id;
cache.categories.write().await.remove(&channel_id);
},
Channel::Private(ref channel) => {
let id = {
channel.id
};
cache.private_channels.write().await.remove(&id);
},
};
cache.messages.write().await.remove(&self.channel.id());
None
}
}
impl<'de> Deserialize<'de> for ChannelDeleteEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
channel: Channel::deserialize(deserializer)?,
_nonexhaustive: (),
})
}
}
impl Serialize for ChannelDeleteEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
Channel::serialize(&self.channel, serializer)
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ChannelPinsUpdateEvent {
pub guild_id: Option<GuildId>,
pub channel_id: ChannelId,
pub last_pin_timestamp: Option<DateTime<Utc>>,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for ChannelPinsUpdateEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
if let Some(channel) = cache.channels.write().await.get_mut(&self.channel_id) {
channel.last_pin_timestamp = self.last_pin_timestamp;
return None;
}
if let Some(channel) = cache.private_channels.write().await.get_mut(&self.channel_id) {
channel.last_pin_timestamp = self.last_pin_timestamp;
return None;
}
None
}
}
#[derive(Clone, Debug)]
pub struct ChannelUpdateEvent {
pub channel: Channel,
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for ChannelUpdateEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
match self.channel {
Channel::Guild(ref channel) => {
let (guild_id, channel_id) = (channel.guild_id, channel.id);
cache.channels.write().await.insert(channel_id, channel.clone());
cache
.guilds
.write()
.await
.get_mut(&guild_id)
.map(|g| g.channels.insert(channel_id, channel.clone()));
},
Channel::Private(ref channel) => {
if let Some(c) = cache.private_channels.write().await.get_mut(&channel.id) {
c.clone_from(channel);
}
},
Channel::Category(ref category) => {
if let Some(c) = cache.categories.write().await.get_mut(&category.id) {
c.clone_from(category);
}
},
}
None
}
}
impl<'de> Deserialize<'de> for ChannelUpdateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
channel: Channel::deserialize(deserializer)?,
_nonexhaustive: (),
})
}
}
impl Serialize for ChannelUpdateEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
Channel::serialize(&self.channel, serializer)
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GuildBanAddEvent {
pub guild_id: GuildId,
pub user: User,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GuildBanRemoveEvent {
pub guild_id: GuildId,
pub user: User,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug)]
pub struct GuildCreateEvent {
pub guild: Guild,
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildCreateEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
cache.unavailable_guilds.write().await.remove(&self.guild.id);
let mut guild = self.guild.clone();
for (user_id, member) in &mut guild.members {
cache.update_user_entry(&member.user).await;
if let Some(u) = cache.user(user_id).await {
member.user = u;
}
}
cache.channels.write().await.extend(guild.channels.clone().into_iter());
cache
.guilds
.write()
.await
.insert(self.guild.id, guild);
None
}
}
impl<'de> Deserialize<'de> for GuildCreateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
guild: Guild::deserialize(deserializer)?,
_nonexhaustive: (),
})
}
}
impl Serialize for GuildCreateEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
Guild::serialize(&self.guild, serializer)
}
}
#[derive(Clone, Debug)]
pub struct GuildDeleteEvent {
pub guild: GuildUnavailable,
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildDeleteEvent {
type Output = Guild;
async fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
match cache.guilds.write().await.remove(&self.guild.id) {
Some(guild) => {
for channel_id in guild.channels.keys() {
cache.channels.write().await.remove(channel_id);
cache.messages.write().await.remove(channel_id);
}
Some(guild)
},
None => None,
}
}
}
impl<'de> Deserialize<'de> for GuildDeleteEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
guild: GuildUnavailable::deserialize(deserializer)?,
_nonexhaustive: (),
})
}
}
impl Serialize for GuildDeleteEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
GuildUnavailable::serialize(&self.guild, serializer)
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GuildEmojisUpdateEvent {
#[serde(serialize_with = "serialize_emojis", deserialize_with = "deserialize_emojis")] pub emojis: HashMap<EmojiId, Emoji>,
pub guild_id: GuildId,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildEmojisUpdateEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
if let Some(guild) = cache.guilds.write().await.get_mut(&self.guild_id) {
guild.emojis.clone_from(&self.emojis);
}
None
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GuildIntegrationsUpdateEvent {
pub guild_id: GuildId,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug)]
pub struct GuildMemberAddEvent {
pub guild_id: GuildId,
pub member: Member,
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildMemberAddEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
let user_id = self.member.user.id;
cache.update_user_entry(&self.member.user).await;
if let Some(u) = cache.user(user_id).await {
self.member.user = u;
}
if let Some(guild) = cache.guilds.write().await.get_mut(&self.guild_id) {
guild.member_count += 1;
guild.members.insert(user_id, self.member.clone());
}
None
}
}
impl<'de> Deserialize<'de> for GuildMemberAddEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
let map = JsonMap::deserialize(deserializer)?;
let guild_id = map.get("guild_id")
.ok_or_else(|| DeError::custom("missing member add guild id"))
.and_then(GuildId::deserialize)
.map_err(DeError::custom)?;
Ok(GuildMemberAddEvent {
guild_id,
member: Member::deserialize(Value::Object(map))
.map_err(DeError::custom)?,
_nonexhaustive: (),
})
}
}
impl Serialize for GuildMemberAddEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
let mut s: Vec<u8> = Vec::new();
let mut ser = serde_json::Serializer::new(&mut s);
Member::serialize(&self.member, &mut ser).unwrap();
let mut map: JsonMap = serde_json::from_str(std::str::from_utf8(&s).unwrap()).unwrap();
map.insert(
"guild_id".to_string(),
serde_json::value::Value::Number(serde_json::Number::from(self.guild_id.0)),
);
map.serialize(serializer)
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GuildMemberRemoveEvent {
pub guild_id: GuildId,
pub user: User,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildMemberRemoveEvent {
type Output = Member;
async fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
if let Some(guild) = cache.guilds.write().await.get_mut(&self.guild_id) {
guild.member_count -= 1;
return guild.members.remove(&self.user.id);
}
None
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GuildMemberUpdateEvent {
pub guild_id: GuildId,
pub nick: Option<String>,
pub roles: Vec<RoleId>,
pub user: User,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildMemberUpdateEvent {
type Output = Member;
async fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
cache.update_user_entry(&self.user).await;
if let Some(guild) = cache.guilds.write().await.get_mut(&self.guild_id) {
let mut found = false;
let item = if let Some(member) = guild.members.get_mut(&self.user.id) {
let item = Some(member.clone());
member.nick.clone_from(&self.nick);
member.roles.clone_from(&self.roles);
member.user.clone_from(&self.user);
found = true;
item
} else {
None
};
if !found {
guild.members.insert(
self.user.id,
Member {
deaf: false,
guild_id: self.guild_id,
joined_at: None,
mute: false,
nick: self.nick.clone(),
roles: self.roles.clone(),
user: self.user.clone(),
_nonexhaustive: (),
},
);
}
item
} else {
None
}
}
}
#[derive(Clone, Debug, Serialize)]
pub struct GuildMembersChunkEvent {
pub guild_id: GuildId,
pub members: HashMap<UserId, Member>,
pub chunk_index: u32,
pub chunk_count: u32,
pub nonce: Option<String>,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildMembersChunkEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
for member in self.members.values() {
cache.update_user_entry(&member.user).await;
}
if let Some(g) = cache.guilds.write().await.get_mut(&self.guild_id) {
g.members.extend(self.members.clone());
}
None
}
}
impl<'de> Deserialize<'de> for GuildMembersChunkEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
let mut map = JsonMap::deserialize(deserializer)?;
let guild_id = map.get("guild_id")
.ok_or_else(|| DeError::custom("missing member chunk guild id"))
.and_then(GuildId::deserialize)
.map_err(DeError::custom)?;
let mut members = map.remove("members")
.ok_or_else(|| DeError::custom("missing member chunk members"))?;
let chunk_index = map.get("chunk_index")
.ok_or_else(|| DeError::custom("missing member chunk index"))
.and_then(u32::deserialize)
.map_err(DeError::custom)?;
let chunk_count = map.get("chunk_count")
.ok_or_else(|| DeError::custom("missing member chunk count"))
.and_then(u32::deserialize)
.map_err(DeError::custom)?;
if let Some(members) = members.as_array_mut() {
let num = Value::Number(Number::from(guild_id.0));
for member in members {
if let Some(map) = member.as_object_mut() {
map.insert("guild_id".to_string(), num.clone());
}
}
}
let members = serde_json::from_value::<Vec<Member>>(members)
.map(|members| members
.into_iter()
.fold(HashMap::new(), |mut acc, member| {
let id = member.user.id;
acc.insert(id, member);
acc
}))
.map_err(DeError::custom)?;
let nonce = map.get("nonce")
.and_then(|nonce| nonce.as_str())
.map(|nonce| nonce.to_string());
Ok(GuildMembersChunkEvent {
guild_id,
members,
chunk_index,
chunk_count,
nonce,
_nonexhaustive: (),
})
}
}
#[derive(Clone, Debug, Serialize)]
pub struct GuildRoleCreateEvent {
pub guild_id: GuildId,
pub role: Role,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildRoleCreateEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
cache
.guilds
.write()
.await
.get_mut(&self.guild_id)
.map(|g| g.roles.insert(self.role.id, self.role.clone()));
None
}
}
impl<'de> Deserialize<'de> for GuildRoleCreateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
let mut map = JsonMap::deserialize(deserializer)?;
let guild_id = map.remove("guild_id")
.ok_or_else(|| DeError::custom("expected guild_id"))
.and_then(GuildId::deserialize)
.map_err(DeError::custom)?;
let id = *guild_id.as_u64();
if let Some(value) = map.get_mut("role") {
if let Some(role) = value.as_object_mut() {
role.insert("guild_id".to_string(), Value::Number(Number::from(id)));
}
}
let role = map.remove("role")
.ok_or_else(|| DeError::custom("expected role"))
.and_then(Role::deserialize)
.map_err(DeError::custom)?;
Ok(Self {
guild_id,
role,
_nonexhaustive: (),
})
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GuildRoleDeleteEvent {
pub guild_id: GuildId,
pub role_id: RoleId,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildRoleDeleteEvent {
type Output = Role;
async fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
cache
.guilds
.write()
.await
.get_mut(&self.guild_id)
.and_then(|g| g.roles.remove(&self.role_id))
}
}
#[derive(Clone, Debug, Serialize)]
pub struct GuildRoleUpdateEvent {
pub guild_id: GuildId,
pub role: Role,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildRoleUpdateEvent {
type Output = Role;
async fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
if let Some(guild) = cache.guilds.write().await.get_mut(&self.guild_id) {
if let Some(role) = guild.roles.get_mut(&self.role.id) {
return Some(mem::replace(role, self.role.clone()));
}
}
None
}
}
impl<'de> Deserialize<'de> for GuildRoleUpdateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
let mut map = JsonMap::deserialize(deserializer)?;
let guild_id = map.remove("guild_id")
.ok_or_else(|| DeError::custom("expected guild_id"))
.and_then(GuildId::deserialize)
.map_err(DeError::custom)?;
let id = *guild_id.as_u64();
if let Some(value) = map.get_mut("role") {
if let Some(role) = value.as_object_mut() {
role.insert("guild_id".to_string(), Value::Number(Number::from(id)));
}
}
let role = map.remove("role")
.ok_or_else(|| DeError::custom("expected role"))
.and_then(Role::deserialize)
.map_err(DeError::custom)?;
Ok(Self {
guild_id,
role,
_nonexhaustive: (),
})
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
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,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct InviteDeleteEvent {
pub channel_id: ChannelId,
pub guild_id: Option<GuildId>,
pub code: String,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct GuildUnavailableEvent {
#[serde(rename = "id")] pub guild_id: GuildId,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildUnavailableEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
cache.unavailable_guilds.write().await.insert(self.guild_id);
cache.guilds.write().await.remove(&self.guild_id);
None
}
}
#[derive(Clone, Debug)]
pub struct GuildUpdateEvent {
pub guild: PartialGuild,
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for GuildUpdateEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
if let Some(guild) = cache.guilds.write().await.get_mut(&self.guild.id) {
guild.afk_timeout = self.guild.afk_timeout;
guild.afk_channel_id.clone_from(&self.guild.afk_channel_id);
guild.icon.clone_from(&self.guild.icon);
guild.name.clone_from(&self.guild.name);
guild.owner_id.clone_from(&self.guild.owner_id);
guild.region.clone_from(&self.guild.region);
guild.roles.clone_from(&self.guild.roles);
guild.verification_level = self.guild.verification_level;
}
None
}
}
impl<'de> Deserialize<'de> for GuildUpdateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
guild: PartialGuild::deserialize(deserializer)?,
_nonexhaustive: (),
})
}
}
impl Serialize for GuildUpdateEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
PartialGuild::serialize(&self.guild, serializer)
}
}
#[derive(Clone, Debug)]
pub struct MessageCreateEvent {
pub message: Message,
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for MessageCreateEvent {
type Output = Message;
async fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
let max = cache.settings().await.max_messages;
if max == 0 {
return None;
}
let mut messages_map = cache.messages.write().await;
let messages = messages_map.entry(self.message.channel_id).or_insert_with(Default::default);
let mut message_queues = cache.message_queue.write().await;
let queue = message_queues
.entry(self.message.channel_id)
.or_insert_with(Default::default);
let mut removed_msg = None;
if messages.len() == max {
if let Some(id) = queue.pop_front() {
removed_msg = messages.remove(&id);
}
}
queue.push_back(self.message.id);
messages.insert(self.message.id, self.message.clone());
removed_msg
}
}
impl<'de> Deserialize<'de> for MessageCreateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
message: Message::deserialize(deserializer)?,
_nonexhaustive: (),
})
}
}
impl Serialize for MessageCreateEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
Message::serialize(&self.message, serializer)
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct MessageDeleteBulkEvent {
pub guild_id: Option<GuildId>,
pub channel_id: ChannelId,
pub ids: Vec<MessageId>,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct MessageDeleteEvent {
pub guild_id: Option<GuildId>,
pub channel_id: ChannelId,
#[serde(rename = "id")] pub message_id: MessageId,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
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<DateTime<Utc>>,
pub edited_timestamp: Option<DateTime<Utc>>,
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<Value>>,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for MessageUpdateEvent {
type Output = Message;
async fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
if let Some(messages) = cache.messages.write().await.get_mut(&self.channel_id) {
if let Some(message) = messages.get_mut(&self.id) {
let item = message.clone();
if let Some(attachments) = self.attachments.clone() {
message.attachments = attachments;
}
if let Some(content) = self.content.clone() {
message.content = content;
}
if let Some(edited_timestamp) = self.edited_timestamp {
message.edited_timestamp = Some(edited_timestamp);
}
if let Some(mentions) = self.mentions.clone() {
message.mentions = mentions;
}
if let Some(mention_everyone) = self.mention_everyone {
message.mention_everyone = mention_everyone;
}
if let Some(mention_roles) = self.mention_roles.clone() {
message.mention_roles = mention_roles;
}
if let Some(pinned) = self.pinned {
message.pinned = pinned;
}
return Some(item);
}
}
None
}
}
#[derive(Clone, Debug, Serialize)]
pub struct PresenceUpdateEvent {
pub guild_id: Option<GuildId>,
pub presence: Presence,
pub roles: Option<Vec<RoleId>>,
#[serde(skip_serializing)]
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for PresenceUpdateEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
let user_id = self.presence.user_id;
if let Some(user) = self.presence.user.as_mut() {
cache.update_user_entry(&user).await;
if let Some(u) = cache.user(user_id).await {
*user = u;
}
}
if let Some(guild_id) = self.guild_id {
if let Some(guild) = cache.guilds.write().await.get_mut(&guild_id) {
if self.presence.status == OnlineStatus::Offline {
guild.presences.remove(&self.presence.user_id);
} else {
guild
.presences
.insert(self.presence.user_id, self.presence.clone());
}
if !guild.members.contains_key(&self.presence.user_id) {
if let Some(user) = self.presence.user.as_ref() {
let roles = self.roles.clone().unwrap_or_default();
guild.members.insert(self.presence.user_id, Member {
deaf: false,
guild_id,
joined_at: None,
mute: false,
nick: self.presence.nick.clone(),
user: user.clone(),
roles,
_nonexhaustive: (),
});
}
}
}
} else if self.presence.status == OnlineStatus::Offline {
cache.presences.write().await.remove(&self.presence.user_id);
} else {
cache
.presences
.write()
.await
.insert(self.presence.user_id, self.presence.clone());
}
None
}
}
impl<'de> Deserialize<'de> for PresenceUpdateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
let mut map = JsonMap::deserialize(deserializer)?;
let guild_id = match map.remove("guild_id") {
Some(v) => serde_json::from_value::<Option<GuildId>>(v)
.map_err(DeError::custom)?,
None => None,
};
let roles = match map.remove("roles") {
Some(v) => serde_json::from_value::<Option<Vec<RoleId>>>(v)
.map_err(DeError::custom)?,
None => None,
};
let presence = Presence::deserialize(Value::Object(map))
.map_err(DeError::custom)?;
Ok(Self {
guild_id,
presence,
roles,
_nonexhaustive: (),
})
}
}
#[derive(Clone, Debug)]
pub struct PresencesReplaceEvent {
pub presences: Vec<Presence>,
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for PresencesReplaceEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
cache.presences.write().await.extend({
let mut p: HashMap<UserId, Presence> = HashMap::default();
for presence in &self.presences {
p.insert(presence.user_id, presence.clone());
}
p
});
None
}
}
impl<'de> Deserialize<'de> for PresencesReplaceEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
let presences: Vec<Presence> = Deserialize::deserialize(deserializer)?;
Ok(Self {
presences,
_nonexhaustive: (),
})
}
}
impl Serialize for PresencesReplaceEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
let mut seq = serializer.serialize_seq(Some(self.presences.len()))?;
for value in &self.presences {
seq.serialize_element(value)?;
}
seq.end()
}
}
#[derive(Clone, Debug)]
pub struct ReactionAddEvent {
pub reaction: Reaction,
pub(crate) _nonexhaustive: (),
}
impl<'de> Deserialize<'de> for ReactionAddEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
reaction: Reaction::deserialize(deserializer)?,
_nonexhaustive: (),
})
}
}
impl Serialize for ReactionAddEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
Reaction::serialize(&self.reaction, serializer)
}
}
#[derive(Clone, Debug)]
pub struct ReactionRemoveEvent {
pub reaction: Reaction,
pub(crate) _nonexhaustive: (),
}
impl<'de> Deserialize<'de> for ReactionRemoveEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
reaction: Reaction::deserialize(deserializer)?,
_nonexhaustive: (),
})
}
}
impl Serialize for ReactionRemoveEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
Reaction::serialize(&self.reaction, serializer)
}
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct ReactionRemoveAllEvent {
pub guild_id: Option<GuildId>,
pub channel_id: ChannelId,
pub message_id: MessageId,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug)]
pub struct ReadyEvent {
pub ready: Ready,
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for ReadyEvent {
type Output = ();
async fn update(&mut self, cache: &Cache) -> Option<()> {
let mut ready = self.ready.clone();
for guild in ready.guilds {
match guild {
GuildStatus::Offline(unavailable) => {
cache.guilds.write().await.remove(&unavailable.id);
cache.unavailable_guilds.write().await.insert(unavailable.id);
},
GuildStatus::OnlineGuild(guild) => {
cache.unavailable_guilds.write().await.remove(&guild.id);
cache.guilds.write().await.insert(guild.id, guild);
},
GuildStatus::OnlinePartialGuild(_) => {},
}
}
for (user_id, presence) in &mut ready.presences {
if let Some(ref user) = presence.user {
cache.update_user_entry(user).await;
}
presence.user = match cache.user(user_id).await {
Some(user) => Some(user),
None => None,
};
}
cache.presences.write().await.extend(ready.presences);
*cache.shard_count.write().await = ready.shard.map_or(1, |s| s[1]);
*cache.user.write().await = ready.user;
None
}
}
impl<'de> Deserialize<'de> for ReadyEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
ready: Ready::deserialize(deserializer)?,
_nonexhaustive: (),
})
}
}
impl Serialize for ReadyEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
Ready::serialize(&self.ready, serializer)
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ResumedEvent {
#[serde(rename = "_trace")] pub trace: Vec<Option<String>>,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct TypingStartEvent {
pub guild_id: Option<GuildId>,
pub channel_id: ChannelId,
pub timestamp: u64,
pub user_id: UserId,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct UnknownEvent {
pub kind: String,
pub value: Value,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug)]
pub struct UserUpdateEvent {
pub current_user: CurrentUser,
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for UserUpdateEvent {
type Output = CurrentUser;
async fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
let mut user = cache.user.write().await;
Some(mem::replace(&mut user, self.current_user.clone()))
}
}
impl<'de> Deserialize<'de> for UserUpdateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
Ok(Self {
current_user: CurrentUser::deserialize(deserializer)?,
_nonexhaustive: (),
})
}
}
impl Serialize for UserUpdateEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
CurrentUser::serialize(&self.current_user, serializer)
}
}
#[derive(Clone, Deserialize, Serialize)]
pub struct VoiceServerUpdateEvent {
pub channel_id: Option<ChannelId>,
pub endpoint: Option<String>,
pub guild_id: Option<GuildId>,
pub token: String,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
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)]
pub struct VoiceStateUpdateEvent {
pub guild_id: Option<GuildId>,
pub voice_state: VoiceState,
pub(crate) _nonexhaustive: (),
}
#[cfg(feature = "cache")]
#[async_trait]
impl CacheUpdate for VoiceStateUpdateEvent {
type Output = VoiceState;
async fn update(&mut self, cache: &Cache) -> Option<VoiceState> {
if let Some(guild_id) = self.guild_id {
if let Some(guild) = cache.guilds.write().await.get_mut(&guild_id) {
if self.voice_state.channel_id.is_some() {
guild
.voice_states
.insert(self.voice_state.user_id, self.voice_state.clone())
} else {
guild
.voice_states
.remove(&self.voice_state.user_id)
}
} else {
None
}
} else {
None
}
}
}
impl<'de> Deserialize<'de> for VoiceStateUpdateEvent {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
let map = JsonMap::deserialize(deserializer)?;
let guild_id = match map.get("guild_id") {
Some(v) => Some(GuildId::deserialize(v).map_err(DeError::custom)?),
None => None,
};
Ok(VoiceStateUpdateEvent {
guild_id,
voice_state: VoiceState::deserialize(Value::Object(map))
.map_err(DeError::custom)?,
_nonexhaustive: (),
})
}
}
impl Serialize for VoiceStateUpdateEvent {
fn serialize<S>(&self, serializer: S) -> StdResult<S::Ok, S::Error>
where S: Serializer {
let mut s: Vec<u8> = Vec::new();
let mut ser = serde_json::Serializer::new(&mut s);
VoiceState::serialize(&self.voice_state, &mut ser).unwrap();
let mut map: JsonMap = serde_json::from_str(std::str::from_utf8(&s).unwrap()).unwrap();
if let Some(guild_id) = self.guild_id {
map.insert(
"guild_id".to_string(),
serde_json::value::Value::Number(serde_json::Number::from(guild_id.0)),
);
}
map.serialize(serializer)
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct WebhookUpdateEvent {
pub channel_id: ChannelId,
pub guild_id: GuildId,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[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::Object(map))
}).map_err(DeError::custom)?;
let x = deserialize_event_with_type(kind, payload)
.map_err(DeError::custom)?;
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 {
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),
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),
Unknown(UnknownEvent),
}
pub fn deserialize_event_with_type(kind: EventType, v: Value) -> Result<Event> {
Ok(match kind {
EventType::ChannelCreate => Event::ChannelCreate(serde_json::from_value(v)?),
EventType::ChannelDelete => Event::ChannelDelete(serde_json::from_value(v)?),
EventType::ChannelPinsUpdate => {
Event::ChannelPinsUpdate(serde_json::from_value(v)?)
},
EventType::ChannelUpdate => Event::ChannelUpdate(serde_json::from_value(v)?),
EventType::GuildBanAdd => Event::GuildBanAdd(serde_json::from_value(v)?),
EventType::GuildBanRemove => Event::GuildBanRemove(serde_json::from_value(v)?),
EventType::GuildCreate | EventType::GuildUnavailable => {
let mut map = JsonMap::deserialize(v)?;
if map.remove("unavailable")
.and_then(|v| v.as_bool())
.unwrap_or(false) {
let guild_data = serde_json::from_value(Value::Object(map))?;
Event::GuildUnavailable(guild_data)
} else {
Event::GuildCreate(serde_json::from_value(Value::Object(map))?)
}
},
EventType::GuildDelete => {
let mut map = JsonMap::deserialize(v)?;
if map.remove("unavailable")
.and_then(|v| v.as_bool())
.unwrap_or(false) {
let guild_data = serde_json::from_value(Value::Object(map))?;
Event::GuildUnavailable(guild_data)
} else {
Event::GuildDelete(serde_json::from_value(Value::Object(map))?)
}
},
EventType::GuildEmojisUpdate => {
Event::GuildEmojisUpdate(serde_json::from_value(v)?)
},
EventType::GuildIntegrationsUpdate => {
Event::GuildIntegrationsUpdate(serde_json::from_value(v)?)
},
EventType::GuildMemberAdd => Event::GuildMemberAdd(serde_json::from_value(v)?),
EventType::GuildMemberRemove => {
Event::GuildMemberRemove(serde_json::from_value(v)?)
},
EventType::GuildMemberUpdate => {
Event::GuildMemberUpdate(serde_json::from_value(v)?)
},
EventType::GuildMembersChunk => {
Event::GuildMembersChunk(serde_json::from_value(v)?)
},
EventType::GuildRoleCreate => {
Event::GuildRoleCreate(serde_json::from_value(v)?)
},
EventType::GuildRoleDelete => {
Event::GuildRoleDelete(serde_json::from_value(v)?)
},
EventType::GuildRoleUpdate => {
Event::GuildRoleUpdate(serde_json::from_value(v)?)
},
EventType::InviteCreate => Event::InviteCreate(serde_json::from_value(v)?),
EventType::InviteDelete => Event::InviteDelete(serde_json::from_value(v)?),
EventType::GuildUpdate => Event::GuildUpdate(serde_json::from_value(v)?),
EventType::MessageCreate => Event::MessageCreate(serde_json::from_value(v)?),
EventType::MessageDelete => Event::MessageDelete(serde_json::from_value(v)?),
EventType::MessageDeleteBulk => {
Event::MessageDeleteBulk(serde_json::from_value(v)?)
},
EventType::ReactionAdd => {
Event::ReactionAdd(serde_json::from_value(v)?)
},
EventType::ReactionRemove => {
Event::ReactionRemove(serde_json::from_value(v)?)
},
EventType::ReactionRemoveAll => {
Event::ReactionRemoveAll(serde_json::from_value(v)?)
},
EventType::MessageUpdate => Event::MessageUpdate(serde_json::from_value(v)?),
EventType::PresenceUpdate => Event::PresenceUpdate(serde_json::from_value(v)?),
EventType::PresencesReplace => {
Event::PresencesReplace(serde_json::from_value(v)?)
},
EventType::Ready => Event::Ready(serde_json::from_value(v)?),
EventType::Resumed => Event::Resumed(serde_json::from_value(v)?),
EventType::TypingStart => Event::TypingStart(serde_json::from_value(v)?),
EventType::UserUpdate => Event::UserUpdate(serde_json::from_value(v)?),
EventType::VoiceServerUpdate => {
Event::VoiceServerUpdate(serde_json::from_value(v)?)
},
EventType::VoiceStateUpdate => {
Event::VoiceStateUpdate(serde_json::from_value(v)?)
},
EventType::WebhookUpdate => Event::WebhookUpdate(serde_json::from_value(v)?),
EventType::Other(kind) => Event::Unknown(UnknownEvent {
kind,
value: v,
_nonexhaustive: (),
}),
})
}
#[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord)]
#[non_exhaustive]
pub enum EventType {
ChannelCreate,
ChannelDelete,
ChannelPinsUpdate,
ChannelUpdate,
GuildBanAdd,
GuildBanRemove,
GuildCreate,
GuildDelete,
GuildEmojisUpdate,
GuildIntegrationsUpdate,
GuildMemberAdd,
GuildMemberRemove,
GuildMemberUpdate,
GuildMembersChunk,
GuildRoleCreate,
GuildRoleDelete,
GuildRoleUpdate,
GuildUnavailable,
GuildUpdate,
InviteCreate,
InviteDelete,
MessageCreate,
MessageDelete,
MessageDeleteBulk,
MessageUpdate,
PresenceUpdate,
PresencesReplace,
ReactionAdd,
ReactionRemove,
ReactionRemoveAll,
Ready,
Resumed,
TypingStart,
UserUpdate,
VoiceStateUpdate,
VoiceServerUpdate,
WebhookUpdate,
Other(String),
}
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 Formatter<'_>) -> FmtResult {
f.write_str("event type str")
}
fn visit_str<E>(self, v: &str) -> StdResult<Self::Value, E>
where E: DeError {
Ok(match v {
"CHANNEL_CREATE" => EventType::ChannelCreate,
"CHANNEL_DELETE" => EventType::ChannelDelete,
"CHANNEL_PINS_UPDATE" => EventType::ChannelPinsUpdate,
"CHANNEL_UPDATE" => EventType::ChannelUpdate,
"GUILD_BAN_ADD" => EventType::GuildBanAdd,
"GUILD_BAN_REMOVE" => EventType::GuildBanRemove,
"GUILD_CREATE" => EventType::GuildCreate,
"GUILD_DELETE" => EventType::GuildDelete,
"GUILD_EMOJIS_UPDATE" => EventType::GuildEmojisUpdate,
"GUILD_INTEGRATIONS_UPDATE" => EventType::GuildIntegrationsUpdate,
"GUILD_MEMBER_ADD" => EventType::GuildMemberAdd,
"GUILD_MEMBER_REMOVE" => EventType::GuildMemberRemove,
"GUILD_MEMBER_UPDATE" => EventType::GuildMemberUpdate,
"GUILD_MEMBERS_CHUNK" => EventType::GuildMembersChunk,
"GUILD_ROLE_CREATE" => EventType::GuildRoleCreate,
"GUILD_ROLE_DELETE" => EventType::GuildRoleDelete,
"GUILD_ROLE_UPDATE" => EventType::GuildRoleUpdate,
"INVITE_CREATE" => EventType::InviteCreate,
"INVITE_DELETE" => EventType::InviteDelete,
"GUILD_UPDATE" => EventType::GuildUpdate,
"MESSAGE_CREATE" => EventType::MessageCreate,
"MESSAGE_DELETE" => EventType::MessageDelete,
"MESSAGE_DELETE_BULK" => EventType::MessageDeleteBulk,
"MESSAGE_REACTION_ADD" => EventType::ReactionAdd,
"MESSAGE_REACTION_REMOVE" => EventType::ReactionRemove,
"MESSAGE_REACTION_REMOVE_ALL" => EventType::ReactionRemoveAll,
"MESSAGE_UPDATE" => EventType::MessageUpdate,
"PRESENCE_UPDATE" => EventType::PresenceUpdate,
"PRESENCES_REPLACE" => EventType::PresencesReplace,
"READY" => EventType::Ready,
"RESUMED" => EventType::Resumed,
"TYPING_START" => EventType::TypingStart,
"USER_UPDATE" => EventType::UserUpdate,
"VOICE_SERVER_UPDATE" => EventType::VoiceServerUpdate,
"VOICE_STATE_UPDATE" => EventType::VoiceStateUpdate,
"WEBHOOKS_UPDATE" => EventType::WebhookUpdate,
other => EventType::Other(other.to_owned()),
})
}
}
deserializer.deserialize_str(EventTypeVisitor)
}
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct VoiceHeartbeat {
pub nonce: u64,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Copy, Debug, Serialize)]
pub struct VoiceHeartbeatAck {
pub nonce: u64,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
impl<'de> Deserialize<'de> for VoiceHeartbeatAck {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
deserialize_u64(deserializer)
.map(|nonce| Self { nonce, _nonexhaustive: () })
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct VoiceReady {
pub heartbeat_interval: u64,
pub modes: Vec<String>,
pub ip: String,
pub port: u16,
pub ssrc: u32,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct VoiceHello {
pub heartbeat_interval: u64,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct VoiceSessionDescription {
pub mode: String,
pub secret_key: Vec<u8>,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct VoiceSpeaking {
pub speaking: bool,
pub ssrc: u32,
pub user_id: UserId,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Deserialize, Serialize)]
pub struct VoiceResume {
pub server_id: String,
pub session_id: String,
pub token: String,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
impl fmt::Debug for VoiceResume {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("VoiceResume")
.field("server_id", &self.server_id)
.field("session_id", &self.session_id)
.finish()
}
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct VoiceClientConnect {
pub audio_ssrc: u32,
pub user_id: UserId,
pub video_ssrc: u32,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub struct VoiceClientDisconnect {
pub user_id: UserId,
#[serde(skip)]
pub(crate) _nonexhaustive: (),
}
#[derive(Clone, Debug, Serialize)]
#[non_exhaustive]
#[serde(untagged)]
pub enum VoiceEvent {
Ready(VoiceReady),
SessionDescription(VoiceSessionDescription),
Speaking(VoiceSpeaking),
HeartbeatAck(VoiceHeartbeatAck),
Hello(VoiceHello),
Resumed,
ClientConnect(VoiceClientConnect),
ClientDisconnect(VoiceClientDisconnect),
Unknown(VoiceOpCode, Value),
}
impl<'de> Deserialize<'de> for VoiceEvent {
fn deserialize<D>(deserializer: D) -> StdResult<Self, D::Error>
where D: Deserializer<'de> {
let mut map = JsonMap::deserialize(deserializer)?;
let op = map.remove("op")
.ok_or_else(|| DeError::custom("expected voice event op"))
.and_then(VoiceOpCode::deserialize)
.map_err(DeError::custom)?;
let v = map.remove("d")
.ok_or_else(|| DeError::custom("expected voice gateway payload"))
.and_then(Value::deserialize)
.map_err(DeError::custom)?;
Ok(match op {
VoiceOpCode::HeartbeatAck => {
let v = serde_json::from_value(v).map_err(DeError::custom)?;
VoiceEvent::HeartbeatAck(v)
},
VoiceOpCode::Ready => {
let v = VoiceReady::deserialize(v).map_err(DeError::custom)?;
VoiceEvent::Ready(v)
},
VoiceOpCode::Hello => {
let v = serde_json::from_value(v).map_err(DeError::custom)?;
VoiceEvent::Hello(v)
},
VoiceOpCode::SessionDescription => {
let v = VoiceSessionDescription::deserialize(v)
.map_err(DeError::custom)?;
VoiceEvent::SessionDescription(v)
},
VoiceOpCode::Speaking => {
let v = VoiceSpeaking::deserialize(v).map_err(DeError::custom)?;
VoiceEvent::Speaking(v)
},
VoiceOpCode::Resumed => VoiceEvent::Resumed,
VoiceOpCode::ClientConnect => {
let v = VoiceClientConnect::deserialize(v).map_err(DeError::custom)?;
VoiceEvent::ClientConnect(v)
},
VoiceOpCode::ClientDisconnect => {
let v = VoiceClientDisconnect::deserialize(v).map_err(DeError::custom)?;
VoiceEvent::ClientDisconnect(v)
},
other => VoiceEvent::Unknown(other, v),
})
}
}