Skip to content

Commit 70789bd

Browse files
committed
Change MessageUpdateEvent to just contain a full Message (serenity-rs#3061)
1 parent 1e3f1cf commit 70789bd

File tree

7 files changed

+13
-169
lines changed

7 files changed

+13
-169
lines changed

examples/e09_collectors/src/main.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,10 @@ impl EventHandler for Handler {
102102
// 5 of them.
103103
let mut collector = serenity::collector::collect(&ctx.shard, move |event| match event {
104104
// Only collect MessageUpdate events for the 5 MessageIds we're interested in.
105-
Event::MessageUpdate(event) if collected.iter().any(|msg| event.id == msg.id) => {
106-
Some(event.id)
105+
Event::MessageUpdate(event)
106+
if collected.iter().any(|msg| event.message.id == msg.id) =>
107+
{
108+
Some(event.message.id)
107109
},
108110
_ => None,
109111
})

examples/testing/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> {
182182

183183
let msg_id = msg.id;
184184
let mut message_updates = serenity::collector::collect(&ctx.shard, move |ev| match ev {
185-
Event::MessageUpdate(x) if x.id == msg_id => Some(()),
185+
Event::MessageUpdate(x) if x.message.id == msg_id => Some(()),
186186
_ => None,
187187
});
188188
let _ = tokio::time::timeout(Duration::from_millis(2000), message_updates.next()).await;

src/cache/event.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,10 +379,10 @@ impl CacheUpdate for MessageUpdateEvent {
379379
type Output = Message;
380380

381381
fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
382-
for message in cache.messages.get_mut(&self.channel_id)?.iter_mut() {
383-
if message.id == self.id {
382+
for message in cache.messages.get_mut(&self.message.channel_id)?.iter_mut() {
383+
if message.id == self.message.id {
384384
let old_message = message.clone();
385-
self.apply_to_message(message);
385+
message.clone_from(&self.message);
386386
return Some(old_message);
387387
}
388388
}

src/gateway/client/dispatch.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,11 +302,9 @@ fn update_cache_with_event(
302302
},
303303
Event::MessageUpdate(mut event) => {
304304
let before = if_cache!(event.update(cache));
305-
let after = if_cache!(cache.message(event.channel_id, event.id).map(|m| m.clone()));
306305

307306
FullEvent::MessageUpdate {
308307
old_if_available: before,
309-
new: after,
310308
event,
311309
}
312310
},

src/gateway/client/event_handler.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -299,9 +299,8 @@ event_handler! {
299299

300300
/// Dispatched when a message is updated.
301301
///
302-
/// Provides the message update data, as well as the actual old and new message if cache
303-
/// feature is enabled and the data is available.
304-
MessageUpdate { old_if_available: Option<Message>, new: Option<Message>, event: MessageUpdateEvent } => async fn message_update(&self, ctx: Context);
302+
/// Provides the message update data, as well as the old message if cache feature is enabled and the data is available.
303+
MessageUpdate { old_if_available: Option<Message>, event: MessageUpdateEvent } => async fn message_update(&self, ctx: Context);
305304

306305
/// Dispatched when a new reaction is attached to a message.
307306
///

src/model/event.rs

Lines changed: 3 additions & 146 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,14 @@
33
//! Every event includes the gateway intent required to receive it, as well as a link to the
44
//! Discord documentation for the event.
55
6-
// Just for MessageUpdateEvent (for some reason the #[allow] doesn't work when placed directly)
7-
#![allow(clippy::option_option)]
8-
9-
use nonmax::NonMaxU64;
106
use serde::de::Error as DeError;
117
use serde::Serialize;
128
use strum::{EnumCount, IntoStaticStr, VariantNames};
139

1410
use crate::constants::Opcode;
1511
use crate::internal::utils::lending_for_each;
1612
use crate::model::prelude::*;
17-
use crate::model::utils::{optional_deserialize_components, remove_from_map};
13+
use crate::model::utils::remove_from_map;
1814

1915
/// Requires no gateway intents.
2016
///
@@ -467,154 +463,15 @@ pub struct MessageDeleteEvent {
467463
pub message_id: MessageId,
468464
}
469465

470-
// Any value that is present is considered Some value, including null.
471-
// Taken from https://github.com/serde-rs/serde/issues/984#issuecomment-314143738
472-
fn deserialize_some<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
473-
where
474-
T: Deserialize<'de>,
475-
D: Deserializer<'de>,
476-
{
477-
Deserialize::deserialize(deserializer).map(Some)
478-
}
479-
480466
/// Requires [`GatewayIntents::GUILD_MESSAGES`].
481467
///
482-
/// Contains identical fields to [`Message`], except everything but `id` and `channel_id` are
483-
/// optional. Even fields that cannot change in a message update event are included, because Discord
484-
/// may include them anyways, independent from whether they have actually changed (like
485-
/// [`Self::guild_id`])
486-
///
487468
/// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-update).
488469
#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
489470
#[derive(Clone, Debug, Deserialize, Serialize)]
490471
#[non_exhaustive]
491472
pub struct MessageUpdateEvent {
492-
pub id: MessageId,
493-
pub channel_id: ChannelId,
494-
pub author: Option<User>,
495-
pub content: Option<FixedString<u16>>,
496-
pub timestamp: Option<Timestamp>,
497-
pub edited_timestamp: Option<Timestamp>,
498-
pub tts: Option<bool>,
499-
pub mention_everyone: Option<bool>,
500-
pub mentions: Option<FixedArray<User>>,
501-
pub mention_roles: Option<FixedArray<RoleId>>,
502-
pub mention_channels: Option<FixedArray<ChannelMention>>,
503-
pub attachments: Option<FixedArray<Attachment>>,
504-
pub embeds: Option<FixedArray<Embed>>,
505-
pub reactions: Option<FixedArray<MessageReaction>>,
506-
pub pinned: Option<bool>,
507-
#[serde(default, deserialize_with = "deserialize_some")]
508-
pub webhook_id: Option<Option<WebhookId>>,
509-
#[serde(rename = "type")]
510-
pub kind: Option<MessageType>,
511-
#[serde(default, deserialize_with = "deserialize_some")]
512-
pub activity: Option<Option<MessageActivity>>,
513-
#[serde(default, deserialize_with = "deserialize_some")]
514-
pub application: Option<Option<MessageApplication>>,
515-
#[serde(default, deserialize_with = "deserialize_some")]
516-
pub application_id: Option<Option<ApplicationId>>,
517-
pub message_reference: Option<Option<MessageReference>>,
518-
#[serde(default, deserialize_with = "deserialize_some")]
519-
pub flags: Option<Option<MessageFlags>>,
520-
#[serde(default, deserialize_with = "deserialize_some")]
521-
pub referenced_message: Option<Option<Box<Message>>>,
522-
#[serde(default, deserialize_with = "deserialize_some")]
523-
#[cfg(not(feature = "unstable"))]
524-
pub interaction: Option<Option<Box<MessageInteraction>>>,
525-
pub interaction_metadata: Option<Option<Box<MessageInteractionMetadata>>>,
526-
#[serde(default, deserialize_with = "deserialize_some")]
527-
pub thread: Option<Option<Box<GuildChannel>>>,
528-
#[serde(default, deserialize_with = "optional_deserialize_components")]
529-
pub components: Option<FixedArray<ActionRow>>,
530-
pub sticker_items: Option<FixedArray<StickerItem>>,
531-
pub position: Option<Option<NonMaxU64>>,
532-
pub role_subscription_data: Option<Option<RoleSubscriptionData>>,
533-
pub guild_id: Option<GuildId>,
534-
pub member: Option<Option<Box<PartialMember>>>,
535-
}
536-
537-
impl MessageUpdateEvent {
538-
#[expect(clippy::clone_on_copy)] // For consistency between fields
539-
#[rustfmt::skip]
540-
/// Writes the updated data in this message update event into the given [`Message`].
541-
pub fn apply_to_message(&self, message: &mut Message) {
542-
// Destructure, so we get an `unused` warning when we forget to process one of the fields
543-
// in this method
544-
let Self {
545-
id,
546-
channel_id,
547-
author,
548-
content,
549-
timestamp,
550-
edited_timestamp,
551-
tts,
552-
mention_everyone,
553-
mentions,
554-
mention_roles,
555-
mention_channels,
556-
attachments,
557-
embeds,
558-
reactions,
559-
pinned,
560-
webhook_id,
561-
kind,
562-
activity,
563-
application,
564-
application_id,
565-
message_reference,
566-
flags,
567-
referenced_message,
568-
#[cfg(not(feature = "unstable"))]
569-
interaction,
570-
interaction_metadata,
571-
thread,
572-
components,
573-
sticker_items,
574-
position,
575-
role_subscription_data,
576-
guild_id,
577-
member,
578-
} = self;
579-
580-
// Discord won't send a MessageUpdateEvent with a different MessageId and ChannelId than we
581-
// already have. But let's set the fields anyways, in case the user calls this method with
582-
// a self-constructed MessageUpdateEvent that does change these fields.
583-
message.id = *id;
584-
message.channel_id = *channel_id;
585-
586-
if let Some(x) = author { message.author = x.clone() }
587-
if let Some(x) = content { message.content.clone_from(x) }
588-
if let Some(x) = timestamp { message.timestamp = x.clone() }
589-
message.edited_timestamp = *edited_timestamp;
590-
if let Some(x) = tts { message.set_tts(*x) }
591-
if let Some(x) = mention_everyone { message.set_mention_everyone(*x) }
592-
if let Some(x) = mentions { message.mentions.clone_from(x) }
593-
if let Some(x) = mention_roles { message.mention_roles.clone_from(x) }
594-
if let Some(x) = mention_channels { message.mention_channels.clone_from(x) }
595-
if let Some(x) = attachments { message.attachments.clone_from(x) }
596-
if let Some(x) = embeds { message.embeds.clone_from(x) }
597-
if let Some(x) = reactions { message.reactions.clone_from(x) }
598-
if let Some(x) = pinned { message.set_pinned(*x) }
599-
if let Some(x) = webhook_id { message.webhook_id.clone_from(x) }
600-
if let Some(x) = kind { message.kind = x.clone() }
601-
if let Some(x) = activity { message.activity.clone_from(x) }
602-
if let Some(x) = application { message.application.clone_from(x) }
603-
if let Some(x) = application_id { message.application_id.clone_from(x) }
604-
if let Some(x) = message_reference { message.message_reference.clone_from(x) }
605-
if let Some(x) = flags { message.flags.clone_from(x) }
606-
if let Some(x) = referenced_message { message.referenced_message.clone_from(x) }
607-
#[cfg(not(feature = "unstable"))]
608-
if let Some(x) = interaction { message.interaction.clone_from(x) }
609-
if let Some(x) = interaction_metadata { message.interaction_metadata.clone_from(x) }
610-
if let Some(x) = thread { message.thread.clone_from(x) }
611-
if let Some(x) = components { message.components.clone_from(x) }
612-
if let Some(x) = sticker_items { message.sticker_items.clone_from(x) }
613-
if let Some(x) = position { message.position.clone_from(x) }
614-
if let Some(x) = role_subscription_data { message.role_subscription_data.clone_from(x) }
615-
message.guild_id = *guild_id;
616-
if let Some(x) = member { message.member.clone_from(x) }
617-
}
473+
#[serde(flatten)]
474+
pub message: Message,
618475
}
619476

620477
/// Requires [`GatewayIntents::GUILD_PRESENCES`].

src/model/utils.rs

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -255,18 +255,6 @@ where
255255
.collect()
256256
}
257257

258-
// A function used for deserializing components within a MessageUpdateEvent.
259-
// Due to discord now sending the whole message payload, we don't need to distinguish between None
260-
// and empty, as such we always return Some.
261-
pub fn optional_deserialize_components<'de, D>(
262-
deserializer: D,
263-
) -> Result<Option<FixedArray<ActionRow>>, D::Error>
264-
where
265-
D: Deserializer<'de>,
266-
{
267-
deserialize_components(deserializer).map(Some)
268-
}
269-
270258
// Custom deserialize function to deserialize components safely without knocking the whole message
271259
// out when new components are found but not supported.
272260
pub fn deserialize_components<'de, D>(deserializer: D) -> Result<FixedArray<ActionRow>, D::Error>

0 commit comments

Comments
 (0)