Source code for bac_py.serialization

"""External format serialization (JSON, etc.) for BACnet data.

This module provides a pluggable serialization API for converting BACnet
data structures to and from external interchange formats.
"""

from __future__ import annotations

import logging
from typing import Any, Protocol, runtime_checkable

from bac_py.serialization.json import json_default

logger = logging.getLogger(__name__)

__all__ = ["Serializer", "deserialize", "get_serializer", "json_default", "serialize"]


[docs] @runtime_checkable class Serializer(Protocol): """Interface for format-specific serialization backends."""
[docs] def encode(self, data: dict[str, Any]) -> bytes: # pragma: no cover """Encode a dict to the target format.""" ...
[docs] def decode(self, raw: bytes) -> dict[str, Any]: # pragma: no cover """Decode bytes in the target format to a dict.""" ...
@property def content_type(self) -> str: # pragma: no cover """MIME type for the output format (e.g. 'application/json').""" ...
[docs] def get_serializer(format: str = "json", **kwargs: Any) -> Serializer: """Get a serializer instance for the given format. :param format: Output format. Currently supported: ``"json"``. :param kwargs: Format-specific options passed to the serializer constructor. :returns: A :class:`Serializer` instance. :raises ValueError: If the format is not supported. :raises ImportError: If the required dependency is not installed. """ if format == "json": from bac_py.serialization.json import JsonSerializer return JsonSerializer(**kwargs) msg = f"Unsupported serialization format: {format}" raise ValueError(msg)
[docs] def serialize(obj: Any, format: str = "json", **kwargs: Any) -> bytes: """Serialize a BACnet object or dict to the specified format. Accepts any object with a ``to_dict()`` method, or a plain dict. :param obj: Object to serialize. :param format: Output format (default ``"json"``). :param kwargs: Format-specific options. :returns: Serialized bytes. """ serializer = get_serializer(format, **kwargs) data = obj.to_dict() if hasattr(obj, "to_dict") else obj logger.debug("serialize: %s", type(obj).__name__) return serializer.encode(data)
[docs] def deserialize(raw: bytes, format: str = "json") -> dict[str, Any]: """Deserialize bytes to a dict. :param raw: Bytes to deserialize. :param format: Input format (default ``"json"``). :returns: Deserialized dict. """ serializer = get_serializer(format) logger.debug("deserialize: %s", format) return serializer.decode(raw)