Skip to main content

relay_actions/cache/
mod.rs

1mod 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}