1use super::{Cache, CacheUpdate};
2use crate::model::channel::{GuildChannel, Message};
3use crate::model::event::{
4 ChannelCreateEvent,
5 ChannelDeleteEvent,
6 ChannelPinsUpdateEvent,
7 ChannelUpdateEvent,
8 GuildCreateEvent,
9 GuildDeleteEvent,
10 GuildEmojisUpdateEvent,
11 GuildMemberAddEvent,
12 GuildMemberRemoveEvent,
13 GuildMemberUpdateEvent,
14 GuildMembersChunkEvent,
15 GuildRoleCreateEvent,
16 GuildRoleDeleteEvent,
17 GuildRoleUpdateEvent,
18 GuildStickersUpdateEvent,
19 GuildUpdateEvent,
20 MessageCreateEvent,
21 MessageUpdateEvent,
22 PresenceUpdateEvent,
23 ReadyEvent,
24 ThreadCreateEvent,
25 ThreadDeleteEvent,
26 ThreadUpdateEvent,
27 UserUpdateEvent,
28 VoiceChannelStatusUpdateEvent,
29 VoiceStateUpdateEvent,
30};
31use crate::model::gateway::ShardInfo;
32use crate::model::guild::{Guild, GuildMemberFlags, Member, Role};
33use crate::model::id::ShardId;
34use crate::model::user::{CurrentUser, OnlineStatus};
35use crate::model::voice::VoiceState;
36
37impl CacheUpdate for ChannelCreateEvent {
38 type Output = GuildChannel;
39
40 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
41 let old_channel = cache
42 .guilds
43 .get_mut(&self.channel.guild_id)
44 .and_then(|mut g| g.channels.insert(self.channel.id, self.channel.clone()));
45
46 cache.channels.insert(self.channel.id, self.channel.guild_id);
47 old_channel
48 }
49}
50
51impl CacheUpdate for ChannelDeleteEvent {
52 type Output = Vec<Message>;
53
54 fn update(&mut self, cache: &Cache) -> Option<Vec<Message>> {
55 let (channel_id, guild_id) = (self.channel.id, self.channel.guild_id);
56
57 cache.channels.remove(&channel_id);
58 cache.guilds.get_mut(&guild_id).map(|mut g| g.channels.remove(&channel_id));
59
60 cache.messages.remove(&channel_id).map(|(_, messages)| messages.into_values().collect())
62 }
63}
64
65impl CacheUpdate for ChannelUpdateEvent {
66 type Output = GuildChannel;
67
68 fn update(&mut self, cache: &Cache) -> Option<GuildChannel> {
69 cache.channels.insert(self.channel.id, self.channel.guild_id);
70
71 cache
72 .guilds
73 .get_mut(&self.channel.guild_id)
74 .and_then(|mut g| g.channels.insert(self.channel.id, self.channel.clone()))
75 }
76}
77
78impl CacheUpdate for ChannelPinsUpdateEvent {
79 type Output = ();
80
81 fn update(&mut self, cache: &Cache) -> Option<()> {
82 if let Some(guild_id) = self.guild_id {
83 if let Some(mut guild) = cache.guilds.get_mut(&guild_id) {
84 if let Some(channel) = guild.channels.get_mut(&self.channel_id) {
85 channel.last_pin_timestamp = self.last_pin_timestamp;
86 }
87 }
88 }
89
90 None
91 }
92}
93
94impl CacheUpdate for GuildCreateEvent {
95 type Output = ();
96
97 fn update(&mut self, cache: &Cache) -> Option<()> {
98 cache.unavailable_guilds.remove(&self.guild.id);
99 let mut guild = self.guild.clone();
100
101 for (user_id, member) in &mut guild.members {
102 cache.update_user_entry(&member.user);
103 if let Some(u) = cache.user(user_id) {
104 member.user = u.clone();
105 }
106 }
107
108 cache.guilds.insert(self.guild.id, guild);
109 for channel_id in self.guild.channels.keys() {
110 cache.channels.insert(*channel_id, self.guild.id);
111 }
112
113 None
114 }
115}
116
117impl CacheUpdate for GuildDeleteEvent {
118 type Output = Guild;
119
120 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
121 if self.guild.unavailable {
122 cache.unavailable_guilds.insert(self.guild.id, ());
123 cache.guilds.remove(&self.guild.id);
124
125 return None;
126 }
127
128 match cache.guilds.remove(&self.guild.id) {
129 Some(guild) => {
130 for channel_id in guild.1.channels.keys() {
131 cache.channels.remove(channel_id);
133
134 cache.messages.remove(channel_id);
136 }
137
138 Some(guild.1)
139 },
140 None => None,
141 }
142 }
143}
144
145impl CacheUpdate for GuildEmojisUpdateEvent {
146 type Output = ();
147
148 fn update(&mut self, cache: &Cache) -> Option<()> {
149 if let Some(mut guild) = cache.guilds.get_mut(&self.guild_id) {
150 guild.emojis.clone_from(&self.emojis);
151 }
152
153 None
154 }
155}
156
157impl CacheUpdate for GuildMemberAddEvent {
158 type Output = ();
159
160 fn update(&mut self, cache: &Cache) -> Option<()> {
161 let user_id = self.member.user.id;
162 cache.update_user_entry(&self.member.user);
163 if let Some(u) = cache.user(user_id) {
164 self.member.user = u.clone();
165 }
166
167 if let Some(mut guild) = cache.guilds.get_mut(&self.member.guild_id) {
168 guild.member_count += 1;
169 guild.members.insert(user_id, self.member.clone());
170 }
171
172 None
173 }
174}
175
176impl CacheUpdate for GuildMemberRemoveEvent {
177 type Output = Member;
178
179 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
180 if let Some(mut guild) = cache.guilds.get_mut(&self.guild_id) {
181 guild.member_count -= 1;
182 return guild.members.remove(&self.user.id);
183 }
184
185 None
186 }
187}
188
189impl CacheUpdate for GuildMemberUpdateEvent {
190 type Output = Member;
191
192 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
193 cache.update_user_entry(&self.user);
194
195 if let Some(mut guild) = cache.guilds.get_mut(&self.guild_id) {
196 let item = if let Some(member) = guild.members.get_mut(&self.user.id) {
197 let item = Some(member.clone());
198
199 member.joined_at.clone_from(&Some(self.joined_at));
200 member.nick.clone_from(&self.nick);
201 member.roles.clone_from(&self.roles);
202 member.user.clone_from(&self.user);
203 member.pending.clone_from(&self.pending);
204 member.premium_since.clone_from(&self.premium_since);
205 member.deaf.clone_from(&self.deaf);
206 member.mute.clone_from(&self.mute);
207 member.avatar.clone_from(&self.avatar);
208 member.banner.clone_from(&self.banner);
209 member.communication_disabled_until.clone_from(&self.communication_disabled_until);
210 member.unusual_dm_activity_until.clone_from(&self.unusual_dm_activity_until);
211
212 item
213 } else {
214 None
215 };
216
217 if item.is_none() {
218 guild.members.insert(self.user.id, Member {
219 deaf: false,
220 guild_id: self.guild_id,
221 joined_at: Some(self.joined_at),
222 mute: false,
223 nick: self.nick.clone(),
224 roles: self.roles.clone(),
225 user: self.user.clone(),
226 pending: self.pending,
227 premium_since: self.premium_since,
228 permissions: None,
229 avatar: self.avatar,
230 banner: self.banner,
231 communication_disabled_until: self.communication_disabled_until,
232 flags: self.flags.unwrap_or_default(),
233 unusual_dm_activity_until: self.unusual_dm_activity_until,
234 avatar_decoration_data: self.avatar_decoration_data,
235 });
236 }
237
238 item
239 } else {
240 None
241 }
242 }
243}
244
245impl CacheUpdate for GuildMembersChunkEvent {
246 type Output = ();
247
248 fn update(&mut self, cache: &Cache) -> Option<()> {
249 for member in self.members.values() {
250 cache.update_user_entry(&member.user);
251 }
252
253 if let Some(mut g) = cache.guilds.get_mut(&self.guild_id) {
254 g.members.extend(self.members.clone());
255 }
256
257 None
258 }
259}
260
261impl CacheUpdate for GuildRoleCreateEvent {
262 type Output = ();
263
264 fn update(&mut self, cache: &Cache) -> Option<()> {
265 cache
266 .guilds
267 .get_mut(&self.role.guild_id)
268 .map(|mut g| g.roles.insert(self.role.id, self.role.clone()));
269
270 None
271 }
272}
273
274impl CacheUpdate for GuildRoleDeleteEvent {
275 type Output = Role;
276
277 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
278 cache.guilds.get_mut(&self.guild_id).and_then(|mut g| g.roles.remove(&self.role_id))
279 }
280}
281
282impl CacheUpdate for GuildRoleUpdateEvent {
283 type Output = Role;
284
285 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
286 if let Some(mut guild) = cache.guilds.get_mut(&self.role.guild_id) {
287 if let Some(role) = guild.roles.get_mut(&self.role.id) {
288 return Some(std::mem::replace(role, self.role.clone()));
289 }
290 }
291
292 None
293 }
294}
295
296impl CacheUpdate for GuildStickersUpdateEvent {
297 type Output = ();
298
299 fn update(&mut self, cache: &Cache) -> Option<()> {
300 if let Some(mut guild) = cache.guilds.get_mut(&self.guild_id) {
301 guild.stickers.clone_from(&self.stickers);
302 }
303
304 None
305 }
306}
307
308impl CacheUpdate for GuildUpdateEvent {
309 type Output = ();
310
311 fn update(&mut self, cache: &Cache) -> Option<()> {
312 if let Some(mut guild) = cache.guilds.get_mut(&self.guild.id) {
313 guild.afk_metadata.clone_from(&self.guild.afk_metadata);
314 guild.banner.clone_from(&self.guild.banner);
315 guild.description.clone_from(&self.guild.description);
316 guild.discovery_splash.clone_from(&self.guild.discovery_splash);
317 guild.emojis.clone_from(&self.guild.emojis);
318 guild.features.clone_from(&self.guild.features);
319 guild.icon.clone_from(&self.guild.icon);
320 guild.icon_hash.clone_from(&self.guild.icon_hash);
321 guild.name.clone_from(&self.guild.name);
322 guild.owner_id.clone_from(&self.guild.owner_id);
323 guild.preferred_locale.clone_from(&self.guild.preferred_locale);
324 guild.roles.clone_from(&self.guild.roles);
325 guild.splash.clone_from(&self.guild.splash);
326 guild.stickers.clone_from(&self.guild.stickers);
327 guild.vanity_url_code.clone_from(&self.guild.vanity_url_code);
328 guild.welcome_screen.clone_from(&self.guild.welcome_screen);
329 guild.application_id = self.guild.application_id;
330 guild.approximate_member_count = self.guild.approximate_member_count;
331 guild.approximate_presence_count = self.guild.approximate_presence_count;
332 guild.default_message_notifications = self.guild.default_message_notifications;
333 guild.explicit_content_filter = self.guild.explicit_content_filter;
334 guild.max_members = self.guild.max_members;
335 guild.max_presences = self.guild.max_presences;
336 guild.max_video_channel_users = self.guild.max_video_channel_users;
337 guild.max_stage_video_channel_users = self.guild.max_stage_video_channel_users;
338 guild.mfa_level = self.guild.mfa_level;
339 guild.nsfw_level = self.guild.nsfw_level;
340 guild.premium_progress_bar_enabled = self.guild.premium_progress_bar_enabled;
341 guild.premium_subscription_count = self.guild.premium_subscription_count;
342 guild.premium_tier = self.guild.premium_tier;
343 guild.public_updates_channel_id = self.guild.public_updates_channel_id;
344 guild.rules_channel_id = self.guild.rules_channel_id;
345 guild.system_channel_flags = self.guild.system_channel_flags;
346 guild.system_channel_id = self.guild.system_channel_id;
347 guild.verification_level = self.guild.verification_level;
348 guild.widget_channel_id = self.guild.widget_channel_id;
349 guild.widget_enabled = self.guild.widget_enabled;
350 }
351
352 None
353 }
354}
355
356impl CacheUpdate for MessageCreateEvent {
357 type Output = Message;
359
360 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
361 let guild = self.message.guild_id.and_then(|g_id| cache.guilds.get_mut(&g_id));
363
364 if let Some(mut guild) = guild {
365 if let Some(channel) = guild.channels.get_mut(&self.message.channel_id) {
366 update_channel_last_message_id(&self.message, channel, cache);
367 } else {
368 let thread =
370 guild.threads.iter_mut().find(|thread| thread.id == self.message.channel_id);
371 if let Some(thread) = thread {
372 update_channel_last_message_id(&self.message, thread, cache);
373 }
374 }
375 }
376
377 let max = cache.settings().max_messages;
379
380 if max == 0 {
381 return None;
382 }
383
384 let mut messages = cache.messages.entry(self.message.channel_id).or_default();
385 let mut queue = cache.message_queue.entry(self.message.channel_id).or_default();
386
387 let mut removed_msg = None;
388
389 if messages.len() == max {
390 if let Some(id) = queue.pop_front() {
391 removed_msg = messages.remove(&id);
392 }
393 }
394
395 queue.push_back(self.message.id);
396 messages.insert(self.message.id, self.message.clone());
397
398 removed_msg
399 }
400}
401
402fn update_channel_last_message_id(message: &Message, channel: &mut GuildChannel, cache: &Cache) {
403 if let Some(last_message_id) = channel.last_message_id {
404 let most_recent_timestamp = cache.message(channel.id, last_message_id).map(|m| m.timestamp);
405 if let Some(most_recent_timestamp) = most_recent_timestamp {
406 if message.timestamp > most_recent_timestamp {
407 channel.last_message_id = Some(message.id);
408 }
409 } else {
410 channel.last_message_id = Some(message.id);
411 }
412 } else {
413 channel.last_message_id = Some(message.id);
414 }
415}
416
417impl CacheUpdate for MessageUpdateEvent {
418 type Output = Message;
419
420 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
421 let mut messages = cache.messages.get_mut(&self.channel_id)?;
422 let message = messages.get_mut(&self.id)?;
423 let old_message = message.clone();
424
425 self.apply_to_message(message);
426
427 Some(old_message)
428 }
429}
430
431impl CacheUpdate for PresenceUpdateEvent {
432 type Output = ();
433
434 fn update(&mut self, cache: &Cache) -> Option<()> {
435 if let Some(user) = self.presence.user.to_user() {
436 cache.update_user_entry(&user);
437 }
438
439 if let Some(user) = cache.user(self.presence.user.id) {
440 self.presence.user.update_with_user(&user);
441 }
442
443 if let Some(guild_id) = self.presence.guild_id {
444 if let Some(mut guild) = cache.guilds.get_mut(&guild_id) {
445 if self.presence.status == OnlineStatus::Offline {
447 guild.presences.remove(&self.presence.user.id);
448 } else {
449 guild.presences.insert(self.presence.user.id, self.presence.clone());
450 }
451
452 if let Some(user) = self.presence.user.to_user() {
454 guild.members.entry(self.presence.user.id).or_insert_with(|| Member {
455 deaf: false,
456 guild_id,
457 joined_at: None,
458 mute: false,
459 nick: None,
460 user,
461 roles: vec![],
462 pending: false,
463 premium_since: None,
464 permissions: None,
465 avatar: None,
466 banner: None,
467 communication_disabled_until: None,
468 flags: GuildMemberFlags::default(),
469 unusual_dm_activity_until: None,
470 avatar_decoration_data: None,
471 });
472 }
473 }
474 }
475
476 None
477 }
478}
479
480impl CacheUpdate for ReadyEvent {
481 type Output = ();
482
483 fn update(&mut self, cache: &Cache) -> Option<()> {
484 let ready = self.ready.clone();
485
486 for unavailable in ready.guilds {
487 cache.guilds.remove(&unavailable.id);
488 cache.unavailable_guilds.insert(unavailable.id, ());
489 }
490
491 let shard_data = self.ready.shard.unwrap_or_else(|| ShardInfo::new(ShardId(1), 1));
492
493 {
494 let mut cached_shard_data = cache.shard_data.write();
495 cached_shard_data.total = shard_data.total;
496 cached_shard_data.connected.insert(shard_data.id);
497 }
498 *cache.user.write() = ready.user;
499
500 None
501 }
502}
503
504impl CacheUpdate for ThreadCreateEvent {
505 type Output = GuildChannel;
506
507 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
508 let (guild_id, thread_id) = (self.thread.guild_id, self.thread.id);
509
510 cache.guilds.get_mut(&guild_id).and_then(|mut g| {
511 if let Some(i) = g.threads.iter().position(|e| e.id == thread_id) {
512 Some(std::mem::replace(&mut g.threads[i], self.thread.clone()))
513 } else {
514 g.threads.push(self.thread.clone());
515 None
516 }
517 })
518 }
519}
520
521impl CacheUpdate for ThreadUpdateEvent {
522 type Output = GuildChannel;
523
524 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
525 let (guild_id, thread_id) = (self.thread.guild_id, self.thread.id);
526
527 cache.guilds.get_mut(&guild_id).and_then(|mut g| {
528 if let Some(i) = g.threads.iter().position(|e| e.id == thread_id) {
529 Some(std::mem::replace(&mut g.threads[i], self.thread.clone()))
530 } else {
531 g.threads.push(self.thread.clone());
532 None
533 }
534 })
535 }
536}
537
538impl CacheUpdate for ThreadDeleteEvent {
539 type Output = GuildChannel;
540
541 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
542 let (guild_id, thread_id) = (self.thread.guild_id, self.thread.id);
543
544 cache.guilds.get_mut(&guild_id).and_then(|mut g| {
545 g.threads.iter().position(|e| e.id == thread_id).map(|i| g.threads.remove(i))
546 })
547 }
548}
549
550impl CacheUpdate for UserUpdateEvent {
551 type Output = CurrentUser;
552
553 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
554 let mut user = cache.user.write();
555 Some(std::mem::replace(&mut user, self.current_user.clone()))
556 }
557}
558
559impl CacheUpdate for VoiceStateUpdateEvent {
560 type Output = VoiceState;
561
562 fn update(&mut self, cache: &Cache) -> Option<VoiceState> {
563 if let Some(guild_id) = self.voice_state.guild_id {
564 if let Some(mut guild) = cache.guilds.get_mut(&guild_id) {
565 if let Some(member) = &self.voice_state.member {
566 guild.members.insert(member.user.id, member.clone());
567 }
568
569 if self.voice_state.channel_id.is_some() {
570 guild.voice_states.insert(self.voice_state.user_id, self.voice_state.clone())
572 } else {
573 guild.voice_states.remove(&self.voice_state.user_id)
575 }
576 } else {
577 None
578 }
579 } else {
580 None
581 }
582 }
583}
584
585impl CacheUpdate for VoiceChannelStatusUpdateEvent {
586 type Output = String;
587
588 fn update(&mut self, cache: &Cache) -> Option<Self::Output> {
589 let mut guild = cache.guilds.get_mut(&self.guild_id)?;
590 let channel = guild.channels.get_mut(&self.id)?;
591
592 let old = channel.status.clone();
593 channel.status.clone_from(&self.status);
594 old
595 }
596}