whatsapp_rust/features/
chatstate.rs1use crate::client::Client;
2use log::debug;
3use wacore_binary::builder::NodeBuilder;
4use wacore_binary::jid::Jid;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum ChatStateType {
8 Composing,
9
10 Recording,
11
12 Paused,
13}
14
15impl ChatStateType {
16 fn as_str(&self) -> &'static str {
17 match self {
18 ChatStateType::Composing => "composing",
19 ChatStateType::Recording => "recording",
20 ChatStateType::Paused => "paused",
21 }
22 }
23}
24
25impl std::fmt::Display for ChatStateType {
26 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27 write!(f, "{}", self.as_str())
28 }
29}
30
31pub struct Chatstate<'a> {
32 client: &'a Client,
33}
34
35impl<'a> Chatstate<'a> {
36 pub(crate) fn new(client: &'a Client) -> Self {
37 Self { client }
38 }
39
40 pub async fn send(
41 &self,
42 to: &Jid,
43 state: ChatStateType,
44 ) -> Result<(), crate::client::ClientError> {
45 debug!(target: "Chatstate", "Sending {} to {}", state, to);
46
47 let node = self.build_chatstate_node(to, state);
48 self.client.send_node(node).await
49 }
50
51 pub async fn send_composing(&self, to: &Jid) -> Result<(), crate::client::ClientError> {
52 self.send(to, ChatStateType::Composing).await
53 }
54
55 pub async fn send_recording(&self, to: &Jid) -> Result<(), crate::client::ClientError> {
56 self.send(to, ChatStateType::Recording).await
57 }
58
59 pub async fn send_paused(&self, to: &Jid) -> Result<(), crate::client::ClientError> {
60 self.send(to, ChatStateType::Paused).await
61 }
62
63 fn build_chatstate_node(&self, to: &Jid, state: ChatStateType) -> wacore_binary::node::Node {
64 let child = match state {
65 ChatStateType::Composing => NodeBuilder::new("composing").build(),
66 ChatStateType::Recording => {
67 NodeBuilder::new("composing").attr("media", "audio").build()
68 }
69 ChatStateType::Paused => NodeBuilder::new("paused").build(),
70 };
71
72 NodeBuilder::new("chatstate")
73 .attr("to", to.to_string())
74 .children([child])
75 .build()
76 }
77}
78
79impl Client {
80 pub fn chatstate(&self) -> Chatstate<'_> {
81 Chatstate::new(self)
82 }
83}
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn test_chat_state_type_display() {
91 assert_eq!(ChatStateType::Composing.to_string(), "composing");
92 assert_eq!(ChatStateType::Recording.to_string(), "recording");
93 assert_eq!(ChatStateType::Paused.to_string(), "paused");
94 }
95
96 #[test]
97 fn test_chat_state_type_as_str() {
98 assert_eq!(ChatStateType::Composing.as_str(), "composing");
99 assert_eq!(ChatStateType::Recording.as_str(), "recording");
100 assert_eq!(ChatStateType::Paused.as_str(), "paused");
101 }
102}