from typing import Any
import enum
import dataclasses


def unparse(data: Any) -> Any:
    """
    Coerces `data` into a JSON-like or YAML-like object.

    Informally, this function acts as the inverse of `parse`. The order of
    fields in data classes will be preserved if the implementation of `dict`
    preserves the insertion order of keys.
    """

    if isinstance(data, enum.Enum):
        return data.value

    if dataclasses.is_dataclass(data):
        new_data = {}

        for field in dataclasses.fields(data):
            k = field.name
            v = getattr(data, field.name)

            if v is not field.default or field.default is not None:
                new_data[unparse(k)] = unparse(v)

        return new_data

    if isinstance(data, list):
        return [unparse(x) for x in data]

    if isinstance(data, dict):
        return {unparse(k): unparse(v) for (k, v) in sorted(data.items())}

    return data