Skip to main content

filthy_rich/
client.rs

1use tokio::sync::{mpsc::Sender, oneshot};
2
3use crate::{
4    errors::PresenceClientError,
5    types::{Activity, IPCCommand},
6};
7
8/// A client handle for communicating with [`super::PresenceRunner`] and its inner loop.
9#[derive(Debug, Clone)]
10pub struct PresenceClient {
11    pub(crate) tx: Sender<IPCCommand>,
12    pub(crate) client_id: String,
13}
14
15impl PresenceClient {
16    /// Returns the client ID.
17    #[must_use]
18    pub fn client_id(&self) -> String {
19        self.client_id.clone()
20    }
21
22    /// Sets/updates the Discord Rich presence activity.
23    /// The runner must be started before calling this.
24    pub async fn set_activity(&self, activity: Activity) -> Result<(), PresenceClientError> {
25        self.tx
26            .send(IPCCommand::SetActivity {
27                activity: Box::new(activity),
28            })
29            .await
30            .map_err(|_| PresenceClientError::ActivitySendError)?;
31
32        Ok(())
33    }
34
35    /// Clears a previously set Discord Rich Presence activity.
36    pub async fn clear_activity(&self) -> Result<(), PresenceClientError> {
37        self.tx
38            .send(IPCCommand::ClearActivity)
39            .await
40            .map_err(|_| PresenceClientError::ActivitySendError)?;
41
42        Ok(())
43    }
44
45    /// Closes the current connection if any.
46    pub async fn close(&self) -> Result<(), PresenceClientError> {
47        let (done_tx, done_rx) = oneshot::channel::<()>();
48
49        if self
50            .tx
51            .send(IPCCommand::Close { done: done_tx })
52            .await
53            .is_err()
54        {
55            return Ok(());
56        }
57
58        done_rx.await?;
59
60        Ok(())
61    }
62}