use anyhow::{Context, Result};
use std::path::Path;
use rustledger_loader::{
CacheEntry, CachedOptions, CachedPlugin, LoadResult, Loader, cache_disabled_by_env,
load_cache_entry, reintern_directives, save_cache_entry,
};
pub fn load_result_cached(
file: &Path,
no_cache: bool,
verbose: bool,
) -> Result<(LoadResult, bool)> {
let cache_disabled = no_cache || cache_disabled_by_env();
let cache_entry = if cache_disabled {
None
} else {
load_cache_entry(file)
};
if let Some(mut entry) = cache_entry {
if verbose {
eprintln!("Loaded {} directives from cache", entry.directives.len());
}
let dedup_count = reintern_directives(&mut entry.directives);
if verbose {
eprintln!("Re-interned strings ({dedup_count} deduplicated)");
}
return Ok((entry.into_load_result(), true));
}
if verbose {
eprintln!("Loading {}...", file.display());
}
let mut loader = Loader::new();
let result = loader
.load(file)
.with_context(|| format!("failed to load {}", file.display()))?;
if !cache_disabled && result.errors.is_empty() && result.options.warnings.is_empty() {
let files: Vec<String> = result
.source_map
.files()
.iter()
.map(|f| f.path.to_string_lossy().into_owned())
.collect();
let files = if files.is_empty() {
vec![file.to_string_lossy().into_owned()]
} else {
files
};
let entry = CacheEntry {
directives: result.directives.clone(),
options: CachedOptions::from(&result.options),
plugins: result
.plugins
.iter()
.map(|p| CachedPlugin {
name: p.name.clone(),
config: p.config.clone(),
force_python: p.force_python,
})
.collect(),
files,
};
if let Err(e) = save_cache_entry(file, &entry) {
if verbose {
eprintln!("Warning: failed to save cache: {e}");
}
} else if verbose {
eprintln!("Saved {} directives to cache", result.directives.len());
}
}
Ok((result, false))
}