relay_actions/cache/
mod.rs1mod agent;
2mod records;
3
4pub use agent::{AgentsCache, CachedAgent};
5pub use records::{CachedRecord, RecordsCache};
6
7use std::path::{Path, PathBuf};
8
9pub trait Cache: Default {
10 fn load(base: &Path) -> anyhow::Result<Self>
11 where
12 Self: Sized;
13 fn save(&self, base: &Path) -> anyhow::Result<()>;
14
15 fn verify(&mut self) -> anyhow::Result<()> {
16 Ok(())
17 }
18 fn cleanup(&mut self) -> anyhow::Result<()> {
19 Ok(())
20 }
21}
22
23pub struct CacheManager {
24 base: PathBuf,
25
26 pub agents: AgentsCache,
27 pub records: RecordsCache,
28}
29
30impl CacheManager {
31 pub fn init() -> anyhow::Result<Self> {
32 let base = dirs::cache_dir()
33 .unwrap_or_else(|| PathBuf::from("."))
34 .join("relay");
35
36 let mut manager = Self {
37 base,
38 agents: AgentsCache::default(),
39 records: RecordsCache::default(),
40 };
41
42 manager.load()?;
43
44 Ok(manager)
45 }
46
47 pub fn load(&mut self) -> anyhow::Result<()> {
48 self.agents = Self::load_cache::<AgentsCache>(&self.base)?;
49 self.records = Self::load_cache::<RecordsCache>(&self.base)?;
50 Ok(())
51 }
52
53 pub fn save(&mut self) -> anyhow::Result<()> {
54 Self::save_cache(&self.base, &mut self.agents)?;
55 Self::save_cache(&self.base, &mut self.records)?;
56 Ok(())
57 }
58
59 pub fn purge(&mut self) -> anyhow::Result<()> {
60 std::fs::remove_dir_all(&self.base)?;
61 self.load()?;
62 Ok(())
63 }
64
65 pub fn base(&self) -> &PathBuf {
66 &self.base
67 }
68
69 fn load_cache<T: Cache>(base: &Path) -> anyhow::Result<T> {
70 let mut cache = T::load(base)?;
71 cache.verify()?;
72 cache.cleanup()?;
73 Ok(cache)
74 }
75
76 fn save_cache<T: Cache>(base: &Path, cache: &mut T) -> anyhow::Result<()> {
77 if let Some(parent) = base.parent() {
78 std::fs::create_dir_all(parent)?;
79 }
80
81 cache.verify()?;
82 cache.cleanup()?;
83 cache.save(base)?;
84 Ok(())
85 }
86}