candle_graph/
analysis_cache.rs1use std::path::{Path, PathBuf};
7
8use anyhow::{Context, Result};
9
10use crate::model_ir::ModelIr;
11
12pub fn cache_enabled(explicit: bool) -> bool {
13 explicit || std::env::var("CANDLE_GRAPH_CACHE")
14 .map(|value| matches!(value.as_str(), "1" | "true" | "yes"))
15 .unwrap_or(false)
16}
17
18pub fn cache_dir() -> PathBuf {
19 std::env::var("CANDLE_GRAPH_CACHE_DIR")
20 .map(PathBuf::from)
21 .or_else(|_| {
22 std::env::var("XDG_CACHE_HOME")
23 .map(|home| PathBuf::from(home).join("candle-graph"))
24 .or_else(|_| std::env::var("HOME").map(|home| PathBuf::from(home).join(".cache/candle-graph")))
25 })
26 .unwrap_or_else(|_| PathBuf::from("/tmp/candle-graph-cache"))
27}
28
29pub fn cache_path(analysis_id: &str) -> PathBuf {
30 let safe = analysis_id
31 .chars()
32 .map(|c| if c.is_ascii_alphanumeric() { c } else { '_' })
33 .collect::<String>();
34 cache_dir().join(format!("{safe}.json"))
35}
36
37pub fn load(path: &Path) -> Result<Option<ModelIr>> {
38 if !path.is_file() {
39 return Ok(None);
40 }
41 let text = std::fs::read_to_string(path)
42 .with_context(|| format!("reading analysis cache {}", path.display()))?;
43 let model: ModelIr =
44 serde_json::from_str(&text).context("parsing cached model IR")?;
45 Ok(Some(model))
46}
47
48pub fn save(path: &Path, model: &ModelIr) -> Result<()> {
49 if let Some(parent) = path.parent() {
50 std::fs::create_dir_all(parent)
51 .with_context(|| format!("creating cache dir {}", parent.display()))?;
52 }
53 let text = serde_json::to_string(model).context("serializing model IR for cache")?;
54 std::fs::write(path, text).with_context(|| format!("writing analysis cache {}", path.display()))?;
55 Ok(())
56}