Fixes/upgrades

This commit is contained in:
2026-07-30 21:12:29 -04:00
parent e00b3a177e
commit 9494549861
13 changed files with 823 additions and 60 deletions

View File

@@ -0,0 +1,36 @@
"""Rust identifier hygiene."""
from __future__ import annotations
# Strict and reserved-for-future-use keywords from the Rust reference's
# keyword table, 2021 edition.
_RUST_KEYWORDS = frozenset({
"as", "break", "const", "continue", "crate", "else", "enum", "extern",
"false", "fn", "for", "if", "impl", "in", "let", "loop", "match", "mod",
"move", "mut", "pub", "ref", "return", "self", "Self", "static", "struct",
"super", "trait", "true", "type", "unsafe", "use", "where", "while",
"async", "await", "dyn",
"abstract", "become", "box", "do", "final", "macro", "override", "priv",
"typeof", "unsized", "virtual", "yield",
"try",
"union", # contextual, but escaping it costs nothing
})
def to_rust_ident(name: str) -> str:
"""`name`, or `r#name` when it collides with a keyword.
Field casing is left alone — the caller owns that convention.
"""
if name in _RUST_KEYWORDS:
return f"r#{name}"
return name
def to_rust_variant_ident(python_member_name: str) -> str:
"""`SONNET` -> `Sonnet`, `MY_OPTION` -> `MyOption`.
Enum declarations and enum-valued defaults are emitted from different
places and both call this; two implementations would disagree.
"""
return "".join(part.capitalize() for part in python_member_name.split("_") if part)