mutiny_rs/
client.rs

1use std::sync::Arc;
2use moka::future::Cache;
3use crate::{context::Context, model::message::Message, websocket::WebSocket};
4use crate::model::channel::Channel;
5use crate::model::ready::Ready;
6use crate::model::user::User;
7
8#[async_trait::async_trait]
9pub trait EventHandler: Send + Sync + 'static {
10    async fn ready(&self, _ctx: Context, _ready: Ready) {}
11    async fn message(&self, _ctx: Context, _message: Message) {}
12}
13
14
15pub struct Client {
16    pub token: String,
17    pub websocket: Option<Arc<WebSocket>>,
18}
19
20
21impl Client {
22    pub fn new(token: String) -> Self {
23        Self {
24            token,
25            websocket: None,
26        }
27    }
28
29
30    pub async fn run<S>(&mut self, event_handler: S)
31    where
32        S: EventHandler + Send + Sync + 'static,
33    {
34        let (websocket, handle) = WebSocket::connect(Box::new(event_handler), self.token.clone()).await;
35
36        self.websocket = Some(websocket);
37
38
39        // This pauses the main function until the WebSocket disconnects or crashes.
40        // If the WS dies, this line finishes, and the program can exit (or restart).
41        handle.await.unwrap();
42
43        println!("The WebSocket task has stopped. Bot is shutting down.");
44    }
45}
46#[derive(Clone)]
47pub struct ClientCache {
48    pub users: Cache<String, User>,
49    pub channels: Cache<String, Channel>,
50    pub messages: Cache<String, Message>,
51}
52
53impl ClientCache {
54    pub fn new() -> Self {
55        Self {
56            users: Cache::builder()
57                .max_capacity(10_000)
58                .build(),
59
60            channels: Cache::builder()
61                .max_capacity(1_000)
62                .build(),
63
64            messages: Cache::builder()
65                .max_capacity(5_000)
66                .build(),
67        }
68    }
69    pub(crate) async fn hydrate(&self, ready: &Ready) {
70        for user in &ready.users {
71            self.users.insert(user.id.clone(), user.clone()).await;
72        }
73
74        for channel in &ready.channels {
75            self.channels.insert(channel.id().to_string(), channel.clone()).await;
76        }
77
78        for _server in &ready.servers {
79
80        }
81    }
82    /// Efficiently removes a list of messages from the cache.
83    pub(crate) async fn remove_messages(&self, message_ids: Vec<String>) {
84        for id in message_ids {
85            // Moka's invalidate is fast and thread-safe
86            self.messages.invalidate(&id).await;
87        }
88    }
89}