4
4
5
5
import 'dart:collection' ;
6
6
7
+ import 'package:meta/meta.dart' ;
8
+
7
9
/// A map whose keys are converted to canonical values of type `C` .
8
10
///
9
11
/// This is useful for using case-insensitive String keys, for example. It's
10
12
/// more efficient than a [LinkedHashMap] with a custom equality operator
11
13
/// because it only canonicalizes each key once, rather than doing so for each
12
14
/// comparison.
13
- final class CanonicalizedMap <C , K , V > implements Map <K , V > {
15
+ @sealed // TODO: Make `final` when no longer extended.
16
+ class CanonicalizedMap <C , K , V > implements Map <K , V > {
14
17
final C Function (K ) _canonicalize;
15
18
16
19
final bool Function (K )? _isValidKeyFn;
@@ -25,10 +28,11 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
25
28
/// The [isValidKey] function is called before calling [canonicalize] for
26
29
/// methods that take arbitrary objects. It can be used to filter out keys
27
30
/// that can't be canonicalized.
28
- CanonicalizedMap (C Function (K key) canonicalize,
29
- {bool Function (K key)? isValidKey})
30
- : _canonicalize = canonicalize,
31
- _isValidKeyFn = isValidKey;
31
+ CanonicalizedMap (
32
+ C Function (K key) canonicalize, {
33
+ bool Function (K key)? isValidKey,
34
+ }) : _canonicalize = canonicalize,
35
+ _isValidKeyFn = isValidKey;
32
36
33
37
/// Creates a canonicalized map that is initialized with the key/value pairs
34
38
/// of [other] .
@@ -39,10 +43,12 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
39
43
/// The [isValidKey] function is called before calling [canonicalize] for
40
44
/// methods that take arbitrary objects. It can be used to filter out keys
41
45
/// that can't be canonicalized.
42
- CanonicalizedMap .from (Map <K , V > other, C Function (K key) canonicalize,
43
- {bool Function (K key)? isValidKey})
44
- : _canonicalize = canonicalize,
45
- _isValidKeyFn = isValidKey {
46
+ CanonicalizedMap .from (
47
+ Map <K , V > other,
48
+ C Function (K key) canonicalize, {
49
+ bool Function (K key)? isValidKey,
50
+ }) : _canonicalize = canonicalize,
51
+ _isValidKeyFn = isValidKey {
46
52
addAll (other);
47
53
}
48
54
@@ -56,15 +62,19 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
56
62
/// methods that take arbitrary objects. It can be used to filter out keys
57
63
/// that can't be canonicalized.
58
64
CanonicalizedMap .fromEntries (
59
- Iterable <MapEntry <K , V >> entries, C Function (K key) canonicalize,
60
- {bool Function (K key)? isValidKey})
61
- : _canonicalize = canonicalize,
62
- _isValidKeyFn = isValidKey {
65
+ Iterable <MapEntry <K , V >> entries,
66
+ C Function (K key) canonicalize, {
67
+ bool Function (K key)? isValidKey,
68
+ }) : _canonicalize = canonicalize,
69
+ _isValidKeyFn = isValidKey {
63
70
addEntries (entries);
64
71
}
65
72
66
73
CanonicalizedMap ._(
67
- this ._canonicalize, this ._isValidKeyFn, Map <C , MapEntry <K , V >> base ) {
74
+ this ._canonicalize,
75
+ this ._isValidKeyFn,
76
+ Map <C , MapEntry <K , V >> base ,
77
+ ) {
68
78
_base.addAll (base );
69
79
}
70
80
@@ -92,8 +102,11 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
92
102
}
93
103
94
104
@override
95
- void addEntries (Iterable <MapEntry <K , V >> entries) => _base.addEntries (entries
96
- .map ((e) => MapEntry (_canonicalize (e.key), MapEntry (e.key, e.value))));
105
+ void addEntries (Iterable <MapEntry <K , V >> entries) => _base.addEntries (
106
+ entries.map (
107
+ (e) => MapEntry (_canonicalize (e.key), MapEntry (e.key, e.value)),
108
+ ),
109
+ );
97
110
98
111
@override
99
112
Map <K2 , V2 > cast <K2 , V2 >() => _base.cast <K2 , V2 >();
@@ -158,14 +171,16 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
158
171
159
172
@override
160
173
V update (K key, V Function (V ) update, {V Function ()? ifAbsent}) =>
161
- _base.update (_canonicalize (key), (pair) {
162
- var value = pair.value;
163
- var newValue = update (value);
164
- if (identical (newValue, value)) return pair;
165
- return MapEntry (key, newValue);
166
- },
167
- ifAbsent:
168
- ifAbsent == null ? null : () => MapEntry (key, ifAbsent ())).value;
174
+ _base.update (
175
+ _canonicalize (key),
176
+ (pair) {
177
+ var value = pair.value;
178
+ var newValue = update (value);
179
+ if (identical (newValue, value)) return pair;
180
+ return MapEntry (key, newValue);
181
+ },
182
+ ifAbsent: ifAbsent == null ? null : () => MapEntry (key, ifAbsent ()),
183
+ ).value;
169
184
170
185
@override
171
186
void updateAll (V Function (K key, V value) update) =>
@@ -193,5 +208,6 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
193
208
/// Creates a `Map<C,V>` (with the canonicalized keys).
194
209
/// See [toMap] .
195
210
Map <C , V > toMapOfCanonicalKeys () => Map <C , V >.fromEntries (
196
- _base.entries.map ((e) => MapEntry <C , V >(e.key, e.value.value)));
211
+ _base.entries.map ((e) => MapEntry <C , V >(e.key, e.value.value)),
212
+ );
197
213
}
0 commit comments