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 pub by_url: HashMap<String, CacheEntry>,
9 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