#![allow(clippy::missing_panics_doc)]
use std::fs;
use std::path::{Path, PathBuf};
fn workspace_root() -> PathBuf {
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let mut cur = manifest_dir;
for _ in 0..8 {
if let Ok(text) = fs::read_to_string(cur.join("Cargo.toml")) {
if text.contains("[workspace]") {
return cur;
}
}
if !cur.pop() {
break;
}
}
panic!("could not locate workspace root");
}
fn extract_md_links(src: &str) -> Vec<String> {
let bytes = src.as_bytes();
let mut out: Vec<String> = Vec::new();
let mut i = 0usize;
while i < bytes.len() {
if bytes[i] == b']' && i + 1 < bytes.len() && bytes[i + 1] == b'(' {
let start = i + 2;
let mut end = start;
while end < bytes.len() && bytes[end] != b')' && bytes[end] != b'\n' {
end += 1;
}
if end < bytes.len() && bytes[end] == b')' {
let raw = &src[start..end];
let path = raw.split('#').next().unwrap_or(raw).trim();
if !path.is_empty()
&& !path.starts_with("http://")
&& !path.starts_with("https://")
&& !path.starts_with("mailto:")
&& !path.starts_with('/')
&& std::path::Path::new(path)
.extension()
.is_some_and(|ext| ext.eq_ignore_ascii_case("md"))
{
out.push(path.to_owned());
}
i = end + 1;
continue;
}
}
i += 1;
}
out
}
fn resolve(from_dir: &Path, link: &str) -> PathBuf {
let mut out: PathBuf = from_dir.to_path_buf();
for segment in link.split('/') {
match segment {
"" | "." => {}
".." => {
out.pop();
}
other => out.push(other),
}
}
out
}
#[test]
fn every_intra_docs_md_link_resolves() {
let root = workspace_root();
let docs = root.join("docs");
assert!(docs.is_dir(), "docs/ must exist at workspace root");
let mut failures: Vec<String> = Vec::new();
let entries = fs::read_dir(&docs).expect("read_dir docs/");
for entry in entries {
let entry = entry.expect("dir entry");
let path = entry.path();
if path.extension().and_then(|s| s.to_str()) != Some("md") {
continue;
}
let text =
fs::read_to_string(&path).unwrap_or_else(|e| panic!("read {}: {e}", path.display()));
let links = extract_md_links(&text);
for link in links {
let resolved = resolve(path.parent().expect("parent"), &link);
if !resolved.exists() {
failures.push(format!(
"{}: link `{}` resolves to missing file `{}`",
path.file_name().and_then(|s| s.to_str()).unwrap_or("?"),
link,
resolved.display(),
));
}
}
}
assert!(
failures.is_empty(),
"broken intra-docs links:\n{}",
failures.join("\n")
);
}