const MIN_RECOVERY_RATIO: f64 = 0.98;
#[derive(Debug, Clone, Default, PartialEq)]
pub struct ConversionReport {
pub pages: usize,
pub extracted_words: usize,
pub rendered_words: usize,
pub extracted_chars: usize,
pub rendered_chars: usize,
pub headings_found: usize,
pub lists_found: usize,
pub tables_found: usize,
pub citations_found: usize,
}
impl ConversionReport {
pub fn recovery_ratio(&self) -> f64 {
if self.extracted_chars == 0 {
return 1.0;
}
self.rendered_chars as f64 / self.extracted_chars as f64
}
pub fn word_recovery_ratio(&self) -> f64 {
if self.extracted_words == 0 {
return 1.0;
}
self.rendered_words as f64 / self.extracted_words as f64
}
pub fn passes(&self) -> bool {
self.recovery_ratio() >= MIN_RECOVERY_RATIO
}
}
impl std::fmt::Display for ConversionReport {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
writeln!(f, "Pages: {}", self.pages)?;
writeln!(f)?;
writeln!(f, "Recovery (characters, authoritative for PASS/FAIL):")?;
writeln!(f, " Extracted: {} chars", self.extracted_chars)?;
writeln!(f, " Rendered: {} chars", self.rendered_chars)?;
writeln!(f, " Ratio: {:.1}%", self.recovery_ratio() * 100.0)?;
writeln!(f)?;
writeln!(f, "Words (informational only, not authoritative -- see kopitiam-wwr):")?;
writeln!(f, " Extracted: {}", self.extracted_words)?;
writeln!(f, " Rendered: {}", self.rendered_words)?;
writeln!(f)?;
writeln!(f, "Headings: {}", self.headings_found)?;
writeln!(f, "Lists: {}", self.lists_found)?;
writeln!(f, "Tables: {}", self.tables_found)?;
writeln!(f, "Citations: {}", self.citations_found)?;
writeln!(f)?;
write!(f, "Status: {}", if self.passes() { "PASS" } else { "FAIL" })
}
}