from typing import Any, Callable

from ._IdentityDataSerializer import IdentityDataSerializer


class FunctionDataSerializer(IdentityDataSerializer):
    """Adapter that allows using a callable as a Serializer."""

    def __init__(
        self,
        fn: Callable[[Any], dict],
        fn_error: Callable[[Any, Exception, dict], dict | str] | None = None,
        fn_parser_error: Callable[[bytes, Exception], dict | str] | None = None,
    ):
        """Args:
        fn: Callable that receives the call_business result and returns a serializable dict.
        fn_error: Callable that receives (input_obj, exception, original_payload) and returns a serializable response.
                  If None, serialize_error returns an empty string.
        fn_parser_error: Callable that receives (data, exception) and returns a serializable response.
                         If None, serialize_parser_error returns an empty string.
        """
        self._fn = fn
        self._fn_error = fn_error
        self._fn_parser_error = fn_parser_error

    def serialize(self, result: Any) -> dict:
        return self._fn(result)

    def serialize_error(self, input_obj: Any, exception: Exception, original_payload: dict) -> dict | str:
        if self._fn_error is None:
            return super().serialize_error(input_obj, exception, original_payload)
        return self._fn_error(input_obj, exception, original_payload)

    def serialize_parser_error(self, data: bytes, exception: Exception) -> dict | str:
        if self._fn_parser_error is None:
            return super().serialize_parser_error(data, exception)
        return self._fn_parser_error(data, exception)
