Standardize unimplemented API failures

This commit is contained in:
2026-08-08 11:44:46 +02:00
parent 3179d7a57d
commit d3f5e27f52
41 changed files with 1875 additions and 1608 deletions

View File

@@ -175,6 +175,12 @@ RUST_KEYWORDS = {
"macro", "override", "priv", "typeof", "unsized", "virtual", "yield", "try",
}
FAKE_BODY = re.compile(
r"\b(?:Default::default|unwrap_or_default|Vec::new|String::new|UUID::nil|Uuid::nil|"
r"(?:std::iter|stream)::empty)\s*\(|\b(?:return\s+)?(?:false|true|0)\s*;|"
r"\b(?:Ok|Some)\(\s*(?:false|true|0|None|Vec::new\(\)|String::new\(\))\s*\)"
)
def snake(name: str) -> str:
name = name.lstrip("@").replace("#", "_")
@@ -345,6 +351,60 @@ def render_tsv(fieldnames: list[str], rows: list[dict[str, str]]) -> str:
return output.getvalue()
def function_bodies(text: str) -> list[str]:
bodies = []
function = re.compile(r"(?m)^[ \t]*(?:pub(?:\([^)]*\))?\s+)?(?:async\s+)?fn\s+[A-Za-z_][A-Za-z0-9_]*")
for match in function.finditer(text):
brace = text.find("{", match.end())
semicolon = text.find(";", match.end())
if brace < 0 or (semicolon >= 0 and semicolon < brace):
continue
depth = 0
quote = None
escaped = False
index = brace
while index < len(text):
char = text[index]
if quote:
if escaped:
escaped = False
elif char == "\\":
escaped = True
elif char == quote:
quote = None
elif char == '"':
quote = char
elif text.startswith("//", index):
newline = text.find("\n", index)
index = len(text) if newline < 0 else newline
elif text.startswith("/*", index):
end = text.find("*/", index + 2)
index = len(text) if end < 0 else end + 1
elif char == "{":
depth += 1
elif char == "}":
depth -= 1
if depth == 0:
bodies.append(text[brace + 1 : index])
break
index += 1
else:
raise ValueError("unbalanced generated Rust function body")
return bodies
def validate_generated_shims() -> None:
for path in sorted((ROOT / "crates").glob("*/src/generated*.rs")):
text = path.read_text()
if re.search(r"#\[derive\([^]]*\bDefault\b", text):
raise ValueError(f"generated shim derives a plausible Default: {path.relative_to(ROOT)}")
for body in function_bodies(text):
if FAKE_BODY.search(body):
raise ValueError(f"generated shim returns a plausible fallback: {path.relative_to(ROOT)}")
if not any(marker in body for marker in ("unimplemented_api!", "not_implemented(", "NotImplemented::new(")):
raise ValueError(f"generated shim function does not use the standardized failure: {path.relative_to(ROOT)}")
def build_type_rows(catalog: dict) -> tuple[list[dict[str, str]], dict[str, str]]:
rows = []
resolved: dict[str, str] = {}
@@ -629,6 +689,8 @@ def build_member_rows(catalog: dict, mapper: Mapper) -> list[dict[str, str]]:
def validate(catalog: dict, type_rows: list[dict[str, str]], member_rows: list[dict[str, str]], mapper: Mapper) -> None:
validate_generated_shims()
def unique(rows: list[dict[str, str]], field: str) -> None:
duplicates = [value for value, count in Counter(row[field] for row in rows).items() if count > 1]
if duplicates:
@@ -711,7 +773,8 @@ def coverage_report(catalog: dict, type_rows: list[dict[str, str]], member_rows:
f"- C# public members mapped: **{len(member_rows):,} / {catalog['summary']['public_member_count']:,} (100%)**",
f"- External signature types resolved: **{len(external):,} / {len(catalog['external_types']):,} (100%)**",
"- Duplicate C# IDs: **0**", "- Duplicate Rust destinations: **0**", "- Stale or missing catalog IDs: **0**",
"- Unresolved referenced types: **0**", "- Platform-specific mappings: **0**", "",
"- Unresolved referenced types: **0**", "- Platform-specific mappings: **0**",
"- Plausible generated fallback bodies/default derives: **0**", "",
"## Assembly representatives", "", "| Assembly | Rust crate | Members | Representative mapping |", "|---|---|---:|---|",
]
for assembly in catalog["assemblies"]:
@@ -761,6 +824,8 @@ def self_check() -> None:
assert split_top_level("A<B, C<D, E>>, F") == ["A<B, C<D, E>>", "F"]
assert type_parts("A<B<C>, D>.Nested[]") == ("A.Nested", ["B<C>", "D"], "[]")
assert snake("HTTPRequest2") == "http_request2"
assert function_bodies("pub fn value() -> bool { false }") == [" false "]
assert FAKE_BODY.search(function_bodies("pub fn value() -> bool { false; }")[0])
def main() -> None: