twilight_cache_inmemory/event/
role.rs

1use crate::{config::ResourceType, CacheableModels, InMemoryCache, UpdateCache};
2use twilight_model::{
3    gateway::payload::incoming::{RoleCreate, RoleDelete, RoleUpdate},
4    guild::Role,
5    id::{
6        marker::{GuildMarker, RoleMarker},
7        Id,
8    },
9};
10
11impl<CacheModels: CacheableModels> InMemoryCache<CacheModels> {
12    pub(crate) fn cache_roles(
13        &self,
14        guild_id: Id<GuildMarker>,
15        roles: impl IntoIterator<Item = Role>,
16    ) {
17        for role in roles {
18            self.cache_role(guild_id, role);
19        }
20    }
21
22    fn cache_role(&self, guild_id: Id<GuildMarker>, role: Role) {
23        // Insert the role into the guild_roles map
24        self.guild_roles
25            .entry(guild_id)
26            .or_default()
27            .insert(role.id);
28
29        // Insert the role into the all roles map
30        crate::upsert_guild_item(
31            &self.roles,
32            guild_id,
33            role.id,
34            CacheModels::Role::from(role),
35        );
36    }
37
38    fn delete_role(&self, role_id: Id<RoleMarker>) {
39        if let Some((_, role)) = self.roles.remove(&role_id) {
40            if let Some(mut roles) = self.guild_roles.get_mut(&role.guild_id) {
41                roles.remove(&role_id);
42            }
43        }
44    }
45}
46
47impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for RoleCreate {
48    fn update(&self, cache: &InMemoryCache<CacheModels>) {
49        if !cache.wants(ResourceType::ROLE) {
50            return;
51        }
52
53        cache.cache_role(self.guild_id, self.role.clone());
54    }
55}
56
57impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for RoleDelete {
58    fn update(&self, cache: &InMemoryCache<CacheModels>) {
59        if !cache.wants(ResourceType::ROLE) {
60            return;
61        }
62
63        cache.delete_role(self.role_id);
64    }
65}
66
67impl<CacheModels: CacheableModels> UpdateCache<CacheModels> for RoleUpdate {
68    fn update(&self, cache: &InMemoryCache<CacheModels>) {
69        if !cache.wants(ResourceType::ROLE) {
70            return;
71        }
72
73        cache.cache_role(self.guild_id, self.role.clone());
74    }
75}
76
77#[cfg(test)]
78mod tests {
79    use crate::{test, DefaultInMemoryCache};
80    use twilight_model::{gateway::payload::incoming::RoleCreate, id::Id};
81
82    #[test]
83    fn insert_role_on_event() {
84        let cache = DefaultInMemoryCache::new();
85
86        cache.update(&RoleCreate {
87            guild_id: Id::new(1),
88            role: test::role(Id::new(2)),
89        });
90
91        {
92            assert_eq!(1, cache.guild_roles.get(&Id::new(1)).unwrap().len());
93            assert_eq!(1, cache.roles.len());
94
95            assert_eq!("test".to_string(), cache.role(Id::new(2)).unwrap().name);
96        }
97    }
98
99    #[test]
100    fn cache_role() {
101        let cache = DefaultInMemoryCache::new();
102
103        // Single inserts
104        {
105            // The role ids for the guild with id 1
106            let guild_1_role_ids = (1..=10).map(Id::new).collect::<Vec<_>>();
107            // Map the role ids to a test role
108            let guild_1_roles = guild_1_role_ids
109                .iter()
110                .copied()
111                .map(test::role)
112                .collect::<Vec<_>>();
113            // Cache all the roles using cache role
114            for role in guild_1_roles.clone() {
115                cache.cache_role(Id::new(1), role);
116            }
117
118            // Check for the cached guild role ids
119            let cached_roles = cache.guild_roles(Id::new(1)).unwrap();
120            assert_eq!(cached_roles.len(), guild_1_role_ids.len());
121            assert!(guild_1_role_ids.iter().all(|id| cached_roles.contains(id)));
122
123            // Check for the cached role
124            assert!(guild_1_roles.into_iter().all(|role| cache
125                .role(role.id)
126                .expect("Role missing from cache")
127                .resource()
128                == &role));
129        }
130
131        // Bulk inserts
132        {
133            // The role ids for the guild with id 2
134            let guild_2_role_ids = (101..=110).map(Id::new).collect::<Vec<_>>();
135            // Map the role ids to a test role
136            let guild_2_roles = guild_2_role_ids
137                .iter()
138                .copied()
139                .map(test::role)
140                .collect::<Vec<_>>();
141            // Cache all the roles using cache roles
142            cache.cache_roles(Id::new(2), guild_2_roles.clone());
143
144            // Check for the cached guild role ids
145            let cached_roles = cache.guild_roles(Id::new(2)).unwrap();
146            assert_eq!(cached_roles.len(), guild_2_role_ids.len());
147            assert!(guild_2_role_ids.iter().all(|id| cached_roles.contains(id)));
148
149            // Check for the cached role
150            assert!(guild_2_roles.into_iter().all(|role| cache
151                .role(role.id)
152                .expect("Role missing from cache")
153                .resource()
154                == &role));
155        }
156    }
157}