diff --git a/json_serializable/lib/src/type_helpers/enum_helper.dart b/json_serializable/lib/src/type_helpers/enum_helper.dart index bf1128fcd..a1713fac4 100644 --- a/json_serializable/lib/src/type_helpers/enum_helper.dart +++ b/json_serializable/lib/src/type_helpers/enum_helper.dart @@ -43,10 +43,10 @@ class EnumHelper extends TypeHelper { return null; } - context.addMember(_enumDecodeHelper); - if (context.nullable) { context.addMember(_enumDecodeHelperNullable); + } else { + context.addMember(_enumDecodeHelper); } context.addMember(memberContent); @@ -96,14 +96,15 @@ T _$enumDecode( } final value = enumValues.entries - .singleWhere((e) => e.value == source, orElse: () => null) - ?.key; + .singleWhere((e) => e.value == source, orElse: () => null) + ?.key ?? + unknownValue; - if (value == null && unknownValue == null) { + if (value == null) { throw ArgumentError('`$source` is not one of the supported values: ' '${enumValues.values.join(', ')}'); } - return value ?? unknownValue; + return value; } '''; @@ -116,5 +117,7 @@ T _$enumDecodeNullable( if (source == null) { return null; } - return _$enumDecode(enumValues, source, unknownValue: unknownValue); + return enumValues.entries + .singleWhere((e) => e.value == source, orElse: () => null) + ?.key ?? unknownValue; }'''; diff --git a/json_serializable/test/integration/integration_test.dart b/json_serializable/test/integration/integration_test.dart index fa51cfbe2..5dbff741b 100644 --- a/json_serializable/test/integration/integration_test.dart +++ b/json_serializable/test/integration/integration_test.dart @@ -280,4 +280,18 @@ void main() { expect(instance.enumList, [Category.notDiscoveredYet]); expect(instance.enumSet, [Category.notDiscoveredYet]); }); + + test('NullableUnknownEnumValue', () { + final instance = NullableUnknownEnumValue.fromJson({ + 'enumValue': 'nope', + 'enumIterable': ['nope'], + 'enumList': ['nope'], + 'enumSet': ['nope'], + }); + + expect(instance.enumValue, null); + expect(instance.enumIterable, [null]); + expect(instance.enumList, [null]); + expect(instance.enumSet, [null]); + }); } diff --git a/json_serializable/test/integration/json_test_example.dart b/json_serializable/test/integration/json_test_example.dart index f23831961..40b867c62 100644 --- a/json_serializable/test/integration/json_test_example.dart +++ b/json_serializable/test/integration/json_test_example.dart @@ -194,3 +194,23 @@ class UnknownEnumValue { factory UnknownEnumValue.fromJson(Map json) => _$UnknownEnumValueFromJson(json); } + +@JsonSerializable(createToJson: false) +class NullableUnknownEnumValue { + @JsonKey() + Category enumValue; + + @JsonKey() + Iterable enumIterable; + + @JsonKey() + List enumList; + + @JsonKey() + Set enumSet; + + NullableUnknownEnumValue(); + + factory NullableUnknownEnumValue.fromJson(Map json) => + _$NullableUnknownEnumValueFromJson(json); +} diff --git a/json_serializable/test/integration/json_test_example.g.dart b/json_serializable/test/integration/json_test_example.g.dart index 4ec605cc3..6846f70b3 100644 --- a/json_serializable/test/integration/json_test_example.g.dart +++ b/json_serializable/test/integration/json_test_example.g.dart @@ -76,7 +76,11 @@ T _$enumDecodeNullable( if (source == null) { return null; } - return _$enumDecode(enumValues, source, unknownValue: unknownValue); + + return enumValues.entries + .singleWhere((e) => e.value == source, orElse: () => null) + ?.key ?? + unknownValue; } const _$CategoryEnumMap = { @@ -234,3 +238,17 @@ UnknownEnumValue _$UnknownEnumValueFromJson(Map json) { unknownValue: Category.notDiscoveredYet)) ?.toSet(); } + +NullableUnknownEnumValue _$NullableUnknownEnumValueFromJson( + Map json) { + return NullableUnknownEnumValue() + ..enumValue = _$enumDecodeNullable(_$CategoryEnumMap, json['enumValue']) + ..enumIterable = (json['enumIterable'] as List) + .map((e) => _$enumDecodeNullable(_$CategoryEnumMap, e)) + ..enumList = (json['enumList'] as List) + .map((e) => _$enumDecodeNullable(_$CategoryEnumMap, e)) + .toList() + ..enumSet = (json['enumSet'] as List) + .map((e) => _$enumDecodeNullable(_$CategoryEnumMap, e)) + .toSet(); +}