deserialize method
String?
deserialize(
- DartType targetType,
- String expression,
- TypeHelperContextWithConfig context,
- bool defaultProvided,
override
Returns Dart code that deserializes an expression
representing a JSON
literal to into targetType
.
If targetType
is not supported, returns null
.
Let's say you want to deserialize a class Foo
by taking an int
stored
in a JSON literal and calling the Foo.fromInt
constructor.
Treating expression
as a opaque Dart expression representing a JSON
literal, the deserialize implementation could be a simple as:
String deserialize(DartType targetType, String expression) =>
"new Foo.fromInt($expression)";
```.
Note that [targetType] is not used here. If you wanted to support many
types of [targetType] you could write:
```dart
String deserialize(DartType targetType, String expression) =>
"new ${targetType.name}.fromInt($expression)";
```.
Implementation
@override
String? deserialize(
DartType targetType,
String expression,
TypeHelperContextWithConfig context,
bool defaultProvided,
) {
if (!coreMapTypeChecker.isExactlyType(targetType)) {
return null;
}
final typeArgs = targetType.typeArgumentsOf(coreMapTypeChecker)!;
assert(typeArgs.length == 2);
final keyArg = typeArgs.first;
final valueArg = typeArgs.last;
_checkSafeKeyType(expression, keyArg);
final valueArgIsAny = valueArg is DynamicType ||
(valueArg.isDartCoreObject && valueArg.isNullableType);
final isKeyStringable = _isKeyStringable(keyArg);
final targetTypeIsNullable = defaultProvided || targetType.isNullableType;
final optionalQuestion = targetTypeIsNullable ? '?' : '';
if (!isKeyStringable) {
if (valueArgIsAny) {
if (context.config.anyMap) {
if (keyArg.isLikeDynamic) {
return '$expression as Map$optionalQuestion';
}
} else {
// this is the trivial case. Do a runtime cast to the known type of
// JSON map values - `Map<String, dynamic>`
return '$expression as Map<String, dynamic>$optionalQuestion';
}
}
if (!targetTypeIsNullable &&
(valueArgIsAny ||
// explicitly exclude double since we need to do an explicit
// `toDouble` on input values
valueArg.isSimpleJsonTypeNotDouble)) {
// No mapping of the values or null check required!
final valueString = valueArg.getDisplayString();
return 'Map<String, $valueString>.from($expression as Map)';
}
}
// In this case, we're going to create a new Map with matching reified
// types.
final itemSubVal = context.deserialize(valueArg, closureArg);
var mapCast = context.config.anyMap ? 'as Map' : 'as Map<String, dynamic>';
if (targetTypeIsNullable) {
mapCast += '?';
}
String keyUsage;
if (keyArg.isEnum) {
keyUsage = context.deserialize(keyArg, _keyParam).toString();
} else if (context.config.anyMap &&
!(keyArg.isDartCoreObject || keyArg is DynamicType)) {
keyUsage = '$_keyParam as String';
} else if (context.config.anyMap &&
keyArg.isDartCoreObject &&
!keyArg.isNullableType) {
keyUsage = '$_keyParam as Object';
} else {
keyUsage = _keyParam;
}
final toFromString = _forType(keyArg);
if (toFromString != null) {
keyUsage =
toFromString.deserialize(keyArg, keyUsage, false, true).toString();
}
return '($expression $mapCast)$optionalQuestion.map( '
'($_keyParam, $closureArg) => MapEntry($keyUsage, $itemSubVal),)';
}