1use std::{
2 fs::{self, File},
3 io::Write,
4 path::{Path, PathBuf},
5 time::{Duration, SystemTime, UNIX_EPOCH},
6};
7
8use sha256::digest;
9use url::Url;
10
11use crate::{errors::DevrcResult, loader::LoadingConfig};
12
13const DEVRC_CACHE_DIR_NAME: &str = "devrc";
14
15pub fn get_cache_path() -> Option<PathBuf> {
17 dirs_next::cache_dir().map(|path| Path::new(&path).join(DEVRC_CACHE_DIR_NAME))
18}
19
20pub fn get_file_cache_meta(url: &Url) -> Option<PathBuf> {
21 let hash = digest(url.as_str());
22 get_cache_path().map(|path| path.join(format!("{:}.cache", hash)))
23}
24
25#[derive(Debug, Default)]
26pub struct Cache {}
27
28pub fn save(url: &Url, content: &str) -> DevrcResult<()> {
29 if let Some(file) = get_file_cache_meta(url) {
30 if let Some(dir) = file.parent() {
31 if !dir.exists() {
32 fs::create_dir_all(dir)?;
33 }
34 }
35
36 let mut f = File::create(file)?;
37 f.write_all(content.as_bytes())?;
38 }
39 Ok(())
40}
41
42pub fn load(
43 url: &Url,
44 _loading_config: &LoadingConfig,
45 _checksum: Option<&str>,
46 ttl: &Duration,
47) -> Option<String> {
48 if let Some(file) = get_file_cache_meta(url) {
49 if !file.exists() {
50 return None;
51 }
52
53 if let Ok(modified) = fs::metadata(&file).ok()?.modified() {
54 let now_timestamp = SystemTime::now().duration_since(UNIX_EPOCH).ok()?;
55 let created_timestamp = modified.duration_since(UNIX_EPOCH).ok()?;
56
57 let duration = now_timestamp - created_timestamp;
58
59 if duration < *ttl {
60 return fs::read_to_string(file).ok();
61 }
62 }
63 }
64 None
65}