use crate::errors::AudDError;
use crate::http::BareHttpClient;
use crate::retry::{RetryClass, RetryPolicy};
use crate::streams::{spawn_longpoll, LongpollDriver, LongpollPoll};
const LONGPOLL_URL: &str = "https://api.audd.io/longpoll/";
#[derive(Debug, Clone)]
pub struct LongpollConsumerBuilder {
category: String,
max_attempts: u32,
backoff_factor: f64,
reqwest_client: Option<reqwest::Client>,
base_url: String,
}
impl LongpollConsumerBuilder {
fn new(category: impl Into<String>) -> Self {
Self {
category: category.into(),
max_attempts: 3,
backoff_factor: 0.5,
reqwest_client: None,
base_url: LONGPOLL_URL.to_string(),
}
}
#[must_use]
pub fn max_attempts(mut self, n: u32) -> Self {
self.max_attempts = n;
self
}
#[must_use]
pub fn backoff_factor(mut self, f: f64) -> Self {
self.backoff_factor = f;
self
}
#[must_use]
pub fn reqwest_client(mut self, client: reqwest::Client) -> Self {
self.reqwest_client = Some(client);
self
}
#[must_use]
pub fn base_url(mut self, url: impl Into<String>) -> Self {
self.base_url = url.into();
self
}
pub fn build(self) -> Result<LongpollConsumer, AudDError> {
let http = if let Some(c) = self.reqwest_client {
BareHttpClient::from_client(c)
} else {
BareHttpClient::new()?
};
Ok(LongpollConsumer {
category: self.category,
http,
policy: RetryPolicy::new(RetryClass::Read)
.with_max_attempts(self.max_attempts)
.with_backoff_factor(self.backoff_factor),
url: self.base_url,
})
}
}
#[derive(Debug, Clone)]
pub struct LongpollConsumer {
category: String,
http: BareHttpClient,
policy: RetryPolicy,
url: String,
}
#[derive(Debug, Clone)]
pub struct LongpollIterateOptions {
pub since_time: Option<i64>,
pub timeout: i64,
}
impl Default for LongpollIterateOptions {
fn default() -> Self {
Self {
since_time: None,
timeout: 50,
}
}
}
impl LongpollConsumer {
#[must_use]
pub fn new(category: impl Into<String>) -> Self {
Self::builder(category)
.build()
.expect("default reqwest::Client should build")
}
pub fn builder(category: impl Into<String>) -> LongpollConsumerBuilder {
LongpollConsumerBuilder::new(category)
}
#[must_use]
pub fn iterate(&self, opts: LongpollIterateOptions) -> LongpollPoll {
spawn_longpoll(LongpollDriver::Tokenless {
http: self.http.clone(),
url: self.url.clone(),
policy: self.policy,
category: self.category.clone(),
since_time: opts.since_time,
timeout: opts.timeout,
})
}
pub fn close(self) {
drop(self);
}
}