function readTypeAndMaybeValue(bufferReader, name) {
  const start = bufferReader.index;
  const cc = bufferReader.readByte();
  // Structure types, don't read value
  if (cc === LIST_START) {
    return { type: 'list', value: null };
  }
  if (cc === SET_START) {
    return { type: 'set', value: null };
  }
  if (cc === DICT_START) {
    return { type: 'dictionary', value: null };
  }
  if (cc === RECORD_START) {
    return { type: 'record', value: null };
  }
  // Atom types, read value
  if (cc === TRUE) {
    return { type: 'boolean', value: true };
  }
  if (cc === FALSE) {
    return { type: 'boolean', value: false };
  }
  if (cc === FLOAT64) {
    // eslint-disable-next-line no-use-before-define
    const value = readFloat64Body(bufferReader, name);
    return { type: 'float64', value };
  }
  // Number-prefixed types, read value
  if (cc < ZERO || cc > NINE) {
    throw Error(
      `Unexpected character ${quote(toChar(cc))}, at index ${bufferReader.index} of ${name}`,
    );
  }
  // Parse number-prefix
  let end;
  let byte;
  for (;;) {
    byte = bufferReader.readByte();
    if (byte < ZERO || byte > NINE) {
      end = bufferReader.index - 1;
      break;
    }
  }
  const typeByte = byte;
  const numberBuffer = bufferReader.bytesAt(start, end - start);
  const numberString = textDecoder.decode(numberBuffer);
  if (typeByte === PLUS) {
    const integer = BigInt(numberString);
    return { type: 'integer', value: integer };
  }
  if (typeByte === MINUS) {
    const integer = BigInt(numberString);
    return { type: 'integer', value: -integer };
  }
  if (typeByte === BYTES_START) {
    const number = Number.parseInt(numberString, 10);
    const valueBytes = bufferReader.read(number);
    return { type: 'bytestring', value: valueBytes };
  }
  if (typeByte === STRING_START) {
    const number = Number.parseInt(numberString, 10);
    const valueBytes = bufferReader.read(number);
    // TextDecoder does not interpret surrogate pairs,
    // so we don't need to check for invalid characters.
    return { type: 'string', value: textDecoder.decode(valueBytes) };
  }
  if (typeByte === SELECTOR_START) {
    const number = Number.parseInt(numberString, 10);
    const valueBytes = bufferReader.read(number);
    return { type: 'selector', value: textDecoder.decode(valueBytes) };
  }
  throw Error(
    `Unexpected character ${quote(toChar(typeByte))}, at index ${bufferReader.index} of ${name}`,
  );
}
@param {BufferReader} bufferReader
@param {string} name
@returns {ReadTypeAndMaybeValueResult}
Reads until it can determine the type of the next value.