immich_lib/models/
execution.rs1use std::path::PathBuf;
7
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, Clone)]
12pub struct ExecutionConfig {
13 pub requests_per_sec: u32,
15
16 pub max_concurrent: usize,
18
19 pub backup_dir: PathBuf,
21
22 pub force_delete: bool,
24}
25
26impl Default for ExecutionConfig {
27 fn default() -> Self {
28 Self {
29 requests_per_sec: 10,
30 max_concurrent: 5,
31 backup_dir: PathBuf::from("./backups"),
32 force_delete: false,
33 }
34 }
35}
36
37#[derive(Debug, Clone, Serialize)]
39#[serde(tag = "status", rename_all = "snake_case")]
40pub enum OperationResult {
41 Success {
43 id: String,
45 #[serde(skip_serializing_if = "Option::is_none")]
47 path: Option<PathBuf>,
48 },
49
50 Failed {
52 id: String,
54 error: String,
56 },
57
58 Skipped {
60 id: String,
62 reason: String,
64 },
65}
66
67#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct ConsolidationResult {
72 pub gps_transferred: bool,
74
75 pub datetime_transferred: bool,
77
78 pub description_transferred: bool,
80
81 #[serde(skip_serializing_if = "Option::is_none")]
83 pub source_asset_id: Option<String>,
84}
85
86impl ConsolidationResult {
87 pub fn any_transferred(&self) -> bool {
89 self.gps_transferred || self.datetime_transferred || self.description_transferred
90 }
91}
92
93#[derive(Debug, Clone, Serialize)]
95pub struct GroupResult {
96 pub duplicate_id: String,
98
99 pub winner_id: String,
101
102 #[serde(skip_serializing_if = "Option::is_none")]
104 pub consolidation_result: Option<ConsolidationResult>,
105
106 pub download_results: Vec<OperationResult>,
108
109 #[serde(skip_serializing_if = "Option::is_none")]
111 pub delete_result: Option<OperationResult>,
112}
113
114#[derive(Debug, Clone, Serialize)]
116pub struct ExecutionReport {
117 pub total_groups: usize,
119
120 pub downloaded: usize,
122
123 pub deleted: usize,
125
126 pub failed: usize,
128
129 pub skipped: usize,
131
132 pub results: Vec<GroupResult>,
134}
135
136impl ExecutionReport {
137 pub fn new() -> Self {
139 Self {
140 total_groups: 0,
141 downloaded: 0,
142 deleted: 0,
143 failed: 0,
144 skipped: 0,
145 results: Vec::new(),
146 }
147 }
148
149 pub fn add_group_result(&mut self, result: GroupResult) {
151 self.total_groups += 1;
152
153 for download in &result.download_results {
155 match download {
156 OperationResult::Success { .. } => self.downloaded += 1,
157 OperationResult::Failed { .. } => self.failed += 1,
158 OperationResult::Skipped { .. } => self.skipped += 1,
159 }
160 }
161
162 if let Some(ref delete) = result.delete_result {
164 match delete {
165 OperationResult::Success { .. } => {
166 self.deleted += result
168 .download_results
169 .iter()
170 .filter(|r| matches!(r, OperationResult::Success { .. }))
171 .count();
172 }
173 OperationResult::Failed { .. } => self.failed += 1,
174 OperationResult::Skipped { .. } => self.skipped += 1,
175 }
176 }
177
178 self.results.push(result);
179 }
180}
181
182impl Default for ExecutionReport {
183 fn default() -> Self {
184 Self::new()
185 }
186}