use std::fs;
use std::path::{Path, PathBuf};
const FORBIDDEN_CONSUMER_NAMES: &[&str] = &["surgec", "gossan", "keyhog", "warpscan", "pyrograph"];
#[test]
fn source_docs_are_consumer_neutral() {
let root = Path::new(env!("CARGO_MANIFEST_DIR"));
let mut files = Vec::new();
collect_rust_sources(&root.join("src"), &mut files);
files.sort();
let mut violations = Vec::new();
for file in files {
let source = fs::read_to_string(&file)
.unwrap_or_else(|error| panic!("{} must be readable: {error}", file.display()));
for (line_index, line) in source.lines().enumerate() {
let trimmed = line.trim_start();
let is_doc_or_comment = trimmed.starts_with("//!")
|| trimmed.starts_with("///")
|| trimmed.starts_with("// ")
|| trimmed.starts_with("/*")
|| trimmed.starts_with('*');
if !is_doc_or_comment {
continue;
}
let lower = trimmed.to_ascii_lowercase();
for forbidden in FORBIDDEN_CONSUMER_NAMES {
if lower.contains(forbidden) {
violations.push(format!(
"{}:{} names downstream consumer `{}`",
file.strip_prefix(root).unwrap_or(&file).display(),
line_index + 1,
forbidden
));
}
}
}
}
assert!(
violations.is_empty(),
"Weir source docs must stay dataflow-generic; consumer-specific names belong in consumer integration tests/evidence:\n{}",
violations.join("\n")
);
}
fn collect_rust_sources(path: &Path, out: &mut Vec<PathBuf>) {
if path.is_file() {
if path.extension().is_some_and(|extension| extension == "rs") {
out.push(path.to_path_buf());
}
return;
}
if !path.is_dir() {
return;
}
for entry in fs::read_dir(path)
.unwrap_or_else(|error| panic!("{} must be readable: {error}", path.display()))
{
let path = entry
.unwrap_or_else(|error| panic!("source directory entry must be readable: {error}"))
.path();
collect_rust_sources(&path, out);
}
}