use super::{ClaimCoverage, ClaimExercise, CoverageRefusal, Exercise, RunReport};
use crate::descriptor::{ClaimRef, TablePosture};
type Tally = (ClaimRef, usize, usize);
pub fn claim_coverage(report: &RunReport) -> Result<ClaimCoverage, CoverageRefusal> {
match report.posture() {
TablePosture::Authored => {}
TablePosture::Staged { parent } => {
return Err(CoverageRefusal::StagedPosture { parent });
}
}
let mut tallies: Vec<Tally> = Vec::new();
for entry in report.census() {
let exercise = entry.disposition().exercise();
let claim = entry.claim();
match tallies.iter_mut().find(|tally| tally.0 == claim) {
Some(tally) => counted_into(tally, exercise),
None => tallies.push(opened(claim, exercise)),
}
}
Ok(ClaimCoverage::read(
tallies
.into_iter()
.map(|(claim, exercised, unexercised)| {
ClaimExercise::counted(claim, exercised, unexercised)
})
.collect(),
))
}
fn opened(claim: ClaimRef, exercise: Exercise) -> Tally {
match exercise {
Exercise::Exercised => (claim, 1usize, 0usize),
Exercise::Unexercised => (claim, 0usize, 1usize),
}
}
fn counted_into(tally: &mut Tally, exercise: Exercise) {
match exercise {
Exercise::Exercised => tally.1 = tally.1.saturating_add(1),
Exercise::Unexercised => tally.2 = tally.2.saturating_add(1),
}
}