use std::collections::BTreeMap;
use std::path::{Path, PathBuf};
use varar_core::hash::hash_source;
use varar_core::result::{ExampleResult, OathResults, ReferencedDocument, 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>>,
documents: BTreeMap<String, BTreeMap<String, String>>,
}
impl Results {
pub fn new() -> Results {
Results::default()
}
pub fn record(
&mut self,
oath_path: &str,
source: &str,
result: ExampleResult,
referenced_sources: &BTreeMap<String, String>,
) {
self.sources
.entry(oath_path.to_string())
.or_insert_with(|| source.to_string());
self.examples
.entry(oath_path.to_string())
.or_default()
.push(result);
if !referenced_sources.is_empty() {
self.documents
.entry(oath_path.to_string())
.or_default()
.extend(
referenced_sources
.iter()
.map(|(k, v)| (k.clone(), v.clone())),
);
}
}
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 documents = self
.documents
.get(&oath_path)
.map(|docs| {
docs.iter()
.map(|(path, text)| ReferencedDocument {
path: path.clone(),
source_hash: hash_source(text),
})
.collect()
})
.unwrap_or_default();
let results = OathResults {
version: 2,
oath_path: oath_path.clone(),
source_hash: hash_source(source),
documents,
examples,
};
let _ = write_oath_results(root, &results);
}
}
}