compareCloudValues function
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');
}