import codecs


def deserializer_with_decoder_constructor(deserialization_func, decoder_type='utf-8', decoder_error_mode='replace'):
    """
    Wrap a deserialization function with string encoding. This is important for JSON, as it expects to operate on
    strings (potentially unicode), NOT bytetsteams. A decoding steps is needed in between.

    :param deserialization_func: The base deserialization function.
    :param decoder_type: The decoder type. Default: 'utf-8'
    :param decoder_error_mode: The decode error mode. Default: 'replace'.
    :return: The deserializer function wrapped with specified decoder.
    :rtype: bytes | bytearray | str -> T
    """
    decoder = codecs.getdecoder(decoder_type)

    def deserialize(payload):
        decoded, _ = decoder(payload, decoder_error_mode)
        return deserialization_func(decoded)
    return deserialize