@Override
    public V decodeValue(ByteBuffer buffer) {
        if (buffer == null) {
            return null;
        }
        if (valueDecoder == null) {
            try {
                byte[] bytes = new byte[buffer.remaining()];
                buffer.get(bytes);
                return (V) Unpooled.wrappedBuffer(bytes);
            } catch (Exception e) {
                throw new UnsupportedOperationException(
                        "No value decoder to decode the key buffer: "
                                + buffer);
            }
        }
        return (V) valueDecoder.decode(buffer);
    }
@implNote We don't use Unpooled.wrappedBuffer(buffer) to wrap ByteBuffer to ByteBuf because
          the internal buffer is shared with the buffer of value by Lettuce. So the internal
          buffer will change and we must parse them when the buffer is passed
@see io.lettuce.core.protocol.RedisStateMachine#readBytes0(io.netty.buffer.ByteBuf, int)
turms-server-common/src/main/java/im/turms/server/common/storage/redis/codec/TurmsRedisCodecAdapter.java