Skip to content

Commit

Permalink
feat: Add JsonSerializable(createJsonMeta)
Browse files Browse the repository at this point in the history
  • Loading branch information
rrousselGit committed Jun 24, 2022
1 parent dee0e5a commit e386254
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 0 deletions.
8 changes: 8 additions & 0 deletions json_annotation/lib/src/json_serializable.dart
Expand Up @@ -64,6 +64,13 @@ class JsonSerializable {
/// This setting has no effect if [createFactory] is `false`.
final String? constructor;

/// If `true` (defaults to false), a private, static `_$ExampleJsonMeta`
/// constant is created in the generated part file.
///
/// This constant can be used by other code-generators to support features
/// such as [fieldRename].
final bool? createJsonMeta;

/// If `true` (the default), a private, static `_$ExampleFromJson` method
/// is created in the generated part file.
///
Expand Down Expand Up @@ -231,6 +238,7 @@ class JsonSerializable {
this.anyMap,
this.checked,
this.constructor,
this.createJsonMeta,
this.createFactory,
this.createToJson,
this.disallowUnrecognizedKeys,
Expand Down
20 changes: 20 additions & 0 deletions json_serializable/lib/src/encoder_helper.dart
Expand Up @@ -16,6 +16,26 @@ import 'unsupported_type_error.dart';
abstract class EncodeHelper implements HelperCore {
String _fieldAccess(FieldElement field) => '$_toJsonParamName.${field.name}';

/// Generates an object containing metadatas related to the encoding,
/// destined to be used by other code-generators.
String createJsonMeta(Set<FieldElement> accessibleFieldSet) {
assert(config.createJsonMeta);

final buffer =
StringBuffer('const _\$${element.name}JsonMeta = <String, String> {');

for (final field in accessibleFieldSet) {
buffer.writeln(
'${escapeDartString(field.name)}: '
'${escapeDartString(nameAccess(field))},',
);
}

buffer.write('};');

return buffer.toString();
}

Iterable<String> createToJson(Set<FieldElement> accessibleFields) sync* {
assert(config.createToJson);

Expand Down
4 changes: 4 additions & 0 deletions json_serializable/lib/src/generator_helper.dart
Expand Up @@ -108,6 +108,10 @@ class GeneratorHelper extends HelperCore with EncodeHelper, DecodeHelper {
},
);

if (config.createJsonMeta) {
yield createJsonMeta(accessibleFieldSet);
}

if (config.createToJson) {
yield* createToJson(accessibleFieldSet);
}
Expand Down
6 changes: 6 additions & 0 deletions json_serializable/lib/src/type_helpers/config_types.dart
Expand Up @@ -45,6 +45,7 @@ class ClassConfig {
final String constructor;
final bool createFactory;
final bool createToJson;
final bool createJsonMeta;
final bool disallowUnrecognizedKeys;
final bool explicitToJson;
final FieldRename fieldRename;
Expand All @@ -60,6 +61,7 @@ class ClassConfig {
required this.constructor,
required this.createFactory,
required this.createToJson,
required this.createJsonMeta,
required this.disallowUnrecognizedKeys,
required this.explicitToJson,
required this.fieldRename,
Expand All @@ -76,6 +78,8 @@ class ClassConfig {
checked: config.checked ?? ClassConfig.defaults.checked,
anyMap: config.anyMap ?? ClassConfig.defaults.anyMap,
constructor: config.constructor ?? ClassConfig.defaults.constructor,
createJsonMeta:
config.createJsonMeta ?? ClassConfig.defaults.createJsonMeta,
createFactory:
config.createFactory ?? ClassConfig.defaults.createFactory,
createToJson: config.createToJson ?? ClassConfig.defaults.createToJson,
Expand All @@ -101,6 +105,7 @@ class ClassConfig {
constructor: '',
createFactory: true,
createToJson: true,
createJsonMeta: false,
disallowUnrecognizedKeys: false,
explicitToJson: false,
fieldRename: FieldRename.none,
Expand All @@ -115,6 +120,7 @@ class ClassConfig {
constructor: constructor,
createFactory: createFactory,
createToJson: createToJson,
createJsonMeta: createJsonMeta,
ignoreUnannotated: ignoreUnannotated,
explicitToJson: explicitToJson,
includeIfNull: includeIfNull,
Expand Down
2 changes: 2 additions & 0 deletions json_serializable/lib/src/utils.dart
Expand Up @@ -56,6 +56,7 @@ JsonSerializable _valueForAnnotation(ConstantReader reader) => JsonSerializable(
constructor: reader.read('constructor').literalValue as String?,
createFactory: reader.read('createFactory').literalValue as bool?,
createToJson: reader.read('createToJson').literalValue as bool?,
createJsonMeta: reader.read('createJsonMeta').literalValue as bool?,
disallowUnrecognizedKeys:
reader.read('disallowUnrecognizedKeys').literalValue as bool?,
explicitToJson: reader.read('explicitToJson').literalValue as bool?,
Expand Down Expand Up @@ -101,6 +102,7 @@ ClassConfig mergeConfig(
constructor: constructor,
createFactory: annotation.createFactory ?? config.createFactory,
createToJson: annotation.createToJson ?? config.createToJson,
createJsonMeta: annotation.createJsonMeta ?? config.createJsonMeta,
disallowUnrecognizedKeys:
annotation.disallowUnrecognizedKeys ?? config.disallowUnrecognizedKeys,
explicitToJson: annotation.explicitToJson ?? config.explicitToJson,
Expand Down
1 change: 1 addition & 0 deletions json_serializable/test/config_test.dart
Expand Up @@ -152,6 +152,7 @@ const _invalidConfig = {
'checked': 42,
'constructor': 42,
'create_factory': 42,
'create_json_meta': 42,
'create_to_json': 42,
'disallow_unrecognized_keys': 42,
'explicit_to_json': 42,
Expand Down
11 changes: 11 additions & 0 deletions json_serializable/test/integration/integration_test.dart
Expand Up @@ -7,6 +7,7 @@ import 'package:test/test.dart';

import '../test_utils.dart';
import 'json_enum_example.dart';
import 'json_meta_example.dart';
import 'json_test_common.dart' show Category, Platform, StatusCode;
import 'json_test_example.dart';

Expand Down Expand Up @@ -322,4 +323,14 @@ void main() {
isNull,
);
});

test(r'_$ModelJsonMeta', () {
expect(
modelMeta,
{
'firstName': 'first-name',
'lastName': 'LAST_NAME',
},
);
});
}
28 changes: 28 additions & 0 deletions json_serializable/test/integration/json_meta_example.dart
@@ -0,0 +1,28 @@
import 'package:json_annotation/json_annotation.dart';

part 'json_meta_example.g.dart';

@JsonSerializable(createJsonMeta: true, fieldRename: FieldRename.kebab)
class Model {
Model({
required this.firstName,
required this.lastName,
this.ignoredName,
});

factory Model.fromJson(Map<String, Object?> json) => _$ModelFromJson(json);

final String firstName;

@JsonKey(name: 'LAST_NAME')
final String lastName;

@JsonKey(ignore: true)
final String? ignoredName;

String get fullName => '$firstName $lastName';

Map<String, Object?> toJson() => _$ModelToJson(this);
}

const modelMeta = _$ModelJsonMeta;
24 changes: 24 additions & 0 deletions json_serializable/test/integration/json_meta_example.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions json_serializable/test/shared_config.dart
Expand Up @@ -19,6 +19,7 @@ final generatorConfigNonDefaultJson =
constructor: 'something',
createFactory: false,
createToJson: false,
createJsonMeta: true,
disallowUnrecognizedKeys: true,
explicitToJson: true,
fieldRename: FieldRename.kebab,
Expand Down
1 change: 1 addition & 0 deletions json_serializable/test/test_sources/test_sources.dart
Expand Up @@ -15,6 +15,7 @@ class ConfigurationImplicitDefaults {
constructor: '',
createFactory: true,
createToJson: true,
createJsonMeta: false,
disallowUnrecognizedKeys: false,
explicitToJson: false,
fieldRename: FieldRename.none,
Expand Down

0 comments on commit e386254

Please sign in to comment.