#[cfg(test)]
mod tests {
use std::path::{Path, PathBuf};
fn repo_root() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR"))
.ancestors()
.nth(2)
.expect("crates/ferrosintesis sits two levels below the repo root")
.to_path_buf()
}
fn workspace_manifests() -> Vec<PathBuf> {
let root = repo_root();
let mut out = vec![root.join("Cargo.toml")];
let crates = root.join("crates");
let entries = std::fs::read_dir(&crates)
.unwrap_or_else(|e| panic!("cannot list {}: {e}", crates.display()));
let mut found: Vec<PathBuf> = entries
.filter_map(Result::ok)
.map(|e| e.path().join("Cargo.toml"))
.filter(|p| p.is_file())
.collect();
found.sort();
out.extend(found);
assert!(
out.len() > 5,
"found only {} manifests under {} — the oracle is not scanning the \
workspace it thinks it is",
out.len(),
root.display()
);
out
}
#[derive(Clone, Copy)]
enum StringKind {
Basic,
Literal,
}
fn structural_braces(line: &str) -> (usize, usize) {
let mut string = None;
let mut escaped = false;
let mut opens = 0;
let mut closes = 0;
for c in line.chars() {
match string {
Some(StringKind::Basic) => {
if escaped {
escaped = false;
} else {
match c {
'\\' => escaped = true,
'"' => string = None,
_ => {}
}
}
}
Some(StringKind::Literal) => {
if c == '\'' {
string = None;
}
}
None => match c {
'"' => string = Some(StringKind::Basic),
'\'' => string = Some(StringKind::Literal),
'#' => break,
'{' => opens += 1,
'}' => closes += 1,
_ => {}
},
}
}
(opens, closes)
}
fn unclosed_inline_tables(text: &str) -> Vec<(usize, String)> {
let mut out = Vec::new();
for (idx, raw) in text.lines().enumerate() {
let (opens, closes) = structural_braces(raw);
if opens > closes {
out.push((idx + 1, raw.trim().to_string()));
}
}
out
}
#[test]
fn no_manifest_uses_a_multi_line_inline_table() {
let mut failures = Vec::new();
for manifest in workspace_manifests() {
let text = std::fs::read_to_string(&manifest)
.unwrap_or_else(|e| panic!("cannot read {}: {e}", manifest.display()));
for (line_no, line) in unclosed_inline_tables(&text) {
let shown = manifest
.strip_prefix(repo_root())
.unwrap_or(&manifest)
.display()
.to_string();
failures.push(format!("{shown}:{line_no}: {line}"));
}
}
assert!(
failures.is_empty(),
"TOML 1.0 requires an inline table to be on one line, and cargo at our \
declared MSRV (rust-version = \"1.87\") refuses a manifest that breaks \
this — it fails at parse time, before compiling anything. Newer cargo \
accepts it, so an ordinary build will NOT catch this.\n\n\
Put each of these on a single line:\n {}",
failures.join("\n ")
);
}
#[test]
fn the_oracle_detects_the_shape_it_is_meant_to_catch() {
let bad = "[dependencies]\nfoo = {\n path = \"../foo\",\n}\n";
assert_eq!(unclosed_inline_tables(bad).len(), 1);
let good = "[dependencies]\nfoo = { path = \"../foo\", version = \"=0.1.0\" }\n";
assert!(unclosed_inline_tables(good).is_empty());
let hashed = "a = { file = \"F#6.wav\" } # trailing comment\n";
assert!(unclosed_inline_tables(hashed).is_empty());
let literal_hash = "foo = { path = 'vendor/a#b' }\n";
assert!(unclosed_inline_tables(literal_hash).is_empty());
let literal_braces = "foo = { pattern = '{not structure}' }\n";
assert!(unclosed_inline_tables(literal_braces).is_empty());
let hidden_by_literal_quote = "foo = { path = 'vendor/\"quoted' # }\n";
assert_eq!(unclosed_inline_tables(hidden_by_literal_quote).len(), 1);
let commented = "# foo = {\nbar = 1\n";
assert!(unclosed_inline_tables(commented).is_empty());
let array = "include = [\n \"src/**\",\n \"README.md\",\n]\n";
assert!(unclosed_inline_tables(array).is_empty());
}
}