getDiscriminatedUnionDecoder function
Returns a decoder for discriminated unions.
This decoder deserializes maps that follow the discriminated union pattern by reading a numerical discriminator and mapping it to the corresponding variant.
variants is a list of (discriminatorValue, decoder) pairs.
discriminator is the property name used as the discriminator
(defaults to '__kind').
size is the number decoder for the discriminator prefix (defaults to u8).
Implementation
Decoder<Map<String, Object?>> getDiscriminatedUnionDecoder(
List<(Object?, Decoder<Object?>)> variants, {
String discriminator = '__kind',
Decoder<num>? size,
}) {
final prefix = size ?? getU8Decoder();
final variantDecoders = variants.map((entry) {
final (discriminatorValue, variant) = entry;
return transformDecoder<List<Object?>, Map<String, Object?>>(
getTupleDecoder([prefix as Decoder<Object?>, variant]),
(tuple, bytes, offset) {
final value = tuple[1];
final result = <String, Object?>{discriminator: discriminatorValue};
if (value is Map<String, Object?>) {
result.addAll(value);
}
return result;
},
);
}).toList();
// Determine fixed/variable size.
final fixedSize = _getUnionFixedSize(variantDecoders);
(Map<String, Object?>, int) readImpl(Uint8List bytes, int offset) {
final (value, _) = prefix.read(bytes, offset);
final index = value.toInt();
_assertValidVariantIndex(variantDecoders, index);
return variantDecoders[index].read(bytes, offset);
}
if (fixedSize != null) {
return FixedSizeDecoder<Map<String, Object?>>(
fixedSize: fixedSize,
read: readImpl,
);
}
final maxSize = _getUnionMaxSize(variantDecoders);
return VariableSizeDecoder<Map<String, Object?>>(
read: readImpl,
maxSize: maxSize,
);
}