tulpje_cache/models/
emoji.rs1use serde::{Deserialize, Serialize};
2use twilight_model::{
3 guild::Emoji,
4 id::{
5 Id,
6 marker::{EmojiMarker, GuildMarker, RoleMarker, UserMarker},
7 },
8};
9
10use crate::{Cache, Error, GuildResource};
11
12#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
13pub struct CachedEmoji {
14 pub animated: bool,
15 pub available: bool,
16 pub id: Id<EmojiMarker>,
17 pub managed: bool,
18 pub name: String,
19 pub require_colons: bool,
20 pub roles: Vec<Id<RoleMarker>>,
21 pub user_id: Option<Id<UserMarker>>,
22}
23
24impl From<Emoji> for CachedEmoji {
25 fn from(emoji: Emoji) -> Self {
26 let Emoji {
27 animated,
28 available,
29 id,
30 managed,
31 name,
32 require_colons,
33 roles,
34 user,
35 } = emoji;
36
37 Self {
38 animated,
39 available,
40 id,
41 managed,
42 name,
43 require_colons,
44 roles,
45 user_id: user.map(|user| user.id),
46 }
47 }
48}
49
50impl PartialEq<Emoji> for CachedEmoji {
51 fn eq(&self, other: &Emoji) -> bool {
52 self.id == other.id
53 && self.animated == other.animated
54 && self.managed == other.managed
55 && self.name == other.name
56 && self.require_colons == other.require_colons
57 && self.roles == other.roles
58 && self.user_id == other.user.as_ref().map(|user| user.id)
59 && self.available == other.available
60 }
61}
62
63impl Cache {
64 pub(crate) async fn cache_emojis(
65 &self,
66 guild_id: Id<GuildMarker>,
67 emojis: Vec<Emoji>,
68 ) -> Result<(), Error> {
69 let guild_emojis = self.guild_emojis.members(&guild_id).await?;
70 if !guild_emojis.is_empty() {
71 let incoming: Vec<_> = emojis.iter().map(|e| e.id).collect();
72
73 let removal_filter: Vec<_> = guild_emojis
74 .iter()
75 .copied()
76 .filter(|e| !incoming.contains(e))
77 .collect();
78
79 self.guild_emojis
80 .remove_multi(&guild_id, &removal_filter)
81 .await?;
82
83 self.emojis.remove_multi(&removal_filter).await?;
84 }
85
86 for emoji in &emojis {
87 self.cache_emoji(guild_id, emoji).await?;
88 }
89
90 Ok(())
91 }
92
93 pub(crate) async fn cache_emoji(
94 &self,
95 guild_id: Id<GuildMarker>,
96 emoji: &Emoji,
97 ) -> Result<(), Error> {
98 if let Some(user) = emoji.user.as_ref() {
99 self.cache_user(user, Some(guild_id)).await?;
100 }
101
102 if let Some(cached_emoji) = self.emojis.get(&emoji.id).await?
103 && cached_emoji.value == *emoji
104 {
105 return Ok(());
106 }
107
108 let emoji_id = emoji.id;
109 let cached = CachedEmoji::from(emoji.clone());
110
111 self.emojis
112 .insert(
113 &emoji_id,
114 &GuildResource {
115 guild_id,
116 value: cached,
117 },
118 )
119 .await?;
120
121 self.guild_emojis.insert(&guild_id, &emoji_id).await?;
122
123 Ok(())
124 }
125}