use std::path::PathBuf;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone)]
pub struct ExecutionConfig {
pub requests_per_sec: u32,
pub max_concurrent: usize,
pub backup_dir: PathBuf,
pub force_delete: bool,
}
impl Default for ExecutionConfig {
fn default() -> Self {
Self {
requests_per_sec: 10,
max_concurrent: 5,
backup_dir: PathBuf::from("./backups"),
force_delete: false,
}
}
}
#[derive(Debug, Clone, Serialize)]
#[serde(tag = "status", rename_all = "snake_case")]
pub enum OperationResult {
Success {
id: String,
#[serde(skip_serializing_if = "Option::is_none")]
path: Option<PathBuf>,
},
Failed {
id: String,
error: String,
},
Skipped {
id: String,
reason: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConsolidationResult {
pub gps_transferred: bool,
pub datetime_transferred: bool,
pub description_transferred: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_asset_id: Option<String>,
}
impl ConsolidationResult {
pub fn any_transferred(&self) -> bool {
self.gps_transferred || self.datetime_transferred || self.description_transferred
}
}
#[derive(Debug, Clone, Serialize)]
pub struct GroupResult {
pub duplicate_id: String,
pub winner_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub consolidation_result: Option<ConsolidationResult>,
pub download_results: Vec<OperationResult>,
#[serde(skip_serializing_if = "Option::is_none")]
pub delete_result: Option<OperationResult>,
}
#[derive(Debug, Clone, Serialize)]
pub struct ExecutionReport {
pub total_groups: usize,
pub downloaded: usize,
pub deleted: usize,
pub failed: usize,
pub skipped: usize,
pub results: Vec<GroupResult>,
}
impl ExecutionReport {
pub fn new() -> Self {
Self {
total_groups: 0,
downloaded: 0,
deleted: 0,
failed: 0,
skipped: 0,
results: Vec::new(),
}
}
pub fn add_group_result(&mut self, result: GroupResult) {
self.total_groups += 1;
for download in &result.download_results {
match download {
OperationResult::Success { .. } => self.downloaded += 1,
OperationResult::Failed { .. } => self.failed += 1,
OperationResult::Skipped { .. } => self.skipped += 1,
}
}
if let Some(ref delete) = result.delete_result {
match delete {
OperationResult::Success { .. } => {
self.deleted += result
.download_results
.iter()
.filter(|r| matches!(r, OperationResult::Success { .. }))
.count();
}
OperationResult::Failed { .. } => self.failed += 1,
OperationResult::Skipped { .. } => self.skipped += 1,
}
}
self.results.push(result);
}
}
impl Default for ExecutionReport {
fn default() -> Self {
Self::new()
}
}