use async_trait::async_trait;
use std::sync::Arc;
use tokio::sync::RwLock;
use wacore_binary::Jid;
use whatsapp_rust::client::Client;
#[async_trait]
pub trait WhatsAppGateway: Send + Sync {
async fn check_phones(&self, phones: Vec<String>) -> Result<Vec<bool>, String>;
async fn statuses(&self, phones: Vec<String>) -> Result<Vec<Option<String>>, String>;
}
pub struct GatewayImpl {
client: RwLock<Option<Arc<Client>>>,
}
#[async_trait]
impl WhatsAppGateway for GatewayImpl {
async fn check_phones(&self, phones: Vec<String>) -> Result<Vec<bool>, String> {
let guard = self.client.read().await;
let client = guard.as_ref().expect("client").clone();
drop(guard);
let jids: Vec<Jid> = phones.iter().map(|p| Jid::pn(p.as_str())).collect();
let results = client
.contacts()
.is_on_whatsapp(&jids)
.await
.map_err(|e| e.to_string())?;
Ok(results.into_iter().map(|r| r.is_registered).collect())
}
async fn statuses(&self, phones: Vec<String>) -> Result<Vec<Option<String>>, String> {
let guard = self.client.read().await;
let client = guard.as_ref().expect("client").clone();
drop(guard);
let jids: Vec<Jid> = phones.iter().map(|p| Jid::pn(p.as_str())).collect();
let info = client
.contacts()
.get_user_info(&jids)
.await
.map_err(|e| e.to_string())?;
Ok(jids
.iter()
.map(|jid| info.get(jid).and_then(|i| i.status.clone()))
.collect())
}
}
#[test]
fn async_trait_consumers_compile() {
fn assert_impl<T: WhatsAppGateway>() {}
assert_impl::<GatewayImpl>();
}