Skip to main content

whatsapp_rust/features/
blocking.rs

1//! Blocking feature for managing blocked contacts.
2//!
3//! This module provides high-level APIs for blocking and unblocking contacts.
4//! Protocol-level types are defined in `wacore::iq::blocklist`.
5
6use crate::client::Client;
7use crate::request::IqError;
8use log::debug;
9pub use wacore::iq::blocklist::BlocklistEntry;
10use wacore::iq::blocklist::{GetBlocklistSpec, UpdateBlocklistSpec};
11use wacore_binary::jid::Jid;
12
13/// Feature handle for blocklist operations.
14pub struct Blocking<'a> {
15    client: &'a Client,
16}
17
18impl<'a> Blocking<'a> {
19    pub(crate) fn new(client: &'a Client) -> Self {
20        Self { client }
21    }
22
23    /// Block a contact.
24    pub async fn block(&self, jid: &Jid) -> Result<(), IqError> {
25        debug!(target: "Blocking", "Blocking contact: {}", jid);
26        self.client.execute(UpdateBlocklistSpec::block(jid)).await?;
27        debug!(target: "Blocking", "Successfully blocked contact: {}", jid);
28        Ok(())
29    }
30
31    /// Unblock a contact.
32    pub async fn unblock(&self, jid: &Jid) -> Result<(), IqError> {
33        debug!(target: "Blocking", "Unblocking contact: {}", jid);
34        self.client
35            .execute(UpdateBlocklistSpec::unblock(jid))
36            .await?;
37        debug!(target: "Blocking", "Successfully unblocked contact: {}", jid);
38        Ok(())
39    }
40
41    /// Get the full blocklist.
42    pub async fn get_blocklist(&self) -> anyhow::Result<Vec<BlocklistEntry>> {
43        debug!(target: "Blocking", "Fetching blocklist...");
44        let entries = self.client.execute(GetBlocklistSpec).await?;
45        debug!(target: "Blocking", "Fetched {} blocked contacts", entries.len());
46        Ok(entries)
47    }
48
49    /// Check if a contact is blocked.
50    ///
51    /// Compares only the user part of the JID, ignoring device ID,
52    /// since blocking applies to the entire user account, not individual devices.
53    pub async fn is_blocked(&self, jid: &Jid) -> anyhow::Result<bool> {
54        let blocklist = self.get_blocklist().await?;
55        Ok(blocklist.iter().any(|e| e.jid.user == jid.user))
56    }
57}
58
59impl Client {
60    /// Access blocking operations.
61    pub fn blocking(&self) -> Blocking<'_> {
62        Blocking::new(self)
63    }
64}