writeBoundedMetadataPreview function

BoundedMetadataPreview writeBoundedMetadataPreview(
  1. Object? value, {
  2. required ChatInputBudget budget,
})

Implementation

BoundedMetadataPreview writeBoundedMetadataPreview(
  Object? value, {
  required ChatInputBudget budget,
}) {
  budget.validate();
  final sink = _BoundedPreviewSink(budget);
  final activeContainers = HashSet<Object>.identity();
  final stack = <_WriteFrame>[_ValueFrame(value)];

  try {
    while (stack.isNotEmpty && sink.omission == null) {
      final frame = stack.removeLast();
      switch (frame) {
        case _LiteralFrame(:final text):
          sink.writeAscii(text);
        case _StringFrame(:final value):
          _writeJsonString(value, sink);
        case _ListFrame(:final value, :final index):
          if (index >= value.length) {
            sink.writeAscii(']');
            activeContainers.remove(value);
          } else {
            if (index != 0) sink.writeAscii(',');
            stack.add(_ListFrame(value, index + 1));
            stack.add(_ValueFrame(value[index]));
          }
        case _MapFrame(:final value, :final iterator, :final first):
          if (!iterator.moveNext()) {
            sink.writeAscii('}');
            activeContainers.remove(value);
          } else {
            final entry = iterator.current;
            final key = entry.key;
            if (key is! String) throw const _InvalidMetadataPreview();
            if (!first) sink.writeAscii(',');
            stack.add(_MapFrame(value, iterator, false));
            stack.add(_ValueFrame(entry.value));
            stack.add(const _LiteralFrame(':'));
            stack.add(_StringFrame(key));
          }
        case _ValueFrame(:final value):
          if (value == null) {
            sink.writeAscii('null');
          } else if (value is String) {
            _writeJsonString(value, sink);
          } else if (value is bool) {
            sink.writeAscii(value ? 'true' : 'false');
          } else if (value is int) {
            sink.writeAscii(value.toString());
          } else if (value is double) {
            if (!value.isFinite) throw const _InvalidMetadataPreview();
            sink.writeAscii(value.toString());
          } else if (value is num) {
            if (!value.isFinite) throw const _InvalidMetadataPreview();
            sink.writeAscii(value.toString());
          } else if (value is List) {
            if (!activeContainers.add(value)) {
              throw const _InvalidMetadataPreview();
            }
            sink.writeAscii('[');
            stack.add(_ListFrame(value, 0));
          } else if (value is Map) {
            if (!activeContainers.add(value)) {
              throw const _InvalidMetadataPreview();
            }
            sink.writeAscii('{');
            stack.add(_MapFrame(value, value.entries.iterator, true));
          } else {
            throw const _InvalidMetadataPreview();
          }
      }
    }
  } on Object {
    return BoundedMetadataPreview(
      text: '',
      omission: ChatInputOmission(
        reason: ChatInputOmissionReason.invalidStructure,
        resource: 'metadata preview',
        truncated: false,
      ),
    );
  }

  return BoundedMetadataPreview(text: sink.text, omission: sink.omission);
}