use std::pin::Pin;
use std::sync::atomic::AtomicU64;
use std::time::Duration;
use async_trait::async_trait;
use futures::io::AsyncRead;
use secrecy::SecretBox;
use url::Url;
use zeroize::Zeroize;
#[cfg(feature = "reqwest")]
mod reqwest;
use crate::error::Result;
use crate::protocol::commands::{Request, Response};
use crate::utils::rsa::RsaPrivateKey;
#[derive(Debug, Clone, Zeroize)]
pub struct UserSession {
pub(crate) sid: String,
pub(crate) key: [u8; 16],
pub(crate) sek: [u8; 16],
pub(crate) privk: RsaPrivateKey,
pub(crate) user_handle: String,
}
#[derive(Debug)]
pub struct ClientState {
pub(crate) origin: Url,
pub(crate) max_retries: usize,
pub(crate) min_retry_delay: Duration,
pub(crate) max_retry_delay: Duration,
pub(crate) timeout: Option<Duration>,
pub(crate) https: bool,
pub(crate) id_counter: AtomicU64,
pub(crate) session: Option<SecretBox<UserSession>>,
}
#[async_trait]
pub trait HttpClient: Send + Sync {
async fn send_requests(
&self,
state: &ClientState,
requests: &[Request],
query_params: &[(&str, &str)],
) -> Result<Vec<Response>>;
async fn get(&self, url: Url) -> Result<Pin<Box<dyn AsyncRead + Send>>>;
async fn post(
&self,
url: Url,
body: Pin<Box<dyn AsyncRead + Send + Sync>>,
content_length: Option<u64>,
) -> Result<Pin<Box<dyn AsyncRead + Send>>>;
}