from typing import Union
from enum import Enum
from typing import Type


def deserialize_enum_value(value: Union[str, Enum], enum_type: Type[Enum]):
    """
    Deserializes a value to an instance of a certain Enum. This checks whether the `value` passed is already an
    instance of the target Enum, in which case this function just returns the input `value`. If value is a string, this
    function returns the corresponding instance of the Enum passed in `enum_type`.

    :param value: value to deserialize
    :param enum_type: class (should be a subclass of Enum) that the name belongs to
    :return: instance of `enum_type`.`value`
    """
    if isinstance(value, enum_type):
        instance = value
    elif isinstance(value, str):
        instance = enum_type[value.upper()]
    else:
        raise ValueError(
            f"Invalid input data type, {type(value)} cannot be converted to an instance "
            f"of {enum_type}."
        )
    return instance