use url::Url;
use crate::backend::Backend;
use crate::client::download::DownloadResponse;
pub struct BackgroundDownloadBuilder {
backend: Backend,
url: Url,
session_identifier: Option<String>,
file_path: Option<std::path::PathBuf>,
progress_callback: Option<Box<dyn Fn(u64, Option<u64>) + Send + Sync + 'static>>,
}
impl BackgroundDownloadBuilder {
pub(crate) fn new(backend: Backend, url: Url) -> Self {
Self {
backend,
url,
session_identifier: None,
file_path: None,
progress_callback: None,
}
}
pub fn session_identifier(mut self, identifier: impl Into<String>) -> Self {
self.session_identifier = Some(identifier.into());
self
}
pub fn to_file<P: AsRef<std::path::Path>>(mut self, path: P) -> Self {
self.file_path = Some(path.as_ref().to_path_buf());
self
}
pub fn progress<F>(mut self, callback: F) -> Self
where
F: Fn(u64, Option<u64>) + Send + Sync + 'static,
{
self.progress_callback = Some(Box::new(callback));
self
}
pub async fn send(self) -> crate::Result<DownloadResponse> {
let file_path = self.file_path.clone().ok_or_else(|| {
crate::Error::Internal("Background download file path not specified".to_string())
})?;
if let Some(parent) = file_path.parent() {
std::fs::create_dir_all(parent).map_err(|e| {
crate::Error::Internal(format!("Failed to create parent directory: {}", e))
})?;
}
self.backend
.execute_background_download(
self.url,
file_path,
self.session_identifier,
self.progress_callback,
)
.await
}
}