from __future__ import annotations
import re
from pathlib import Path
def ensure_mod_chain(
crate_src: Path, expected_file: str, *, dry_run: bool = False
) -> list[str]:
segments = expected_file.removesuffix(".rs").split("/")
actions: list[str] = []
for i in range(len(segments) - 1):
dir_path = crate_src.joinpath(*segments[: i + 1])
next_seg = segments[i + 1]
mod_rs = dir_path / "mod.rs"
actions.extend(_ensure_pub_mod(mod_rs, next_seg, dry_run=dry_run))
return actions
def _ensure_pub_mod(
mod_rs: Path, segment: str, *, dry_run: bool
) -> list[str]:
line = f"pub mod {segment};"
if mod_rs.exists():
content = mod_rs.read_text(encoding="utf-8")
if _has_pub_mod(content, segment):
return [] if dry_run:
return [f"[MOD] {mod_rs}: +{line}"]
new_content = content.rstrip() + "\n" + line + "\n"
mod_rs.write_text(new_content, encoding="utf-8")
return [f"[MOD] {mod_rs}: +{line}"]
if dry_run:
return [f"[CREATE] {mod_rs}"]
mod_rs.parent.mkdir(parents=True, exist_ok=True)
mod_rs.write_text(
f"//! {segment} 模块(由 codegen 自动创建)。\n\n{line}\n", encoding="utf-8"
)
return [f"[CREATE] {mod_rs}"]
def _has_pub_mod(content: str, segment: str) -> bool:
return bool(
re.search(rf"^\s*pub\s+mod\s+{re.escape(segment)}\s*;", content, re.MULTILINE)
)