From e80999f9a8b65bd21b3e70702ec14be3201fc53a Mon Sep 17 00:00:00 2001 From: Michael Krasnitski <42564254+mkrasnitski@users.noreply.github.com> Date: Sun, 24 Dec 2023 12:03:11 -0500 Subject: [PATCH] Fix deserialization of `GuildMembersChunkEvent` (#2672) Specifically, the `members` field was being incorrectly deserialized. In #2287, the logic for collecting the received array of members into a hashmap was removed, meaning the deserializer now looked for a map instead of a sequence, causing deserialization to fail. This PR adds that logic back. Closes #2666 --- src/model/event.rs | 10 +++++++++- src/model/guild/mod.rs | 3 +-- src/model/utils.rs | 21 +++++++++++++++++---- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/model/event.rs b/src/model/event.rs index b003cb3b1a5..327721409e0 100644 --- a/src/model/event.rs +++ b/src/model/event.rs @@ -13,7 +13,14 @@ use serde::Serialize; use super::application::ActionRow; use super::prelude::*; -use super::utils::{deserialize_val, emojis, remove_from_map, remove_from_map_opt, stickers}; +use super::utils::{ + deserialize_val, + emojis, + members, + remove_from_map, + remove_from_map_opt, + stickers, +}; use crate::constants::Opcode; use crate::model::application::{CommandPermissions, Interaction}; use crate::model::guild::audit_log::AuditLogEntry; @@ -272,6 +279,7 @@ pub struct GuildMembersChunkEvent { /// ID of the guild. pub guild_id: GuildId, /// Set of guild members. + #[serde(with = "members")] pub members: HashMap, /// Chunk index in the expected chunks for this response (0 <= chunk_index < chunk_count). pub chunk_index: u32, diff --git a/src/model/guild/mod.rs b/src/model/guild/mod.rs index e4f4d895782..822ef7907cb 100644 --- a/src/model/guild/mod.rs +++ b/src/model/guild/mod.rs @@ -255,8 +255,7 @@ pub struct Guild { /// /// Members might not all be available when the [`ReadyEvent`] is received if the /// [`Self::member_count`] is greater than the [`LARGE_THRESHOLD`] set by the library. - #[serde(serialize_with = "serialize_map_values")] - #[serde(deserialize_with = "deserialize_members")] + #[serde(with = "members")] pub members: HashMap, /// All voice and text channels contained within a guild. /// diff --git a/src/model/utils.rs b/src/model/utils.rs index 02b9f06e925..98572deaaa2 100644 --- a/src/model/utils.rs +++ b/src/model/utils.rs @@ -111,10 +111,23 @@ pub fn deserialize_guild_channels<'de, D: Deserializer<'de>>( Ok(map) } -pub fn deserialize_members<'de, D: Deserializer<'de>>( - deserializer: D, -) -> StdResult, D::Error> { - deserializer.deserialize_seq(SequenceToMapVisitor::new(|member: &Member| member.user.id)) +/// Used with `#[serde(with = "members")] +pub mod members { + use std::collections::HashMap; + + use serde::Deserializer; + + use super::SequenceToMapVisitor; + use crate::model::guild::Member; + use crate::model::id::UserId; + + pub fn deserialize<'de, D: Deserializer<'de>>( + deserializer: D, + ) -> Result, D::Error> { + deserializer.deserialize_seq(SequenceToMapVisitor::new(|member: &Member| member.user.id)) + } + + pub use super::serialize_map_values as serialize; } /// Used with `#[serde(with = "presences")]`