From 165c1ed237b190164ca8bb4ee8db20c0367c3bd9 Mon Sep 17 00:00:00 2001 From: GnomedDev Date: Mon, 25 Nov 2024 09:27:42 +0000 Subject: [PATCH] Change MessageUpdateEvent to just contain a full Message --- examples/e09_collectors/src/main.rs | 6 +- examples/testing/src/main.rs | 2 +- src/cache/event.rs | 6 +- src/gateway/client/dispatch.rs | 2 - src/gateway/client/event_handler.rs | 5 +- src/model/event.rs | 146 +--------------------------- 6 files changed, 12 insertions(+), 155 deletions(-) diff --git a/examples/e09_collectors/src/main.rs b/examples/e09_collectors/src/main.rs index e2c45dec104..16da459dc65 100644 --- a/examples/e09_collectors/src/main.rs +++ b/examples/e09_collectors/src/main.rs @@ -102,8 +102,10 @@ impl EventHandler for Handler { // 5 of them. let mut collector = serenity::collector::collect(&ctx.shard, move |event| match event { // Only collect MessageUpdate events for the 5 MessageIds we're interested in. - Event::MessageUpdate(event) if collected.iter().any(|msg| event.id == msg.id) => { - Some(event.id) + Event::MessageUpdate(event) + if collected.iter().any(|msg| event.message.id == msg.id) => + { + Some(event.message.id) }, _ => None, }) diff --git a/examples/testing/src/main.rs b/examples/testing/src/main.rs index eb0011c8c8b..ce8204876c6 100644 --- a/examples/testing/src/main.rs +++ b/examples/testing/src/main.rs @@ -182,7 +182,7 @@ async fn message(ctx: &Context, msg: Message) -> Result<(), serenity::Error> { let msg_id = msg.id; let mut message_updates = serenity::collector::collect(&ctx.shard, move |ev| match ev { - Event::MessageUpdate(x) if x.id == msg_id => Some(()), + Event::MessageUpdate(x) if x.message.id == msg_id => Some(()), _ => None, }); let _ = tokio::time::timeout(Duration::from_millis(2000), message_updates.next()).await; diff --git a/src/cache/event.rs b/src/cache/event.rs index 64cdeb3f016..3a1e61b6aa3 100644 --- a/src/cache/event.rs +++ b/src/cache/event.rs @@ -379,10 +379,10 @@ impl CacheUpdate for MessageUpdateEvent { type Output = Message; fn update(&mut self, cache: &Cache) -> Option { - for message in cache.messages.get_mut(&self.channel_id)?.iter_mut() { - if message.id == self.id { + for message in cache.messages.get_mut(&self.message.channel_id)?.iter_mut() { + if message.id == self.message.id { let old_message = message.clone(); - self.apply_to_message(message); + message.clone_from(&self.message); return Some(old_message); } } diff --git a/src/gateway/client/dispatch.rs b/src/gateway/client/dispatch.rs index ecb5408884a..cab767f7a7c 100644 --- a/src/gateway/client/dispatch.rs +++ b/src/gateway/client/dispatch.rs @@ -302,11 +302,9 @@ fn update_cache_with_event( }, Event::MessageUpdate(mut event) => { let before = if_cache!(event.update(cache)); - let after = if_cache!(cache.message(event.channel_id, event.id).map(|m| m.clone())); FullEvent::MessageUpdate { old_if_available: before, - new: after, event, } }, diff --git a/src/gateway/client/event_handler.rs b/src/gateway/client/event_handler.rs index 3a05e4ff6b3..35e74e5cd18 100644 --- a/src/gateway/client/event_handler.rs +++ b/src/gateway/client/event_handler.rs @@ -299,9 +299,8 @@ event_handler! { /// Dispatched when a message is updated. /// - /// Provides the message update data, as well as the actual old and new message if cache - /// feature is enabled and the data is available. - MessageUpdate { old_if_available: Option, new: Option, event: MessageUpdateEvent } => async fn message_update(&self, ctx: Context); + /// Provides the message update data, as well as the old message if cache feature is enabled and the data is available. + MessageUpdate { old_if_available: Option, event: MessageUpdateEvent } => async fn message_update(&self, ctx: Context); /// Dispatched when a new reaction is attached to a message. /// diff --git a/src/model/event.rs b/src/model/event.rs index 29b25d072dd..5fad1f9c599 100644 --- a/src/model/event.rs +++ b/src/model/event.rs @@ -3,10 +3,6 @@ //! Every event includes the gateway intent required to receive it, as well as a link to the //! Discord documentation for the event. -// Just for MessageUpdateEvent (for some reason the #[allow] doesn't work when placed directly) -#![allow(clippy::option_option)] - -use nonmax::NonMaxU64; use serde::de::Error as DeError; use serde::Serialize; use strum::{EnumCount, IntoStaticStr, VariantNames}; @@ -467,153 +463,15 @@ pub struct MessageDeleteEvent { pub message_id: MessageId, } -// Any value that is present is considered Some value, including null. -// Taken from https://github.com/serde-rs/serde/issues/984#issuecomment-314143738 -fn deserialize_some<'de, T, D>(deserializer: D) -> Result, D::Error> -where - T: Deserialize<'de>, - D: Deserializer<'de>, -{ - Deserialize::deserialize(deserializer).map(Some) -} - /// Requires [`GatewayIntents::GUILD_MESSAGES`]. /// -/// Contains identical fields to [`Message`], except everything but `id` and `channel_id` are -/// optional. Even fields that cannot change in a message update event are included, because Discord -/// may include them anyways, independent from whether they have actually changed (like -/// [`Self::guild_id`]) -/// /// [Discord docs](https://discord.com/developers/docs/topics/gateway-events#message-update). #[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))] #[derive(Clone, Debug, Deserialize, Serialize)] #[non_exhaustive] pub struct MessageUpdateEvent { - pub id: MessageId, - pub channel_id: ChannelId, - pub author: Option, - pub content: Option>, - pub timestamp: Option, - pub edited_timestamp: Option, - pub tts: Option, - pub mention_everyone: Option, - pub mentions: Option>, - pub mention_roles: Option>, - pub mention_channels: Option>, - pub attachments: Option>, - pub embeds: Option>, - pub reactions: Option>, - pub pinned: Option, - #[serde(default, deserialize_with = "deserialize_some")] - pub webhook_id: Option>, - #[serde(rename = "type")] - pub kind: Option, - #[serde(default, deserialize_with = "deserialize_some")] - pub activity: Option>, - #[serde(default, deserialize_with = "deserialize_some")] - pub application: Option>, - #[serde(default, deserialize_with = "deserialize_some")] - pub application_id: Option>, - pub message_reference: Option>, - #[serde(default, deserialize_with = "deserialize_some")] - pub flags: Option>, - #[serde(default, deserialize_with = "deserialize_some")] - pub referenced_message: Option>>, - #[serde(default, deserialize_with = "deserialize_some")] - #[cfg(not(feature = "unstable"))] - pub interaction: Option>>, - pub interaction_metadata: Option>>, - #[serde(default, deserialize_with = "deserialize_some")] - pub thread: Option>>, - pub components: Option>, - pub sticker_items: Option>, - pub position: Option>, - pub role_subscription_data: Option>, - pub guild_id: Option, - pub member: Option>>, -} - -impl MessageUpdateEvent { - #[expect(clippy::clone_on_copy)] // For consistency between fields - #[rustfmt::skip] - /// Writes the updated data in this message update event into the given [`Message`]. - pub fn apply_to_message(&self, message: &mut Message) { - // Destructure, so we get an `unused` warning when we forget to process one of the fields - // in this method - let Self { - id, - channel_id, - author, - content, - timestamp, - edited_timestamp, - tts, - mention_everyone, - mentions, - mention_roles, - mention_channels, - attachments, - embeds, - reactions, - pinned, - webhook_id, - kind, - activity, - application, - application_id, - message_reference, - flags, - referenced_message, - #[cfg(not(feature = "unstable"))] - interaction, - interaction_metadata, - thread, - components, - sticker_items, - position, - role_subscription_data, - guild_id, - member, - } = self; - - // Discord won't send a MessageUpdateEvent with a different MessageId and ChannelId than we - // already have. But let's set the fields anyways, in case the user calls this method with - // a self-constructed MessageUpdateEvent that does change these fields. - message.id = *id; - message.channel_id = *channel_id; - - if let Some(x) = author { message.author = x.clone() } - if let Some(x) = content { message.content.clone_from(x) } - if let Some(x) = timestamp { message.timestamp = x.clone() } - message.edited_timestamp = *edited_timestamp; - if let Some(x) = tts { message.set_tts(*x) } - if let Some(x) = mention_everyone { message.set_mention_everyone(*x) } - if let Some(x) = mentions { message.mentions.clone_from(x) } - if let Some(x) = mention_roles { message.mention_roles.clone_from(x) } - if let Some(x) = mention_channels { message.mention_channels.clone_from(x) } - if let Some(x) = attachments { message.attachments.clone_from(x) } - if let Some(x) = embeds { message.embeds.clone_from(x) } - if let Some(x) = reactions { message.reactions.clone_from(x) } - if let Some(x) = pinned { message.set_pinned(*x) } - if let Some(x) = webhook_id { message.webhook_id.clone_from(x) } - if let Some(x) = kind { message.kind = x.clone() } - if let Some(x) = activity { message.activity.clone_from(x) } - if let Some(x) = application { message.application.clone_from(x) } - if let Some(x) = application_id { message.application_id.clone_from(x) } - if let Some(x) = message_reference { message.message_reference.clone_from(x) } - if let Some(x) = flags { message.flags.clone_from(x) } - if let Some(x) = referenced_message { message.referenced_message.clone_from(x) } - #[cfg(not(feature = "unstable"))] - if let Some(x) = interaction { message.interaction.clone_from(x) } - if let Some(x) = interaction_metadata { message.interaction_metadata.clone_from(x) } - if let Some(x) = thread { message.thread.clone_from(x) } - if let Some(x) = components { message.components.clone_from(x) } - if let Some(x) = sticker_items { message.sticker_items.clone_from(x) } - if let Some(x) = position { message.position.clone_from(x) } - if let Some(x) = role_subscription_data { message.role_subscription_data.clone_from(x) } - message.guild_id = *guild_id; - if let Some(x) = member { message.member.clone_from(x) } - } + #[serde(flatten)] + pub message: Message, } /// Requires [`GatewayIntents::GUILD_PRESENCES`].