Skip to main content

filthy_rich/
client.rs

1use std::sync::{
2    Arc,
3    atomic::{AtomicBool, Ordering},
4};
5use tokio::sync::mpsc::Sender;
6
7use crate::Activity;
8use crate::types::IPCCommand;
9
10/// A client handle for controlling Discord IPC.
11#[derive(Debug, Clone)]
12pub struct DiscordIPCClient {
13    pub(crate) tx: Sender<IPCCommand>,
14    pub(crate) client_id: String,
15    pub(crate) running: Arc<AtomicBool>,
16}
17
18impl DiscordIPCClient {
19    /// Returns the client ID.
20    pub fn client_id(&self) -> String {
21        self.client_id.clone()
22    }
23
24    /// Checks if the task is running.
25    pub fn is_running(&self) -> bool {
26        self.running.load(Ordering::SeqCst)
27    }
28
29    /// Sets/updates the Discord Rich presence activity.
30    /// The runner must be started before calling this.
31    pub async fn set_activity(&self, activity: Activity) -> Result<(), anyhow::Error> {
32        if !self.is_running() {
33            anyhow::bail!("Call .run() before .set_activity() execution.");
34        }
35
36        self.tx.send(IPCCommand::SetActivity { activity }).await?;
37        Ok(())
38    }
39
40    /// Clears a previously set Discord Rich Presence activity.
41    pub async fn clear_activity(&self) -> Result<(), anyhow::Error> {
42        if self.is_running() {
43            self.tx.send(IPCCommand::ClearActivity).await?;
44        }
45
46        Ok(())
47    }
48
49    /// Closes the current connection if any.
50    pub async fn close(&self) -> Result<(), anyhow::Error> {
51        if self.is_running() {
52            let _ = self.tx.send(IPCCommand::Close).await;
53        }
54
55        Ok(())
56    }
57}