twilight_cache_inmemory/event/
channel.rs

1use crate::{traits::CacheableChannel, CacheableModels, InMemoryCache, ResourceType, UpdateCache};
2use twilight_model::{
3    channel::Channel,
4    gateway::payload::incoming::{ChannelCreate, ChannelDelete, ChannelPinsUpdate, ChannelUpdate},
5    id::{marker::ChannelMarker, Id},
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            if let Some(guild_id) = channel.guild_id() {
34                let maybe_channels = self.guild_channels.get_mut(&guild_id);
35
36                if let Some(mut channels) = maybe_channels {
37                    channels.remove(&channel_id);
38                }
39            }
40        }
41    }
42}
43
44impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for ChannelCreate {
45    fn update(&self, cache: &InMemoryCache<CacheModels>) {
46        if !cache.wants(ResourceType::CHANNEL) {
47            return;
48        }
49
50        cache.cache_channel(self.0.clone());
51    }
52}
53
54impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for ChannelDelete {
55    fn update(&self, cache: &InMemoryCache<CacheModels>) {
56        if !cache.wants(ResourceType::CHANNEL) {
57            return;
58        }
59
60        cache.delete_channel(self.0.id);
61    }
62}
63
64impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for ChannelPinsUpdate {
65    fn update(&self, cache: &InMemoryCache<CacheModels>) {
66        if !cache.wants(ResourceType::CHANNEL) {
67            return;
68        }
69
70        if let Some(mut channel) = cache.channels.get_mut(&self.channel_id) {
71            channel.set_last_pin_timestamp(self.last_pin_timestamp);
72        }
73    }
74}
75
76impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for ChannelUpdate {
77    fn update(&self, cache: &InMemoryCache<CacheModels>) {
78        if !cache.wants(ResourceType::CHANNEL) {
79            return;
80        }
81
82        cache.cache_channel(self.0.clone());
83    }
84}
85
86#[cfg(test)]
87mod tests {
88    use crate::{test, DefaultInMemoryCache};
89    use twilight_model::gateway::{
90        event::Event,
91        payload::incoming::{ChannelDelete, ChannelUpdate},
92    };
93
94    #[test]
95    fn channel_delete_guild() {
96        let cache = DefaultInMemoryCache::new();
97        let (guild_id, channel_id, channel) = test::guild_channel_text();
98
99        cache.cache_channel(channel.clone());
100        assert_eq!(1, cache.channels.len());
101        assert!(cache
102            .guild_channels
103            .get(&guild_id)
104            .unwrap()
105            .contains(&channel_id));
106
107        cache.update(&Event::ChannelDelete(Box::new(ChannelDelete(channel))));
108        assert!(cache.channels.is_empty());
109        assert!(cache.guild_channels.get(&guild_id).unwrap().is_empty());
110    }
111
112    #[test]
113    fn channel_update_guild() {
114        let cache = DefaultInMemoryCache::new();
115        let (guild_id, channel_id, channel) = test::guild_channel_text();
116
117        cache.update(&ChannelUpdate(channel));
118        assert_eq!(1, cache.channels.len());
119        assert!(cache
120            .guild_channels
121            .get(&guild_id)
122            .unwrap()
123            .contains(&channel_id));
124    }
125}