use std::fmt;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;
use crate::downloads::store::{DownloadConflict, DownloadNamer, DownloadValidator};
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum DownloadEvent {
Started,
Completed,
Failed,
Cancelled,
}
impl DownloadEvent {
pub fn as_str(&self) -> &'static str {
match self {
Self::Started => "started",
Self::Completed => "completed",
Self::Failed => "failed",
Self::Cancelled => "cancelled",
}
}
}
impl fmt::Display for DownloadEvent {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DownloadArtifact {
pub id: String,
pub url: Option<String>,
pub suggested_filename: Option<String>,
pub state: DownloadEvent,
pub started_at: String,
pub completed_at: Option<String>,
pub path: Option<PathBuf>,
pub mime_type: Option<String>,
pub bytes: Option<u64>,
pub checksum: Option<String>,
pub failure: Option<String>,
}
#[derive(Clone, Default)]
pub struct CaptureOptions {
pub filename: Option<DownloadNamer>,
pub timeout: Option<Duration>,
pub validate: Option<DownloadValidator>,
pub conflict: Option<DownloadConflict>,
}
impl CaptureOptions {
pub fn named(name: impl Into<String>) -> Self {
let name = name.into();
Self {
filename: Some(Arc::new(move |_naming| name.clone())),
..Self::default()
}
}
pub fn within(mut self, timeout: Duration) -> Self {
self.timeout = Some(timeout);
self
}
pub fn validated_by(mut self, validate: DownloadValidator) -> Self {
self.validate = Some(validate);
self
}
pub fn on_conflict(mut self, conflict: DownloadConflict) -> Self {
self.conflict = Some(conflict);
self
}
}
impl fmt::Debug for CaptureOptions {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("CaptureOptions")
.field("filename", &self.filename.is_some())
.field("timeout", &self.timeout)
.field("validate", &self.validate.is_some())
.field("conflict", &self.conflict)
.finish()
}
}
#[derive(Clone)]
pub struct DownloadOptions {
pub directory: Option<String>,
pub persist: bool,
pub conflict: DownloadConflict,
pub filename: Option<DownloadNamer>,
pub validate: Option<DownloadValidator>,
pub poll_interval: Option<Duration>,
}
impl Default for DownloadOptions {
fn default() -> Self {
Self {
directory: None,
persist: true,
conflict: DownloadConflict::default(),
filename: None,
validate: None,
poll_interval: None,
}
}
}
impl DownloadOptions {
pub fn directory(mut self, directory: impl Into<String>) -> Self {
self.directory = Some(directory.into());
self
}
pub fn conflict(mut self, conflict: DownloadConflict) -> Self {
self.conflict = conflict;
self
}
pub fn filename(mut self, filename: DownloadNamer) -> Self {
self.filename = Some(filename);
self
}
pub fn validate(mut self, validate: DownloadValidator) -> Self {
self.validate = Some(validate);
self
}
pub fn poll_interval(mut self, interval: Duration) -> Self {
self.poll_interval = Some(interval);
self
}
}
impl fmt::Debug for DownloadOptions {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DownloadOptions")
.field("directory", &self.directory)
.field("persist", &self.persist)
.field("conflict", &self.conflict)
.field("filename", &self.filename.is_some())
.field("validate", &self.validate.is_some())
.field("poll_interval", &self.poll_interval)
.finish()
}
}