getUnion3Decoder<T0, T1, T2> function

Decoder<Union3<T0, T1, T2>> getUnion3Decoder<T0, T1, T2>(
  1. Decoder<T0> variant0,
  2. Decoder<T1> variant1,
  3. Decoder<T2> variant2,
  4. int getIndexFromBytes(
    1. Uint8List bytes,
    2. int offset
    ),
)

Returns a decoder for a three-variant typed union.

Implementation

Decoder<Union3<T0, T1, T2>> getUnion3Decoder<T0, T1, T2>(
  Decoder<T0> variant0,
  Decoder<T1> variant1,
  Decoder<T2> variant2,
  int Function(Uint8List bytes, int offset) getIndexFromBytes,
) {
  final variants = <Object>[variant0, variant1, variant2];
  final fixedSize = _getUnionFixedSize(variants);

  (Union3<T0, T1, T2>, int) readImpl(Uint8List bytes, int offset) {
    final index = getIndexFromBytes(bytes, offset);
    _assertValidVariantIndex(variants, index);

    return switch (index) {
      0 => () {
        final (value, nextOffset) = variant0.read(bytes, offset);
        return (Union3Variant0<T0, T1, T2>(value), nextOffset);
      }(),
      1 => () {
        final (value, nextOffset) = variant1.read(bytes, offset);
        return (Union3Variant1<T0, T1, T2>(value), nextOffset);
      }(),
      2 => () {
        final (value, nextOffset) = variant2.read(bytes, offset);
        return (Union3Variant2<T0, T1, T2>(value), nextOffset);
      }(),
      _ => throw StateError('Unreachable variant index: $index'),
    };
  }

  if (fixedSize != null) {
    return FixedSizeDecoder<Union3<T0, T1, T2>>(
      fixedSize: fixedSize,
      read: readImpl,
    );
  }

  final maxSize = _getUnionMaxSize(variants);
  return VariableSizeDecoder<Union3<T0, T1, T2>>(
    read: readImpl,
    maxSize: maxSize,
  );
}