twilight_cache_inmemory/event/
sticker.rs1use std::{borrow::Cow, collections::HashSet};
2
3use crate::{
4 config::ResourceType, CacheableModels, CacheableSticker, GuildResource, InMemoryCache,
5 UpdateCache,
6};
7use twilight_model::{
8 channel::message::Sticker,
9 gateway::payload::incoming::GuildStickersUpdate,
10 id::{marker::GuildMarker, Id},
11};
12
13impl<CacheModels: CacheableModels> InMemoryCache<CacheModels> {
14 pub(crate) fn cache_stickers(&self, guild_id: Id<GuildMarker>, stickers: Vec<Sticker>) {
15 if let Some(mut guild_stickers) = self.guild_stickers.get_mut(&guild_id) {
16 let incoming_sticker_ids = stickers
17 .iter()
18 .map(|sticker| sticker.id)
19 .collect::<HashSet<_>>();
20
21 guild_stickers.retain(|sticker_id| {
28 let retain = incoming_sticker_ids.contains(sticker_id);
29
30 if !retain {
31 self.stickers.remove(sticker_id);
32 }
33
34 retain
35 });
36 }
37
38 for sticker in stickers {
39 self.cache_sticker(guild_id, sticker);
40 }
41 }
42
43 pub(crate) fn cache_sticker(&self, guild_id: Id<GuildMarker>, sticker: Sticker) {
44 if let Some(cached_sticker) = self.stickers.get(&sticker.id) {
45 if cached_sticker.value == sticker {
46 return;
47 }
48 }
49
50 if let Some(user) = sticker.user.clone() {
51 self.cache_user(Cow::Owned(user), Some(guild_id));
52 }
53
54 let sticker_id = sticker.id;
55 let cached = CacheModels::Sticker::from(sticker);
56
57 self.stickers.insert(
58 cached.id(),
59 GuildResource {
60 guild_id,
61 value: cached,
62 },
63 );
64
65 self.guild_stickers
66 .entry(guild_id)
67 .or_default()
68 .insert(sticker_id);
69 }
70}
71
72impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for GuildStickersUpdate {
73 fn update(&self, cache: &InMemoryCache<CacheModels>) {
74 if !cache.wants(ResourceType::STICKER) {
75 return;
76 }
77
78 cache.cache_stickers(self.guild_id, self.stickers.clone());
79 }
80}
81
82#[cfg(test)]
83mod tests {
84 use crate::{test, DefaultCacheModels, InMemoryCache};
85 use twilight_model::id::{
86 marker::{GuildMarker, StickerMarker},
87 Id,
88 };
89
90 const GUILD_ID: Id<GuildMarker> = Id::new(1);
91 const STICKER_ONE_ID: Id<StickerMarker> = Id::new(2);
92 const STICKER_TWO_ID: Id<StickerMarker> = Id::new(3);
93
94 fn cache_with_stickers() -> InMemoryCache<DefaultCacheModels> {
95 let cache = test::cache();
96 let one = test::sticker(STICKER_ONE_ID, GUILD_ID);
97 let two = test::sticker(STICKER_TWO_ID, GUILD_ID);
98 cache.cache_stickers(GUILD_ID, Vec::from([one, two]));
99
100 cache
101 }
102
103 #[test]
107 fn cache_stickers() {
108 let cache = cache_with_stickers();
109 assert_eq!(cache.stickers.len(), 2);
110 let one = test::sticker(STICKER_ONE_ID, GUILD_ID);
111 let two = test::sticker(STICKER_TWO_ID, GUILD_ID);
112 assert!(cache
113 .stickers
114 .get(&STICKER_ONE_ID)
115 .is_some_and(|r| r.id == STICKER_ONE_ID));
116 assert!(cache
117 .stickers
118 .get(&STICKER_TWO_ID)
119 .is_some_and(|r| r.id == STICKER_TWO_ID));
120
121 let guild_stickers = cache
122 .guild_stickers
123 .get(&GUILD_ID)
124 .expect("cache has stickers for guild");
125 assert_eq!(guild_stickers.len(), 2);
126 assert!(guild_stickers.contains(&one.id));
127 assert!(guild_stickers.contains(&two.id));
128 }
129
130 #[test]
138 fn cache_stickers_removal() {
139 let cache = cache_with_stickers();
140 let one = test::sticker(STICKER_ONE_ID, GUILD_ID);
141 cache.cache_stickers(GUILD_ID, Vec::from([one]));
142 assert_eq!(cache.stickers.len(), 1);
143 assert!(cache
144 .stickers
145 .get(&STICKER_ONE_ID)
146 .is_some_and(|r| r.id == STICKER_ONE_ID));
147 let guild_stickers = cache
148 .guild_stickers
149 .get(&GUILD_ID)
150 .expect("cache has stickers for guild");
151 assert_eq!(guild_stickers.len(), 1);
152 assert!(guild_stickers.contains(&STICKER_ONE_ID));
153 }
154}