From 01d43deef2c13ae06c531206141338df1db7fa62 Mon Sep 17 00:00:00 2001 From: Thomas Beckmann Date: Fri, 26 May 2023 10:24:11 +0200 Subject: [PATCH] Support unknownEnumValue on Map values (#1093) --- json_serializable/lib/src/json_key_utils.dart | 4 +++- .../lib/src/shared_checkers.dart | 12 ++++++++++ .../test/json_serializable_test.dart | 2 ++ .../src/unknown_enum_value_test_input.dart | 24 ++++++++++++++++++- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/json_serializable/lib/src/json_key_utils.dart b/json_serializable/lib/src/json_key_utils.dart index 42eb0cfce..5a197ac7b 100644 --- a/json_serializable/lib/src/json_key_utils.dart +++ b/json_serializable/lib/src/json_key_utils.dart @@ -162,11 +162,13 @@ KeyConfig _from(FieldElement element, ClassConfig classAnnotation) { targetEnumType = element.type; } else if (coreIterableTypeChecker.isAssignableFromType(element.type)) { targetEnumType = coreIterableGenericType(element.type); + } else if (coreMapTypeChecker.isAssignableFromType(element.type)) { + targetEnumType = coreMapGenericValueType(element.type); } else { throwUnsupported( element, '`$fieldName` can only be set on fields of type enum or on ' - 'Iterable, List, or Set instances of an enum type.', + 'Iterable, List, Set or Map instances of an enum type.', ); } diff --git a/json_serializable/lib/src/shared_checkers.dart b/json_serializable/lib/src/shared_checkers.dart index d2da8dbe8..476343a3b 100644 --- a/json_serializable/lib/src/shared_checkers.dart +++ b/json_serializable/lib/src/shared_checkers.dart @@ -19,6 +19,18 @@ const coreMapTypeChecker = TypeChecker.fromUrl('dart:core#Map'); DartType coreIterableGenericType(DartType type) => type.typeArgumentsOf(coreIterableTypeChecker)!.single; +/// Returns the generic key type of the [Map] represented by [type]. +/// +/// If [type] does not extend [Map], an error is thrown. +DartType coreMapGenericKeyType(DartType type) => + type.typeArgumentsOf(coreMapTypeChecker)![0]; + +/// Returns the generic value type of the [Map] represented by [type]. +/// +/// If [type] does not extend [Map], an error is thrown. +DartType coreMapGenericValueType(DartType type) => + type.typeArgumentsOf(coreMapTypeChecker)![1]; + /// A [TypeChecker] for [String], [bool] and [num]. const simpleJsonTypeChecker = TypeChecker.any([ coreStringTypeChecker, diff --git a/json_serializable/test/json_serializable_test.dart b/json_serializable/test/json_serializable_test.dart index 5644b51cb..86fa7bf7b 100644 --- a/json_serializable/test/json_serializable_test.dart +++ b/json_serializable/test/json_serializable_test.dart @@ -133,6 +133,8 @@ const _expectedAnnotatedTests = { 'UnknownEnumValue', 'UnknownEnumValueListWrongEnumType', 'UnknownEnumValueListWrongType', + 'UnknownEnumValueMapValueWrongEnumType', + 'UnknownEnumValueMapValueWrongType', 'UnknownEnumValueNotEnumField', 'UnknownEnumValueWrongEnumType', 'UnsupportedDateTimeField', diff --git a/json_serializable/test/src/unknown_enum_value_test_input.dart b/json_serializable/test/src/unknown_enum_value_test_input.dart index c2f745899..64e2c49ee 100644 --- a/json_serializable/test/src/unknown_enum_value_test_input.dart +++ b/json_serializable/test/src/unknown_enum_value_test_input.dart @@ -53,6 +53,28 @@ class UnknownEnumValueListWrongEnumType { late List value; } +@ShouldThrow( + 'Error with `@JsonKey` on the `value` field. `unknownEnumValue` has type ' + '`int`, but the provided unknownEnumValue is of type ' + '`WrongEnumType`.', +) +@JsonSerializable() +class UnknownEnumValueMapValueWrongType { + @JsonKey(unknownEnumValue: WrongEnumType.otherValue) + late Map value; +} + +@ShouldThrow( + 'Error with `@JsonKey` on the `value` field. `unknownEnumValue` has type ' + '`UnknownEnumValueItems`, but the provided unknownEnumValue is of type ' + '`WrongEnumType`.', +) +@JsonSerializable() +class UnknownEnumValueMapValueWrongEnumType { + @JsonKey(unknownEnumValue: WrongEnumType.otherValue) + late Map value; +} + enum WrongEnumType { otherValue } @ShouldThrow( @@ -68,7 +90,7 @@ class UnknownEnumValueWrongEnumType { @ShouldThrow( 'Error with `@JsonKey` on the `value` field. `unknownEnumValue` can only be ' - 'set on fields of type enum or on Iterable, List, or Set instances of an ' + 'set on fields of type enum or on Iterable, List, Set or Map instances of an ' 'enum type.', ) @JsonSerializable()