This commit is contained in:
Mateusz Gruszczyński committed 2026-10-04 11:15:58 +02:00
1 parent 87e571c170
commit fa7abc9e53
308 files changed
+49746 -50237

No files matched your search

+43
View File
@@ -0,0 +1,43 @@
"""Helpers for source-level contracts over split Rust modules.
The project intentionally keeps Rust source files small and composes several modules
with include!("..."). Static contracts must inspect the logical source, not only the
thin facade file.
"""
from __future__ import annotations
from pathlib import Path
import re
_INCLUDE = re.compile(r'include!\(\s*"([^"]+\.rs)"\s*\)\s*;?')
def expanded_source(path: Path, _stack: tuple[Path, ...] = ()) -> str:
path = path.resolve()
if path in _stack:
chain = " -> ".join(str(item) for item in (*_stack, path))
raise RuntimeError(f"cyclic Rust include!: {chain}")
text = path.read_text(encoding="utf-8")
def replace(match: re.Match[str]) -> str:
child = (path.parent / match.group(1)).resolve()
if not child.is_file():
raise FileNotFoundError(f"{path}: include target does not exist: {match.group(1)}")
return expanded_source(child, (*_stack, path))
return _INCLUDE.sub(replace, text)
def rust_source(root: Path, relative: str) -> str:
"""Read one logical Rust source file, recursively expanding include! fragments."""
return expanded_source(root / relative)
def rust_tree(root: Path, relative_dir: str) -> str:
"""Read every Rust file beneath a module directory (including mod-declared children)."""
directory = root / relative_dir
return "\n".join(
expanded_source(path)
for path in sorted(directory.rglob("*.rs"))
if path.is_file()
)