use std::num::NonZeroUsize;
use std::ops::Range;
use std::time::Duration;
use educe::Educe;
use tokio_util::sync::CancellationToken;
pub(crate) type ProgressFn<S> = Box<dyn FnMut(&S, StreamState, &CancellationToken) + Send + Sync>;
pub(crate) type ReconnectFn<S> = Box<dyn FnMut(&S, &CancellationToken) + Send + Sync>;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub enum StreamPhase {
#[non_exhaustive]
Prefetching {
target: u64,
chunk_size: usize,
},
#[non_exhaustive]
Downloading {
chunk_size: usize,
},
Complete,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[non_exhaustive]
pub struct StreamState {
pub current_position: u64,
pub elapsed: Duration,
pub phase: StreamPhase,
pub current_chunk: Range<u64>,
}
#[derive(Educe)]
#[educe(Debug, PartialEq, Eq)]
pub struct Settings<S> {
pub(crate) prefetch_bytes: u64,
pub(crate) batch_write_size: usize,
pub(crate) retry_timeout: Duration,
pub(crate) cancel_on_drop: bool,
#[educe(Debug = false, PartialEq = false)]
pub(crate) on_progress: Option<ProgressFn<S>>,
#[educe(Debug = false, PartialEq = false)]
pub(crate) on_reconnect: Option<ReconnectFn<S>>,
}
impl<S> Default for Settings<S> {
fn default() -> Self {
Self {
prefetch_bytes: 256 * 1024,
batch_write_size: 4096,
retry_timeout: Duration::from_secs(5),
cancel_on_drop: true,
on_progress: None,
on_reconnect: None,
}
}
}
impl<S> Settings<S> {
#[must_use]
pub fn prefetch_bytes(self, prefetch_bytes: u64) -> Self {
Self {
prefetch_bytes,
..self
}
}
pub fn batch_write_size(self, batch_write_size: NonZeroUsize) -> Self {
Self {
batch_write_size: batch_write_size.get(),
..self
}
}
#[must_use]
pub fn retry_timeout(self, retry_timeout: Duration) -> Self {
Self {
retry_timeout,
..self
}
}
#[must_use]
pub fn cancel_on_drop(self, cancel_on_drop: bool) -> Self {
Self {
cancel_on_drop,
..self
}
}
#[must_use]
pub fn on_progress<F>(mut self, f: F) -> Self
where
F: FnMut(&S, StreamState, &CancellationToken) + Send + Sync + 'static,
{
self.on_progress = Some(Box::new(f));
self
}
#[must_use]
pub fn on_reconnect<F>(mut self, f: F) -> Self
where
F: FnMut(&S, &CancellationToken) + Send + Sync + 'static,
{
self.on_reconnect = Some(Box::new(f));
self
}
pub const fn get_prefetch_bytes(&self) -> u64 {
self.prefetch_bytes
}
pub const fn get_write_batch_size(&self) -> usize {
self.batch_write_size
}
}
#[cfg(feature = "reqwest-middleware")]
impl Settings<crate::http::HttpStream<::reqwest_middleware::ClientWithMiddleware>> {
pub fn add_default_middleware<M>(middleware: M)
where
M: reqwest_middleware::Middleware,
{
crate::http::reqwest_middleware_client::add_default_middleware(middleware);
}
}