use std::collections::BTreeMap;
use super::coverpoint::Coverage;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Score {
pub percent: f64,
pub covered: u64,
pub total: u64,
pub contributes: bool,
}
pub fn empty_score(weight: i64) -> Score {
Score {
percent: if weight != 0 { 0.0 } else { 100.0 },
covered: 0,
total: 0,
contributes: false,
}
}
pub fn item_score(weight: i64, cov: Coverage) -> Score {
match cov.percent() {
Some(percent) => Score {
percent,
covered: cov.covered,
total: cov.total,
contributes: true,
},
None => empty_score(weight),
}
}
pub fn weighted_score(weight: i64, parts: &[(i64, Score)]) -> Score {
let mut num = 0.0f64;
let mut den = 0.0f64;
let mut covered = 0u64;
let mut total = 0u64;
for (w, s) in parts.iter().filter(|(_, s)| s.contributes) {
num += *w as f64 * s.percent;
den += *w as f64;
covered = covered.saturating_add(s.covered);
total = total.saturating_add(s.total);
}
if den == 0.0 {
return empty_score(weight);
}
Score {
percent: num / den,
covered,
total,
contributes: true,
}
}
pub fn merge_bins(views: &[(u64, Vec<(String, u64)>)]) -> Coverage {
let at_least = views.iter().map(|(a, _)| *a).max().unwrap_or(1);
let mut union: BTreeMap<&str, u64> = BTreeMap::new();
for (_, bins) in views {
for (name, hits) in bins {
let h = union.entry(name.as_str()).or_insert(0);
*h = h.saturating_add(*hits);
}
}
Coverage {
covered: union.values().filter(|&&h| h >= at_least).count() as u64,
total: union.len() as u64,
}
}