"""
cl_sii "extras" / Django REST Framework (DRF) fields.

(for serializers)

"""
try:
    import rest_framework
except ImportError as exc:  # pragma: no cover
    raise ImportError("Package 'djangorestframework' is required to use this module.") from exc

import rest_framework.fields

from cl_sii.rut import Rut


class RutField(rest_framework.fields.CharField):

    """
    DRF field for RUT.

    Data types:
    * native/primitive/internal/deserialized: :class:`cl_sii.rut.Rut`
    * representation/serialized: str, same as for DRF field
      :class:`rest_framework.fields.CharField`

    It verifies only that the input is syntactically valid; it does NOT check
    that the value is within boundaries deemed acceptable by the SII.

    The field performs some input value cleaning when it is an str;
    for example ``' 1.111.111-k \t '`` is allowed and the resulting value
    is ``Rut('1111111-K')``.

    .. seealso::
        :class:`.dj_model_fields.RutField` and :class:`.mm_fields.RutField`

    Implementation partially inspired in
    :class:`rest_framework.fields.UUIDField`.

    """

    default_error_messages = {
        'invalid': "'{value}' is not a syntactically valid RUT.",
    }

    def to_internal_value(self, data: object) -> Rut:
        """
        Deserialize.

        > Restore a primitive datatype into its internal python representation.

        :raises rest_framework.exceptions.ValidationError:
            if the data can't be converted

        """
        if isinstance(data, Rut):
            converted_data = data
        else:
            try:
                if isinstance(data, str):
                    converted_data = Rut(data, validate_dv=False)
                else:
                    self.fail('invalid', value=data)
            except (AttributeError, TypeError, ValueError):
                self.fail('invalid', value=data)

        return converted_data

    def to_representation(self, value: Rut) -> str:
        """
        Serialize.

        > Convert the initial datatype into a primitive, serializable datatype.

        """
        return value.canonical

"""
cl_sii "extras" / Django REST Framework (DRF) fields.

(for serializers)

"""
try:
    import rest_framework
except ImportError as exc:  # pragma: no cover
    raise ImportError("Package 'djangorestframework' is required to use this module.") from exc

import rest_framework.fields

from cl_sii.rut import Rut


class RutField(rest_framework.fields.CharField):

    """
    DRF field for RUT.

    Data types:
    * native/primitive/internal/deserialized: :class:`cl_sii.rut.Rut`
    * representation/serialized: str, same as for DRF field
      :class:`rest_framework.fields.CharField`

    It verifies only that the input is syntactically valid; it does NOT check
    that the value is within boundaries deemed acceptable by the SII.

    The field performs some input value cleaning when it is an str;
    for example ``' 1.111.111-k \t '`` is allowed and the resulting value
    is ``Rut('1111111-K')``.

    .. seealso::
        :class:`.dj_model_fields.RutField` and :class:`.mm_fields.RutField`

    Implementation partially inspired in
    :class:`rest_framework.fields.UUIDField`.

    """

    default_error_messages = {
        'invalid': "'{value}' is not a syntactically valid RUT.",
    }

    def to_internal_value(self, data: object) -> Rut:
        """
        Deserialize.

        > Restore a primitive datatype into its internal python representation.

        :raises rest_framework.exceptions.ValidationError:
            if the data can't be converted

        """
        if isinstance(data, Rut):
            converted_data = data
        else:
            try:
                if isinstance(data, str):
                    converted_data = Rut(data, validate_dv=False)
                else:
                    self.fail('invalid', value=data)
            except (AttributeError, TypeError, ValueError):
                self.fail('invalid', value=data)

        return converted_data

    def to_representation(self, value: Rut) -> str:
        """
        Serialize.

        > Convert the initial datatype into a primitive, serializable datatype.

        """
        return value.canonical

cl_sii "extras" / Django REST Framework (DRF) fields.  (for serializers) # pragma: no cover DRF field for RUT.      Data types:     * native/primitive/internal/deserialized: :class:`cl_sii.rut.Rut`     * representation/serialized: str, same as for DRF field       :class:`rest_framework.fields.CharField`      It verifies only that the input is syntactically valid; it does NOT check     that the value is within boundaries deemed acceptable by the SII.      The field performs some input value cleaning when it is an str;     for example ``' 1.111.111-k \t '`` is allowed and the resulting value     is ``Rut('1111111-K')``.      .. seealso::         :class:`.dj_model_fields.RutField` and :class:`.mm_fields.RutField`      Implementation partially inspired in     :class:`rest_framework.fields.UUIDField`. Deserialize.          > Restore a primitive datatype into its internal python representation.          :raises rest_framework.exceptions.ValidationError:             if the data can't be converted Serialize.          > Convert the initial datatype into a primitive, serializable datatype.