0.0.1-alpha.3

This commit is contained in:
2026-09-27 22:23:43 +02:00
parent 8cd187b700
commit 6b6bdcfc71
29 changed files with 1973 additions and 32 deletions

View File

@@ -0,0 +1,74 @@
#!/usr/bin/env python3
# file: scripts/audit_rust_trait_import_blocks.py
# version: 1
"""Audit placement and contiguity of module-level Rust trait-import blocks."""
from __future__ import annotations
import argparse
import pathlib
import re
import sys
from _rust_audit_common import line_depths, mask_source, selected_files
_DECLARATION = re.compile(r"^(?:pub(?:\(crate\))?\s+)?(?:async\s+|const\s+|unsafe\s+)*(?:const|static|type|struct|enum|trait|union|fn|impl)\b")
_USE = re.compile(r"^use\s+")
def audit_file(path: pathlib.Path) -> list[str]:
"""Require ordinary module-level uses before declarations and in one compact block."""
text = path.read_text(encoding="utf-8")
lines = text.splitlines()
masked, _ = mask_source(text)
depths = line_depths(masked)
seen_declaration = False
uses: list[int] = []
errors: list[str] = []
for number, line in enumerate(lines, 1):
if depths[number - 1] != 0:
continue
stripped = line.strip()
if _DECLARATION.match(stripped):
seen_declaration = True
if _USE.match(stripped):
uses.append(number)
if seen_declaration:
errors.append(f"{path}:{number}: module-level trait import must precede Rust declarations")
for previous, current in zip(uses, uses[1:]):
between = lines[previous:current - 1]
if any(not candidate.strip() for candidate in between):
errors.append(f"{path}:{current}: module-level trait import block contains an empty line")
return errors
def main() -> int:
"""Run the read-only trait-import-block audit on explicitly selected Rust files."""
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("paths", nargs="+", help="Rust files or directories to inspect")
args = parser.parse_args()
files, errors = selected_files(args.paths)
if errors or not files:
for error in errors or ["no Rust files selected"]:
print(f"Rust trait-import-block audit: {error}", file=sys.stderr)
return 2
for path in files:
try:
errors.extend(audit_file(path))
except (OSError, UnicodeError) as error:
print(f"Rust trait-import-block audit: cannot read {path}: {error}", file=sys.stderr)
return 2
for error in errors:
print(error, file=sys.stderr)
if errors:
print(f"Rust trait-import-block audit: {len(errors)} error(s) across {len(files)} file(s)", file=sys.stderr)
return 1
print(f"Rust trait-import-block audit: clean ({len(files)} file(s))")
return 0
if __name__ == "__main__":
raise SystemExit(main())