This commit is contained in:
Mateusz Gruszczyński committed 2026-10-07 22:22:54 +02:00
1 parent e84df445c6
commit e87a382a7e
109 files changed
+1092 -2925

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()
)