| import 'package:collection/collection.dart'; |
| import 'package:equatable/equatable.dart'; |
| |
| /// Returns a `hashCode` for [props]. |
| int mapPropsToHashCode(Iterable? props) => |
| _finish(props == null ? 0 : props.fold(0, _combine)); |
| |
| const DeepCollectionEquality _equality = DeepCollectionEquality(); |
| |
| /// Determines whether [list1] and [list2] are equal. |
| bool equals(List? list1, List? list2) { |
| if (identical(list1, list2)) return true; |
| if (list1 == null || list2 == null) return false; |
| final length = list1.length; |
| if (length != list2.length) return false; |
| |
| for (var i = 0; i < length; i++) { |
| final dynamic unit1 = list1[i]; |
| final dynamic unit2 = list2[i]; |
| |
| if (_isEquatable(unit1) && _isEquatable(unit2)) { |
| if (unit1 != unit2) return false; |
| } else if (unit1 is Iterable || unit1 is Map) { |
| if (!_equality.equals(unit1, unit2)) return false; |
| } else if (unit1?.runtimeType != unit2?.runtimeType) { |
| return false; |
| } else if (unit1 != unit2) { |
| return false; |
| } |
| } |
| return true; |
| } |
| |
| bool _isEquatable(dynamic object) { |
| return object is Equatable || object is EquatableMixin; |
| } |
| |
| /// Jenkins Hash Functions |
| /// https://en.wikipedia.org/wiki/Jenkins_hash_function |
| int _combine(int hash, dynamic object) { |
| if (object is Map) { |
| object.forEach((dynamic key, dynamic value) { |
| hash = hash ^ _combine(hash, <dynamic>[key, value]); |
| }); |
| return hash; |
| } |
| if (object is Iterable) { |
| for (final value in object) { |
| hash = hash ^ _combine(hash, value); |
| } |
| return hash ^ object.length; |
| } |
| |
| hash = 0x1fffffff & (hash + object.hashCode); |
| hash = 0x1fffffff & (hash + ((0x0007ffff & hash) << 10)); |
| return hash ^ (hash >> 6); |
| } |
| |
| int _finish(int hash) { |
| hash = 0x1fffffff & (hash + ((0x03ffffff & hash) << 3)); |
| hash = hash ^ (hash >> 11); |
| return 0x1fffffff & (hash + ((0x00003fff & hash) << 15)); |
| } |
| |
| /// Returns a string for [props]. |
| String mapPropsToString(Type runtimeType, List<Object?> props) => |
| '$runtimeType(${props.map((prop) => prop.toString()).join(', ')})'; |