"""Shared base utilities for therminal model dataclasses."""

from __future__ import annotations

import dataclasses
from typing import Any


class DictLikeMixin:
    """Mixin providing dict-style access on frozen dataclasses.

    Supports obs["field"], "field" in obs, obs.get("field", default).
    """

    def __getitem__(self, key: str) -> Any:
        return getattr(self, key)

    def __contains__(self, key: object) -> bool:
        return hasattr(self, key)

    def get(self, key: str, default: Any = None) -> Any:
        return getattr(self, key, default)

    def to_dict(self) -> dict[str, Any]:
        return dataclasses.asdict(self)


def _to_int(v: Any) -> int | None:
    """Coerce to int, or None if input is None."""
    if v is None:
        return None
    return int(v)


def _to_float(v: Any) -> float | None:
    """Coerce to float, or None if input is None."""
    if v is None:
        return None
    return float(v)
