fluxer/cache.rs
1//! In-memory cache populated automatically from gateway events.
2//! Attached to every [`Context`](crate::client::Context) as `ctx.cache`.
3//!
4//! ```rust,no_run
5//! # use fluxer::prelude::*;
6//! # async fn example(ctx: Context, msg: Message) {
7//! if let Some(guild) = ctx.cache.guild(msg.guild_id.as_deref().unwrap_or("")).await {
8//! println!("Guild name: {}", guild.name.unwrap_or_default());
9//! }
10//! println!("Bot is in {} guild(s)", ctx.cache.guild_count().await);
11//! # }
12//! ```
13
14use std::collections::HashMap;
15use std::sync::Arc;
16use tokio::sync::RwLock;
17use crate::model::{Channel, Guild, Snowflake, User};
18
19/// In-memory gateway cache.
20pub struct Cache {
21 pub guilds: RwLock<HashMap<Snowflake, Guild>>,
22 pub channels: RwLock<HashMap<Snowflake, Channel>>,
23 pub users: RwLock<HashMap<Snowflake, User>>,
24 pub current_user: RwLock<Option<User>>,
25}
26
27impl Cache {
28 pub fn new() -> Arc<Self> {
29 Arc::new(Self {
30 guilds: RwLock::new(HashMap::new()),
31 channels: RwLock::new(HashMap::new()),
32 users: RwLock::new(HashMap::new()),
33 current_user: RwLock::new(None),
34 })
35 }
36
37 /// Looks up a guild by ID. Populated from `GUILD_CREATE` / `GUILD_UPDATE` events.
38 pub async fn guild(&self, id: &str) -> Option<Guild> {
39 self.guilds.read().await.get(id).cloned()
40 }
41
42 /// Looks up a channel by ID. Populated from `GUILD_CREATE` and `CHANNEL_CREATE` / `CHANNEL_UPDATE` events.
43 pub async fn channel(&self, id: &str) -> Option<Channel> {
44 self.channels.read().await.get(id).cloned()
45 }
46
47 /// Looks up a user by ID. Populated from `GUILD_CREATE` member lists and `MESSAGE_CREATE` authors.
48 pub async fn user(&self, id: &str) -> Option<User> {
49 self.users.read().await.get(id).cloned()
50 }
51
52 /// Returns the bot's own `User` object, populated from the READY event.
53 pub async fn current_user(&self) -> Option<User> {
54 self.current_user.read().await.clone()
55 }
56
57 /// Returns the number of guilds currently in cache.
58 pub async fn guild_count(&self) -> usize {
59 self.guilds.read().await.len()
60 }
61}