butterfly_dl/core/
stream.rs

1//! Streaming implementations for butterfly-dl
2//!
3//! Provides AsyncRead implementations for different download sources.
4
5use futures::TryStreamExt;
6use std::pin::Pin;
7use std::sync::Arc;
8use std::task::{Context, Poll};
9use tokio::io::{AsyncRead, ReadBuf};
10
11/// A unified stream for HTTP sources
12pub enum DownloadStream {
13    /// HTTP stream using reqwest
14    Http(Box<dyn AsyncRead + Send + Unpin>),
15}
16
17impl AsyncRead for DownloadStream {
18    fn poll_read(
19        mut self: Pin<&mut Self>,
20        cx: &mut Context<'_>,
21        buf: &mut ReadBuf<'_>,
22    ) -> Poll<std::io::Result<()>> {
23        match &mut *self {
24            DownloadStream::Http(stream) => Pin::new(stream).poll_read(cx, buf),
25        }
26    }
27}
28
29/// Progress callback function type
30pub type ProgressCallback = Arc<dyn Fn(u64, u64) + Send + Sync>;
31
32/// Overwrite behavior for existing files
33#[derive(Debug, Clone, PartialEq)]
34pub enum OverwriteBehavior {
35    /// Prompt user for confirmation (default)
36    Prompt,
37    /// Force overwrite without prompting
38    Force,
39    /// Never overwrite, fail if file exists
40    NeverOverwrite,
41}
42
43impl Default for OverwriteBehavior {
44    fn default() -> Self {
45        Self::Prompt
46    }
47}
48
49/// Options for download operations
50pub struct DownloadOptions {
51    /// Optional progress callback
52    pub progress: Option<ProgressCallback>,
53
54    /// Buffer size for streaming operations
55    pub buffer_size: usize,
56
57    /// Maximum number of parallel connections for HTTP downloads
58    pub max_connections: usize,
59
60    /// Behavior when destination file already exists
61    pub overwrite: OverwriteBehavior,
62}
63
64impl Default for DownloadOptions {
65    fn default() -> Self {
66        Self {
67            progress: None,
68            buffer_size: 64 * 1024, // 64KB
69            max_connections: 16,
70            overwrite: OverwriteBehavior::default(),
71        }
72    }
73}
74
75/// Creates a DownloadStream from an HTTP response
76pub fn create_http_stream(response: reqwest::Response) -> DownloadStream {
77    let stream = Box::new(tokio_util::io::StreamReader::new(
78        response.bytes_stream().map_err(std::io::Error::other),
79    ));
80    DownloadStream::Http(stream)
81}