| 1 |  |  | import 'package:meta/meta.dart'; | 
                
                
                    | 2 |  |  |  | 
                
                
                    | 3 |  |  | import '../squadron_singleton.dart'; | 
                
                
                    | 4 |  |  | import '../typedefs.dart'; | 
                
                
                    | 5 |  |  | import 'converter.dart'; | 
                
                
                    | 6 |  |  | import 'lazy_in_place_list.dart'; | 
                
                
                    | 7 |  |  | import 'lazy_in_place_map.dart'; | 
                
                
                    | 8 |  |  | import 'serialization_context.dart'; | 
                
                
                    | 9 |  |  |  | 
                
                
                    | 10 |  |  | class ContextAwareConverter extends Converter { | 
                
                
                    | 11 |  | 4 |   ContextAwareConverter([Converter? converter]) | 
                
                
                    | 12 |  | 3 |       : _converter = converter ?? Squadron.converter; | 
                
                
                    | 13 |  |  |  | 
                
                
                    | 14 |  |  |   final Converter _converter; | 
                
                
                    | 15 |  |  |   // use Squadron.identical to handle JS objects | 
                
                
                    | 16 |  |  |   final _arguments = SerializationContext(Squadron.identical); | 
                
                
                    | 17 |  |  |  | 
                
                
                    | 18 |  |  |   // non-nullable value | 
                
                
                    | 19 |  | 4 |   @override | 
                
                
                    | 20 |  |  |   Cast<T> value<T extends Object>() { | 
                
                
                    | 21 |  | 8 |     final op = _converter.value<T>(); | 
                
                
                    | 22 |  | 7 |     if (Converter.isNumber<T>() || Converter.isIdentity<T>(op)) { | 
                
                
                    | 23 |  |  |       // no context needed for numbers / identity converters | 
                
                
                    | 24 |  |  |       return op; | 
                
                
                    | 25 |  |  |     } | 
                
                
                    | 26 |  | 0 |     return (dynamic x) { | 
                
                
                    | 27 |  |  |       x as Object; | 
                
                
                    | 28 |  | 0 |       var ref = _arguments.getReference<T>(x); | 
                
                
                    | 29 |  |  |       if (ref != null) return ref; | 
                
                
                    | 30 |  | 0 |       ref = op(x); | 
                
                
                    | 31 |  | 0 |       _arguments.setReference(x, ref); | 
                
                
                    | 32 |  |  |       return ref; | 
                
                
                    | 33 |  |  |     }; | 
                
                
                    | 34 |  |  |   } | 
                
                
                    | 35 |  |  |  | 
                
                
                    | 36 |  |  |   // list | 
                
                
                    | 37 |  | 4 |   @override | 
                
                
                    | 38 |  |  |   Cast<List<T>> list<T extends Object>([Cast<T>? cast]) { | 
                
                
                    | 39 |  | 4 |     final op = cast ?? value<T>(); | 
                
                
                    | 40 |  | 4 |     if (Converter.isIdentity<T>(op)) { | 
                
                
                    | 41 |  | 6 |       final toList = _converter.list<T>(); // elements will be cast | 
                
                
                    | 42 |  | 3 |       return (dynamic x) { | 
                
                
                    | 43 |  | 6 |         var ref = _arguments.getReference<List<T>>(x); | 
                
                
                    | 44 |  |  |         if (ref != null) return ref; | 
                
                
                    | 45 |  | 3 |         ref = toList(x); | 
                
                
                    | 46 |  | 6 |         _arguments.setReference(x, ref); | 
                
                
                    | 47 |  |  |         return ref; | 
                
                
                    | 48 |  |  |       }; | 
                
                
                    | 49 |  |  |     } else { | 
                
                
                    | 50 |  | 2 |       return (dynamic x) { | 
                
                
                    | 51 |  | 4 |         var ref = _arguments.getReference<List<T>>(x); | 
                
                
                    | 52 |  |  |         if (ref != null) return ref; | 
                
                
                    | 53 |  | 2 |         ref = LazyInPlaceList(x, op); // elements will be converted upon access | 
                
                
                    | 54 |  | 4 |         _arguments.setReference(x, ref); | 
                
                
                    | 55 |  |  |         return ref; | 
                
                
                    | 56 |  |  |       }; | 
                
                
                    | 57 |  |  |     } | 
                
                
                    | 58 |  |  |   } | 
                
                
                    | 59 |  |  |  | 
                
                
                    | 60 |  | 1 |   @override | 
                
                
                    | 61 |  |  |   Cast<List<T?>> nlist<T extends Object>([Cast<T>? cast]) { | 
                
                
                    | 62 |  | 0 |     final op = cast ?? value<T>(); | 
                
                
                    | 63 |  | 1 |     if (Converter.isIdentity<T>(op)) { | 
                
                
                    | 64 |  | 0 |       final toList = _converter.nlist<T>(); // elements will be cast | 
                
                
                    | 65 |  | 0 |       return (dynamic x) { | 
                
                
                    | 66 |  | 0 |         var ref = _arguments.getReference<List<T?>>(x); | 
                
                
                    | 67 |  |  |         if (ref != null) return ref; | 
                
                
                    | 68 |  | 0 |         ref = toList(x); | 
                
                
                    | 69 |  | 0 |         _arguments.setReference(x, ref); | 
                
                
                    | 70 |  |  |         return ref; | 
                
                
                    | 71 |  |  |       }; | 
                
                
                    | 72 |  |  |     } else { | 
                
                
                    | 73 |  | 1 |       final nop = Converter.allowNull(op); | 
                
                
                    | 74 |  | 1 |       return (dynamic x) { | 
                
                
                    | 75 |  | 2 |         var ref = _arguments.getReference<List<T?>>(x); | 
                
                
                    | 76 |  |  |         if (ref != null) return ref; | 
                
                
                    | 77 |  | 1 |         ref = LazyInPlaceList(x, nop); // elements will be converted upon access | 
                
                
                    | 78 |  | 2 |         _arguments.setReference(x, ref); | 
                
                
                    | 79 |  |  |         return ref; | 
                
                
                    | 80 |  |  |       }; | 
                
                
                    | 81 |  |  |     } | 
                
                
                    | 82 |  |  |   } | 
                
                
                    | 83 |  |  |  | 
                
                
                    | 84 |  |  |   // set | 
                
                
                    | 85 |  | 1 |   @override | 
                
                
                    | 86 |  |  |   Cast<Set<T>> set<T extends Object>([Cast<T>? cast]) { | 
                
                
                    | 87 |  | 1 |     final op = cast ?? value<T>(); | 
                
                
                    | 88 |  | 1 |     if (Converter.isIdentity<T>(op)) { | 
                
                
                    | 89 |  | 0 |       final toSet = _converter.set<T>(); // elements will be cast | 
                
                
                    | 90 |  | 0 |       return (dynamic x) { | 
                
                
                    | 91 |  | 0 |         var ref = _arguments.getReference<Set<T>>(x); | 
                
                
                    | 92 |  |  |         if (ref != null) return ref; | 
                
                
                    | 93 |  | 0 |         ref = toSet(x); | 
                
                
                    | 94 |  | 0 |         _arguments.setReference(x, ref); | 
                
                
                    | 95 |  |  |         return ref; | 
                
                
                    | 96 |  |  |       }; | 
                
                
                    | 97 |  |  |     } else { | 
                
                
                    | 98 |  | 1 |       return (dynamic x) { | 
                
                
                    | 99 |  | 2 |         var ref = _arguments.getReference<Set<T>>(x); | 
                
                
                    | 100 |  |  |         if (ref != null) return ref; | 
                
                
                    | 101 |  |  |         ref = <T>{}; // TODO: implement a lazy set? | 
                
                
                    | 102 |  | 2 |         _arguments.setReference(x, ref); | 
                
                
                    | 103 |  | 2 |         ref.addAll((x as Iterable).map(op)); | 
                
                
                    | 104 |  |  |         return ref; | 
                
                
                    | 105 |  |  |       }; | 
                
                
                    | 106 |  |  |     } | 
                
                
                    | 107 |  |  |   } | 
                
                
                    | 108 |  |  |  | 
                
                
                    | 109 |  | 1 |   @override | 
                
                
                    | 110 |  |  |   Cast<Set<T?>> nset<T extends Object>([Cast<T>? cast]) { | 
                
                
                    | 111 |  | 1 |     final op = cast ?? value<T>(); | 
                
                
                    | 112 |  | 1 |     if (Converter.isIdentity<T>(op)) { | 
                
                
                    | 113 |  | 0 |       final toSet = _converter.nset<T>(); // elements will be cast | 
                
                
                    | 114 |  | 0 |       return (dynamic x) { | 
                
                
                    | 115 |  | 0 |         var ref = _arguments.getReference<Set<T?>>(x); | 
                
                
                    | 116 |  |  |         if (ref != null) return ref; | 
                
                
                    | 117 |  | 0 |         ref = toSet(x); | 
                
                
                    | 118 |  | 0 |         _arguments.setReference(x, ref); | 
                
                
                    | 119 |  |  |         return ref; | 
                
                
                    | 120 |  |  |       }; | 
                
                
                    | 121 |  |  |     } else { | 
                
                
                    | 122 |  | 1 |       final nop = Converter.allowNull(op); | 
                
                
                    | 123 |  | 1 |       return (dynamic x) { | 
                
                
                    | 124 |  | 2 |         var ref = _arguments.getReference<Set<T?>>(x); | 
                
                
                    | 125 |  |  |         if (ref != null) return ref; | 
                
                
                    | 126 |  |  |         ref = <T?>{}; // TODO: implement a lazy set? | 
                
                
                    | 127 |  | 2 |         _arguments.setReference(x, ref); | 
                
                
                    | 128 |  | 2 |         ref.addAll((x as Iterable).map(nop)); | 
                
                
                    | 129 |  |  |         return ref; | 
                
                
                    | 130 |  |  |       }; | 
                
                
                    | 131 |  |  |     } | 
                
                
                    | 132 |  |  |   } | 
                
                
                    | 133 |  |  |  | 
                
                
                    | 134 |  |  |   // map | 
                
                
                    | 135 |  | 2 |   @override | 
                
                
                    | 136 |  |  |   Cast<Map<K, V>> map<K extends Object, V extends Object>( | 
                
                
                    | 137 |  |  |       {Cast<K>? kcast, Cast<V>? vcast}) { | 
                
                
                    | 138 |  | 2 |     final kop = kcast ?? value<K>(); | 
                
                
                    | 139 |  | 2 |     final vop = vcast ?? value<V>(); | 
                
                
                    | 140 |  | 4 |     if (Converter.isIdentity<K>(kop) && Converter.isIdentity<V>(vop)) { | 
                
                
                    | 141 |  | 2 |       final toMap = _converter.map<K, V>(); // elements will be cast | 
                
                
                    | 142 |  | 1 |       return (dynamic x) { | 
                
                
                    | 143 |  | 2 |         var ref = _arguments.getReference<Map<K, V>>(x); | 
                
                
                    | 144 |  |  |         if (ref != null) return ref; | 
                
                
                    | 145 |  | 1 |         ref = toMap(x); | 
                
                
                    | 146 |  | 2 |         _arguments.setReference(x, ref); | 
                
                
                    | 147 |  |  |         return ref; | 
                
                
                    | 148 |  |  |       }; | 
                
                
                    | 149 |  | 1 |     } else if (Converter.isIdentity(kop)) { | 
                
                
                    | 150 |  | 1 |       return (dynamic x) { | 
                
                
                    | 151 |  | 2 |         var ref = _arguments.getReference<Map<K, V>>(x); | 
                
                
                    | 152 |  |  |         if (ref != null) return ref; | 
                
                
                    | 153 |  | 1 |         ref = LazyInPlaceMap(x, vop); // elements will be converted upon access | 
                
                
                    | 154 |  | 2 |         _arguments.setReference(x, ref); | 
                
                
                    | 155 |  |  |         return ref; | 
                
                
                    | 156 |  |  |       }; | 
                
                
                    | 157 |  |  |     } else { | 
                
                
                    | 158 |  | 0 |       return (dynamic x) { | 
                
                
                    | 159 |  | 0 |         var ref = _arguments.getReference<Map<K, V>>(x); | 
                
                
                    | 160 |  |  |         if (ref != null) return ref; | 
                
                
                    | 161 |  | 0 |         ref = <K, V>{}; // TODO: implements a lazy map with convertible keys? | 
                
                
                    | 162 |  | 0 |         _arguments.setReference(x, ref); | 
                
                
                    | 163 |  | 0 |         ref.addEntries( | 
                
                
                    | 164 |  | 0 |           (x as Map).entries.map((e) => MapEntry(kop(e.key), vop(e.value))), | 
                
                
                    | 165 |  |  |         ); | 
                
                
                    | 166 |  |  |         return ref; | 
                
                
                    | 167 |  |  |       }; | 
                
                
                    | 168 |  |  |     } | 
                
                
                    | 169 |  |  |   } | 
                
                
                    | 170 |  |  |  | 
                
                
                    | 171 |  | 1 |   @override | 
                
                
                    | 172 |  |  |   Cast<Map<K, V?>> nmap<K extends Object, V extends Object>( | 
                
                
                    | 173 |  |  |       {Cast<K>? kcast, Cast<V>? vcast}) { | 
                
                
                    | 174 |  | 1 |     final kop = kcast ?? value<K>(); | 
                
                
                    | 175 |  | 1 |     final vop = vcast ?? value<V>(); | 
                
                
                    | 176 |  | 2 |     if (Converter.isIdentity<K>(kop) && Converter.isIdentity<V>(vop)) { | 
                
                
                    | 177 |  | 0 |       final toMap = _converter.nmap<K, V>(); // elements will be cast | 
                
                
                    | 178 |  | 0 |       return (dynamic x) { | 
                
                
                    | 179 |  | 0 |         var ref = _arguments.getReference<Map<K, V?>>(x); | 
                
                
                    | 180 |  |  |         if (ref != null) return ref; | 
                
                
                    | 181 |  | 0 |         ref = toMap(x); | 
                
                
                    | 182 |  | 0 |         _arguments.setReference(x, ref); | 
                
                
                    | 183 |  |  |         return ref; | 
                
                
                    | 184 |  |  |       }; | 
                
                
                    | 185 |  | 1 |     } else if (Converter.isIdentity(kop)) { | 
                
                
                    | 186 |  | 1 |       final nvop = Converter.allowNull(vop); | 
                
                
                    | 187 |  | 1 |       return (dynamic x) { | 
                
                
                    | 188 |  | 2 |         var ref = _arguments.getReference<Map<K, V?>>(x); | 
                
                
                    | 189 |  |  |         if (ref != null) return ref; | 
                
                
                    | 190 |  | 1 |         ref = LazyInPlaceMap(x, nvop); // elements will be converted upon access | 
                
                
                    | 191 |  | 2 |         _arguments.setReference(x, ref); | 
                
                
                    | 192 |  |  |         return ref; | 
                
                
                    | 193 |  |  |       }; | 
                
                
                    | 194 |  |  |     } else { | 
                
                
                    | 195 |  | 0 |       final nvop = Converter.allowNull(vop); | 
                
                
                    | 196 |  | 0 |       return (dynamic x) { | 
                
                
                    | 197 |  | 0 |         var ref = _arguments.getReference<Map<K, V?>>(x); | 
                
                
                    | 198 |  |  |         if (ref != null) return ref; | 
                
                
                    | 199 |  | 0 |         ref = <K, V?>{}; // TODO: implements a lazy map with convertible keys? | 
                
                
                    | 200 |  | 0 |         _arguments.setReference(x, ref); | 
                
                
                    | 201 |  | 0 |         ref.addEntries( | 
                
                
                    | 202 |  | 0 |           (x as Map).entries.map((e) => MapEntry(kop(e.key), nvop(e.value))), | 
                
                
                    | 203 |  |  |         ); | 
                
                
                    | 204 |  |  |         return ref; | 
                
                
                    | 205 |  |  |       }; | 
                
                
                    | 206 |  |  |     } | 
                
                
                    | 207 |  |  |   } | 
                
                
                    | 208 |  |  | } | 
                
                
                    | 209 |  |  |  | 
                
                
                    | 210 |  |  | @internal | 
                
                
                    | 211 |  |  | extension ContextAwareConverterImpl on ContextAwareConverter { | 
                
                
                    | 212 |  | 3 |   void reset() => _arguments.reset(); | 
                
                
                    | 213 |  |  | } |