"""Storage metadata models for generated datasets."""
from dataclasses import dataclass, field, fields, is_dataclass
from pathlib import Path
from typing import TypeAlias, cast
JsonPrimitive: TypeAlias = str | int | float | bool | None
JsonValue: TypeAlias = JsonPrimitive | list["JsonValue"] | dict[str, "JsonValue"]
[docs]
def dataclass_to_dict(obj: object) -> JsonValue:
"""Recursively convert dataclasses, tuples, and paths into JSON-safe objects."""
if is_dataclass(obj) and not isinstance(obj, type):
result: dict[str, JsonValue] = {}
for data_field in fields(obj):
result[data_field.name] = dataclass_to_dict(getattr(obj, data_field.name))
return result
if isinstance(obj, Path):
return str(obj)
if isinstance(obj, (str, int, float, bool)) or obj is None:
return obj
if isinstance(obj, tuple):
tuple_obj = cast(tuple[object, ...], obj)
return [dataclass_to_dict(value) for value in tuple_obj]
if isinstance(obj, list):
list_obj = cast(list[object], obj)
return [dataclass_to_dict(value) for value in list_obj]
if isinstance(obj, dict):
dict_obj = cast(dict[object, object], obj)
return {str(key): dataclass_to_dict(value) for key, value in dict_obj.items()}
raise TypeError(
f"Unsupported metadata type for serialization: {type(obj).__name__}"
)