Files
mediaproc/tools/modelgen/types.py

140 lines
4.3 KiB
Python

"""
Type Dispatch Tables
Type mappings for each output format.
Used by generators to convert Python types to target framework types.
"""
from typing import Any, Callable, get_args
# =============================================================================
# Django Type Mappings
# =============================================================================
DJANGO_TYPES: dict[Any, str] = {
str: "models.CharField(max_length={max_length}{opts})",
int: "models.IntegerField({opts})",
float: "models.FloatField({opts})",
bool: "models.BooleanField(default={default})",
"UUID": "models.UUIDField({opts})",
"datetime": "models.DateTimeField({opts})",
"dict": "models.JSONField(default=dict, blank=True)",
"list": "models.JSONField(default=list, blank=True)",
"text": "models.TextField(blank=True, default='')",
"bigint": "models.BigIntegerField({opts})",
"enum": "models.CharField(max_length=20, choices=Status.choices{opts})",
}
DJANGO_SPECIAL: dict[str, str] = {
"id": "models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)",
"created_at": "models.DateTimeField(auto_now_add=True)",
"updated_at": "models.DateTimeField(auto_now=True)",
}
# =============================================================================
# Pydantic Type Resolvers
# =============================================================================
def _get_list_inner(type_hint: Any) -> str:
"""Get inner type of List[T] for Pydantic."""
args = get_args(type_hint)
if args and args[0] in (str, int, float, bool):
return {str: "str", int: "int", float: "float", bool: "bool"}[args[0]]
return "str"
PYDANTIC_RESOLVERS: dict[Any, Callable[[Any], str]] = {
str: lambda _: "str",
int: lambda _: "int",
float: lambda _: "float",
bool: lambda _: "bool",
"UUID": lambda _: "UUID",
"datetime": lambda _: "datetime",
"dict": lambda _: "Dict[str, Any]",
"list": lambda base: f"List[{_get_list_inner(base)}]",
"enum": lambda base: base.__name__,
}
# =============================================================================
# TypeScript Type Resolvers
# =============================================================================
def _resolve_ts_list(base: Any) -> str:
"""Resolve TypeScript list type."""
args = get_args(base)
if args:
inner = args[0]
if inner is str:
return "string[]"
elif inner is int or inner is float:
return "number[]"
elif inner is bool:
return "boolean[]"
return "string[]"
TS_RESOLVERS: dict[Any, Callable[[Any], str]] = {
str: lambda _: "string",
int: lambda _: "number",
float: lambda _: "number",
bool: lambda _: "boolean",
"UUID": lambda _: "string",
"datetime": lambda _: "string",
"dict": lambda _: "Record<string, unknown>",
"list": _resolve_ts_list,
"enum": lambda base: base.__name__,
}
# =============================================================================
# Protobuf Type Resolvers
# =============================================================================
def _resolve_proto_list(base: Any) -> str:
"""Resolve Protobuf repeated type."""
args = get_args(base)
if args:
inner = args[0]
if inner is str:
return "repeated string"
elif inner is int:
return "repeated int32"
elif inner is float:
return "repeated float"
elif inner is bool:
return "repeated bool"
return "repeated string"
PROTO_RESOLVERS: dict[Any, Callable[[Any], str]] = {
str: lambda _: "string",
int: lambda _: "int32",
float: lambda _: "float",
bool: lambda _: "bool",
"list": _resolve_proto_list,
}
# =============================================================================
# Prisma Type Mappings
# =============================================================================
PRISMA_TYPES: dict[Any, str] = {
str: "String",
int: "Int",
float: "Float",
bool: "Boolean",
"UUID": "String @default(uuid())",
"datetime": "DateTime",
"dict": "Json",
"list": "Json",
"bigint": "BigInt",
}
PRISMA_SPECIAL: dict[str, str] = {
"id": "String @id @default(uuid())",
"created_at": "DateTime @default(now())",
"updated_at": "DateTime @updatedAt",
}