"""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