Skip to content

Commit dc6b554

Browse files
authored
Fix top-level component deserialization for messages (#3312)
`RawValue` can't be used as the outer deserialization doesn't use it. Instead, use `JsonMap` again.
1 parent e4131a1 commit dc6b554

File tree

3 files changed

+12
-18
lines changed

3 files changed

+12
-18
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ zerofrom = "=0.1.5"
3434

3535
# Required dependencies
3636
bitflags = "2.4.2"
37-
serde_json = { version = "1.0.108", features = ["raw_value"] }
37+
serde_json = "1.0.108"
3838
async-trait = "0.1.74"
3939
tracing = { version = "0.1.40", features = ["log"] }
4040
serde = { version = "1.0.192", features = ["derive"] }

src/model/channel/message.rs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::gateway::ShardMessenger;
2222
#[cfg(feature = "model")]
2323
use crate::http::{CacheHttp, Http};
2424
use crate::model::prelude::*;
25-
use crate::model::utils::{discord_colours, StrOrInt};
25+
use crate::model::utils::{deserialize_val, discord_colours, StrOrInt};
2626
#[cfg(all(feature = "model", feature = "cache"))]
2727
use crate::utils;
2828

@@ -157,12 +157,6 @@ fn deserialize_components<'de, D>(deserializer: D) -> Result<Vec<ActionRow>, D::
157157
where
158158
D: Deserializer<'de>,
159159
{
160-
#[derive(Deserialize)]
161-
struct MinComponent {
162-
#[serde(rename = "type")]
163-
kind: u8,
164-
}
165-
166160
struct ComponentsVisitor;
167161

168162
impl<'de> Visitor<'de> for ComponentsVisitor {
@@ -178,23 +172,23 @@ where
178172
{
179173
let mut components = Vec::with_capacity(seq.size_hint().unwrap_or_default());
180174

181-
while let Some(raw) = seq.next_element::<&serde_json::value::RawValue>()? {
175+
while let Some(map) = seq.next_element::<JsonMap>()? {
182176
// We deserialize only the `kind` field to determine the component type.
183177
// We later use this to check if its a supported component before deserializing the
184178
// entire payload.
185-
let min_component =
186-
MinComponent::deserialize(raw).map_err(serde::de::Error::custom)?;
179+
let raw_kind =
180+
map.get("type").ok_or_else(|| DeError::missing_field("type"))?.clone();
181+
let kind: i64 = deserialize_val(raw_kind)?;
187182

188183
// Action rows are the only top level component supported in serenity at this time.
189-
if min_component.kind == 1 {
190-
components.push(ActionRow::deserialize(raw).map_err(serde::de::Error::custom)?);
184+
if kind == 1 {
185+
let value = Value::from(map);
186+
components
187+
.push(ActionRow::deserialize(value).map_err(serde::de::Error::custom)?);
191188
} else {
192189
// Top level component is not an action row and cannot be supported on
193190
// serenity@current without breaking changes, so we skip them.
194-
tracing::debug!(
195-
"Skipping component with unsupported kind: {}",
196-
min_component.kind
197-
);
191+
tracing::debug!("Skipping component with unsupported kind: {kind}");
198192
}
199193
}
200194

src/model/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub use self::timestamp::Timestamp;
6262
pub mod prelude {
6363
pub(crate) use std::collections::HashMap;
6464

65-
pub(crate) use serde::de::Visitor;
65+
pub(crate) use serde::de::{Error as DeError, Visitor};
6666
pub(crate) use serde::{Deserialize, Deserializer};
6767

6868
pub use super::guild::automod::EventType as AutomodEventType;

0 commit comments

Comments
 (0)