''' Serializers/Deserializers (SerDe) convert between configuration strings (or numbers) and
different Python structures.

You should subclass :class:`ConfigSerDeBase` and override the following static fields:

- ``name``: the description of the structure this serde can convert, for example "Comma-separated
  list of integers". This text will be used in the documentation generated by the ConfigBase CLI.
- ``serialize``: Take the Python structure and returns a string representation.
- ``deserialize``: Take a string representation of the value and return a Python structure.
'''

from typing import Any, List, Sequence
from abc import ABC, abstractmethod

class ConfigSerDeBase(ABC):
    ''' Defines a serializer / deserializer interface. '''

    name : str = 'Describe the structure here'

    @staticmethod
    @abstractmethod
    def serialize(value: Any) -> str:
        ''' Serializes a config value to a string.

        Args:
            value (Any): a Python object to be serialized.

        Returns:
            The object serialized into a string.
        '''

    @staticmethod
    @abstractmethod
    def deserialize(value: str) -> Any:
        ''' Deserializes a string to a config value.

        Args:
            value (str): a Python object serialized into a string

        Returns:
            The the restored Python object.
        '''


class IntegerListSerDe(ConfigSerDeBase):
    ''' De/serializes a string containing a comma-separated list of integers.

    Example string: ``0, 1, 2``
    '''

    name : str = 'Comma-separated list of integers'

    @staticmethod
    def serialize(value: Sequence[int]) -> str:
        ''' Serializes a list of integers into a string.

        Args:
            value (Sequence[int]): The list of integers.

        Returns:
            The list of integers serialized into a string.
        '''
        return ', '.join(str(e) for e in value)

    @staticmethod
    def deserialize(value: str) -> List[int]:
        '''Restores a list of integers from a string.

        Args:
            value (str): A string containing a serialized list of integers.

        Returns:
            The list of integers restored from the string.

        Raises:
            Exception: exceptions related to invalid string format.
        '''
        return [int(e) for e in value.split(',')]
