toMarbles method

String toMarbles()

Converts back the event sequence to a marble string.

Implementation

String toMarbles() {
  final buffer = StringBuffer();
  final lastEvent = naturalComparable<num>
      .onResultOf<TestEvent<T>>((event) => event.index)
      .maxOf(events);
  final lastIndex = lastEvent.index;
  final eventsByIndex = ListMultimap<int, TestEvent<T>>.fromIterables(
      events.map((event) => event.index), events);
  for (var index = 0; index <= lastIndex; index++) {
    final eventsAtIndex = eventsByIndex[index];
    if (eventsAtIndex.isEmpty) {
      buffer.write(advanceMarker);
    } else {
      if (eventsAtIndex.length > 1) {
        buffer.write(groupStartMarker);
      }
      for (final eventAtIndex in eventsAtIndex) {
        switch (eventAtIndex) {
          case WrappedEvent<T>(event: NextEvent<T>(value: final value)):
            if (values.containsValue(value)) {
              buffer.write(values.inverse[value]);
            } else {
              final unusedCharacter = value is String && value.length == 1
                  ? value
                  : nextMarkers
                      .toList()
                      .firstWhere((char) => !values.containsKey(char));
              values[unusedCharacter] = value;
              buffer.write(unusedCharacter);
            }
          case WrappedEvent<T>(event: ErrorEvent<T>()):
            buffer.write(errorMarker);
          case WrappedEvent<T>(event: CompleteEvent<T>()):
            buffer.write(completeMarker);
          case SubscribeEvent<T>():
            buffer.write(subscribeMarker);
          case UnsubscribeEvent<T>():
            buffer.write(unsubscribeMarker);
        }
      }
      if (eventsAtIndex.length > 1) {
        buffer.write(groupEndMarker);
      }
    }
  }
  return buffer.toString();
}