Description
Hi,
If json_serializable is used with IMap a Type error occurs when string is converted in the into bool / int/ double (num) or duration (FromJson). However DateTime, BigInt or Uri for example are parsed as expected.
json_serializable: ^6.7.0
fast_immutable_collections: ^9.1.5
FromJson
Looking to the generated code some types are not parsed correctly with the function FromJson:
Type error
IMap<X, String>.fromJson
X = int: (value) => value as bool,
X = bool: (value) => value as bool,
X double: (value) => (value as num).toDouble(),
Works good
IMap<X, String>.fromJson
X: (value) => DateTime.parse(value as String),
X: (value) => BigInt.parse(value as String),
ToJson
I do not known if it is necessary, but not everything is converted to string:
Not converted to string (problem?):
double/int/bool: (value) => value (Should this not be a String?)
Converted to string (works good)
DateTime: (value) => value.toIso8601String()
BigInt: (value) => value.toString(),
If this is resolved, I can resolve marcglasberg/fast_immutable_collections#58.
Thank you.
Example
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:imap_test/example.dart';
void main() {
final SerializableExample serializable = SerializableExample(
// Works as espected:
iMap: {DateTime(2023, 6, 25): 'IMap<DateTime,String>'}.lock,
iEnumMap: {TestEnum.testValue: 'IMap<Enum,String>'}.lock,
iStringMap: {'stringKey': 'IMap<String,String>'}.lock,
iBigIntMap: {BigInt.from(8) : 'IMap<BigInt,String>'}.lock,
iUriMap: {Uri(
scheme: 'https',
host: 'dart.dev',
path: '/guides/libraries/library-tour',
fragment: 'numbers') : 'Imap wit uri'}.lock,
// Bug value as Type -> error
// iDoubleMap : {5.5: 'IMap<double,String>'}.lock,
// iDurationMap: {Duration(milliseconds:200): 'IMap<Duration,String>'}.lock,
// iIntMap: {2: 'IMap<Int,String>'}.lock,
// iboolMap: {true : 'IMap<bool,String>'}.lock,
);
final Map<String, dynamic> json = serializable.toJson();
final fromJsonTestMap = SerializableExample.fromJson(json);
print('Output test serializableExample:\n ${fromJsonTestMap.toString()}');
}
SerializableExample
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'example.g.dart';
enum TestEnum {
testValue,
}
// BigInt, bool, DateTime, double, Duration, Enum, int, Iterable, List, Map, num, Object, Record, Set, String, Uri
@JsonSerializable()
class SerializableExample {
/// The generated code assumes these values exist in JSON.
final IMap<DateTime, String> iMap;
final IMap<TestEnum, String> iEnumMap;
final IMap<String, String> iStringMap;
final IMap<BigInt, String> iBigIntMap;
final IMap<bool, String> iboolMap;
final IMap<int, String> iIntMap;
final IMap<Duration, String> iDurationMap;
final IMap<double, String> iDoubleMap;
final IMap<Object, String> iObjectMap;
final IMap<Uri, String> iUriMap;
final Map<int, String> intMap;
SerializableExample({
this.iMap = const IMapConst({}),
this.iEnumMap= const IMapConst({}),
this.iStringMap = const IMapConst({}),
this.iBigIntMap = const IMapConst({}),
this.iboolMap = const IMapConst({}),
this.iIntMap = const IMapConst({}),
this.iDurationMap = const IMapConst({}),
this.iDoubleMap = const IMapConst({}),
this.iObjectMap = const IMapConst({}),
this.iUriMap = const IMapConst({}),
this.intMap = const{}
});
/// Connect the generated [_$PersonFromJson] function to the `fromJson`
/// factory.
factory SerializableExample.fromJson(Map<String, dynamic> json) =>
_$SerializableExampleFromJson(json);
/// Connect the generated [_$PersonToJson] function to the `toJson` method.
Map<String, dynamic> toJson() => _$SerializableExampleToJson(this);
@override
String toString() {
return 'SerializableExample(iMap: $iMap, iEnumMap: $iEnumMap, iStringMap: $iStringMap, iBigIntMap: $iBigIntMap, iboolMap: $iboolMap, iIntMap: $iIntMap, iDurationMap: $iDurationMap, iDoubleMap: $iDoubleMap, iObjectMap: $iObjectMap, iUriMap: $iUriMap, intMap: $intMap)';
}
}
Generator code
part of 'example.dart';
// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************
SerializableExample _$SerializableExampleFromJson(Map<String, dynamic> json) =>
SerializableExample(
iMap: json['iMap'] == null
? const IMapConst({})
: IMap<DateTime, String>.fromJson(
json['iMap'] as Map<String, dynamic>,
(value) => DateTime.parse(value as String),
(value) => value as String),
iEnumMap: json['iEnumMap'] == null
? const IMapConst({})
: IMap<TestEnum, String>.fromJson(
json['iEnumMap'] as Map<String, dynamic>,
(value) => $enumDecode(_$TestEnumEnumMap, value),
(value) => value as String),
iStringMap: json['iStringMap'] == null
? const IMapConst({})
: IMap<String, String>.fromJson(
json['iStringMap'] as Map<String, dynamic>,
(value) => value as String,
(value) => value as String),
iBigIntMap: json['iBigIntMap'] == null
? const IMapConst({})
: IMap<BigInt, String>.fromJson(
json['iBigIntMap'] as Map<String, dynamic>,
(value) => BigInt.parse(value as String),
(value) => value as String),
iboolMap: json['iboolMap'] == null
? const IMapConst({})
: IMap<bool, String>.fromJson(
json['iboolMap'] as Map<String, dynamic>,
(value) => value as bool,
(value) => value as String),
iIntMap: json['iIntMap'] == null
? const IMapConst({})
: IMap<int, String>.fromJson(json['iIntMap'] as Map<String, dynamic>,
(value) => value as int, (value) => value as String),
iDurationMap: json['iDurationMap'] == null
? const IMapConst({})
: IMap<Duration, String>.fromJson(
json['iDurationMap'] as Map<String, dynamic>,
(value) => Duration(microseconds: value as int),
(value) => value as String),
iDoubleMap: json['iDoubleMap'] == null
? const IMapConst({})
: IMap<double, String>.fromJson(
json['iDoubleMap'] as Map<String, dynamic>,
(value) => (value as num).toDouble(),
(value) => value as String),
iObjectMap: json['iObjectMap'] == null
? const IMapConst({})
: IMap<Object, String>.fromJson(
json['iObjectMap'] as Map<String, dynamic>,
(value) => value as Object,
(value) => value as String),
iUriMap: json['iUriMap'] == null
? const IMapConst({})
: IMap<Uri, String>.fromJson(
json['iUriMap'] as Map<String, dynamic>,
(value) => Uri.parse(value as String),
(value) => value as String),
intMap: (json['intMap'] as Map<String, dynamic>?)?.map(
(k, e) => MapEntry(int.parse(k), e as String),
) ??
const {},
);
Map<String, dynamic> _$SerializableExampleToJson(
SerializableExample instance) =>
<String, dynamic>{
'iMap': instance.iMap.toJson(
(value) => value.toIso8601String(),
(value) => value,
),
'iEnumMap': instance.iEnumMap.toJson(
(value) => _$TestEnumEnumMap[value]!,
(value) => value,
),
'iStringMap': instance.iStringMap.toJson(
(value) => value,
(value) => value,
),
'iBigIntMap': instance.iBigIntMap.toJson(
(value) => value.toString(),
(value) => value,
),
'iboolMap': instance.iboolMap.toJson(
(value) => value,
(value) => value,
),
'iIntMap': instance.iIntMap.toJson(
(value) => value,
(value) => value,
),
'iDurationMap': instance.iDurationMap.toJson(
(value) => value.inMicroseconds,
(value) => value,
),
'iDoubleMap': instance.iDoubleMap.toJson(
(value) => value,
(value) => value,
),
'iObjectMap': instance.iObjectMap.toJson(
(value) => value,
(value) => value,
),
'iUriMap': instance.iUriMap.toJson(
(value) => value.toString(),
(value) => value,
),
'intMap': instance.intMap.map((k, e) => MapEntry(k.toString(), e)),
};
const _$TestEnumEnumMap = {
TestEnum.testValue: 'testValue',
};