use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use varar_core::hash::hash_source;
use varar_core::result::{ExampleResult, OathResults, to_wire_json};
pub fn result_file_path(root: &Path, oath_path: &str) -> PathBuf {
root.join(".varar").join(format!("{oath_path}.json"))
}
pub fn write_oath_results(root: &Path, results: &OathResults) -> std::io::Result<PathBuf> {
let out = result_file_path(root, &results.oath_path);
if let Some(parent) = out.parent() {
std::fs::create_dir_all(parent)?;
}
std::fs::write(&out, format!("{}\n", to_wire_json(results)))?;
Ok(out)
}
fn document_order(examples: &mut [ExampleResult]) {
examples.sort_by(|a, b| {
let line = |e: &ExampleResult| e.lines.first().copied().unwrap_or(0);
line(a).cmp(&line(b)).then_with(|| a.name.cmp(&b.name))
});
}
#[derive(Default)]
pub struct Results {
sources: BTreeMap<String, String>,
examples: BTreeMap<String, Vec<ExampleResult>>,
}
impl Results {
pub fn new() -> Results {
Results::default()
}
pub fn record(&mut self, oath_path: &str, source: &str, result: ExampleResult) {
self.sources
.entry(oath_path.to_string())
.or_insert_with(|| source.to_string());
self.examples
.entry(oath_path.to_string())
.or_default()
.push(result);
}
pub fn flush_all(&mut self, root: &Path) {
for (oath_path, mut examples) in std::mem::take(&mut self.examples) {
let Some(source) = self.sources.get(&oath_path) else {
continue;
};
document_order(&mut examples);
let results = OathResults {
version: 1,
oath_path: oath_path.clone(),
source_hash: hash_source(source),
examples,
};
let _ = write_oath_results(root, &results);
}
}
}