compareCloudValues function

int compareCloudValues(
  1. Object? a,
  2. Object? b
)

Compares a and b the way Firestore orders them: by cloudTypeOrder first, then by value within a type.

Implementation

int compareCloudValues(Object? a, Object? b) {
  final int typeComparison = cloudTypeOrder(a).compareTo(cloudTypeOrder(b));
  if (typeComparison != 0) return typeComparison;
  switch ((a, b)) {
    case (null, null):
      return 0;
    case (final bool a, final bool b):
      return a == b ? 0 : (a ? 1 : -1);
    case (final num a, final num b):
      if (a.isNaN || b.isNaN) return a.isNaN ? (b.isNaN ? 0 : -1) : 1;
      return a < b ? -1 : (a > b ? 1 : 0);
    case (final Object a, final Object b) when cloudTypeOrder(a) == 3:
      return _microseconds(a).compareTo(_microseconds(b));
    case (final String a, final String b):
      return compareCloudStrings(a, b);
    case (final Object a, final Object b) when cloudTypeOrder(a) == 6:
      return _compareLists(_bytes(a), _bytes(b));
    case (final DocumentReference a, final DocumentReference b):
      return _compareLists(a.path.split('/'), b.path.split('/'));
    case (final GeoPoint a, final GeoPoint b):
      final int latitude = compareCloudValues(a.latitude, b.latitude);
      return latitude != 0
          ? latitude
          : compareCloudValues(a.longitude, b.longitude);
    case (final List a, final List b):
      return _compareLists(a, b);
    case (final Map a, final Map b):
      final List<String> aKeys = a.keys.map((key) => '$key').toList()
        ..sort(compareCloudStrings);
      final List<String> bKeys = b.keys.map((key) => '$key').toList()
        ..sort(compareCloudStrings);
      for (int i = 0; i < aKeys.length && i < bKeys.length; i++) {
        final int key = compareCloudStrings(aKeys[i], bKeys[i]);
        if (key != 0) return key;
        final int value = compareCloudValues(a[aKeys[i]], b[bKeys[i]]);
        if (value != 0) return value;
      }
      return aKeys.length.compareTo(bKeys.length);
  }
  return '$a'.compareTo('$b');
}