use futures::TryStreamExt;
use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};
use tokio::io::{AsyncRead, ReadBuf};
pub enum DownloadStream {
Http(Box<dyn AsyncRead + Send + Unpin>),
}
impl AsyncRead for DownloadStream {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut ReadBuf<'_>,
) -> Poll<std::io::Result<()>> {
match &mut *self {
DownloadStream::Http(stream) => Pin::new(stream).poll_read(cx, buf),
}
}
}
pub type ProgressCallback = Arc<dyn Fn(u64, u64) + Send + Sync>;
#[derive(Debug, Clone, PartialEq)]
pub enum OverwriteBehavior {
Prompt,
Force,
NeverOverwrite,
}
impl Default for OverwriteBehavior {
fn default() -> Self {
Self::Prompt
}
}
pub struct DownloadOptions {
pub progress: Option<ProgressCallback>,
pub buffer_size: usize,
pub max_connections: usize,
pub overwrite: OverwriteBehavior,
}
impl Default for DownloadOptions {
fn default() -> Self {
Self {
progress: None,
buffer_size: 64 * 1024, max_connections: 16,
overwrite: OverwriteBehavior::default(),
}
}
}
pub fn create_http_stream(response: reqwest::Response) -> DownloadStream {
let stream = Box::new(tokio_util::io::StreamReader::new(
response.bytes_stream().map_err(std::io::Error::other),
));
DownloadStream::Http(stream)
}