use anyhow::Result;
use async_trait::async_trait;
use bytes::Bytes;
use std::collections::HashMap;
use std::sync::Arc;
pub const WHATSAPP_WEB_WS_URL: &str = "wss://web.whatsapp.com/ws/chat";
#[derive(Debug, Clone)]
pub enum TransportEvent {
Connected,
DataReceived(Bytes),
Disconnected,
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait Transport: Send + Sync {
async fn send(&self, data: Bytes) -> Result<(), anyhow::Error>;
async fn disconnect(&self);
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait TransportFactory: Send + Sync {
async fn create_transport(
&self,
) -> Result<(Arc<dyn Transport>, async_channel::Receiver<TransportEvent>), anyhow::Error>;
}
#[derive(Debug, Clone)]
pub struct HttpRequest {
pub url: String,
pub method: String, pub headers: HashMap<String, String>,
pub body: Option<Vec<u8>>,
}
impl HttpRequest {
pub fn get(url: impl Into<String>) -> Self {
Self {
url: url.into(),
method: "GET".to_string(),
headers: HashMap::new(),
body: None,
}
}
pub fn post(url: impl Into<String>) -> Self {
Self {
url: url.into(),
method: "POST".to_string(),
headers: HashMap::new(),
body: None,
}
}
pub fn with_header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.headers.insert(key.into(), value.into());
self
}
pub fn with_body(mut self, body: Vec<u8>) -> Self {
self.body = Some(body);
self
}
}
#[derive(Debug, Clone)]
pub struct HttpResponse {
pub status_code: u16,
pub body: Vec<u8>,
}
impl HttpResponse {
pub fn body_string(&self) -> Result<String> {
Ok(String::from_utf8(self.body.clone())?)
}
}
pub struct StreamingHttpResponse {
pub status_code: u16,
pub body: Box<dyn std::io::Read + Send>,
}
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait HttpClient: Send + Sync {
async fn execute(&self, request: HttpRequest) -> Result<HttpResponse>;
fn supports_streaming(&self) -> bool {
false
}
fn execute_streaming(&self, _request: HttpRequest) -> Result<StreamingHttpResponse> {
Err(anyhow::anyhow!(
"Streaming not supported by this HTTP client"
))
}
}