pub(super) fn rows(page: &str, heading: &str) -> Vec<Vec<String>> {
let path = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.join("../../docs")
.join(page);
let doc = std::fs::read_to_string(&path)
.unwrap_or_else(|e| panic!("reading {}: {e}", path.display()));
let after = doc
.split_once(heading)
.unwrap_or_else(|| panic!("{} carries no heading {heading:?}", path.display()))
.1;
let mut rows: Vec<Vec<String>> = Vec::new();
let mut in_table = false;
for line in after.lines() {
let line = line.trim();
if !line.starts_with('|') {
if in_table {
break;
}
continue;
}
in_table = true;
if line.contains("---") {
rows.clear();
continue;
}
rows.push(
line.trim_matches('|')
.split('|')
.map(|c| c.trim().trim_matches('*').trim().to_string())
.collect(),
);
}
assert!(
!rows.is_empty(),
"{} has no table under {heading:?}",
path.display()
);
rows
}
pub(super) fn assert_value(page: &str, cell: &str, code: f64, what: &str) {
let text = cell
.trim_matches('`')
.rsplit('≈')
.next()
.expect("a cell")
.trim()
.replace(['\u{202f}', ' '], "")
.replace("dp/s", "")
.replace("dp", "")
.replace("ms", "")
.replace("µs", "")
.replace("samples", "")
.replace("m/s²", "")
.replace("Hz", "")
.replace('`', "");
let decimals = text.split_once('.').map_or(0, |(_, frac)| frac.len());
assert_eq!(
format!("{code:.decimals$}"),
text,
"docs/{page} says {what} is {cell:?}; the code says {code}"
);
}