marcglasberg / fast_immutable_collections

Dart Package: Immutable lists, sets, maps, and multimaps, which are as fast as their native mutable counterparts. Extension methods and comparators for native Dart collections.
BSD 2-Clause "Simplified" License
218 stars 30 forks source link

type 'String' is not a subtype of type 'Enum' in type cast #39

Open nikitadol opened 2 years ago

nikitadol commented 2 years ago

Error:

Unhandled exception:
type 'String' is not a subtype of type 'TestEnum' in type cast
#0      _safeKeyFromJson (package:fast_immutable_collections/src/imap/imap.dart:1444:14)
#1      new IMap.fromJson.<anonymous closure> (package:fast_immutable_collections/src/imap/imap.dart:414:50)
#2      MapMixin.map (dart:collection/maps.dart:170:28)
#3      new IMap.fromJson (package:fast_immutable_collections/src/imap/imap.dart:413:12)
#4      _$TestClassFromJson (package:bug/main.g.dart:10:18)
#5      new TestClass.fromJson (package:bug/main.dart:25:7)
#6      main (package:bug/main.dart:9:13)

Minimal code:

dependencies:
  flutter:
    sdk: flutter

  fast_immutable_collections: ^7.3.1
  json_annotation: ^4.5.0

dev_dependencies:
  flutter_test:
    sdk: flutter

  build_runner: ^2.1.11
  json_serializable: ^6.2.0
import 'dart:convert';

import 'package:fast_immutable_collections/fast_immutable_collections.dart';
import 'package:json_annotation/json_annotation.dart';

part 'main.g.dart';

void main() {
  TestClass.fromJson(jsonDecode(jsonEncode(const TestClass(
    testField: IMapConst({
      TestEnum.testValue: true,
    }),
  ))));
}

@JsonSerializable()
class TestClass {
  final IMap<TestEnum, bool> testField;

  const TestClass({
    required this.testField,
  });

  factory TestClass.fromJson(Map<String, Object?> json) =>
      _$TestClassFromJson(json);

  Map<String, Object?> toJson() => _$TestClassToJson(this);
}

enum TestEnum {
  testValue,
}
bryantgtx commented 2 years ago

I was just coming in to report this, thanks. My map's key is an enum as well, so pretty much the exact case.

marcglasberg commented 2 years ago

Hello! Thank you for the report. JSON serialization and deserialization was kindly contributed by @knaeckeKami . Maybe he can help you. Or if you know how to fix this, I'm accepting PRs.

The code that needs to be improved is at the very end of this file: https://github.com/marcglasberg/fast_immutable_collections/blob/master/lib/src/imap/imap.dart

Meanwhile, I have published version 7.4.1, which improves the error message. It will now be an unsupported error: JSON deserialization of IMap keys of type $type are not supported at the moment.

Also, created a test for that, at the very end of this file:

https://github.com/marcglasberg/fast_immutable_collections/blob/master/json_serializable_e2e_test/test/json_serialization_and_deserialization_test.dart

nikitadol commented 2 years ago

Hi @marcglasberg

All keys in JSON are strings, so I don't understand why this code is here

Also, why do the _safeKeyFromJson and _safeKeyToJson methods exist?

https://github.com/marcglasberg/fast_immutable_collections/blob/d5aca34b39e697edfedb5245abde013e7733f67e/lib/src/imap/imap.dart#L407-L415

knaeckeKami commented 2 years ago

Hm, I don't see a way how this could be handled without a complete overhaul of serialization.

But you can try using json_serializable_fic (https://pub.dev/packages/json_serializable_fic ). It says discontinued because I thought with the addition of the toJson, fromJson methods this package should be obsolete, but it should still work.

There is a test for enum maps (https://github.com/knaeckeKami/json_serializable_immutable_collections/blob/master/builders/json_serializable_fic/test/integration/model_test.dart ).