Skip to content

Commit fe65115

Browse files
boothedevErk-itohatweb
authored andcommitted
refactor(model, cache): a full message object for MessageUpdate event (twilight-rs#2387)
`MessageUpdate` event now contains a full `Message` object. Refs: - discord/discord-api-docs#7017 --------- Co-authored-by: Erk <[email protected]> Co-authored-by: ITOH <[email protected]>
1 parent 4cc6600 commit fe65115

File tree

6 files changed

+54
-116
lines changed

6 files changed

+54
-116
lines changed

examples/cache-optimization/models/message.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use twilight_cache_inmemory::CacheableMessage;
22
use twilight_model::{
33
channel::{message::Reaction, Message},
4-
gateway::payload::incoming::MessageUpdate,
54
id::{marker::MessageMarker, Id},
65
};
76

@@ -50,10 +49,4 @@ impl CacheableMessage for MinimalCachedMessage {
5049
fn retain_reactions(&mut self, _f: impl FnMut(&Reaction) -> bool) {
5150
// No-op
5251
}
53-
54-
fn update_with_message_update(&mut self, message_update: &MessageUpdate) {
55-
if let Some(content) = &message_update.content {
56-
self.content.clone_from(content);
57-
}
58-
}
5952
}

twilight-cache-inmemory/src/event/message.rs

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{config::ResourceType, CacheableMessage, CacheableModels, InMemoryCache, UpdateCache};
1+
use crate::{config::ResourceType, CacheableModels, InMemoryCache, UpdateCache};
22
use std::borrow::Cow;
33
use twilight_model::gateway::payload::incoming::{
44
MessageCreate, MessageDelete, MessageDeleteBulk, MessageUpdate,
@@ -80,13 +80,45 @@ impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for MessageDeleteBul
8080

8181
impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for MessageUpdate {
8282
fn update(&self, cache: &InMemoryCache<CacheModels>) {
83+
if cache.wants(ResourceType::USER) {
84+
cache.cache_user(Cow::Borrowed(&self.author), self.guild_id);
85+
}
86+
87+
if let (Some(member), Some(guild_id), true) = (
88+
&self.member,
89+
self.guild_id,
90+
cache.wants(ResourceType::MEMBER),
91+
) {
92+
cache.cache_borrowed_partial_member(guild_id, member, self.author.id);
93+
}
94+
8395
if !cache.wants(ResourceType::MESSAGE) {
8496
return;
8597
}
8698

87-
if let Some(mut message) = cache.messages.get_mut(&self.id) {
88-
message.update_with_message_update(self);
99+
// In special cases, this message was popped out due to the limitation
100+
// of the message cache capacity, or its Event::MessageCreate was missed.
101+
// If that is the case, we do not only add it to the message cache but
102+
// also add its ID to the channel messages cache.
103+
if cache
104+
.messages
105+
.insert(self.id, CacheModels::Message::from(self.0.clone()))
106+
.is_some()
107+
{
108+
return;
109+
}
110+
111+
let mut channel_messages = cache.channel_messages.entry(self.0.channel_id).or_default();
112+
113+
// If this channel cache is full, we pop an message ID out of
114+
// the channel cache and also remove it from the message cache.
115+
if channel_messages.len() >= cache.config.message_cache_size() {
116+
if let Some(popped_id) = channel_messages.pop_back() {
117+
cache.messages.remove(&popped_id);
118+
}
89119
}
120+
121+
channel_messages.push_front(self.0.id);
90122
}
91123
}
92124

twilight-cache-inmemory/src/model/message.rs

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use twilight_model::{
1111
},
1212
Attachment, ChannelMention,
1313
},
14-
gateway::payload::incoming::MessageUpdate,
1514
guild::PartialMember,
1615
id::{
1716
marker::{
@@ -427,48 +426,6 @@ impl PartialEq<Message> for CachedMessage {
427426
}
428427

429428
impl CacheableMessage for CachedMessage {
430-
fn update_with_message_update(&mut self, message_update: &MessageUpdate) {
431-
if let Some(attachments) = &message_update.attachments {
432-
self.attachments.clone_from(attachments);
433-
}
434-
435-
if let Some(content) = &message_update.content {
436-
self.content.clone_from(content);
437-
}
438-
439-
if let Some(edited_timestamp) = message_update.edited_timestamp {
440-
self.edited_timestamp.replace(edited_timestamp);
441-
}
442-
443-
if let Some(embeds) = &message_update.embeds {
444-
self.embeds.clone_from(embeds);
445-
}
446-
447-
if let Some(mention_everyone) = message_update.mention_everyone {
448-
self.mention_everyone = mention_everyone;
449-
}
450-
451-
if let Some(mention_roles) = &message_update.mention_roles {
452-
self.mention_roles.clone_from(mention_roles);
453-
}
454-
455-
if let Some(mentions) = &message_update.mentions {
456-
self.mentions = mentions.iter().map(|x| x.id).collect::<Vec<_>>();
457-
}
458-
459-
if let Some(pinned) = message_update.pinned {
460-
self.pinned = pinned;
461-
}
462-
463-
if let Some(timestamp) = message_update.timestamp {
464-
self.timestamp = timestamp;
465-
}
466-
467-
if let Some(tts) = message_update.tts {
468-
self.tts = tts;
469-
}
470-
}
471-
472429
fn reactions(&self) -> &[Reaction] {
473430
&self.reactions
474431
}

twilight-cache-inmemory/src/traits.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use twilight_model::{
3131
Channel, ChannelType, Message, StageInstance,
3232
},
3333
gateway::{
34-
payload::incoming::{GuildUpdate, MemberUpdate, MessageUpdate},
34+
payload::incoming::{GuildUpdate, MemberUpdate},
3535
presence::Presence,
3636
},
3737
guild::{
@@ -235,9 +235,6 @@ pub trait CacheableVoiceState:
235235
pub trait CacheableMessage:
236236
From<Message> + PartialEq<Message> + PartialEq<Self> + Clone + Debug
237237
{
238-
/// Update the cached data with a [`MessageUpdate`] event.
239-
fn update_with_message_update(&mut self, message_update: &MessageUpdate);
240-
241238
/// Reactions added to this message.
242239
fn reactions(&self) -> &[Reaction];
243240

twilight-model/src/gateway/event/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ impl Event {
221221
Event::MessageCreate(e) => e.0.guild_id,
222222
Event::MessageDelete(e) => e.guild_id,
223223
Event::MessageDeleteBulk(e) => e.guild_id,
224-
Event::MessageUpdate(e) => e.guild_id,
224+
Event::MessageUpdate(e) => e.0.guild_id,
225225
Event::MessagePollVoteAdd(e) => e.guild_id,
226226
Event::MessagePollVoteRemove(e) => e.guild_id,
227227
Event::PresenceUpdate(e) => Some(e.0.guild_id),
Lines changed: 17 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,21 @@
1-
use crate::{
2-
channel::{
3-
message::{Embed, Mention, MessageType},
4-
Attachment,
5-
},
6-
id::{
7-
marker::{ChannelMarker, GuildMarker, MessageMarker, RoleMarker},
8-
Id,
9-
},
10-
user::User,
11-
util::Timestamp,
12-
};
1+
use crate::channel::Message;
132
use serde::{Deserialize, Serialize};
3+
use std::ops::{Deref, DerefMut};
144

155
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
16-
pub struct MessageUpdate {
17-
/// List of attachments.
18-
///
19-
/// Refer to the documentation for [`Message::attachments`] for caveats with
20-
/// receiving the attachments of messages.
21-
///
22-
/// [`Message::attachments`]: crate::channel::Message::attachments
23-
#[serde(skip_serializing_if = "Option::is_none")]
24-
pub attachments: Option<Vec<Attachment>>,
25-
#[serde(skip_serializing_if = "Option::is_none")]
26-
pub author: Option<User>,
27-
pub channel_id: Id<ChannelMarker>,
28-
/// Content of the message.
29-
///
30-
/// Refer to the documentation for [`Message::content`] for caveats with
31-
/// receiving the content of messages.
32-
///
33-
/// [`Message::content`]: crate::channel::Message::content
34-
pub content: Option<String>,
35-
#[serde(skip_serializing_if = "Option::is_none")]
36-
pub edited_timestamp: Option<Timestamp>,
37-
/// List of embeds.
38-
///
39-
/// Refer to the documentation for [`Message::embeds`] for caveats with
40-
/// receiving the embeds of messages.
41-
///
42-
/// [`Message::embeds`]: crate::channel::Message::embeds
43-
#[serde(skip_serializing_if = "Option::is_none")]
44-
pub embeds: Option<Vec<Embed>>,
45-
#[serde(skip_serializing_if = "Option::is_none")]
46-
pub guild_id: Option<Id<GuildMarker>>,
47-
pub id: Id<MessageMarker>,
48-
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
49-
pub kind: Option<MessageType>,
50-
#[serde(skip_serializing_if = "Option::is_none")]
51-
pub mention_everyone: Option<bool>,
52-
#[serde(skip_serializing_if = "Option::is_none")]
53-
pub mention_roles: Option<Vec<Id<RoleMarker>>>,
54-
#[serde(skip_serializing_if = "Option::is_none")]
55-
pub mentions: Option<Vec<Mention>>,
56-
#[serde(skip_serializing_if = "Option::is_none")]
57-
pub pinned: Option<bool>,
58-
#[serde(skip_serializing_if = "Option::is_none")]
59-
pub timestamp: Option<Timestamp>,
60-
#[serde(skip_serializing_if = "Option::is_none")]
61-
pub tts: Option<bool>,
6+
#[serde(transparent)]
7+
pub struct MessageUpdate(pub Message);
8+
9+
impl Deref for MessageUpdate {
10+
type Target = Message;
11+
12+
fn deref(&self) -> &Self::Target {
13+
&self.0
14+
}
15+
}
16+
17+
impl DerefMut for MessageUpdate {
18+
fn deref_mut(&mut self) -> &mut Self::Target {
19+
&mut self.0
20+
}
6221
}

0 commit comments

Comments
 (0)