romm_api/core/download/
extras_job.rs1use std::sync::atomic::{AtomicUsize, Ordering};
4
5use crate::core::extras::DownloadAssetKind;
6
7#[derive(Debug, Clone)]
9pub struct ExtrasItemResult {
10 pub title: String,
11 pub kind: DownloadAssetKind,
12 pub ok: bool,
13 pub error: Option<String>,
14}
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18pub enum ExtrasJobStatus {
19 Running,
20 Done,
21 PartialFailure(usize),
23 AllFailed,
24}
25
26#[derive(Debug, Clone)]
28pub struct ExtrasJob {
29 pub id: usize,
30 pub rom_id: u64,
31 pub name: String,
32 pub platform: String,
33 pub completed_items: usize,
34 pub total_items: usize,
35 pub status: ExtrasJobStatus,
36 pub item_results: Vec<ExtrasItemResult>,
37}
38
39static NEXT_EXTRAS_JOB_ID: AtomicUsize = AtomicUsize::new(0);
40
41impl ExtrasJob {
42 pub fn new(rom_id: u64, name: String, platform: String, total_items: usize) -> Self {
43 Self {
44 id: NEXT_EXTRAS_JOB_ID.fetch_add(1, Ordering::Relaxed),
45 rom_id,
46 name,
47 platform,
48 completed_items: 0,
49 total_items,
50 status: ExtrasJobStatus::Running,
51 item_results: Vec::new(),
52 }
53 }
54
55 pub fn percent(&self) -> u16 {
57 if self.total_items == 0 {
58 return 100;
59 }
60 ((self.completed_items.saturating_mul(100)) / self.total_items).min(100) as u16
61 }
62}
63
64pub(crate) fn finalize_extras_job_status(results: &[ExtrasItemResult]) -> ExtrasJobStatus {
65 let n = results.len();
66 if n == 0 {
67 return ExtrasJobStatus::Done;
68 }
69 let failures = results.iter().filter(|r| !r.ok).count();
70 if failures == 0 {
71 ExtrasJobStatus::Done
72 } else if failures == n {
73 ExtrasJobStatus::AllFailed
74 } else {
75 ExtrasJobStatus::PartialFailure(failures)
76 }
77}