Generate extension API shims
This commit is contained in:
@@ -21,11 +21,16 @@ COVERAGE = ROOT / "api/SHIM-COVERAGE.md"
|
||||
TARGETS = {
|
||||
"LibreMetaverse.Imaging.Abstractions": ROOT / "crates/libremetaverse-imaging/src/generated.rs",
|
||||
"LibreMetaverse.Imaging.Skia": ROOT / "crates/libremetaverse-imaging-skia/src/generated.rs",
|
||||
"LibreMetaverse.LslTools": ROOT / "crates/libremetaverse-lsl-tools/src/generated.rs",
|
||||
"LibreMetaverse.PrimMesher": ROOT / "crates/libremetaverse-prim-mesher/src/generated.rs",
|
||||
"LibreMetaverse.RLV": ROOT / "crates/libremetaverse-rlv/src/generated.rs",
|
||||
"LibreMetaverse.Rendering.MeshFoundry": ROOT / "crates/libremetaverse-rendering-mesh-foundry/src/generated.rs",
|
||||
"LibreMetaverse.Rendering.Simple": ROOT / "crates/libremetaverse-rendering-simple/src/generated.rs",
|
||||
"LibreMetaverse.Types": ROOT / "crates/libremetaverse-types/src/generated.rs",
|
||||
"LibreMetaverse.StructuredData": ROOT / "crates/libremetaverse-structured-data/src/generated.rs",
|
||||
"LibreMetaverse.Utilities": ROOT / "crates/libremetaverse-utilities/src/generated.rs",
|
||||
"LibreMetaverse.Voice.Vivox": ROOT / "crates/libremetaverse-voice-vivox/src/generated.rs",
|
||||
"LibreMetaverse.Voice.WebRTC": ROOT / "crates/libremetaverse-voice-webrtc/src/generated.rs",
|
||||
}
|
||||
|
||||
MAIN_TARGET = ROOT / "crates/libremetaverse/src/generated.rs"
|
||||
@@ -297,12 +302,6 @@ PRIVATE_LAYOUTS = {
|
||||
"T:LibreMetaverse.StructuredData.OSDUri": [("value", "libremetaverse_types::compat::Uri")],
|
||||
"T:LibreMetaverse.Imaging.ManagedImage": [("data", "Vec<u8>")],
|
||||
}
|
||||
BOXED_FIELDS = {
|
||||
"F:LibreMetaverse.Caps.Simulator",
|
||||
"F:LibreMetaverse.Simulator.Caps",
|
||||
}
|
||||
|
||||
|
||||
def generic_names(item: dict) -> list[str]:
|
||||
return [parameter["name"] for parameter in item.get("generic_parameters", [])]
|
||||
|
||||
@@ -418,16 +417,14 @@ def render_type(item: dict, type_row: dict, member_rows: dict[str, dict[str, str
|
||||
lines.append(f"pub struct {rust_name};")
|
||||
else:
|
||||
lines.append(f"pub struct {rust_name}{suffix} {{")
|
||||
generics = set(names)
|
||||
for field in fields:
|
||||
field_type = mapper.type(field["type"], field.get("nullability"), generics)
|
||||
if field["doc_id"] in BOXED_FIELDS:
|
||||
field_type = (
|
||||
f"Option<Box<{field_type[7:-1]}>>"
|
||||
if field_type.startswith("Option<")
|
||||
else f"Box<{field_type}>"
|
||||
)
|
||||
lines += [f" /// C# member: `{field['doc_id']}`.", f" pub {mapping.snake(field['name'])}: {field_type},"]
|
||||
field_signature = member_rows[field["doc_id"]]["rust_signature"]
|
||||
field_name_match = re.fullmatch(r"pub ([^:]+): (.+)", field_signature)
|
||||
if not field_name_match:
|
||||
raise ValueError(f"invalid mapped field signature: {field_signature}")
|
||||
field_name = field_name_match.group(1)
|
||||
field_type = field_name_match.group(2)
|
||||
lines += [f" /// C# member: `{field['doc_id']}`.", f" pub {field_name}: {field_type},"]
|
||||
for field_name, field_type in private_fields:
|
||||
lines.append(f" {field_name}: {field_type},")
|
||||
if names:
|
||||
@@ -534,10 +531,25 @@ def render_modules(items: list[tuple[dict, dict, bool]], member_rows: dict[str,
|
||||
def generate_sources(catalog: dict) -> tuple[dict[Path, str], dict[str, tuple[int, int, bool]]]:
|
||||
type_rows, resolved = mapping.build_type_rows(catalog)
|
||||
type_by_id = {row["csharp_type_id"]: row for row in type_rows}
|
||||
member_by_id = {
|
||||
member["doc_id"]: member
|
||||
for assembly in catalog["assemblies"]
|
||||
for item in assembly["types"]
|
||||
for member in item["members"]
|
||||
}
|
||||
configured_main_ids = WIRE_ROOT_TYPES | CORE_ROOT_TYPES | AVATAR_ROOT_TYPES
|
||||
missing_configured_ids = configured_main_ids - type_by_id.keys()
|
||||
if missing_configured_ids:
|
||||
raise ValueError(f"unknown configured main-slice IDs: {sorted(missing_configured_ids)}")
|
||||
missing_boxed_fields = mapping.BOXED_FIELD_IDS - member_by_id.keys()
|
||||
if missing_boxed_fields:
|
||||
raise ValueError(f"unknown configured boxed fields: {sorted(missing_boxed_fields)}")
|
||||
if invalid_boxed_fields := [
|
||||
member_id
|
||||
for member_id in mapping.BOXED_FIELD_IDS
|
||||
if member_by_id[member_id]["kind"] != "field"
|
||||
]:
|
||||
raise ValueError(f"configured boxed members are not fields: {sorted(invalid_boxed_fields)}")
|
||||
interfaces = {
|
||||
*{mapping.type_parts(item["signature"])[0] for assembly in catalog["assemblies"] for item in assembly["types"] if item["kind"] == "interface"},
|
||||
*{
|
||||
|
||||
Reference in New Issue
Block a user