Skip to main content

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}