report.rs
3.0 kB · rust · 103 lines
1use crate::ledger::Book;2use crate::registry::Verdict;3use std::collections::HashSet;45pub struct Run {6 pub key: &'static str,7 pub outcome: Option<Result<(), String>>,8}910#[derive(Default)]11pub struct Sheet {12 rows: usize,13 parts: usize,14 untagged: usize,15 witnessless: usize,16 tags: [usize; 4],17 counts: [usize; 5],18 failures: Vec<(String, String)>,19 orphans: Vec<String>,20 missing: Vec<String>,21}2223impl Sheet {24 pub fn count(&self, verdict: Verdict) -> usize {25 self.counts[verdict as usize]26 }2728 fn record(&mut self, verdict: Verdict, key: &str, why: &str) {29 self.counts[verdict as usize] += 1;30 match verdict {31 Verdict::Failed => self.failures.push((key.to_string(), why.to_string())),32 Verdict::Orphan => self.orphans.push(key.to_string()),33 Verdict::Unchecked => self.missing.push(key.to_string()),34 _ => {}35 }36 }37}3839// TALLY4041pub fn tally(book: &Book, runs: &[Run]) -> Sheet {42 let mut sheet = Sheet {43 rows: book.rows.len(),44 parts: book.parts,45 untagged: book.untagged,46 witnessless: book47 .rows48 .iter()49 .filter(|row| row.witnesses.is_empty())50 .count(),51 ..Sheet::default()52 };53 for row in &book.rows {54 sheet.tags[row.tag as usize] += 1;55 }56 let claimed: HashSet<&str> = book.rows.iter().map(|row| row.key.as_str()).collect();57 let run: HashSet<&str> = runs.iter().map(|entry| entry.key).collect();58 for entry in runs {59 let (verdict, why) = match (claimed.contains(entry.key), &entry.outcome) {60 (false, _) => (Verdict::Orphan, String::new()),61 (true, None) => (Verdict::Skipped, String::new()),62 (true, Some(Ok(()))) => (Verdict::Checked, String::new()),63 (true, Some(Err(why))) => (Verdict::Failed, why.clone()),64 };65 sheet.record(verdict, entry.key, &why);66 }67 for row in &book.rows {68 if !run.contains(row.key.as_str()) {69 sheet.record(Verdict::Unchecked, &row.key, "");70 }71 }72 sheet73}7475// DASHBOARD7677pub fn print(sheet: &Sheet) {78 println!(79 "LEDGER {} rows in {} parts, {} untagged, {} witnessless",80 sheet.rows, sheet.parts, sheet.untagged, sheet.witnessless81 );82 println!(83 "TAGS {} proved, {} verified, {} conjecture, {} refuted",84 sheet.tags[0], sheet.tags[1], sheet.tags[2], sheet.tags[3]85 );86 println!(87 "CLAIMS {} checked, {} failed, {} unchecked, {} skipped, {} orphan",88 sheet.count(Verdict::Checked),89 sheet.count(Verdict::Failed),90 sheet.count(Verdict::Unchecked),91 sheet.count(Verdict::Skipped),92 sheet.count(Verdict::Orphan)93 );94 for (key, why) in &sheet.failures {95 println!("FAILED {key}: {why}");96 }97 for key in &sheet.orphans {98 println!("ORPHAN {key}");99 }100 for key in sheet.missing.iter().take(10) {101 println!("UNCHECKED {key}");102 }103}