1use async_trait::async_trait;
2pub use error::Error;
3use twilight_model::{
4 channel::{Channel, ChannelType, StageInstance},
5 gateway::event::Event,
6 guild::Permissions,
7 id::{
8 marker::{
9 ChannelMarker, EmojiMarker, GuildMarker, MessageMarker, RoleMarker, StageMarker,
10 StickerMarker, UserMarker,
11 },
12 Id,
13 },
14 user::CurrentUser,
15};
16use twilight_util::permission_calculator::PermissionCalculator;
17
18use crate::{
19 model::{
20 CachedActivity, CachedAttachment, CachedChannel, CachedEmbed, CachedEmbedField,
21 CachedEmoji, CachedGuild, CachedMember, CachedMessage, CachedMessageSticker,
22 CachedPresence, CachedReaction, CachedRole, CachedSticker,
23 },
24 Backend,
25};
26
27#[allow(clippy::std_instead_of_core)]
29mod error {
30 use thiserror::Error;
31 use twilight_model::{
32 channel::Channel,
33 id::{
34 marker::{ChannelMarker, GuildMarker, RoleMarker, UserMarker},
35 Id,
36 },
37 };
38
39 use crate::{
40 backend,
41 model::{CachedChannel, CachedMember},
42 };
43
44 #[derive(Error, Debug)]
45 pub enum Error<E: backend::Error> {
47 #[error("An error was returned by the backend:\n{0}")]
49 Backend(E),
50 #[error("The DM channel doesn't have any recipients other than the bot itself:\n{0:?}")]
52 PrivateChannelMissingRecipient(Box<Channel>),
53 #[error("The thread doesn't have a parent ID:\n{0:?}")]
55 ThreadMissingParent(Box<CachedChannel>),
56 #[error("The current user isn't in the cache")]
58 CurrentUserMissing,
59 #[error(
61 "One of the roles of the member to cache isn't in the cache:\nUser ID: {user_id}, \
62 Role ID: {role_id}"
63 )]
64 MemberRoleMissing {
65 user_id: Id<UserMarker>,
67 role_id: Id<RoleMarker>,
69 },
70 #[error(
72 "The communication disabled until timestamp of the given member to calculate \
73 permissions for isn't valid:\n{0:?}"
74 )]
75 MemberBadTimeoutTimestamp(Box<CachedMember>),
76 #[error("The channel to calculate permissions for isn't in the cache:\n{0}")]
78 PermissionsChannelMissing(Id<ChannelMarker>),
79 #[error("The guild to calculate permissions for isn't in the cache:\n{0}")]
81 PermissionsGuildMissing(Id<GuildMarker>),
82 #[error(
84 "The member to calculate permissions for isn't in the cache:\nUser ID: {user_id}, \
85 Guild ID: {guild_id}"
86 )]
87 PermissionsMemberMissing {
88 user_id: Id<UserMarker>,
90 guild_id: Id<GuildMarker>,
92 },
93 #[error(
96 "The everyone role in the guild to calculate permissions for isn't in the cache:\n{0}"
97 )]
98 PermissionsGuildEveryoneRoleMissing(Id<GuildMarker>),
99 #[error("The given channel to calculate permissions for doesn't have a guild ID:\n{0:?}")]
102 PermissionsChannelNotInGuild(Box<CachedChannel>),
103 }
104}
105
106#[async_trait]
118pub trait Cache: Backend {
119 #[allow(clippy::too_many_lines)]
139 async fn update(&self, event: &Event) -> Result<(), Error<Self::Error>> {
140 match event {
141 Event::ChannelCreate(channel) => {
142 self.add_channel(channel).await?;
143 }
144 Event::ChannelUpdate(channel) => {
145 self.add_channel(channel).await?;
146 }
147 Event::ChannelDelete(channel) => {
148 self.delete_channel(channel.id).await?;
149 }
150 Event::ThreadCreate(thread) => {
151 self.add_channel(thread).await?;
152 }
153 Event::ThreadUpdate(thread) => {
154 self.add_channel(thread).await?;
155 }
156 Event::ThreadDelete(thread) => {
157 self.delete_channel(thread.id).await?;
158 }
159 Event::GuildCreate(guild) => {
160 for channel in guild.channels.iter().chain(&guild.threads) {
161 self.add_channel(channel).await?;
162 }
163 for emoji in &guild.emojis {
164 self.upsert_emoji(CachedEmoji::from_emoji(emoji, guild.id))
165 .await?;
166 }
167 for sticker in &guild.stickers {
168 self.upsert_sticker(sticker.into()).await?;
169 }
170 for member in &guild.members {
171 self.add_member_roles(member.user.id, member.roles.clone())
172 .await?;
173 self.upsert_member(member.into()).await?;
174 }
175 for presence in &guild.presences {
176 self.upsert_presence(presence.into()).await?;
177 }
178 for role in &guild.roles {
179 self.upsert_role(CachedRole::from_role(role.clone(), guild.id))
180 .await?;
181 }
182 for stage in &guild.stage_instances {
183 self.upsert_stage_instance(stage.clone()).await?;
184 }
185 self.upsert_guild(CachedGuild::from(&guild.0)).await?;
186 }
187 Event::GuildUpdate(guild) => {
188 if let Some(mut cached_guild) = self.guild(guild.id).await? {
189 cached_guild.update(guild);
190 self.upsert_guild(cached_guild).await?;
191 }
192 }
193 Event::GuildDelete(guild) => {
194 if !guild.unavailable {
195 self.delete_guild_channels(guild.id).await?;
196 self.delete_guild_emojis(guild.id).await?;
197 self.delete_guild_stickers(guild.id).await?;
198 self.delete_guild_members(guild.id).await?;
199 self.delete_guild_presences(guild.id).await?;
200 self.delete_guild_roles(guild.id).await?;
201 self.delete_guild_stage_instances(guild.id).await?;
202 self.delete_guild(guild.id).await?;
203 }
204 }
205 Event::GuildEmojisUpdate(emojis) => {
206 self.delete_guild_emojis(emojis.guild_id).await?;
207 for emoji in &emojis.emojis {
208 self.upsert_emoji(CachedEmoji::from_emoji(emoji, emojis.guild_id))
209 .await?;
210 }
211 }
212 Event::GuildStickersUpdate(stickers) => {
213 self.delete_guild_stickers(stickers.guild_id).await?;
214 for sticker in &stickers.stickers {
215 self.upsert_sticker(sticker.into()).await?;
216 }
217 }
218 Event::MemberAdd(member) => {
219 self.add_member_roles(member.user.id, member.roles.clone())
220 .await?;
221 self.upsert_member(CachedMember::from(&member.0)).await?;
222 }
223 Event::MemberChunk(members) => {
224 for member in &members.members {
225 self.add_member_roles(member.user.id, member.roles.clone())
226 .await?;
227 self.upsert_member(member.into()).await?;
228 }
229 }
230 Event::MemberUpdate(member) => {
231 if let Some(mut cached_member) =
232 self.member(member.guild_id, member.user.id).await?
233 {
234 cached_member.update(member);
235 self.upsert_member(cached_member).await?;
236 self.delete_member_roles(member.guild_id, member.user.id)
237 .await?;
238 self.add_member_roles(member.user.id, member.roles.clone())
239 .await?;
240 }
241 }
242 Event::MemberRemove(member) => {
243 self.delete_member(member.user.id, member.guild_id).await?;
244 self.delete_member_roles(member.guild_id, member.user.id)
245 .await?;
246 }
247 Event::MessageCreate(message) => {
248 for attachment in message.attachments.clone() {
249 self.upsert_attachment(CachedAttachment::from_attachment(
250 attachment, message.id,
251 ))
252 .await?;
253 }
254 for sticker in message.sticker_items.clone() {
255 self.upsert_message_sticker(CachedMessageSticker::from_sticker(
256 sticker, message.id,
257 ))
258 .await?;
259 }
260 for embed in message.embeds.clone() {
261 let fields = embed.fields.clone();
262 let cached_embed = CachedEmbed::from_embed(embed, message.id);
263 for field in fields {
264 self.upsert_embed_field(CachedEmbedField::from_embed_field(
265 field,
266 cached_embed.id,
267 ))
268 .await?;
269 }
270 self.upsert_embed(cached_embed).await?;
271 }
272 self.upsert_message(CachedMessage::from(&message.0)).await?;
273 }
274 Event::MessageUpdate(message) => {
275 if let Some(mut cached_message) = self.message(message.id).await? {
276 cached_message.update(message);
277 if let Some(attachments) = &message.attachments {
278 self.delete_message_attachments(message.id).await?;
279 for attachment in attachments.clone() {
280 self.upsert_attachment(CachedAttachment::from_attachment(
281 attachment, message.id,
282 ))
283 .await?;
284 }
285 }
286 if let Some(embeds) = &message.embeds {
287 let cached_embeds = self.embeds(message.id).await?;
288 for (embed, _) in cached_embeds {
289 self.delete_embed_fields(embed.id).await?;
290 self.delete_embed(embed.id).await?;
291 }
292 for embed in embeds.clone() {
293 let fields = embed.fields.clone();
294 let cached_embed = CachedEmbed::from_embed(embed, message.id);
295 for field in fields {
296 self.upsert_embed_field(CachedEmbedField::from_embed_field(
297 field,
298 cached_embed.id,
299 ))
300 .await?;
301 }
302 self.upsert_embed(cached_embed).await?;
303 }
304 }
305 self.upsert_message(cached_message).await?;
306 }
307 }
308 Event::MessageDelete(message) => {
309 self.remove_message(message.id).await?;
310 }
311 Event::MessageDeleteBulk(messages) => {
312 for message_id in &messages.ids {
313 self.remove_message(*message_id).await?;
314 }
315 }
316 Event::PresenceUpdate(presence) => {
317 self.delete_user_activities(presence.user.id()).await?;
318 for activity in &presence.activities {
319 self.upsert_activity(CachedActivity::from_activity(
320 activity,
321 presence.user.id(),
322 ))
323 .await?;
324 }
325 self.upsert_presence(CachedPresence::from(&presence.0))
326 .await?;
327 }
328 Event::ReactionAdd(reaction) => {
329 self.upsert_reaction(CachedReaction::from(&reaction.0))
330 .await?;
331 }
332 Event::ReactionRemove(reaction) => {
333 self.delete_reaction(
334 reaction.message_id,
335 reaction.user_id,
336 reaction.emoji.clone(),
337 )
338 .await?;
339 }
340 Event::ReactionRemoveEmoji(reaction) => {
341 self.delete_message_reactions_by_emoji(reaction.message_id, reaction.emoji.clone())
342 .await?;
343 }
344 Event::ReactionRemoveAll(reaction) => {
345 self.delete_message_reactions(reaction.message_id).await?;
346 }
347 Event::Ready(ready) => {
348 self.set_current_user(ready.user.clone()).await?;
349 }
350 Event::UserUpdate(user) => {
351 self.set_current_user(user.0.clone()).await?;
352 }
353 Event::RoleCreate(role) => {
354 self.upsert_role(CachedRole::from_role(role.role.clone(), role.guild_id))
355 .await?;
356 }
357 Event::RoleUpdate(role) => {
358 self.upsert_role(CachedRole::from_role(role.role.clone(), role.guild_id))
359 .await?;
360 }
361 Event::RoleDelete(role) => {
362 self.delete_role(role.role_id).await?;
363 }
364 Event::StageInstanceCreate(stage) => {
365 self.upsert_stage_instance(stage.clone().0).await?;
366 }
367 Event::StageInstanceUpdate(stage) => {
368 self.upsert_stage_instance(stage.clone().0).await?;
369 }
370 Event::StageInstanceDelete(stage) => {
371 self.delete_stage_instance(stage.id).await?;
372 }
373 _ => {}
374 }
375
376 Ok(())
377 }
378
379 async fn self_channel_permissions(
393 &self,
394 channel_id: Id<ChannelMarker>,
395 ) -> Result<Permissions, Error<Self::Error>> {
396 let current_user_id = self.current_user().await?.id;
397 self.channel_permissions(current_user_id, channel_id).await
398 }
399
400 async fn self_guild_permissions(
412 &self,
413 guild_id: Id<GuildMarker>,
414 ) -> Result<Permissions, Error<Self::Error>> {
415 let current_user_id = self.current_user().await?.id;
416 self.guild_permissions(guild_id, current_user_id).await
417 }
418
419 async fn channel_permissions(
432 &self,
433 user_id: Id<UserMarker>,
434 channel_id: Id<ChannelMarker>,
435 ) -> Result<Permissions, Error<Self::Error>> {
436 let channel = self
437 .channel(channel_id)
438 .await?
439 .ok_or(Error::PermissionsChannelMissing(channel_id))?;
440 let guild_id = channel
441 .guild_id
442 .ok_or_else(|| Error::PermissionsChannelNotInGuild(Box::new(channel.clone())))?;
443 self.permissions(guild_id, user_id, Some(channel)).await
444 }
445
446 async fn guild_permissions(
457 &self,
458 guild_id: Id<GuildMarker>,
459 user_id: Id<UserMarker>,
460 ) -> Result<Permissions, Error<Self::Error>> {
461 self.permissions(guild_id, user_id, None).await
462 }
463
464 #[doc(hidden)]
475 async fn permissions(
476 &self,
477 guild_id: Id<GuildMarker>,
478 user_id: Id<UserMarker>,
479 cached_channel: Option<CachedChannel>,
480 ) -> Result<Permissions, Error<Self::Error>> {
481 let guild = self
482 .guild(guild_id)
483 .await?
484 .ok_or(Error::PermissionsGuildMissing(guild_id))?;
485 let everyone_role = self
486 .role(guild_id.cast())
487 .await?
488 .ok_or(Error::PermissionsGuildEveryoneRoleMissing(guild_id))?;
489 let roles: Vec<_> = self
490 .member_roles(user_id, guild_id)
491 .await?
492 .iter()
493 .map(|role| (role.id, role.permissions))
494 .collect();
495
496 let calculator =
497 PermissionCalculator::new(guild_id, user_id, everyone_role.permissions, &roles)
498 .owner_id(guild.owner_id);
499 let permissions = if let Some(channel) = cached_channel {
500 calculator.in_channel(
501 channel.kind,
502 &channel.permission_overwrites.unwrap_or_default(),
503 )
504 } else {
505 calculator.root()
506 };
507
508 let member = self
509 .member(guild_id, user_id)
510 .await?
511 .ok_or(Error::PermissionsMemberMissing { user_id, guild_id })?;
512 if !permissions.contains(Permissions::ADMINISTRATOR)
513 && member
514 .communication_disabled()
515 .map_err(|_err| Error::MemberBadTimeoutTimestamp(Box::new(member)))?
516 {
517 Ok(permissions
518 .intersection(Permissions::VIEW_CHANNEL | Permissions::READ_MESSAGE_HISTORY))
519 } else {
520 Ok(permissions)
521 }
522 }
523
524 async fn current_user(&self) -> Result<CurrentUser, Error<Self::Error>>;
531
532 async fn channel(
537 &self,
538 channel_id: Id<ChannelMarker>,
539 ) -> Result<Option<CachedChannel>, Error<Self::Error>>;
540
541 async fn private_channel(
546 &self,
547 recipient_id: Id<UserMarker>,
548 ) -> Result<Option<Id<ChannelMarker>>, Error<Self::Error>>;
549
550 async fn guild(
552 &self,
553 guild_id: Id<GuildMarker>,
554 ) -> Result<Option<CachedGuild>, Error<Self::Error>>;
555
556 async fn emoji(
558 &self,
559 emoji_id: Id<EmojiMarker>,
560 ) -> Result<Option<CachedEmoji>, Error<Self::Error>>;
561
562 async fn sticker(
564 &self,
565 sticker_id: Id<StickerMarker>,
566 ) -> Result<Option<CachedSticker>, Error<Self::Error>>;
567
568 async fn member(
570 &self,
571 guild_id: Id<GuildMarker>,
572 user_id: Id<UserMarker>,
573 ) -> Result<Option<CachedMember>, Error<Self::Error>>;
574
575 async fn message(
581 &self,
582 message_id: Id<MessageMarker>,
583 ) -> Result<Option<CachedMessage>, Error<Self::Error>>;
584
585 async fn embeds(
587 &self,
588 message_id: Id<MessageMarker>,
589 ) -> Result<Vec<(CachedEmbed, Vec<CachedEmbedField>)>, Error<Self::Error>> {
590 let mut embeds = vec![];
591 let cached_embeds = self.cached_embeds(message_id).await?;
592 for embed in cached_embeds {
593 let fields = self.embed_fields(embed.id).await?;
594 embeds.push((embed, fields));
595 }
596 Ok(embeds)
597 }
598
599 async fn attachments(
601 &self,
602 message_id: Id<MessageMarker>,
603 ) -> Result<Vec<CachedAttachment>, Error<Self::Error>>;
604
605 async fn stickers(
607 &self,
608 message_id: Id<MessageMarker>,
609 ) -> Result<Vec<CachedMessageSticker>, Error<Self::Error>>;
610
611 async fn reactions(
613 &self,
614 message_id: Id<MessageMarker>,
615 ) -> Result<Vec<CachedReaction>, Error<Self::Error>>;
616
617 async fn role(&self, role_id: Id<RoleMarker>)
619 -> Result<Option<CachedRole>, Error<Self::Error>>;
620
621 async fn member_roles(
623 &self,
624 user_id: Id<UserMarker>,
625 guild_id: Id<GuildMarker>,
626 ) -> Result<Vec<CachedRole>, Error<Self::Error>>;
627
628 async fn stage_instance(
630 &self,
631 stage_id: Id<StageMarker>,
632 ) -> Result<Option<StageInstance>, Error<Self::Error>>;
633
634 #[doc(hidden)]
643 async fn add_channel(&self, channel: &Channel) -> Result<(), Error<Self::Error>> {
644 if channel.kind == ChannelType::Private {
645 let recipient_user_id = self.private_channel_recipient(channel).await?;
646 self.upsert_private_channel(channel.id, recipient_user_id)
647 .await?;
648 } else {
649 self.upsert_channel(CachedChannel::from(channel)).await?;
650 }
651
652 Ok(())
653 }
654
655 #[doc(hidden)]
662 async fn private_channel_recipient(
663 &self,
664 channel: &Channel,
665 ) -> Result<Id<UserMarker>, Error<Self::Error>> {
666 let current_user_id = self.current_user().await?.id;
667 let recipient_user_id = channel
668 .recipients
669 .as_ref()
670 .and_then(|recipients| recipients.iter().find(|user| user.id == current_user_id))
671 .ok_or_else(|| Error::PrivateChannelMissingRecipient(Box::new(channel.clone())))?
672 .id;
673 Ok(recipient_user_id)
674 }
675
676 #[doc(hidden)]
678 async fn add_member_roles(
679 &self,
680 user_id: Id<UserMarker>,
681 role_ids: Vec<Id<RoleMarker>>,
682 ) -> Result<(), Error<Self::Error>> {
683 for role_id in role_ids {
684 let mut role = self
685 .role(role_id)
686 .await?
687 .ok_or(Error::MemberRoleMissing { user_id, role_id })?;
688 role.user_id = Some(user_id);
689 self.upsert_role(role).await?;
690 }
691
692 Ok(())
693 }
694
695 #[doc(hidden)]
697 async fn remove_message(
698 &self,
699 message_id: Id<MessageMarker>,
700 ) -> Result<(), Error<Self::Error>> {
701 let embeds = self.embeds(message_id).await?;
702 for (embed, _) in embeds {
703 self.delete_embed_fields(embed.id).await?;
704 self.delete_embed(embed.id).await?;
705 }
706 self.delete_message_attachments(message_id).await?;
707 self.delete_message_reactions(message_id).await?;
708 self.delete_message_stickers(message_id).await?;
709 self.delete_message(message_id).await?;
710 Ok(())
711 }
712}