use crate::compiler::model::{
COLLECTOR_VERSION, COMPILER_DIAG_CACHE_VERSION, CompilerDiagCacheFile, CompilerDiagEntry, CompilerDiagKey,
};
use crate::error::RailResult;
use std::path::{Path, PathBuf};
pub struct CompilerDiagnosticsStore {
path: PathBuf,
cache: CompilerDiagCacheFile,
dirty: bool,
}
impl CompilerDiagnosticsStore {
pub fn load(workspace_root: &Path) -> Self {
let path = workspace_root
.join("target")
.join("cargo-rail")
.join("cache")
.join("compiler-diags-v1.json");
let cache = std::fs::read_to_string(&path)
.ok()
.and_then(|raw| serde_json::from_str::<CompilerDiagCacheFile>(&raw).ok())
.filter(|file| file.version == COMPILER_DIAG_CACHE_VERSION)
.unwrap_or_default();
Self {
path,
cache,
dirty: false,
}
}
pub fn get(&self, key: &CompilerDiagKey) -> Option<&CompilerDiagEntry> {
self
.cache
.entries
.get(&key.stable_id())
.filter(|entry| entry.collector_version == COLLECTOR_VERSION)
}
pub fn put(&mut self, entry: CompilerDiagEntry) {
let id = entry.key.stable_id();
self.cache.entries.insert(id, entry);
self.dirty = true;
}
pub fn flush(&mut self) -> RailResult<()> {
if !self.dirty {
return Ok(());
}
if let Some(parent) = self.path.parent() {
std::fs::create_dir_all(parent)?;
}
let json = serde_json::to_string(&self.cache)?;
std::fs::write(&self.path, json)?;
self.dirty = false;
Ok(())
}
}