Skip to main content

mutiny_rs/
client.rs

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