diff --git a/json_serializable/CHANGELOG.md b/json_serializable/CHANGELOG.md index 4f6564098..73f8dba20 100644 --- a/json_serializable/CHANGELOG.md +++ b/json_serializable/CHANGELOG.md @@ -1,3 +1,8 @@ +## 6.3.1 + +- Fixed support for `Duration` fields with default values. + ([#1170](https://github.com/google/json_serializable.dart/issues/1170)) + ## 6.3.0 - Added support for generating `_$ExampleFieldMap`, which can be used by other diff --git a/json_serializable/lib/src/type_helper.dart b/json_serializable/lib/src/type_helper.dart index b01249334..01add6bcf 100644 --- a/json_serializable/lib/src/type_helper.dart +++ b/json_serializable/lib/src/type_helper.dart @@ -6,7 +6,6 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/type.dart'; import 'type_helpers/config_types.dart'; -import 'utils.dart'; /// Context information provided in calls to [TypeHelper.serialize] and /// [TypeHelper.deserialize]. @@ -85,12 +84,3 @@ abstract class TypeHelper { bool defaultProvided, ); } - -Object commonNullPrefix( - bool nullable, - String expression, - Object unsafeExpression, -) => - nullable - ? ifNullOrElse(expression, 'null', '$unsafeExpression') - : unsafeExpression; diff --git a/json_serializable/lib/src/type_helpers/duration_helper.dart b/json_serializable/lib/src/type_helpers/duration_helper.dart index 2a1c534fa..d45cb4222 100644 --- a/json_serializable/lib/src/type_helpers/duration_helper.dart +++ b/json_serializable/lib/src/type_helpers/duration_helper.dart @@ -6,6 +6,7 @@ import 'package:analyzer/dart/element/type.dart'; import 'package:source_gen/source_gen.dart' show TypeChecker; import 'package:source_helper/source_helper.dart'; +import '../default_container.dart'; import '../type_helper.dart'; class DurationHelper extends TypeHelper { @@ -33,7 +34,7 @@ class DurationHelper extends TypeHelper { } @override - String? deserialize( + Object? deserialize( DartType targetType, String expression, TypeHelperContext context, @@ -43,11 +44,10 @@ class DurationHelper extends TypeHelper { return null; } - return commonNullPrefix( - targetType.isNullableType, + return DefaultContainer( expression, 'Duration(microseconds: $expression as int)', - ).toString(); + ); } } diff --git a/json_serializable/lib/src/type_helpers/to_from_string.dart b/json_serializable/lib/src/type_helpers/to_from_string.dart index 55f8aae7e..68ea04a0a 100644 --- a/json_serializable/lib/src/type_helpers/to_from_string.dart +++ b/json_serializable/lib/src/type_helpers/to_from_string.dart @@ -5,7 +5,7 @@ import 'package:analyzer/dart/element/type.dart'; import 'package:source_gen/source_gen.dart'; -import '../type_helper.dart'; +import '../utils.dart'; final bigIntString = ToFromStringHelper( 'BigInt.parse', @@ -76,7 +76,8 @@ class ToFromStringHelper { final parseParam = isString ? expression : '$expression as String'; - return commonNullPrefix(nullable, expression, '$_parse($parseParam)') - .toString(); + final output = '$_parse($parseParam)'; + + return nullable ? ifNullOrElse(expression, 'null', output) : output; } } diff --git a/json_serializable/pubspec.yaml b/json_serializable/pubspec.yaml index a973db9ef..d3cc89601 100644 --- a/json_serializable/pubspec.yaml +++ b/json_serializable/pubspec.yaml @@ -1,5 +1,5 @@ name: json_serializable -version: 6.3.0 +version: 6.3.1 description: >- Automatically generate code for converting to and from JSON by annotating Dart classes. diff --git a/json_serializable/test/default_value/default_value.dart b/json_serializable/test/default_value/default_value.dart index a62894d2c..6b7624b35 100644 --- a/json_serializable/test/default_value/default_value.dart +++ b/json_serializable/test/default_value/default_value.dart @@ -59,6 +59,8 @@ class DefaultValue implements dvi.DefaultValue { }) Map> fieldMapListString; + Duration durationField; + @JsonKey(defaultValue: Greek.beta) Greek fieldEnum; @@ -83,6 +85,7 @@ class DefaultValue implements dvi.DefaultValue { this.fieldMapSimple, this.fieldMapListString, this.fieldEnum, { + this.durationField = Duration.zero, this.constClass = const ConstClass('value'), this.valueFromConverter = const ConstClass('value'), this.valueFromFunction = const ConstClass('value'), diff --git a/json_serializable/test/default_value/default_value.g.dart b/json_serializable/test/default_value/default_value.g.dart index 36088a33f..fef6a04c9 100644 --- a/json_serializable/test/default_value/default_value.g.dart +++ b/json_serializable/test/default_value/default_value.g.dart @@ -36,6 +36,9 @@ DefaultValue _$DefaultValueFromJson(Map json) => DefaultValue( 'root': ['child'] }, $enumDecodeNullable(_$GreekEnumMap, json['fieldEnum']) ?? Greek.beta, + durationField: json['durationField'] == null + ? Duration.zero + : Duration(microseconds: json['durationField'] as int), constClass: json['constClass'] == null ? const ConstClass('value') : ConstClass.fromJson(json['constClass'] as Map), @@ -61,6 +64,7 @@ Map _$DefaultValueToJson(DefaultValue instance) => 'fieldSetSimple': instance.fieldSetSimple.toList(), 'fieldMapSimple': instance.fieldMapSimple, 'fieldMapListString': instance.fieldMapListString, + 'durationField': instance.durationField.inMicroseconds, 'fieldEnum': _$GreekEnumMap[instance.fieldEnum]!, 'constClass': instance.constClass, 'valueFromConverter': diff --git a/json_serializable/test/default_value/default_value.g_any_map__checked.dart b/json_serializable/test/default_value/default_value.g_any_map__checked.dart index 39eeb129a..f56aa1818 100644 --- a/json_serializable/test/default_value/default_value.g_any_map__checked.dart +++ b/json_serializable/test/default_value/default_value.g_any_map__checked.dart @@ -62,6 +62,8 @@ class DefaultValue implements dvi.DefaultValue { }) Map> fieldMapListString; + Duration durationField; + @JsonKey(defaultValue: Greek.beta) Greek fieldEnum; @@ -86,6 +88,7 @@ class DefaultValue implements dvi.DefaultValue { this.fieldMapSimple, this.fieldMapListString, this.fieldEnum, { + this.durationField = Duration.zero, this.constClass = const ConstClass('value'), this.valueFromConverter = const ConstClass('value'), this.valueFromFunction = const ConstClass('value'), diff --git a/json_serializable/test/default_value/default_value.g_any_map__checked.g.dart b/json_serializable/test/default_value/default_value.g_any_map__checked.g.dart index f2ab42ae8..b06e40e86 100644 --- a/json_serializable/test/default_value/default_value.g_any_map__checked.g.dart +++ b/json_serializable/test/default_value/default_value.g_any_map__checked.g.dart @@ -51,6 +51,10 @@ DefaultValue _$DefaultValueFromJson(Map json) => $checkedCreate( }), $checkedConvert('fieldEnum', (v) => $enumDecodeNullable(_$GreekEnumMap, v) ?? Greek.beta), + durationField: $checkedConvert( + 'durationField', + (v) => + v == null ? Duration.zero : Duration(microseconds: v as int)), constClass: $checkedConvert( 'constClass', (v) => v == null @@ -84,6 +88,7 @@ Map _$DefaultValueToJson(DefaultValue instance) => 'fieldSetSimple': instance.fieldSetSimple.toList(), 'fieldMapSimple': instance.fieldMapSimple, 'fieldMapListString': instance.fieldMapListString, + 'durationField': instance.durationField.inMicroseconds, 'fieldEnum': _$GreekEnumMap[instance.fieldEnum]!, 'constClass': instance.constClass, 'valueFromConverter': diff --git a/json_serializable/test/default_value/default_value_interface.dart b/json_serializable/test/default_value/default_value_interface.dart index 9becc6e6f..7c7a4c5ba 100644 --- a/json_serializable/test/default_value/default_value_interface.dart +++ b/json_serializable/test/default_value/default_value_interface.dart @@ -27,6 +27,8 @@ abstract class DefaultValue { Map> get fieldMapListString; + Duration get durationField; + Greek get fieldEnum; ConstClass get constClass; diff --git a/json_serializable/test/default_value/default_value_test.dart b/json_serializable/test/default_value/default_value_test.dart index baee4b811..c345400fe 100644 --- a/json_serializable/test/default_value/default_value_test.dart +++ b/json_serializable/test/default_value/default_value_test.dart @@ -24,6 +24,7 @@ const _defaultInstance = { 'fieldMapListString': { 'root': ['child'] }, + 'durationField': 0, 'fieldEnum': 'beta', 'constClass': {'field': 'value'}, 'valueFromConverter': 'value', @@ -44,6 +45,7 @@ const _otherValues = { 'fieldMapListString': { 'root2': ['alpha'] }, + 'durationField': 1, 'fieldEnum': 'delta', 'constClass': {'field': 'otherValue'}, 'valueFromConverter': 'otherValue', diff --git a/json_serializable/test/default_value/implicit_default_value.dart b/json_serializable/test/default_value/implicit_default_value.dart index ad6c6c52b..4159ee9fe 100644 --- a/json_serializable/test/default_value/implicit_default_value.dart +++ b/json_serializable/test/default_value/implicit_default_value.dart @@ -34,6 +34,8 @@ class DefaultValueImplicit implements dvi.DefaultValue { final Map> fieldMapListString; + final Duration durationField; + final Greek fieldEnum; final ConstClass constClass; @@ -59,6 +61,7 @@ class DefaultValueImplicit implements dvi.DefaultValue { 'root': ['child'] }, this.fieldEnum = Greek.beta, + this.durationField = const Duration(), this.constClass = const ConstClass('value'), this.valueFromConverter = const ConstClass('value'), this.valueFromFunction = const ConstClass('value'), diff --git a/json_serializable/test/default_value/implicit_default_value.g.dart b/json_serializable/test/default_value/implicit_default_value.g.dart index ab9ec52bb..98f1de477 100644 --- a/json_serializable/test/default_value/implicit_default_value.g.dart +++ b/json_serializable/test/default_value/implicit_default_value.g.dart @@ -41,6 +41,9 @@ DefaultValueImplicit _$DefaultValueImplicitFromJson( }, fieldEnum: $enumDecodeNullable(_$GreekEnumMap, json['fieldEnum']) ?? Greek.beta, + durationField: json['durationField'] == null + ? const Duration() + : Duration(microseconds: json['durationField'] as int), constClass: json['constClass'] == null ? const ConstClass('value') : ConstClass.fromJson(json['constClass'] as Map), @@ -67,6 +70,7 @@ Map _$DefaultValueImplicitToJson( 'fieldSetSimple': instance.fieldSetSimple.toList(), 'fieldMapSimple': instance.fieldMapSimple, 'fieldMapListString': instance.fieldMapListString, + 'durationField': instance.durationField.inMicroseconds, 'fieldEnum': _$GreekEnumMap[instance.fieldEnum]!, 'constClass': instance.constClass, 'valueFromConverter':