From bc3491cf3a70a02ce5725e66887746567ae4660c Mon Sep 17 00:00:00 2001 From: acdenisSK Date: Tue, 12 Sep 2017 14:57:52 +0200 Subject: [PATCH] Revamp `CacheEventsImpl` --- src/cache/cache_events_impl.rs | 514 --------------------------- src/cache/cache_update.rs | 7 + src/cache/mod.rs | 10 +- src/client/dispatch.rs | 128 ++++--- src/lib.rs | 2 - src/model/event.rs | 611 +++++++++++++++++++++++++++++++++ 6 files changed, 684 insertions(+), 588 deletions(-) delete mode 100644 src/cache/cache_events_impl.rs create mode 100644 src/cache/cache_update.rs diff --git a/src/cache/cache_events_impl.rs b/src/cache/cache_events_impl.rs deleted file mode 100644 index a1d2e821edd..00000000000 --- a/src/cache/cache_events_impl.rs +++ /dev/null @@ -1,514 +0,0 @@ -use std::collections::hash_map::Entry; -use std::collections::HashMap; -use std::default::Default; -use std::sync::{Arc, RwLock}; -use std::mem; -use model::*; -use model::event::*; -use internal::RwLockExt; - -pub(crate) trait CacheEventsImpl { - fn update_with_channel_create(&mut self, event: &ChannelCreateEvent) -> Option; - - fn update_with_channel_delete(&mut self, event: &ChannelDeleteEvent); - - fn update_with_channel_pins_update(&mut self, event: &ChannelPinsUpdateEvent); - - fn update_with_channel_recipient_add(&mut self, event: &mut ChannelRecipientAddEvent); - - fn update_with_channel_recipient_remove(&mut self, event: &ChannelRecipientRemoveEvent); - - fn update_with_channel_update(&mut self, event: &ChannelUpdateEvent); - - fn update_with_guild_create(&mut self, event: &GuildCreateEvent); - - fn update_with_guild_delete(&mut self, event: &GuildDeleteEvent) -> Option>>; - - fn update_with_guild_emojis_update(&mut self, event: &GuildEmojisUpdateEvent); - - fn update_with_guild_member_add(&mut self, event: &mut GuildMemberAddEvent); - - fn update_with_guild_member_remove(&mut self, event: &GuildMemberRemoveEvent) - -> Option; - - fn update_with_guild_member_update(&mut self, event: &GuildMemberUpdateEvent) - -> Option; - - fn update_with_guild_members_chunk(&mut self, event: &GuildMembersChunkEvent); - - fn update_with_guild_role_create(&mut self, event: &GuildRoleCreateEvent); - - fn update_with_guild_role_delete(&mut self, event: &GuildRoleDeleteEvent) -> Option; - - fn update_with_guild_role_update(&mut self, event: &GuildRoleUpdateEvent) -> Option; - - fn update_with_guild_unavailable(&mut self, event: &GuildUnavailableEvent); - - fn update_with_guild_update(&mut self, event: &GuildUpdateEvent); - - fn update_with_presences_replace(&mut self, event: &PresencesReplaceEvent); - - fn update_with_presence_update(&mut self, event: &mut PresenceUpdateEvent); - - fn update_with_ready(&mut self, event: &ReadyEvent); - - fn update_with_user_update(&mut self, event: &UserUpdateEvent) -> CurrentUser; - - fn update_with_voice_state_update(&mut self, event: &VoiceStateUpdateEvent); -} - -impl CacheEventsImpl for super::Cache { - fn update_with_channel_create(&mut self, event: &ChannelCreateEvent) -> Option { - match event.channel { - Channel::Group(ref group) => { - let group = group.clone(); - - let channel_id = group.with_mut(|writer| { - for (recipient_id, recipient) in &mut writer.recipients { - self.update_user_entry(&recipient.read().unwrap()); - - *recipient = self.users[recipient_id].clone(); - } - - writer.channel_id - }); - - let ch = self.groups.insert(channel_id, group); - - ch.map(Channel::Group) - }, - Channel::Guild(ref channel) => { - let (guild_id, channel_id) = channel.with(|channel| (channel.guild_id, channel.id)); - - self.channels.insert(channel_id, channel.clone()); - - self.guilds - .get_mut(&guild_id) - .and_then(|guild| { - guild.with_mut(|guild| { - guild.channels.insert(channel_id, channel.clone()) - }) - }) - .map(Channel::Guild) - }, - Channel::Private(ref channel) => { - if let Some(channel) = self.private_channels.get(&channel.with(|c| c.id)) { - return Some(Channel::Private((*channel).clone())); - } - - let channel = channel.clone(); - - let id = channel.with_mut(|writer| { - let user_id = writer.recipient.with_mut(|user| { - self.update_user_entry(&user); - - user.id - }); - - writer.recipient = self.users[&user_id].clone(); - writer.id - }); - - let ch = self.private_channels.insert(id, channel.clone()); - ch.map(Channel::Private) - }, - Channel::Category(ref category) => { - self.categories - .insert(category.read().unwrap().id, category.clone()) - .map(Channel::Category) - }, - } - } - - fn update_with_channel_delete(&mut self, event: &ChannelDeleteEvent) { - match event.channel { - Channel::Guild(ref channel) => { - let (guild_id, channel_id) = channel.with(|channel| (channel.guild_id, channel.id)); - - self.channels.remove(&channel_id); - - self.guilds.get_mut(&guild_id).and_then(|guild| { - guild.with_mut(|g| g.channels.remove(&channel_id)) - }); - }, - Channel::Category(ref category) => { - let channel_id = category.with(|cat| cat.id); - - self.categories.remove(&channel_id); - }, - // We ignore these two due to the fact that the delete event for dms/groups - // will _not_ fire anymore. - Channel::Private(_) | - Channel::Group(_) => unreachable!(), - }; - } - - #[allow(dead_code)] - fn update_with_channel_pins_update(&mut self, event: &ChannelPinsUpdateEvent) { - if let Some(channel) = self.channels.get(&event.channel_id) { - channel.with_mut(|c| { - c.last_pin_timestamp = event.last_pin_timestamp; - }); - - return; - } - - if let Some(channel) = self.private_channels.get_mut(&event.channel_id) { - channel.with_mut(|c| { - c.last_pin_timestamp = event.last_pin_timestamp; - }); - - return; - } - - if let Some(group) = self.groups.get_mut(&event.channel_id) { - group.with_mut(|c| { - c.last_pin_timestamp = event.last_pin_timestamp; - }); - - return; - } - } - - fn update_with_channel_recipient_add(&mut self, event: &mut ChannelRecipientAddEvent) { - self.update_user_entry(&event.user); - let user = self.users[&event.user.id].clone(); - - self.groups.get_mut(&event.channel_id).map(|group| { - group.write().unwrap().recipients.insert( - event.user.id, - user, - ); - }); - } - - fn update_with_channel_recipient_remove(&mut self, event: &ChannelRecipientRemoveEvent) { - self.groups.get_mut(&event.channel_id).map(|group| { - group.with_mut(|g| g.recipients.remove(&event.user.id)) - }); - } - - fn update_with_channel_update(&mut self, event: &ChannelUpdateEvent) { - match event.channel { - Channel::Group(ref group) => { - let (ch_id, no_recipients) = - group.with(|g| (g.channel_id, g.recipients.is_empty())); - - match self.groups.entry(ch_id) { - Entry::Vacant(e) => { - e.insert(group.clone()); - }, - Entry::Occupied(mut e) => { - let mut dest = e.get_mut().write().unwrap(); - - if no_recipients { - let recipients = mem::replace(&mut dest.recipients, HashMap::new()); - - dest.clone_from(&group.read().unwrap()); - - dest.recipients = recipients; - } else { - dest.clone_from(&group.read().unwrap()); - } - }, - } - }, - Channel::Guild(ref channel) => { - let (guild_id, channel_id) = channel.with(|channel| (channel.guild_id, channel.id)); - - self.channels.insert(channel_id, channel.clone()); - self.guilds.get_mut(&guild_id).map(|guild| { - guild.with_mut( - |g| g.channels.insert(channel_id, channel.clone()), - ) - }); - }, - Channel::Private(ref channel) => { - self.private_channels - .get_mut(&channel.read().unwrap().id) - .map(|private| private.clone_from(channel)); - }, - Channel::Category(ref category) => { - self.categories.get_mut(&category.read().unwrap().id).map( - |c| { - c.clone_from(category) - }, - ); - }, - } - } - - fn update_with_guild_create(&mut self, event: &GuildCreateEvent) { - self.unavailable_guilds.remove(&event.guild.id); - - let mut guild = event.guild.clone(); - - for (user_id, member) in &mut guild.members { - self.update_user_entry(&member.user.read().unwrap()); - let user = self.users[user_id].clone(); - - member.user = user.clone(); - } - - self.channels.extend(guild.channels.clone()); - self.guilds.insert( - event.guild.id, - Arc::new(RwLock::new(guild)), - ); - } - - fn update_with_guild_delete(&mut self, event: &GuildDeleteEvent) -> Option>> { - // Remove channel entries for the guild if the guild is found. - self.guilds.remove(&event.guild.id).map(|guild| { - for channel_id in guild.write().unwrap().channels.keys() { - self.channels.remove(channel_id); - } - - guild - }) - } - - fn update_with_guild_emojis_update(&mut self, event: &GuildEmojisUpdateEvent) { - self.guilds.get_mut(&event.guild_id).map(|guild| { - guild.with_mut(|g| g.emojis.extend(event.emojis.clone())) - }); - } - - fn update_with_guild_member_add(&mut self, event: &mut GuildMemberAddEvent) { - let user_id = event.member.user.with(|u| u.id); - self.update_user_entry(&event.member.user.read().unwrap()); - - // Always safe due to being inserted above. - event.member.user = self.users[&user_id].clone(); - - self.guilds.get_mut(&event.guild_id).map(|guild| { - guild.with_mut(|guild| { - guild.member_count += 1; - guild.members.insert(user_id, event.member.clone()); - }) - }); - } - - fn update_with_guild_member_remove(&mut self, - event: &GuildMemberRemoveEvent) - -> Option { - self.guilds.get_mut(&event.guild_id).and_then(|guild| { - guild.with_mut(|guild| { - guild.member_count -= 1; - guild.members.remove(&event.user.id) - }) - }) - } - - fn update_with_guild_member_update(&mut self, - event: &GuildMemberUpdateEvent) - -> Option { - self.update_user_entry(&event.user); - - if let Some(guild) = self.guilds.get_mut(&event.guild_id) { - let mut guild = guild.write().unwrap(); - - let mut found = false; - - let item = if let Some(member) = guild.members.get_mut(&event.user.id) { - let item = Some(member.clone()); - - member.nick.clone_from(&event.nick); - member.roles.clone_from(&event.roles); - member.user.write().unwrap().clone_from(&event.user); - - found = true; - - item - } else { - None - }; - - if !found { - guild.members.insert( - event.user.id, - Member { - deaf: false, - guild_id: event.guild_id, - joined_at: None, - mute: false, - nick: event.nick.clone(), - roles: event.roles.clone(), - user: Arc::new(RwLock::new(event.user.clone())), - }, - ); - } - - item - } else { - None - } - } - - fn update_with_guild_members_chunk(&mut self, event: &GuildMembersChunkEvent) { - for member in event.members.values() { - self.update_user_entry(&member.user.read().unwrap()); - } - - self.guilds.get_mut(&event.guild_id).map(|guild| { - guild.with_mut(|g| g.members.extend(event.members.clone())) - }); - } - - fn update_with_guild_role_create(&mut self, event: &GuildRoleCreateEvent) { - self.guilds.get_mut(&event.guild_id).map(|guild| { - guild.write().unwrap().roles.insert( - event.role.id, - event.role.clone(), - ) - }); - } - - fn update_with_guild_role_delete(&mut self, event: &GuildRoleDeleteEvent) -> Option { - self.guilds.get_mut(&event.guild_id).and_then(|guild| { - guild.with_mut(|g| g.roles.remove(&event.role_id)) - }) - } - - fn update_with_guild_role_update(&mut self, event: &GuildRoleUpdateEvent) -> Option { - self.guilds.get_mut(&event.guild_id).and_then(|guild| { - guild.with_mut(|g| { - g.roles.get_mut(&event.role.id).map(|role| { - mem::replace(role, event.role.clone()) - }) - }) - }) - } - - fn update_with_guild_unavailable(&mut self, event: &GuildUnavailableEvent) { - self.unavailable_guilds.insert(event.guild_id); - self.guilds.remove(&event.guild_id); - } - - fn update_with_guild_update(&mut self, event: &GuildUpdateEvent) { - self.guilds.get_mut(&event.guild.id).map(|guild| { - let mut guild = guild.write().unwrap(); - - guild.afk_timeout = event.guild.afk_timeout; - guild.afk_channel_id.clone_from(&event.guild.afk_channel_id); - guild.icon.clone_from(&event.guild.icon); - guild.name.clone_from(&event.guild.name); - guild.owner_id.clone_from(&event.guild.owner_id); - guild.region.clone_from(&event.guild.region); - guild.roles.clone_from(&event.guild.roles); - guild.verification_level = event.guild.verification_level; - }); - } - - fn update_with_presences_replace(&mut self, event: &PresencesReplaceEvent) { - self.presences.extend({ - let mut p: HashMap = HashMap::default(); - - for presence in &event.presences { - p.insert(presence.user_id, presence.clone()); - } - - p - }); - } - - fn update_with_presence_update(&mut self, event: &mut PresenceUpdateEvent) { - let user_id = event.presence.user_id; - - if let Some(user) = event.presence.user.as_mut() { - self.update_user_entry(&user.read().unwrap()); - *user = self.users[&user_id].clone(); - } - - if let Some(guild_id) = event.guild_id { - if let Some(guild) = self.guilds.get_mut(&guild_id) { - let mut guild = guild.write().unwrap(); - - // If the member went offline, remove them from the presence list. - if event.presence.status == OnlineStatus::Offline { - guild.presences.remove(&event.presence.user_id); - } else { - guild.presences.insert( - event.presence.user_id, - event.presence.clone(), - ); - } - } - } else if event.presence.status == OnlineStatus::Offline { - self.presences.remove(&event.presence.user_id); - } else { - self.presences.insert( - event.presence.user_id, - event.presence.clone(), - ); - } - } - - fn update_with_ready(&mut self, event: &ReadyEvent) { - let mut ready = event.ready.clone(); - - for guild in ready.guilds { - match guild { - GuildStatus::Offline(unavailable) => { - self.guilds.remove(&unavailable.id); - self.unavailable_guilds.insert(unavailable.id); - }, - GuildStatus::OnlineGuild(guild) => { - self.unavailable_guilds.remove(&guild.id); - self.guilds.insert(guild.id, Arc::new(RwLock::new(guild))); - }, - GuildStatus::OnlinePartialGuild(_) => {}, - } - } - - // `ready.private_channels` will always be empty, and possibly be removed in the future. - // So don't handle it at all. - - for (user_id, presence) in &mut ready.presences { - if let Some(ref user) = presence.user { - self.update_user_entry(&user.read().unwrap()); - } - - presence.user = self.users.get(user_id).cloned(); - } - - self.presences.extend(ready.presences); - self.shard_count = ready.shard.map_or(1, |s| s[1]); - self.user = ready.user; - } - - fn update_with_user_update(&mut self, event: &UserUpdateEvent) -> CurrentUser { - mem::replace(&mut self.user, event.current_user.clone()) - } - - fn update_with_voice_state_update(&mut self, event: &VoiceStateUpdateEvent) { - if let Some(guild_id) = event.guild_id { - if let Some(guild) = self.guilds.get_mut(&guild_id) { - let mut guild = guild.write().unwrap(); - - if event.voice_state.channel_id.is_some() { - // Update or add to the voice state list - { - let finding = guild.voice_states.get_mut(&event.voice_state.user_id); - - if let Some(srv_state) = finding { - srv_state.clone_from(&event.voice_state); - - return; - } - } - - guild.voice_states.insert( - event.voice_state.user_id, - event.voice_state.clone(), - ); - } else { - // Remove the user from the voice state list - guild.voice_states.remove(&event.voice_state.user_id); - } - } - - return; - } - } -} diff --git a/src/cache/cache_update.rs b/src/cache/cache_update.rs new file mode 100644 index 00000000000..a05cc3d59dc --- /dev/null +++ b/src/cache/cache_update.rs @@ -0,0 +1,7 @@ +use super::Cache; + +pub(crate) trait CacheUpdate { + type Output; + + fn update(&mut self, &mut Cache) -> Option; +} diff --git a/src/cache/mod.rs b/src/cache/mod.rs index 88e4266e7c7..ba9efaa5cc3 100644 --- a/src/cache/mod.rs +++ b/src/cache/mod.rs @@ -47,9 +47,9 @@ use std::default::Default; use std::sync::{Arc, RwLock}; use model::*; -mod cache_events_impl; +mod cache_update; -pub(crate) use self::cache_events_impl::*; +pub(crate) use self::cache_update::*; /// A cache of all events received over a [`Shard`], where storing at least /// some data from the event is possible. @@ -602,7 +602,11 @@ impl Cache { self.categories.get(&channel_id.into()).cloned() } - fn update_user_entry(&mut self, user: &User) { + pub(crate) fn update(&mut self, e: &mut E) -> Option { + e.update(self) + } + + pub(crate) fn update_user_entry(&mut self, user: &User) { match self.users.entry(user.id) { Entry::Vacant(e) => { e.insert(Arc::new(RwLock::new(user.clone()))); diff --git a/src/client/dispatch.rs b/src/client/dispatch.rs index f6d9dd3e9b0..bda06777b87 100644 --- a/src/client/dispatch.rs +++ b/src/client/dispatch.rs @@ -16,23 +16,13 @@ use framework::Framework; #[cfg(feature = "cache")] use super::CACHE; -#[cfg(feature = "cache")] -use super::super::CacheEventsImpl; macro_rules! update { - ($method:ident, @$event:expr) => { - { - #[cfg(feature="cache")] - { - CacheEventsImpl::$method(&mut *CACHE.write().unwrap(), &mut $event) - } - } - }; - ($method:ident, $event:expr) => { + ($event:expr) => { { #[cfg(feature="cache")] { - CacheEventsImpl::$method(&mut *CACHE.write().unwrap(), &$event) + CACHE.write().unwrap().update(&mut $event) } } }; @@ -141,8 +131,8 @@ fn handle_event(event: Event, }; match event { - Event::ChannelCreate(event) => { - update!(update_with_channel_create, event); + Event::ChannelCreate(mut event) => { + update!(event); let context = context(conn, data, tokio_handle); @@ -172,8 +162,8 @@ fn handle_event(event: Event, }, } }, - Event::ChannelDelete(event) => { - update!(update_with_channel_delete, event); + Event::ChannelDelete(mut event) => { + update!(event); let context = context(conn, data, tokio_handle); @@ -196,7 +186,7 @@ fn handle_event(event: Event, }, } }, - Event::ChannelPinsUpdate(event) => { + Event::ChannelPinsUpdate(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -206,7 +196,7 @@ fn handle_event(event: Event, }); }, Event::ChannelRecipientAdd(mut event) => { - update!(update_with_channel_recipient_add, @event); + update!(event); let context = context(conn, data, tokio_handle); @@ -220,8 +210,8 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::ChannelRecipientRemove(event) => { - update!(update_with_channel_recipient_remove, event); + Event::ChannelRecipientRemove(mut event) => { + update!(event); let context = context(conn, data, tokio_handle); @@ -235,8 +225,8 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::ChannelUpdate(event) => { - update!(update_with_channel_update, event); + Event::ChannelUpdate(mut event) => { + update!(event); let context = context(conn, data, tokio_handle); @@ -254,7 +244,7 @@ fn handle_event(event: Event, }); }} }, - Event::GuildBanAdd(event) => { + Event::GuildBanAdd(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -263,7 +253,7 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::GuildBanRemove(event) => { + Event::GuildBanRemove(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -272,7 +262,7 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::GuildCreate(event) => { + Event::GuildCreate(mut event) => { #[cfg(feature="cache")] let _is_new = { let cache = CACHE.read().unwrap(); @@ -280,7 +270,7 @@ fn handle_event(event: Event, !cache.unavailable_guilds.contains(&event.guild.id) }; - update!(update_with_guild_create, event); + update!(event); #[cfg(feature = "cache")] { @@ -321,8 +311,8 @@ fn handle_event(event: Event, }); }} }, - Event::GuildDelete(event) => { - let _full = update!(update_with_guild_delete, event); + Event::GuildDelete(mut event) => { + let _full = update!(event); let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -338,8 +328,8 @@ fn handle_event(event: Event, }); }} }, - Event::GuildEmojisUpdate(event) => { - update!(update_with_guild_emojis_update, event); + Event::GuildEmojisUpdate(mut event) => { + update!(event); let context = context(conn, data, tokio_handle); @@ -353,7 +343,7 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::GuildIntegrationsUpdate(event) => { + Event::GuildIntegrationsUpdate(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -363,7 +353,7 @@ fn handle_event(event: Event, }); }, Event::GuildMemberAdd(mut event) => { - update!(update_with_guild_member_add, @event); + update!(event); let context = context(conn, data, tokio_handle); @@ -377,8 +367,8 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::GuildMemberRemove(event) => { - let _member = update!(update_with_guild_member_remove, event); + Event::GuildMemberRemove(mut event) => { + let _member = update!(event); let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -394,8 +384,8 @@ fn handle_event(event: Event, }); }} }, - Event::GuildMemberUpdate(event) => { - let _before = update!(update_with_guild_member_update, event); + Event::GuildMemberUpdate(mut event) => { + let _before = update!(event); let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -422,8 +412,8 @@ fn handle_event(event: Event, } } }, - Event::GuildMembersChunk(event) => { - update!(update_with_guild_members_chunk, event); + Event::GuildMembersChunk(mut event) => { + update!(event); let context = context(conn, data, tokio_handle); @@ -437,8 +427,8 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::GuildRoleCreate(event) => { - update!(update_with_guild_role_create, event); + Event::GuildRoleCreate(mut event) => { + update!(event); let context = context(conn, data, tokio_handle); @@ -448,8 +438,8 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::GuildRoleDelete(event) => { - let _role = update!(update_with_guild_role_delete, event); + Event::GuildRoleDelete(mut event) => { + let _role = update!(event); let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -465,8 +455,8 @@ fn handle_event(event: Event, }); }} }, - Event::GuildRoleUpdate(event) => { - let _before = update!(update_with_guild_role_update, event); + Event::GuildRoleUpdate(mut event) => { + let _before = update!(event); let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -482,8 +472,8 @@ fn handle_event(event: Event, }); }} }, - Event::GuildUnavailable(event) => { - update!(update_with_guild_unavailable, event); + Event::GuildUnavailable(mut event) => { + update!(event); let context = context(conn, data, tokio_handle); @@ -493,8 +483,8 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::GuildUpdate(event) => { - update!(update_with_guild_update, event); + Event::GuildUpdate(mut event) => { + update!(event); let context = context(conn, data, tokio_handle); @@ -521,7 +511,7 @@ fn handle_event(event: Event, }, // Already handled by the framework check macro Event::MessageCreate(_) => {}, - Event::MessageDeleteBulk(event) => { + Event::MessageDeleteBulk(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -534,7 +524,7 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::MessageDelete(event) => { + Event::MessageDelete(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -547,7 +537,7 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::MessageUpdate(event) => { + Event::MessageUpdate(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -556,8 +546,8 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::PresencesReplace(event) => { - update!(update_with_presences_replace, event); + Event::PresencesReplace(mut event) => { + update!(event); let context = context(conn, data, tokio_handle); @@ -568,7 +558,7 @@ fn handle_event(event: Event, }); }, Event::PresenceUpdate(mut event) => { - update!(update_with_presence_update, @event); + update!(event); let context = context(conn, data, tokio_handle); @@ -578,7 +568,7 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::ReactionAdd(event) => { + Event::ReactionAdd(mut event) => { let h = event_handler.clone(); let context = context(conn, data, tokio_handle); tokio_handle.spawn_fn(move || { @@ -586,7 +576,7 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::ReactionRemove(event) => { + Event::ReactionRemove(mut event) => { let h = event_handler.clone(); let context = context(conn, data, tokio_handle); tokio_handle.spawn_fn(move || { @@ -594,7 +584,7 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::ReactionRemoveAll(event) => { + Event::ReactionRemoveAll(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -607,8 +597,8 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::Ready(event) => { - update!(update_with_ready, event); + Event::Ready(mut event) => { + update!(event); feature_cache!{ { @@ -635,7 +625,7 @@ fn handle_event(event: Event, } } }, - Event::Resumed(event) => { + Event::Resumed(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -644,7 +634,7 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::TypingStart(event) => { + Event::TypingStart(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -653,7 +643,7 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::Unknown(event) => { + Event::Unknown(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -662,14 +652,14 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::UserUpdate(event) => { - let _before = update!(update_with_user_update, event); + Event::UserUpdate(mut event) => { + let _before = update!(event); let context = context(conn, data, tokio_handle); let h = event_handler.clone(); feature_cache! {{ tokio_handle.spawn_fn(move || { - h.on_user_update(context, _before, event.current_user); + h.on_user_update(context, _before.unwrap(), event.current_user); Ok(()) }); } else { @@ -679,7 +669,7 @@ fn handle_event(event: Event, }); }} }, - Event::VoiceServerUpdate(event) => { + Event::VoiceServerUpdate(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); @@ -688,8 +678,8 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::VoiceStateUpdate(event) => { - update!(update_with_voice_state_update, event); + Event::VoiceStateUpdate(mut event) => { + update!(event); let context = context(conn, data, tokio_handle); @@ -703,7 +693,7 @@ fn handle_event(event: Event, Ok(()) }); }, - Event::WebhookUpdate(event) => { + Event::WebhookUpdate(mut event) => { let context = context(conn, data, tokio_handle); let h = event_handler.clone(); diff --git a/src/lib.rs b/src/lib.rs index 066d9264e6e..75774c26785 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -167,8 +167,6 @@ pub use client::Client; #[cfg(feature = "cache")] use cache::Cache; #[cfg(feature = "cache")] -pub(crate) use cache::CacheEventsImpl; -#[cfg(feature = "cache")] use std::sync::RwLock; #[cfg(feature = "cache")] diff --git a/src/model/event.rs b/src/model/event.rs index 22cf6499842..8cdea1f6cf8 100644 --- a/src/model/event.rs +++ b/src/model/event.rs @@ -10,6 +10,14 @@ use super::utils::deserialize_emojis; use super::*; use constants::VoiceOpCode; use internal::prelude::*; +#[cfg(feature = "cache")] +use cache::{Cache, CacheUpdate}; +#[cfg(feature = "cache")] +use internal::RwLockExt; +#[cfg(feature = "cache")] +use std::mem; +#[cfg(feature = "cache")] +use std::collections::hash_map::Entry; #[cfg(feature = "gateway")] use constants::OpCode; @@ -42,11 +50,108 @@ impl<'de> Deserialize<'de> for ChannelCreateEvent { } } +#[cfg(feature = "cache")] +impl CacheUpdate for ChannelCreateEvent { + type Output = Channel; + + fn update(&mut self, cache: &mut Cache) -> Option { + match self.channel { + Channel::Group(ref group) => { + let group = group.clone(); + + let channel_id = group.with_mut(|writer| { + for (recipient_id, recipient) in &mut writer.recipients { + cache.update_user_entry(&recipient.read().unwrap()); + + *recipient = cache.users[recipient_id].clone(); + } + + writer.channel_id + }); + + let ch = cache.groups.insert(channel_id, group); + + ch.map(Channel::Group) + }, + Channel::Guild(ref channel) => { + let (guild_id, channel_id) = channel.with(|channel| (channel.guild_id, channel.id)); + + cache.channels.insert(channel_id, channel.clone()); + + cache.guilds + .get_mut(&guild_id) + .and_then(|guild| { + guild.with_mut(|guild| { + guild.channels.insert(channel_id, channel.clone()) + }) + }) + .map(Channel::Guild) + }, + Channel::Private(ref channel) => { + if let Some(channel) = cache.private_channels.get(&channel.with(|c| c.id)) { + return Some(Channel::Private((*channel).clone())); + } + + let channel = channel.clone(); + + let id = channel.with_mut(|writer| { + let user_id = writer.recipient.with_mut(|user| { + cache.update_user_entry(&user); + + user.id + }); + + writer.recipient = cache.users[&user_id].clone(); + writer.id + }); + + let ch = cache.private_channels.insert(id, channel.clone()); + ch.map(Channel::Private) + }, + Channel::Category(ref category) => { + cache.categories + .insert(category.read().unwrap().id, category.clone()) + .map(Channel::Category) + }, + } + } +} + #[derive(Clone, Debug)] pub struct ChannelDeleteEvent { pub channel: Channel, } +#[cfg(feature = "cache")] +impl CacheUpdate for ChannelDeleteEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + match self.channel { + Channel::Guild(ref channel) => { + let (guild_id, channel_id) = channel.with(|channel| (channel.guild_id, channel.id)); + + cache.channels.remove(&channel_id); + + cache.guilds.get_mut(&guild_id).and_then(|guild| { + guild.with_mut(|g| g.channels.remove(&channel_id)) + }); + }, + Channel::Category(ref category) => { + let channel_id = category.with(|cat| cat.id); + + cache.categories.remove(&channel_id); + }, + // We ignore these two due to the fact that the delete event for dms/groups + // will _not_ fire anymore. + Channel::Private(_) | + Channel::Group(_) => unreachable!(), + }; + + None + } +} + impl<'de> Deserialize<'de> for ChannelDeleteEvent { fn deserialize>(deserializer: D) -> StdResult { Ok(Self { @@ -61,23 +166,149 @@ pub struct ChannelPinsUpdateEvent { pub last_pin_timestamp: Option>, } +#[cfg(feature = "cache")] +impl CacheUpdate for ChannelPinsUpdateEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + if let Some(channel) = cache.channels.get(&self.channel_id) { + channel.with_mut(|c| { + c.last_pin_timestamp = self.last_pin_timestamp; + }); + + return None; + } + + if let Some(channel) = cache.private_channels.get_mut(&self.channel_id) { + channel.with_mut(|c| { + c.last_pin_timestamp = self.last_pin_timestamp; + }); + + return None; + } + + if let Some(group) = cache.groups.get_mut(&self.channel_id) { + group.with_mut(|c| { + c.last_pin_timestamp = self.last_pin_timestamp; + }); + + return None; + } + + None + } +} + + #[derive(Clone, Debug, Deserialize)] pub struct ChannelRecipientAddEvent { pub channel_id: ChannelId, pub user: User, } +#[cfg(feature = "cache")] +impl CacheUpdate for ChannelRecipientAddEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + cache.update_user_entry(&self.user); + let user = cache.users[&self.user.id].clone(); + + cache.groups.get_mut(&self.channel_id).map(|group| { + group.write().unwrap().recipients.insert( + self.user.id, + user, + ); + }); + + None + } +} + + #[derive(Clone, Debug, Deserialize)] pub struct ChannelRecipientRemoveEvent { pub channel_id: ChannelId, pub user: User, } +#[cfg(feature = "cache")] +impl CacheUpdate for ChannelRecipientRemoveEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + cache.groups.get_mut(&self.channel_id).map(|group| { + group.with_mut(|g| g.recipients.remove(&self.user.id)) + }); + + None + } +} + + + #[derive(Clone, Debug)] pub struct ChannelUpdateEvent { pub channel: Channel, } +#[cfg(feature = "cache")] +impl CacheUpdate for ChannelUpdateEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + match self.channel { + Channel::Group(ref group) => { + let (ch_id, no_recipients) = + group.with(|g| (g.channel_id, g.recipients.is_empty())); + + match cache.groups.entry(ch_id) { + Entry::Vacant(e) => { + e.insert(group.clone()); + }, + Entry::Occupied(mut e) => { + let mut dest = e.get_mut().write().unwrap(); + + if no_recipients { + let recipients = mem::replace(&mut dest.recipients, HashMap::new()); + + dest.clone_from(&group.read().unwrap()); + + dest.recipients = recipients; + } else { + dest.clone_from(&group.read().unwrap()); + } + }, + } + }, + Channel::Guild(ref channel) => { + let (guild_id, channel_id) = channel.with(|channel| (channel.guild_id, channel.id)); + + cache.channels.insert(channel_id, channel.clone()); + cache.guilds.get_mut(&guild_id).map(|guild| { + guild.with_mut( + |g| g.channels.insert(channel_id, channel.clone()), + ) + }); + }, + Channel::Private(ref channel) => { + cache.private_channels + .get_mut(&channel.read().unwrap().id) + .map(|private| private.clone_from(channel)); + }, + Channel::Category(ref category) => { + cache.categories.get_mut(&category.read().unwrap().id).map( + |c| { + c.clone_from(category) + }, + ); + }, + } + + None + } +} + impl<'de> Deserialize<'de> for ChannelUpdateEvent { fn deserialize>(deserializer: D) -> StdResult { Ok(Self { @@ -92,6 +323,7 @@ pub struct GuildBanAddEvent { pub user: User, } + #[derive(Clone, Debug, Deserialize)] pub struct GuildBanRemoveEvent { pub guild_id: GuildId, @@ -103,6 +335,32 @@ pub struct GuildCreateEvent { pub guild: Guild, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildCreateEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + cache.unavailable_guilds.remove(&self.guild.id); + + let mut guild = self.guild.clone(); + + for (user_id, member) in &mut guild.members { + cache.update_user_entry(&member.user.read().unwrap()); + let user = cache.users[user_id].clone(); + + member.user = user.clone(); + } + + cache.channels.extend(guild.channels.clone()); + cache.guilds.insert( + self.guild.id, + Arc::new(RwLock::new(guild)), + ); + + None + } +} + impl<'de> Deserialize<'de> for GuildCreateEvent { fn deserialize>(deserializer: D) -> StdResult { Ok(Self { @@ -116,6 +374,22 @@ pub struct GuildDeleteEvent { pub guild: PartialGuild, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildDeleteEvent { + type Output = Arc>; + + fn update(&mut self, cache: &mut Cache) -> Option { + // Remove channel entries for the guild if the guild is found. + cache.guilds.remove(&self.guild.id).map(|guild| { + for channel_id in guild.write().unwrap().channels.keys() { + cache.channels.remove(channel_id); + } + + guild + }) + } +} + impl<'de> Deserialize<'de> for GuildDeleteEvent { fn deserialize>(deserializer: D) -> StdResult { Ok(Self { @@ -131,6 +405,19 @@ pub struct GuildEmojisUpdateEvent { pub guild_id: GuildId, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildEmojisUpdateEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + cache.guilds.get_mut(&self.guild_id).map(|guild| { + guild.with_mut(|g| g.emojis.extend(self.emojis.clone())) + }); + + None + } +} + #[derive(Clone, Debug, Deserialize)] pub struct GuildIntegrationsUpdateEvent { pub guild_id: GuildId, @@ -142,6 +429,29 @@ pub struct GuildMemberAddEvent { pub member: Member, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildMemberAddEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + let user_id = self.member.user.with(|u| u.id); + cache.update_user_entry(&self.member.user.read().unwrap()); + + // Always safe due to being inserted above. + self.member.user = cache.users[&user_id].clone(); + + cache.guilds.get_mut(&self.guild_id).map(|guild| { + guild.with_mut(|guild| { + guild.member_count += 1; + guild.members.insert(user_id, self.member.clone()); + }) + }); + + None + } +} + + impl<'de> Deserialize<'de> for GuildMemberAddEvent { fn deserialize>(deserializer: D) -> StdResult { let map = JsonMap::deserialize(deserializer)?; @@ -166,6 +476,20 @@ pub struct GuildMemberRemoveEvent { pub user: User, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildMemberRemoveEvent { + type Output = Member; + + fn update(&mut self, cache: &mut Cache) -> Option { + cache.guilds.get_mut(&self.guild_id).and_then(|guild| { + guild.with_mut(|guild| { + guild.member_count -= 1; + guild.members.remove(&self.user.id) + }) + }) + } +} + #[derive(Clone, Debug, Deserialize)] pub struct GuildMemberUpdateEvent { pub guild_id: GuildId, @@ -174,12 +498,77 @@ pub struct GuildMemberUpdateEvent { pub user: User, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildMemberUpdateEvent { + type Output = Member; + + fn update(&mut self, cache: &mut Cache) -> Option { + cache.update_user_entry(&self.user); + + if let Some(guild) = cache.guilds.get_mut(&self.guild_id) { + let mut guild = guild.write().unwrap(); + + 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.write().unwrap().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: Arc::new(RwLock::new(self.user.clone())), + }, + ); + } + + item + } else { + None + } + } +} + #[derive(Clone, Debug)] pub struct GuildMembersChunkEvent { pub guild_id: GuildId, pub members: HashMap, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildMembersChunkEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + for member in self.members.values() { + cache.update_user_entry(&member.user.read().unwrap()); + } + + cache.guilds.get_mut(&self.guild_id).map(|guild| { + guild.with_mut(|g| g.members.extend(self.members.clone())) + }); + + None + } +} + impl<'de> Deserialize<'de> for GuildMembersChunkEvent { fn deserialize>(deserializer: D) -> StdResult { let mut map = JsonMap::deserialize(deserializer)?; @@ -219,29 +608,105 @@ pub struct GuildRoleCreateEvent { pub role: Role, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildRoleCreateEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + cache.guilds.get_mut(&self.guild_id).map(|guild| { + guild.write().unwrap().roles.insert( + self.role.id, + self.role.clone(), + ) + }); + + None + } +} + #[derive(Clone, Debug, Deserialize)] pub struct GuildRoleDeleteEvent { pub guild_id: GuildId, pub role_id: RoleId, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildRoleDeleteEvent { + type Output = Role; + + fn update(&mut self, cache: &mut Cache) -> Option { + cache.guilds.get_mut(&self.guild_id).and_then(|guild| { + guild.with_mut(|g| g.roles.remove(&self.role_id)) + }) + } +} + #[derive(Clone, Debug, Deserialize)] pub struct GuildRoleUpdateEvent { pub guild_id: GuildId, pub role: Role, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildRoleUpdateEvent { + type Output = Role; + + fn update(&mut self, cache: &mut Cache) -> Option { + cache.guilds.get_mut(&self.guild_id).and_then(|guild| { + guild.with_mut(|g| { + g.roles.get_mut(&self.role.id).map(|role| { + mem::replace(role, self.role.clone()) + }) + }) + }) + } +} + #[derive(Clone, Debug, Deserialize)] pub struct GuildUnavailableEvent { #[serde(rename = "id")] pub guild_id: GuildId, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildUnavailableEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + cache.unavailable_guilds.insert(self.guild_id); + cache.guilds.remove(&self.guild_id); + + None + } +} + #[derive(Clone, Debug)] pub struct GuildUpdateEvent { pub guild: PartialGuild, } +#[cfg(feature = "cache")] +impl CacheUpdate for GuildUpdateEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + cache.guilds.get_mut(&self.guild.id).map(|guild| { + let mut guild = guild.write().unwrap(); + + 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>(deserializer: D) -> StdResult { Ok(Self { @@ -302,6 +767,45 @@ pub struct PresenceUpdateEvent { pub roles: Option>, } +#[cfg(feature = "cache")] +impl CacheUpdate for PresenceUpdateEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + let user_id = self.presence.user_id; + + if let Some(user) = self.presence.user.as_mut() { + cache.update_user_entry(&user.read().unwrap()); + *user = cache.users[&user_id].clone(); + } + + if let Some(guild_id) = self.guild_id { + if let Some(guild) = cache.guilds.get_mut(&guild_id) { + let mut guild = guild.write().unwrap(); + + // If the member went offline, remove them from the presence list. + if self.presence.status == OnlineStatus::Offline { + guild.presences.remove(&self.presence.user_id); + } else { + guild.presences.insert( + self.presence.user_id, + self.presence.clone(), + ); + } + } + } else if self.presence.status == OnlineStatus::Offline { + cache.presences.remove(&self.presence.user_id); + } else { + cache.presences.insert( + self.presence.user_id, + self.presence.clone(), + ); + } + + None + } +} + impl<'de> Deserialize<'de> for PresenceUpdateEvent { fn deserialize>(deserializer: D) -> StdResult { let mut map = JsonMap::deserialize(deserializer)?; @@ -339,6 +843,25 @@ pub struct PresencesReplaceEvent { pub presences: Vec, } +#[cfg(feature = "cache")] +impl CacheUpdate for PresencesReplaceEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + cache.presences.extend({ + let mut p: HashMap = HashMap::default(); + + for presence in &self.presences { + p.insert(presence.user_id, presence.clone()); + } + + p + }); + + None + } +} + impl<'de> Deserialize<'de> for PresencesReplaceEvent { fn deserialize>(deserializer: D) -> StdResult { let presences: Vec = Deserialize::deserialize(deserializer)?; @@ -387,6 +910,46 @@ pub struct ReadyEvent { pub ready: Ready, } +#[cfg(feature = "cache")] +impl CacheUpdate for ReadyEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + let mut ready = self.ready.clone(); + + for guild in ready.guilds { + match guild { + GuildStatus::Offline(unavailable) => { + cache.guilds.remove(&unavailable.id); + cache.unavailable_guilds.insert(unavailable.id); + }, + GuildStatus::OnlineGuild(guild) => { + cache.unavailable_guilds.remove(&guild.id); + cache.guilds.insert(guild.id, Arc::new(RwLock::new(guild))); + }, + GuildStatus::OnlinePartialGuild(_) => {}, + } + } + + // `ready.private_channels` will always be empty, and possibly be removed in the future. + // So don't handle it at all. + + for (user_id, presence) in &mut ready.presences { + if let Some(ref user) = presence.user { + cache.update_user_entry(&user.read().unwrap()); + } + + presence.user = cache.users.get(user_id).cloned(); + } + + cache.presences.extend(ready.presences); + cache.shard_count = ready.shard.map_or(1, |s| s[1]); + cache.user = ready.user; + + None + } +} + impl<'de> Deserialize<'de> for ReadyEvent { fn deserialize>(deserializer: D) -> StdResult { Ok(Self { @@ -419,6 +982,15 @@ pub struct UserUpdateEvent { pub current_user: CurrentUser, } +#[cfg(feature = "cache")] +impl CacheUpdate for UserUpdateEvent { + type Output = CurrentUser; + + fn update(&mut self, cache: &mut Cache) -> Option { + Some(mem::replace(&mut cache.user, self.current_user.clone())) + } +} + impl<'de> Deserialize<'de> for UserUpdateEvent { fn deserialize>(deserializer: D) -> StdResult { Ok(Self { @@ -435,12 +1007,51 @@ pub struct VoiceServerUpdateEvent { pub token: String, } + #[derive(Clone, Debug)] pub struct VoiceStateUpdateEvent { pub guild_id: Option, pub voice_state: VoiceState, } +#[cfg(feature = "cache")] +impl CacheUpdate for VoiceStateUpdateEvent { + type Output = (); + + fn update(&mut self, cache: &mut Cache) -> Option<()> { + if let Some(guild_id) = self.guild_id { + if let Some(guild) = cache.guilds.get_mut(&guild_id) { + let mut guild = guild.write().unwrap(); + + if self.voice_state.channel_id.is_some() { + // Update or add to the voice state list + { + let finding = guild.voice_states.get_mut(&self.voice_state.user_id); + + if let Some(srv_state) = finding { + srv_state.clone_from(&self.voice_state); + + return None; + } + } + + guild.voice_states.insert( + self.voice_state.user_id, + self.voice_state.clone(), + ); + } else { + // Remove the user from the voice state list + guild.voice_states.remove(&self.voice_state.user_id); + } + } + + return None; + } + + None + } +} + impl<'de> Deserialize<'de> for VoiceStateUpdateEvent { fn deserialize>(deserializer: D) -> StdResult { let map = JsonMap::deserialize(deserializer)?;