enumeration static method

BcsType<Map<String, dynamic>, dynamic> enumeration(
  1. String name,
  2. Map<String, BcsType?> values, [
  3. BcsTypeOptions<Map<String, dynamic>, Map<String, dynamic>>? options
])

Implementation

static BcsType<Map<String, dynamic>, dynamic> enumeration(
  String name,
  Map<String, BcsType?> values,
  [BcsTypeOptions<Map<String, dynamic>, Map<String, dynamic>>? options]
) {
  final canonicalOrder = values.entries.toList();

  return BcsType<Map<String, dynamic>, dynamic>(
    name: name,
    read: (reader) {
      final index = reader.readULEB();
      final entry = canonicalOrder[index];
      final value = entry.value?.read(reader) ?? true;
      return {
        entry.key: value,
        '\$kind': entry.key,
      };
    },
    write: (val, writer) {
      final value = val is Map ? val : val.toJson();
      final entry = value.entries.firstWhere(
        (entry) => values.containsKey(entry.key) && entry.key != '\$kind',
      );
      final index = canonicalOrder.indexWhere((e) => e.key == entry.key);
      writer.writeULEB(index);
      canonicalOrder[index].value?.write(entry.value, writer);
    },
    validate: (val) {
      options?.validate?.call(val);
      final value = val is Map ? val : val.toJson();
      final keys = value.keys.where((k) => k != '\$kind' && values.containsKey(k)).toList();
      if (keys.length != 1) {
        throw ArgumentError('Expected object with one key, but found ${keys.length} for type $name');
      }
      if (!values.containsKey(keys[0])) {
        throw ArgumentError('Invalid enum variant ${keys[0]}');
      }
    },
  );
}