1 | | | import 'converter.dart'; |
2 | | | import 'lazy_in_place_list.dart'; |
3 | | | import 'lazy_in_place_map.dart'; |
4 | | |
|
5 | | | /// This converter converts items in lists and maps **in place**. It avoids |
6 | | | /// creating a copy of the data to hold the conversion result. Additionally, |
7 | | | /// items in the list/map are lazily converted, i.e. only upon accessing them. |
8 | | | final class LazyInPlaceConverter extends Converter { |
9 | | 3 | const LazyInPlaceConverter(this.converter) : super(); |
10 | | |
|
11 | | | final Converter converter; |
12 | | |
|
13 | | 1 | @override |
14 | | 3 | Cast<T> value<T>() => converter.value<T>(); |
15 | | |
|
16 | | 1 | @override |
17 | | 1 | Cast<List<T>> list<T>([Cast<T>? cast]) { |
18 | | 2 | final op = cast ?? value<T>(); |
19 | | 5 | return Converter.isIdentity<T>(op) ? converter.list<T>(op) : _toList(op); |
20 | | 1 | } |
21 | | |
|
22 | | 1 | @override |
23 | | 1 | Cast<Set<T>> set<T>([Cast<T>? cast]) { |
24 | | 2 | final op = cast ?? value<T>(); |
25 | | 5 | return Converter.isIdentity<T>(op) ? converter.set<T>(op) : _toSet(op); |
26 | | 1 | } |
27 | | |
|
28 | | 1 | @override |
29 | | 1 | Cast<Map<K, V>> map<K, V>({Cast<K>? kcast, Cast<V>? vcast}) { |
30 | | 3 | final kop = kcast ?? value<K>(), vop = vcast ?? value<V>(); |
31 | | 3 | return (!Converter.isIdentity<K>(kop) || Converter.isIdentity<V>(vop)) |
32 | | 3 | ? converter.map<K, V>(kcast: kop, vcast: vop) |
33 | | 2 | : _toMap(vop); |
34 | | 1 | } |
35 | | |
|
36 | | 2 | static Cast<List<T>> _toList<T>(Cast<T> cast) => |
37 | | 3 | (x) => LazyInPlaceList(x, cast); |
38 | | |
|
39 | | 2 | static Cast<Set<T>> _toSet<T>(Cast<T> cast) => |
40 | | 4 | (x) => (x as Iterable).map(cast).toSet(); |
41 | | |
|
42 | | 2 | static Cast<Map<K, V>> _toMap<K, V>(Cast<V> vcast) => |
43 | | 3 | (x) => LazyInPlaceMap(x, vcast); |
44 | | | } |