pacenotes_installer\cache/
index.rs1const INDEX_VERSION: u32 = 1;
3
4#[derive(serde::Serialize, serde::Deserialize, Default)]
5struct Index {
6 #[serde(default)]
8 version: u32,
9 #[serde(default)]
10 packages: std::collections::BTreeMap<String, crate::tree::CachedPackage>,
11}
12
13#[derive(Clone, Copy, PartialEq, Eq, Debug)]
16pub enum IndexState {
17 Missing,
18 Unreadable,
20 Loaded,
21}
22
23pub struct Cache {
24 pub(super) root: std::path::PathBuf,
25 index: Index,
26 pub(super) state: IndexState,
27}
28
29impl Cache {
30 pub fn open(root: impl Into<std::path::PathBuf>) -> Cache {
33 let root = root.into();
34 let (index, state) = match std::fs::read(root.join(super::INDEX_FILE)) {
35 Err(_) => (Index::default(), IndexState::Missing),
36 Ok(bytes) => match serde_json::from_slice::<Index>(&bytes) {
37 Ok(index) if index.version <= INDEX_VERSION => (index, IndexState::Loaded),
38 Ok(_) | Err(_) => (Index::default(), IndexState::Unreadable),
39 },
40 };
41 Cache { root, index, state }
42 }
43
44 pub fn index_state(&self) -> IndexState {
45 self.state
46 }
47
48 pub fn root(&self) -> &std::path::Path {
49 &self.root
50 }
51
52 pub fn get(&self, key: &str) -> Option<&crate::tree::CachedPackage> {
53 self.index.packages.get(key)
54 }
55
56 pub fn entries(&self) -> Vec<crate::tree::CachedPackage> {
58 self.index
59 .packages
60 .values()
61 .filter(|entry| self.has_payload(&entry.sha256))
62 .cloned()
63 .collect()
64 }
65
66 pub(super) fn names(&self, sha256: &str) -> bool {
68 self.index
69 .packages
70 .values()
71 .any(|entry| entry.sha256 == sha256)
72 }
73
74 pub(super) fn known_digests(&self) -> std::collections::BTreeSet<&str> {
75 self.index
76 .packages
77 .values()
78 .map(|entry| entry.sha256.as_str())
79 .collect()
80 }
81
82 pub fn insert(&mut self, package: crate::tree::CachedPackage) -> std::io::Result<()> {
84 self.index.packages.insert(package.key(), package);
85 self.save()
86 }
87
88 pub fn remove(&mut self, key: &str) -> std::io::Result<()> {
89 self.index.packages.remove(key);
90 self.save()
91 }
92
93 pub fn save(&mut self) -> std::io::Result<()> {
96 self.index.version = INDEX_VERSION;
97 std::fs::create_dir_all(&self.root)?;
98 let json = serde_json::to_vec_pretty(&self.index)
99 .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))?;
100
101 let temp = self.root.join(format!("{}.tmp", super::INDEX_FILE));
102 std::fs::write(&temp, &json)?;
103 std::fs::rename(&temp, self.root.join(super::INDEX_FILE))?;
104 self.state = IndexState::Loaded;
105 Ok(())
106 }
107}