winbrew_app\operations\update/
planner.rs1use anyhow::Result;
2
3use crate::models::catalog::CatalogMetadata;
4
5use super::metadata::metadata_url_for_snapshot_url;
6use super::types::{CatalogDownloadPlan, CatalogUpdateMode, CatalogUpdateResponse};
7
8pub(super) fn plan_catalog_download(
23 local_metadata: Option<&CatalogMetadata>,
24 selection: CatalogUpdateResponse,
25) -> Result<Option<CatalogDownloadPlan>> {
26 match selection.mode {
27 CatalogUpdateMode::Current => {
28 let current_hash = if selection.current.trim().is_empty() {
29 selection.target.clone()
30 } else {
31 selection.current.clone()
32 };
33
34 if current_hash.trim().is_empty() {
35 return Ok(None);
36 }
37
38 let target_hash = if selection.target.trim().is_empty() {
39 current_hash.clone()
40 } else {
41 selection.target
42 };
43
44 Ok(Some(CatalogDownloadPlan::Current {
45 current_hash,
46 target_hash,
47 }))
48 }
49 CatalogUpdateMode::Full => {
50 if selection.target.trim().is_empty() {
51 return Ok(None);
52 }
53
54 let catalog_url = match selection.snapshot {
55 Some(snapshot) if !snapshot.trim().is_empty() => snapshot,
56 _ => return Ok(None),
57 };
58
59 let metadata_url = metadata_url_for_snapshot_url(&catalog_url)?;
60
61 Ok(Some(CatalogDownloadPlan::Full {
62 catalog_url,
63 metadata_url,
64 expected_hash: Some(selection.target),
65 }))
66 }
67 CatalogUpdateMode::Patch => {
68 if selection.target.trim().is_empty() {
69 return Ok(None);
70 }
71
72 let local_metadata = match local_metadata {
73 Some(metadata) => metadata,
74 None => return Ok(None),
75 };
76
77 if local_metadata.current_hash != selection.current {
78 return Ok(None);
79 }
80
81 if selection.patches.is_empty()
82 || selection.patches.iter().any(|url| url.trim().is_empty())
83 {
84 return Ok(None);
85 }
86
87 Ok(Some(CatalogDownloadPlan::Patch {
88 patch_urls: selection.patches,
89 expected_hash: selection.target,
90 }))
91 }
92 }
93}