use std::collections::HashMap;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SkipReason {
EmptyBody,
BindingOnlyTail,
MissingResolution,
BindingSlotLookupMissing,
PatternSlotShortfall,
BuiltinCtorConstruction,
BuiltinCtorPattern,
UnresolvedCtor,
UnsupportedCallee,
BuiltinRecord,
UnsupportedTry,
UnsupportedTailCall,
UnsupportedList,
UnsupportedTuple,
UnsupportedMap,
UnsupportedInterpolatedStr,
UnsupportedIndependentProduct,
UnresolvedIdent,
UnsupportedOther,
}
impl SkipReason {
pub fn label(self) -> &'static str {
match self {
Self::EmptyBody => "empty body",
Self::BindingOnlyTail => "binding-only tail",
Self::MissingResolution => "missing resolution",
Self::BindingSlotLookupMissing => "binding slot lookup missing",
Self::PatternSlotShortfall => "pattern slot shortfall",
Self::BuiltinCtorConstruction => "built-in ctor construction",
Self::BuiltinCtorPattern => "built-in ctor pattern",
Self::UnresolvedCtor => "unresolved ctor",
Self::UnsupportedCallee => "unsupported callee",
Self::BuiltinRecord => "built-in record type",
Self::UnsupportedTry => "unsupported Try (`?`)",
Self::UnsupportedTailCall => "unsupported tail call",
Self::UnsupportedList => "unsupported list literal",
Self::UnsupportedTuple => "unsupported tuple literal",
Self::UnsupportedMap => "unsupported map literal",
Self::UnsupportedInterpolatedStr => "unsupported interpolated string",
Self::UnsupportedIndependentProduct => "unsupported IndependentProduct",
Self::UnresolvedIdent => "unresolved Ident (resolver gap)",
Self::UnsupportedOther => "unsupported (other)",
}
}
}
#[derive(Debug, Clone, Default)]
pub struct LowerStats {
pub lowered: u32,
pub skipped: HashMap<SkipReason, u32>,
}
impl LowerStats {
pub fn total(&self) -> u32 {
self.lowered + self.skipped.values().sum::<u32>()
}
pub fn coverage_ratio(&self) -> f64 {
let total = self.total();
if total == 0 {
return 1.0;
}
f64::from(self.lowered) / f64::from(total)
}
pub fn record_lowered(&mut self) {
self.lowered += 1;
}
pub fn record_skip(&mut self, reason: SkipReason) {
*self.skipped.entry(reason).or_insert(0) += 1;
}
pub fn skipped_sorted(&self) -> Vec<(SkipReason, u32)> {
let mut entries: Vec<_> = self.skipped.iter().map(|(r, c)| (*r, *c)).collect();
entries.sort_by_key(|(r, _)| *r as u8);
entries
}
}