Scalar.fromJson constructor

Scalar.fromJson(
  1. Map<String, Object?> json
)

Implementation

factory Scalar.fromJson(Map<String, Object?> json) {
  final allowed = {'dtype', 'value', 'floatBits', 'base64', 'unscaled'};
  if (json.keys.any((key) => !allowed.contains(key))) {
    throw const FormatException('Scalar contains an unknown field');
  }
  final rawDtype = json['dtype'];
  if (rawDtype is! Map) {
    throw const FormatException('Scalar.dtype must be an object');
  }
  final dtype = DType.fromJson(rawDtype.cast<String, Object?>());
  final payloads = [
    'value',
    'floatBits',
    'base64',
    'unscaled',
  ].where(json.containsKey).toList(growable: false);
  if (payloads.length != 1) {
    throw const FormatException('Scalar requires exactly one value payload');
  }
  final key = payloads.single;
  final value = json[key];
  try {
    return switch (key) {
      'value' when value == null => Scalar.nullValue(dtype),
      'value' when dtype is DateType && value is String => Scalar.date(
        int.parse(value),
      ),
      'value' when dtype is TimeType && value is String => Scalar.time(
        int.parse(value),
      ),
      'value' => Scalar.typed(dtype, value),
      'floatBits' when value is String => Scalar._(dtype, {
        'floatBits': _validateFloatBits(dtype, value),
      }),
      'base64'
          when value is String &&
              (dtype is BinaryType || dtype is BinaryOffsetType) =>
        Scalar._(dtype, {'base64': base64Encode(base64Decode(value))}),
      'unscaled' when value is String && dtype is DecimalType =>
        Scalar.decimal(BigInt.parse(value), dtype),
      _ => throw const FormatException('Scalar payload does not match dtype'),
    };
  } on FormatException {
    rethrow;
  } on Object catch (error) {
    throw FormatException('Invalid scalar response: $error');
  }
}