Skip to content

Commit

Permalink
Support JsonSerializable(genericArgumentFactories: true) (#696)
Browse files Browse the repository at this point in the history
  • Loading branch information
TimWhiting committed Jul 15, 2022
1 parent df390b6 commit 0ce1e0c
Show file tree
Hide file tree
Showing 14 changed files with 349 additions and 27 deletions.
1 change: 1 addition & 0 deletions packages/_internal/lib/models.dart
Expand Up @@ -101,6 +101,7 @@ class Data with _$Data {
required GenericsDefinitionTemplate genericsDefinitionTemplate,
required GenericsParameterTemplate genericsParameterTemplate,
required bool shouldUseExtends,
required bool genericArgumentFactories,
}) = _Data;
}

Expand Down
41 changes: 33 additions & 8 deletions packages/_internal/lib/models.freezed.dart
Expand Up @@ -1085,7 +1085,8 @@ class _$DataTearOff {
required List<ConstructorDetails> constructors,
required GenericsDefinitionTemplate genericsDefinitionTemplate,
required GenericsParameterTemplate genericsParameterTemplate,
required bool shouldUseExtends}) {
required bool shouldUseExtends,
required bool genericArgumentFactories}) {
return _Data(
name: name,
unionKey: unionKey,
Expand All @@ -1102,6 +1103,7 @@ class _$DataTearOff {
genericsDefinitionTemplate: genericsDefinitionTemplate,
genericsParameterTemplate: genericsParameterTemplate,
shouldUseExtends: shouldUseExtends,
genericArgumentFactories: genericArgumentFactories,
);
}
}
Expand Down Expand Up @@ -1129,6 +1131,7 @@ mixin _$Data {
GenericsParameterTemplate get genericsParameterTemplate =>
throw _privateConstructorUsedError;
bool get shouldUseExtends => throw _privateConstructorUsedError;
bool get genericArgumentFactories => throw _privateConstructorUsedError;

@JsonKey(ignore: true)
$DataCopyWith<Data> get copyWith => throw _privateConstructorUsedError;
Expand All @@ -1153,7 +1156,8 @@ abstract class $DataCopyWith<$Res> {
List<ConstructorDetails> constructors,
GenericsDefinitionTemplate genericsDefinitionTemplate,
GenericsParameterTemplate genericsParameterTemplate,
bool shouldUseExtends});
bool shouldUseExtends,
bool genericArgumentFactories});

$MapConfigCopyWith<$Res> get map;
$WhenConfigCopyWith<$Res> get when;
Expand Down Expand Up @@ -1184,6 +1188,7 @@ class _$DataCopyWithImpl<$Res> implements $DataCopyWith<$Res> {
Object? genericsDefinitionTemplate = freezed,
Object? genericsParameterTemplate = freezed,
Object? shouldUseExtends = freezed,
Object? genericArgumentFactories = freezed,
}) {
return _then(_value.copyWith(
name: name == freezed
Expand Down Expand Up @@ -1246,6 +1251,10 @@ class _$DataCopyWithImpl<$Res> implements $DataCopyWith<$Res> {
? _value.shouldUseExtends
: shouldUseExtends // ignore: cast_nullable_to_non_nullable
as bool,
genericArgumentFactories: genericArgumentFactories == freezed
? _value.genericArgumentFactories
: genericArgumentFactories // ignore: cast_nullable_to_non_nullable
as bool,
));
}

Expand Down Expand Up @@ -1284,7 +1293,8 @@ abstract class _$DataCopyWith<$Res> implements $DataCopyWith<$Res> {
List<ConstructorDetails> constructors,
GenericsDefinitionTemplate genericsDefinitionTemplate,
GenericsParameterTemplate genericsParameterTemplate,
bool shouldUseExtends});
bool shouldUseExtends,
bool genericArgumentFactories});

@override
$MapConfigCopyWith<$Res> get map;
Expand Down Expand Up @@ -1318,6 +1328,7 @@ class __$DataCopyWithImpl<$Res> extends _$DataCopyWithImpl<$Res>
Object? genericsDefinitionTemplate = freezed,
Object? genericsParameterTemplate = freezed,
Object? shouldUseExtends = freezed,
Object? genericArgumentFactories = freezed,
}) {
return _then(_Data(
name: name == freezed
Expand Down Expand Up @@ -1380,6 +1391,10 @@ class __$DataCopyWithImpl<$Res> extends _$DataCopyWithImpl<$Res>
? _value.shouldUseExtends
: shouldUseExtends // ignore: cast_nullable_to_non_nullable
as bool,
genericArgumentFactories: genericArgumentFactories == freezed
? _value.genericArgumentFactories
: genericArgumentFactories // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
Expand All @@ -1402,7 +1417,8 @@ class _$_Data implements _Data {
required this.constructors,
required this.genericsDefinitionTemplate,
required this.genericsParameterTemplate,
required this.shouldUseExtends})
required this.shouldUseExtends,
required this.genericArgumentFactories})
: assert(constructors.isNotEmpty);

@override
Expand Down Expand Up @@ -1435,10 +1451,12 @@ class _$_Data implements _Data {
final GenericsParameterTemplate genericsParameterTemplate;
@override
final bool shouldUseExtends;
@override
final bool genericArgumentFactories;

@override
String toString() {
return 'Data(name: $name, unionKey: $unionKey, generateCopyWith: $generateCopyWith, generateEqual: $generateEqual, generateToString: $generateToString, map: $map, when: $when, generateFromJson: $generateFromJson, generateToJson: $generateToJson, makeCollectionsImmutable: $makeCollectionsImmutable, concretePropertiesName: $concretePropertiesName, constructors: $constructors, genericsDefinitionTemplate: $genericsDefinitionTemplate, genericsParameterTemplate: $genericsParameterTemplate, shouldUseExtends: $shouldUseExtends)';
return 'Data(name: $name, unionKey: $unionKey, generateCopyWith: $generateCopyWith, generateEqual: $generateEqual, generateToString: $generateToString, map: $map, when: $when, generateFromJson: $generateFromJson, generateToJson: $generateToJson, makeCollectionsImmutable: $makeCollectionsImmutable, concretePropertiesName: $concretePropertiesName, constructors: $constructors, genericsDefinitionTemplate: $genericsDefinitionTemplate, genericsParameterTemplate: $genericsParameterTemplate, shouldUseExtends: $shouldUseExtends, genericArgumentFactories: $genericArgumentFactories)';
}

@override
Expand Down Expand Up @@ -1476,7 +1494,10 @@ class _$_Data implements _Data {
genericsParameterTemplate) ||
other.genericsParameterTemplate == genericsParameterTemplate) &&
(identical(other.shouldUseExtends, shouldUseExtends) ||
other.shouldUseExtends == shouldUseExtends));
other.shouldUseExtends == shouldUseExtends) &&
(identical(
other.genericArgumentFactories, genericArgumentFactories) ||
other.genericArgumentFactories == genericArgumentFactories));
}

@override
Expand All @@ -1496,7 +1517,8 @@ class _$_Data implements _Data {
const DeepCollectionEquality().hash(constructors),
genericsDefinitionTemplate,
genericsParameterTemplate,
shouldUseExtends);
shouldUseExtends,
genericArgumentFactories);

@JsonKey(ignore: true)
@override
Expand All @@ -1520,7 +1542,8 @@ abstract class _Data implements Data {
required List<ConstructorDetails> constructors,
required GenericsDefinitionTemplate genericsDefinitionTemplate,
required GenericsParameterTemplate genericsParameterTemplate,
required bool shouldUseExtends}) = _$_Data;
required bool shouldUseExtends,
required bool genericArgumentFactories}) = _$_Data;

@override
String get name;
Expand Down Expand Up @@ -1553,6 +1576,8 @@ abstract class _Data implements Data {
@override
bool get shouldUseExtends;
@override
bool get genericArgumentFactories;
@override
@JsonKey(ignore: true)
_$DataCopyWith<_Data> get copyWith => throw _privateConstructorUsedError;
}
Expand Down
28 changes: 27 additions & 1 deletion packages/freezed/README.md
Expand Up @@ -55,6 +55,7 @@ to focus on the definition of your model.
- [Mixins and Interfaces for individual classes for union types](#mixins-and-interfaces-for-individual-classes-for-union-types)
- [FromJson/ToJson](#fromjsontojson)
- [fromJSON - classes with multiple constructors](#fromjson---classes-with-multiple-constructors)
- [Deserializing generic classes](#deserializing-generic-classes)
- [Configurations](#configurations)
- [Changing the behavior for a specific model](#changing-the-behavior-for-a-specific-model)
- [Changing the behavior for the entire project](#changing-the-behavior-for-the-entire-project)
Expand All @@ -81,7 +82,6 @@ flutter pub add json_annotation
flutter pub add --dev json_serializable
```


If you are using creating a Dart project:

```console
Expand Down Expand Up @@ -1074,6 +1074,32 @@ In order to serialize nested lists of freezed objects, you are supposed to eithe
specify a `@JsonSerializable(explicitToJson: true)` or change `explicit_to_json`
inside your `build.yaml` file ([see the documentation](https://github.com/google/json_serializable.dart/tree/master/json_serializable#build-configuration)).

### Deserializing generic classes

In order to de/serialize generic typed freezed objects, you can enable `genericArgumentFactories`.
All you need to do is change the signature of the `fromJson` method and add `genericArgumentFactories: true` to the freezed configuration.

```dart
@Freezed(genericArgumentFactories: true)
class ApiResponse<T> with _$ApiResponse {
const factory ApiResponse<T>.data(T data) = ApiResponseData;
const factory ApiResponse<T>.error(String message) = ApiResponseError;
factory ApiResponse<T>.fromJson(Map<String, dynamic> json, T Function(Object?) fromJsonT) => _$ApiResponseFromJson(json, fromJsonT);
}
```

Alternatively, you can enable `genericArgumentFactories` for the whole project by modifying your `build.yaml` file to include the following:

```yaml
targets:
$default:
builders:
freezed:
options:
generic_argument_factories: true
```

**What about `@JsonKey` annotation?**

All decorators passed to a constructor parameter are "copy-pasted" to the generated
Expand Down
7 changes: 7 additions & 0 deletions packages/freezed/lib/src/freezed_generator.dart
Expand Up @@ -101,6 +101,7 @@ class FreezedGenerator extends ParserGenerator<GlobalData, Data, Freezed> {
generateEqual: configs.equal ?? !_hasCustomEquals(element),
generateFromJson: configs.fromJson ?? await needsJsonSerializable,
generateToJson: configs.toJson ?? await needsJsonSerializable,
genericArgumentFactories: configs.genericArgumentFactories,
map: MapConfig(
map: configs.map?.map ?? shouldGenerateUnions,
mapOrNull: configs.map?.mapOrNull ?? shouldGenerateUnions,
Expand Down Expand Up @@ -507,6 +508,11 @@ Read here: https://github.com/rrousselGit/freezed/blob/master/packages/freezed/C
decode: (obj) => obj.toBoolValue(),
orElse: () => _buildYamlConfigs.toJson,
),
genericArgumentFactories: annotation.decodeField(
'genericArgumentFactories',
decode: (obj) => obj.toBoolValue()!,
orElse: () => _buildYamlConfigs.genericArgumentFactories,
),
toStringOverride: annotation.decodeField(
'toStringOverride',
decode: (obj) => obj.toBoolValue(),
Expand Down Expand Up @@ -583,6 +589,7 @@ Read here: https://github.com/rrousselGit/freezed/blob/master/packages/freezed/C
constructors: data.constructors,
genericParameters: data.genericsParameterTemplate,
genericDefinitions: data.genericsDefinitionTemplate,
genericArgumentFactories: data.genericArgumentFactories,
);
}

Expand Down
1 change: 1 addition & 0 deletions packages/freezed/lib/src/models.dart
Expand Up @@ -91,6 +91,7 @@ class Data with _$Data {
required GenericsDefinitionTemplate genericsDefinitionTemplate,
required GenericsParameterTemplate genericsParameterTemplate,
required bool shouldUseExtends,
required bool genericArgumentFactories,
}) = _Data;
}

Expand Down
41 changes: 33 additions & 8 deletions packages/freezed/lib/src/models.freezed.dart
Expand Up @@ -1085,7 +1085,8 @@ class _$DataTearOff {
required List<ConstructorDetails> constructors,
required GenericsDefinitionTemplate genericsDefinitionTemplate,
required GenericsParameterTemplate genericsParameterTemplate,
required bool shouldUseExtends}) {
required bool shouldUseExtends,
required bool genericArgumentFactories}) {
return _Data(
name: name,
unionKey: unionKey,
Expand All @@ -1102,6 +1103,7 @@ class _$DataTearOff {
genericsDefinitionTemplate: genericsDefinitionTemplate,
genericsParameterTemplate: genericsParameterTemplate,
shouldUseExtends: shouldUseExtends,
genericArgumentFactories: genericArgumentFactories,
);
}
}
Expand Down Expand Up @@ -1129,6 +1131,7 @@ mixin _$Data {
GenericsParameterTemplate get genericsParameterTemplate =>
throw _privateConstructorUsedError;
bool get shouldUseExtends => throw _privateConstructorUsedError;
bool get genericArgumentFactories => throw _privateConstructorUsedError;

@JsonKey(ignore: true)
$DataCopyWith<Data> get copyWith => throw _privateConstructorUsedError;
Expand All @@ -1153,7 +1156,8 @@ abstract class $DataCopyWith<$Res> {
List<ConstructorDetails> constructors,
GenericsDefinitionTemplate genericsDefinitionTemplate,
GenericsParameterTemplate genericsParameterTemplate,
bool shouldUseExtends});
bool shouldUseExtends,
bool genericArgumentFactories});

$MapConfigCopyWith<$Res> get map;
$WhenConfigCopyWith<$Res> get when;
Expand Down Expand Up @@ -1184,6 +1188,7 @@ class _$DataCopyWithImpl<$Res> implements $DataCopyWith<$Res> {
Object? genericsDefinitionTemplate = freezed,
Object? genericsParameterTemplate = freezed,
Object? shouldUseExtends = freezed,
Object? genericArgumentFactories = freezed,
}) {
return _then(_value.copyWith(
name: name == freezed
Expand Down Expand Up @@ -1246,6 +1251,10 @@ class _$DataCopyWithImpl<$Res> implements $DataCopyWith<$Res> {
? _value.shouldUseExtends
: shouldUseExtends // ignore: cast_nullable_to_non_nullable
as bool,
genericArgumentFactories: genericArgumentFactories == freezed
? _value.genericArgumentFactories
: genericArgumentFactories // ignore: cast_nullable_to_non_nullable
as bool,
));
}

Expand Down Expand Up @@ -1284,7 +1293,8 @@ abstract class _$DataCopyWith<$Res> implements $DataCopyWith<$Res> {
List<ConstructorDetails> constructors,
GenericsDefinitionTemplate genericsDefinitionTemplate,
GenericsParameterTemplate genericsParameterTemplate,
bool shouldUseExtends});
bool shouldUseExtends,
bool genericArgumentFactories});

@override
$MapConfigCopyWith<$Res> get map;
Expand Down Expand Up @@ -1318,6 +1328,7 @@ class __$DataCopyWithImpl<$Res> extends _$DataCopyWithImpl<$Res>
Object? genericsDefinitionTemplate = freezed,
Object? genericsParameterTemplate = freezed,
Object? shouldUseExtends = freezed,
Object? genericArgumentFactories = freezed,
}) {
return _then(_Data(
name: name == freezed
Expand Down Expand Up @@ -1380,6 +1391,10 @@ class __$DataCopyWithImpl<$Res> extends _$DataCopyWithImpl<$Res>
? _value.shouldUseExtends
: shouldUseExtends // ignore: cast_nullable_to_non_nullable
as bool,
genericArgumentFactories: genericArgumentFactories == freezed
? _value.genericArgumentFactories
: genericArgumentFactories // ignore: cast_nullable_to_non_nullable
as bool,
));
}
}
Expand All @@ -1402,7 +1417,8 @@ class _$_Data implements _Data {
required this.constructors,
required this.genericsDefinitionTemplate,
required this.genericsParameterTemplate,
required this.shouldUseExtends})
required this.shouldUseExtends,
required this.genericArgumentFactories})
: assert(constructors.isNotEmpty);

@override
Expand Down Expand Up @@ -1435,10 +1451,12 @@ class _$_Data implements _Data {
final GenericsParameterTemplate genericsParameterTemplate;
@override
final bool shouldUseExtends;
@override
final bool genericArgumentFactories;

@override
String toString() {
return 'Data(name: $name, unionKey: $unionKey, generateCopyWith: $generateCopyWith, generateEqual: $generateEqual, generateToString: $generateToString, map: $map, when: $when, generateFromJson: $generateFromJson, generateToJson: $generateToJson, makeCollectionsImmutable: $makeCollectionsImmutable, concretePropertiesName: $concretePropertiesName, constructors: $constructors, genericsDefinitionTemplate: $genericsDefinitionTemplate, genericsParameterTemplate: $genericsParameterTemplate, shouldUseExtends: $shouldUseExtends)';
return 'Data(name: $name, unionKey: $unionKey, generateCopyWith: $generateCopyWith, generateEqual: $generateEqual, generateToString: $generateToString, map: $map, when: $when, generateFromJson: $generateFromJson, generateToJson: $generateToJson, makeCollectionsImmutable: $makeCollectionsImmutable, concretePropertiesName: $concretePropertiesName, constructors: $constructors, genericsDefinitionTemplate: $genericsDefinitionTemplate, genericsParameterTemplate: $genericsParameterTemplate, shouldUseExtends: $shouldUseExtends, genericArgumentFactories: $genericArgumentFactories)';
}

@override
Expand Down Expand Up @@ -1476,7 +1494,10 @@ class _$_Data implements _Data {
genericsParameterTemplate) ||
other.genericsParameterTemplate == genericsParameterTemplate) &&
(identical(other.shouldUseExtends, shouldUseExtends) ||
other.shouldUseExtends == shouldUseExtends));
other.shouldUseExtends == shouldUseExtends) &&
(identical(
other.genericArgumentFactories, genericArgumentFactories) ||
other.genericArgumentFactories == genericArgumentFactories));
}

@override
Expand All @@ -1496,7 +1517,8 @@ class _$_Data implements _Data {
const DeepCollectionEquality().hash(constructors),
genericsDefinitionTemplate,
genericsParameterTemplate,
shouldUseExtends);
shouldUseExtends,
genericArgumentFactories);

@JsonKey(ignore: true)
@override
Expand All @@ -1520,7 +1542,8 @@ abstract class _Data implements Data {
required List<ConstructorDetails> constructors,
required GenericsDefinitionTemplate genericsDefinitionTemplate,
required GenericsParameterTemplate genericsParameterTemplate,
required bool shouldUseExtends}) = _$_Data;
required bool shouldUseExtends,
required bool genericArgumentFactories}) = _$_Data;

@override
String get name;
Expand Down Expand Up @@ -1553,6 +1576,8 @@ abstract class _Data implements Data {
@override
bool get shouldUseExtends;
@override
bool get genericArgumentFactories;
@override
@JsonKey(ignore: true)
_$DataCopyWith<_Data> get copyWith => throw _privateConstructorUsedError;
}
Expand Down

0 comments on commit 0ce1e0c

Please sign in to comment.