Fixes/upgrades
This commit is contained in:
82
protocol/mizan-codegen/python/pydantic_to_rust/ir.py
Normal file
82
protocol/mizan-codegen/python/pydantic_to_rust/ir.py
Normal file
@@ -0,0 +1,82 @@
|
||||
"""The typed shapes a Pydantic model lowers to before Rust is emitted.
|
||||
|
||||
`TypeShape` is deliberately isomorphic to Mizan's KDL `TypeShape`, so the
|
||||
two can be converted without a lookup table.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import Optional
|
||||
|
||||
|
||||
class Primitive(str, Enum):
|
||||
INTEGER = "integer"
|
||||
NUMBER = "number"
|
||||
BOOLEAN = "boolean"
|
||||
STRING = "string"
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class TypeShape:
|
||||
"""A recursive type shape. Exactly one variant field is set."""
|
||||
|
||||
primitive: Optional[Primitive] = None
|
||||
|
||||
int_width: Optional[int] = None
|
||||
"""8 / 16 / 32 / 64, or None when unspecified. Only read alongside
|
||||
`primitive == INTEGER`, and only by emitters that distinguish widths."""
|
||||
|
||||
int_signed: Optional[bool] = None
|
||||
"""True for i8..i64, False for u8..u64, None when unspecified."""
|
||||
|
||||
float_width: Optional[int] = None
|
||||
"""16 / 32 / 64, or None when unspecified. Only meaningful alongside
|
||||
`primitive == NUMBER`."""
|
||||
|
||||
ref: Optional[str] = None
|
||||
list_inner: Optional["TypeShape"] = None
|
||||
optional_inner: Optional["TypeShape"] = None
|
||||
enum_variants: Optional[tuple[str, ...]] = None
|
||||
union_branches: Optional[tuple["TypeShape", ...]] = None
|
||||
|
||||
map_value: Optional["TypeShape"] = None
|
||||
"""`dict[K, V]` value shape."""
|
||||
|
||||
map_key: Optional["TypeShape"] = None
|
||||
"""Set only when the key is a NewType. Wire keys are always strings;
|
||||
this keeps the typed identity on the Rust side."""
|
||||
|
||||
array_element: Optional["TypeShape"] = None
|
||||
"""Fixed-length element: `tuple[T, T, T]` lowers to element T, length 3,
|
||||
and emits `[T; 3]`."""
|
||||
|
||||
array_length: Optional[int] = None
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class DefaultValue:
|
||||
"""A field default captured during introspection. `kind` discriminates
|
||||
how the emitter renders `literal`."""
|
||||
|
||||
kind: str # integer | number | boolean | string | null | empty_seq |
|
||||
# empty_map | tuple | enum_variant | compound_model | compound
|
||||
literal: object
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class FieldDecl:
|
||||
name: str
|
||||
shape: TypeShape
|
||||
required: bool
|
||||
default: Optional[DefaultValue] = None
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class ModelDecl:
|
||||
"""One Pydantic class, lowered field by field."""
|
||||
|
||||
name: str
|
||||
fields: tuple[FieldDecl, ...] = field(default_factory=tuple)
|
||||
docstring: Optional[str] = None
|
||||
Reference in New Issue
Block a user