debugStringForIterableElements<E> static method

String debugStringForIterableElements<E>({
  1. required Iterable<E> iterable,
  2. required String debugString(
    1. E
    ),
  3. String onTooLarge(
    1. Iterable<E> iterable
    )?,
  4. int maxItems = 100,
  5. int maxLineLength = 60,
  6. int maxOutputLength = 2000,
  7. String indent = ' ',
})

Prints comma-separated items.

Each element is converted to string using debugString.

If iterable is empty, returns an empty string.

If iterable elements do not fit in a single line with maxLineLength characters, the method slits the output into multiple lines. Each line is intended with indent. The first line is empty.

If iterable is too large, returns result of onTooLarge. If onTooLarge is null, returns some unspecified summary string such as "...9999 items...".

The iterable is too large when:

  • It has more than maxItems elements.
  • The string would be longer than maxOutputLength.

Implementation

static String debugStringForIterableElements<E>({
  required Iterable<E> iterable,
  required String Function(E) debugString,
  String Function(Iterable<E> iterable)? onTooLarge,
  int maxItems = 100,
  int maxLineLength = 60,
  int maxOutputLength = 2000,
  String indent = '  ',
}) {
  // Empty?
  if (iterable.isEmpty) {
    return '';
  }

  onTooLarge ??= (iterable) => '...${iterable.length} items...';

  // Too many items?
  if (iterable.length > maxItems) {
    return onTooLarge(iterable);
  }

  // Debug strings for items
  final strings = <String>[];
  var outputLength = 0;
  var isSingleLine = true;
  for (var element in iterable) {
    final s = debugString(element);
    outputLength += s.length + 2;

    // Too long debug string?
    if (outputLength > maxOutputLength) {
      return onTooLarge(iterable);
    }

    if (isSingleLine && (outputLength > maxLineLength || s.contains('\n'))) {
      isSingleLine = false;
    }

    strings.add(s);
  }

  // Single line?
  if (isSingleLine) {
    return strings.join(', ');
  }

  final sb = StringBuffer();
  sb.write('\n');
  final newLineReplacement = '\n$indent';
  for (var string in strings) {
    sb.write(indent);
    sb.write(string.replaceAll('\n', newLineReplacement));
    sb.write(',\n');
  }
  if (sb.length > maxOutputLength) {
    return onTooLarge(iterable);
  }
  return sb.toString();
}