twilight_cache_inmemory/event/
channel.rs

1use crate::{CacheableModels, InMemoryCache, ResourceType, UpdateCache, traits::CacheableChannel};
2use twilight_model::{
3    channel::Channel,
4    gateway::payload::incoming::{ChannelCreate, ChannelDelete, ChannelPinsUpdate, ChannelUpdate},
5    id::{Id, marker::ChannelMarker},
6};
7
8impl<CacheModels: CacheableModels> InMemoryCache<CacheModels> {
9    pub(crate) fn cache_channels(&self, channels: impl IntoIterator<Item = Channel>) {
10        for channel in channels {
11            self.cache_channel(channel);
12        }
13    }
14
15    pub(crate) fn cache_channel(&self, channel: Channel) {
16        if let Some(guild_id) = channel.guild_id {
17            self.guild_channels
18                .entry(guild_id)
19                .or_default()
20                .insert(channel.id);
21        }
22
23        self.channels
24            .insert(channel.id, CacheModels::Channel::from(channel));
25    }
26
27    /// Delete a guild channel from the cache.
28    ///
29    /// The guild channel data itself and the channel entry in its guild's list
30    /// of channels will be deleted.
31    pub(crate) fn delete_channel(&self, channel_id: Id<ChannelMarker>) {
32        if let Some((_, channel)) = self.channels.remove(&channel_id)
33            && let Some(guild_id) = channel.guild_id()
34            && let Some(mut channels) = self.guild_channels.get_mut(&guild_id)
35        {
36            channels.remove(&channel_id);
37        }
38    }
39}
40
41impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for ChannelCreate {
42    fn update(&self, cache: &InMemoryCache<CacheModels>) {
43        if !cache.wants(ResourceType::CHANNEL) {
44            return;
45        }
46
47        cache.cache_channel(self.0.clone());
48    }
49}
50
51impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for ChannelDelete {
52    fn update(&self, cache: &InMemoryCache<CacheModels>) {
53        if !cache.wants(ResourceType::CHANNEL) {
54            return;
55        }
56
57        cache.delete_channel(self.0.id);
58    }
59}
60
61impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for ChannelPinsUpdate {
62    fn update(&self, cache: &InMemoryCache<CacheModels>) {
63        if !cache.wants(ResourceType::CHANNEL) {
64            return;
65        }
66
67        if let Some(mut channel) = cache.channels.get_mut(&self.channel_id) {
68            channel.set_last_pin_timestamp(self.last_pin_timestamp);
69        }
70    }
71}
72
73impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for ChannelUpdate {
74    fn update(&self, cache: &InMemoryCache<CacheModels>) {
75        if !cache.wants(ResourceType::CHANNEL) {
76            return;
77        }
78
79        cache.cache_channel(self.0.clone());
80    }
81}
82
83#[cfg(test)]
84mod tests {
85    use crate::{DefaultInMemoryCache, test};
86    use twilight_model::gateway::{
87        event::Event,
88        payload::incoming::{ChannelDelete, ChannelUpdate},
89    };
90
91    #[test]
92    fn channel_delete_guild() {
93        let cache = DefaultInMemoryCache::new();
94        let (guild_id, channel_id, channel) = test::guild_channel_text();
95
96        cache.cache_channel(channel.clone());
97        assert_eq!(1, cache.channels.len());
98        assert!(
99            cache
100                .guild_channels
101                .get(&guild_id)
102                .unwrap()
103                .contains(&channel_id)
104        );
105
106        cache.update(&Event::ChannelDelete(Box::new(ChannelDelete(channel))));
107        assert!(cache.channels.is_empty());
108        assert!(cache.guild_channels.get(&guild_id).unwrap().is_empty());
109    }
110
111    #[test]
112    fn channel_update_guild() {
113        let cache = DefaultInMemoryCache::new();
114        let (guild_id, channel_id, channel) = test::guild_channel_text();
115
116        cache.update(&ChannelUpdate(channel));
117        assert_eq!(1, cache.channels.len());
118        assert!(
119            cache
120                .guild_channels
121                .get(&guild_id)
122                .unwrap()
123                .contains(&channel_id)
124        );
125    }
126}