pacenotes_installer\restore/
point.rs1pub type Snapshot = std::collections::BTreeMap<String, crate::ledger::LedgerEntry>;
3
4#[derive(Clone, Debug, PartialEq, Eq)]
6pub struct Point {
7 pub name: String,
8 pub snapshot: Snapshot,
10}
11
12pub fn points(game_dir: &std::path::Path) -> Vec<Point> {
19 let dir = game_dir
20 .join(crate::ledger::STATE_DIR)
21 .join(crate::engine::RESTORE_DIR);
22 let Ok(entries) = std::fs::read_dir(&dir) else {
23 return Vec::new();
24 };
25 let mut found: Vec<Point> = entries
26 .flatten()
27 .filter(|entry| entry.path().is_dir())
28 .filter_map(|entry| read(game_dir, &entry.file_name().to_string_lossy()))
29 .collect();
30 found.sort_by(|a, b| b.name.cmp(&a.name));
31 found
32}
33
34pub fn read(game_dir: &std::path::Path, name: &str) -> Option<Point> {
36 let path = crate::engine::snapshot_path(game_dir, name);
37 let snapshot = crate::ledger::Ledger::read_snapshot(&path)?;
38 Some(Point {
39 name: name.to_string(),
40 snapshot,
41 })
42}
43
44pub fn human_time(point: &str) -> String {
50 let stem = point.split('Z').next().unwrap_or(point);
51 let Some((date, time)) = stem.split_once('T') else {
52 return point.to_string();
53 };
54 let mut parts = time.split('-');
55 match (parts.next(), parts.next()) {
56 (Some(hours), Some(minutes)) if date.len() == 10 => format!("{date} {hours}:{minutes}"),
57 _ => point.to_string(),
58 }
59}
60
61pub fn payloads_in_use(game_dir: &std::path::Path) -> Option<Vec<String>> {
69 let ledger = crate::ledger::Ledger::open(game_dir);
70 if ledger.state() == crate::ledger::LedgerState::Unreadable {
71 return None;
72 }
73 let points = points(game_dir);
74 let directories = std::fs::read_dir(
76 game_dir
77 .join(crate::ledger::STATE_DIR)
78 .join(crate::engine::RESTORE_DIR),
79 )
80 .map_or(0, |entries| {
81 entries
82 .flatten()
83 .filter(|entry| entry.path().is_dir())
84 .count()
85 });
86 if points.len() != directories {
87 return None;
88 }
89 let snapshots = points.iter().flat_map(|point| point.snapshot.values());
90 Some(
91 ledger
92 .packages()
93 .values()
94 .chain(snapshots)
95 .map(|entry| entry.sha256.clone())
96 .collect(),
97 )
98}