diff --git a/json_annotation/lib/src/enum_helpers.dart b/json_annotation/lib/src/enum_helpers.dart index c0c5cb3ed..4c862d52c 100644 --- a/json_annotation/lib/src/enum_helpers.dart +++ b/json_annotation/lib/src/enum_helpers.dart @@ -4,6 +4,21 @@ import 'json_key.dart'; +/// Compare an enum value against a source using case-insensitive. +/// +/// Exposed only for code generated by `package:json_serializable`. +/// Not meant to be used directly by user code. +bool $enumCompareCaseInsensitive(V arg1, Object arg2) => + ((arg1 is String) && (arg2 is String)) + ? (arg1.toLowerCase() == arg2.toLowerCase()) + : arg1 == arg2; + +/// Compare an enum value against a source. +/// +/// Exposed only for code generated by `package:json_serializable`. +/// Not meant to be used directly by user code. +bool $enumCompareStandard(V arg1, Object arg2) => arg1 == arg2; + /// Returns the key associated with value [source] from [enumValues], if one /// exists. /// @@ -18,13 +33,16 @@ K? $enumDecodeNullable( Map enumValues, Object? source, { Enum? unknownValue, + bool Function(V arg1, Object arg2)? comparator, }) { if (source == null) { return null; } + comparator ??= $enumCompareStandard; + for (var entry in enumValues.entries) { - if (entry.value == source) { + if (comparator(entry.value, source)) { return entry.key; } } @@ -65,6 +83,7 @@ K $enumDecode( Map enumValues, Object? source, { K? unknownValue, + bool Function(V arg1, Object arg2)? comparator, }) { if (source == null) { throw ArgumentError( @@ -73,8 +92,9 @@ K $enumDecode( ); } + comparator ??= $enumCompareStandard; for (var entry in enumValues.entries) { - if (entry.value == source) { + if (comparator(entry.value, source)) { return entry.key; } } diff --git a/json_annotation/lib/src/json_enum.dart b/json_annotation/lib/src/json_enum.dart index 27d1fb5bc..e05e69cea 100644 --- a/json_annotation/lib/src/json_enum.dart +++ b/json_annotation/lib/src/json_enum.dart @@ -13,6 +13,7 @@ class JsonEnum { const JsonEnum({ this.alwaysCreate = false, this.fieldRename = FieldRename.none, + this.caseInsensitive = false, this.valueField, }); @@ -36,6 +37,12 @@ class JsonEnum { /// for entries annotated with [JsonValue]. final FieldRename fieldRename; + /// If `true`, enum comparison will be done using case-insensitive. + /// + /// The default, `false`, means enum comparison will be done using + /// case-sensitive. + final bool caseInsensitive; + /// Specifies the field within an "enhanced enum" to use as the value /// to use for serialization. /// diff --git a/json_annotation/lib/src/json_key.dart b/json_annotation/lib/src/json_key.dart index d7c97b65b..2e281bc49 100644 --- a/json_annotation/lib/src/json_key.dart +++ b/json_annotation/lib/src/json_key.dart @@ -149,11 +149,18 @@ class JsonKey { /// valid on a nullable enum field. final Enum? unknownEnumValue; + /// If true, enum will be parsed with case-insensitive. + /// Specifically, both values will be lower-cased and compared. + /// + /// Valid only on enum fields with a compatible enum value. + final bool caseInsensitive; + /// Creates a new [JsonKey] instance. /// /// Only required when the default behavior is not desired. const JsonKey({ - @Deprecated('Has no effect') bool? nullable, + @Deprecated('Has no effect') + bool? nullable, this.defaultValue, this.disallowNullValue, this.fromJson, @@ -161,7 +168,7 @@ class JsonKey { 'Use `includeFromJson` and `includeToJson` with a value of `false` ' 'instead.', ) - this.ignore, + this.ignore, this.includeFromJson, this.includeIfNull, this.includeToJson, @@ -170,6 +177,7 @@ class JsonKey { this.required, this.toJson, this.unknownEnumValue, + this.caseInsensitive = false, }); /// Sentinel value for use with [unknownEnumValue].