Skip to main content

sarpro/io/
cache.rs

1use std::collections::HashMap;
2use std::fs;
3use std::path::{Path, PathBuf};
4
5#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Default)]
6pub struct CacheIndex {
7    // Keys: remote_url
8    pub by_url: HashMap<String, CacheEntry>,
9    // Keys: provider:key (e.g., "cdse:uuid")
10    pub by_alias: HashMap<String, CacheEntry>,
11}
12
13#[derive(Debug, serde::Serialize, serde::Deserialize, Clone)]
14pub struct CacheEntry {
15    pub local_path: PathBuf,
16    pub etag: Option<String>,
17    pub content_length: Option<u64>,
18}
19
20pub fn index_path(cache_dir: &Path) -> PathBuf {
21    cache_dir.join(".index.json")
22}
23
24pub fn load_index(cache_dir: &Path) -> CacheIndex {
25    let p = index_path(cache_dir);
26    match fs::read(&p) {
27        Ok(bytes) => serde_json::from_slice(&bytes).unwrap_or_default(),
28        Err(_) => CacheIndex::default(),
29    }
30}
31
32pub fn save_index(cache_dir: &Path, idx: &CacheIndex) {
33    let p = index_path(cache_dir);
34    if let Ok(bytes) = serde_json::to_vec_pretty(idx) {
35        let _ = fs::write(p, bytes);
36    }
37}
38
39pub fn put_url(idx: &mut CacheIndex, url: &str, entry: CacheEntry) {
40    idx.by_url.insert(url.to_string(), entry);
41}
42
43pub fn put_alias(idx: &mut CacheIndex, provider: &str, key: &str, entry: CacheEntry) {
44    idx.by_alias.insert(format!("{}:{}", provider, key), entry);
45}
46
47pub fn get_url<'a>(idx: &'a CacheIndex, url: &str) -> Option<&'a CacheEntry> {
48    idx.by_url.get(url)
49}
50
51pub fn get_alias<'a>(idx: &'a CacheIndex, provider: &str, key: &str) -> Option<&'a CacheEntry> {
52    idx.by_alias.get(&format!("{}:{}", provider, key))
53}
54
55