from typing import Any
import attr


def validated() -> Any:
    """Decorate an entity to handle validation.

    This will let ``attrs`` manage the class, using slots for fields, and forcing attributes to
    be passed as named arguments (this allows to not have to defined all required fields first, then
    optional ones, and resolves problems with inheritance where we can't handle the order)

    Returns
    -------
    type
        The decorated class.

    Examples
    --------
    >>> from isshub.domain.utils.entity import required_field, validated, BaseEntity
    >>>
    >>> @validated()
    ... class MyEntity(BaseEntity):
    ...     my_field: str = required_field(str)
    >>>
    >>> MyEntity.__slots__
    ('my_field',)
    >>>
    >>> instance = MyEntity()
    Traceback (most recent call last):
        ...
    TypeError: __init__() missing 1 required keyword-only argument: 'my_field'
    >>> instance = MyEntity(my_field='foo')
    >>> instance.my_field
    'foo'
    >>> instance.validate()
    >>> instance.my_field = None
    >>> instance.validate()
    Traceback (most recent call last):
        ...
    TypeError: ("'my_field' must be <class 'str'> (got None that is a <class 'NoneType'>)...

    """
    return attr.s(slots=True, kw_only=True, eq=False)