writeBoundedMetadataPreview function
BoundedMetadataPreview
writeBoundedMetadataPreview(
- Object? value, {
- 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);
}