83 lines
2.3 KiB
Python
83 lines
2.3 KiB
Python
"""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
|