getPatternMatchDecoder<TTo> function
Returns a decoder that selects which variant decoder to use based on pattern matching.
This decoder evaluates the byte array against a series of predicate functions in order, and uses the first matching decoder to decode the value.
final decoder = getPatternMatchDecoder<int>([
((bytes) => bytes.length == 1, getU8Decoder()),
((bytes) => bytes.length == 2, getU16Decoder()),
((bytes) => bytes.length <= 4, getU32Decoder()),
]);
decoder.decode(Uint8List.fromList([0x2a])); // 42 as u8
decoder.decode(Uint8List.fromList([0xe8, 0x03])); // 1000 as u16
decoder.decode(Uint8List.fromList([0xa0, 0x86, 0x01, 0x00])); // 100000 as u32
Throws a SolanaError with code SolanaErrorCode.codecsInvalidPatternMatchBytes if the byte array does not match any of the specified patterns.
See also: getPatternMatchEncoder, getPatternMatchCodec.
Implementation
Decoder<TTo> getPatternMatchDecoder<TTo>(
List<PatternMatchDecoderEntry<TTo>> patterns,
) {
int getIndexFromBytes(Uint8List bytes, int offset) {
final index = patterns.indexWhere((p) => p.$1(bytes));
if (index == -1) {
throw SolanaError(SolanaErrorCode.codecsInvalidPatternMatchBytes, {
'bytes': bytes,
});
}
return index;
}
final variants = patterns.map((p) => p.$2 as Decoder<Object?>).toList();
final fixedSize = _getFixedSize(variants);
(TTo, int) readImpl(Uint8List bytes, int offset) {
final index = getIndexFromBytes(bytes, offset);
final (value, newOffset) = variants[index].read(bytes, offset);
return (value as TTo, newOffset);
}
if (fixedSize != null) {
return FixedSizeDecoder<TTo>(fixedSize: fixedSize, read: readImpl);
}
final maxSize = _getMaxSize(variants);
return VariableSizeDecoder<TTo>(read: readImpl, maxSize: maxSize);
}