Browse Source

dynamite: built_value oneOf, anyOf, allOf

Signed-off-by: Nikolas Rimikis <rimikis.nikolas@gmail.com>
pull/194/head
Nikolas Rimikis 2 years ago
parent
commit
c48f13824f
No known key found for this signature in database
GPG Key ID: 85ED1DE9786A4FF2
  1. 273
      packages/dynamite/lib/src/openapi_builder.dart
  2. 2
      packages/dynamite/lib/src/type_result/object.dart

273
packages/dynamite/lib/src/openapi_builder.dart

@ -1312,7 +1312,7 @@ TypeResult resolveObject(
Parameter( Parameter(
(final b) => b (final b) => b
..name = 'json' ..name = 'json'
..type = refer('Map<String, dynamic>'), ..type = refer('Object'),
), ),
) )
..body = const Code('serializers.deserializeWith(serializer, json)!'), ..body = const Code('serializers.deserializeWith(serializer, json)!'),
@ -1520,91 +1520,225 @@ TypeResult resolveType(
), ),
) )
.toList(); .toList();
state.output.add(
Class(
(final b) {
final fields = <String, String>{}; final fields = <String, String>{};
for (final result in results) { for (final result in results) {
final dartName = _toDartName(result.name.replaceFirst(state.prefix, '')); final dartName = _toDartName(result.name.replaceFirst(state.prefix, ''));
fields[result.name] = _toFieldName(dartName, result.name.replaceFirst(state.prefix, '')); fields[result.name] = _toFieldName(dartName, result.name.replaceFirst(state.prefix, ''));
} }
state.output.addAll([
Class(
(final b) {
b b
..name = '${state.prefix}$identifier' ..name = '${state.prefix}$identifier'
..fields.addAll([ ..abstract = true
Field( ..implements.add(
refer(
'Built<${state.prefix}$identifier, ${state.prefix}${identifier}Builder>',
),
)
..constructors.addAll([
Constructor(
(final b) => b
..name = '_'
..constant = true,
),
Constructor(
(final b) => b
..factory = true
..lambda = true
..optionalParameters.add(
Parameter(
(final b) => b
..name = 'b'
..type = refer('void Function(${state.prefix}${identifier}Builder)?'),
),
)
..redirect = refer('_\$${state.prefix}$identifier'),
),
])
..methods.addAll([
Method(
(final b) { (final b) {
b b
..name = '_data' ..name = 'data'
..type = refer('dynamic') ..returns = refer('JsonObject')
..modifier = FieldModifier.final$; ..type = MethodType.getter;
}, },
), ),
for (final result in results) ...[ for (final result in results) ...[
Field( Method(
(final b) { (final b) {
final s = schema.ofs![results.indexOf(result)]; final s = schema.ofs![results.indexOf(result)];
b b
..name = fields[result.name] ..name = fields[result.name]
..type = refer(_makeNullable(result.name, !(schema.allOf?.contains(s) ?? false))) ..returns = refer(_makeNullable(result.name, !(schema.allOf?.contains(s) ?? false)))
..modifier = FieldModifier.final$ ..type = MethodType.getter
..docs.addAll(_descriptionToDocs(s.description)); ..docs.addAll(_descriptionToDocs(s.description));
}, },
), ),
], ],
]) Method(
..constructors.addAll([
Constructor(
(final b) => b (final b) => b
..static = true
..name = 'fromJson'
..lambda = true
..returns = refer('${state.prefix}$identifier')
..requiredParameters.add( ..requiredParameters.add(
Parameter( Parameter(
(final b) => b (final b) => b
..name = '_data' ..name = 'json'
..toThis = true, ..type = refer('Object'),
), ),
) )
..optionalParameters.addAll([ ..body = const Code('serializers.deserializeWith(serializer, json)!'),
for (final result in results) ...[ ),
Method(
(final b) => b
..static = true
..name = 'fromJsonString'
..lambda = true
..returns = refer('${state.prefix}$identifier')
..requiredParameters.add(
Parameter( Parameter(
(final b) => b (final b) => b
..name = fields[result.name]! ..name = 'data'
..toThis = true ..type = refer('String'),
..named = true
..required = schema.allOf != null,
), ),
], )
]), ..body = const Code('serializers.fromJson(serializer, data)!'),
), ),
Constructor( Method(
(final b) { (final b) => b
b ..name = 'toJson'
..factory = true ..returns = refer('Map<String, dynamic>')
..name = 'fromJson' ..lambda = true
..body = const Code('serializers.serializeWith(serializer, this)! as Map<String, dynamic>'),
),
Method(
(final b) => b
..name = 'toJsonString'
..returns = refer('String?')
..lambda = true
..static = true
..requiredParameters.add( ..requiredParameters.add(
Parameter( Parameter(
(final b) => b (final b) => b
..name = 'data' ..name = 'data'
..type = refer('dynamic'), ..type = refer(_makeNullable('${state.prefix}$identifier', true)),
),
)
..body = const Code('data == null ? null : serializers.toJson(serializer, data)'),
),
Method(
(final b) => b
..name = 'serializer'
..returns = refer('Serializer<${state.prefix}$identifier>')
..lambda = true
..static = true
..annotations.add(refer('BuiltValueSerializer').call([], {'custom': refer('true')}))
..body = Code('_\$${state.prefix}${identifier}Serializer()')
..type = MethodType.getter,
),
]);
},
),
Class(
(final b) => b
..name = '_\$${state.prefix}${identifier}Serializer'
..implements.add(refer('PrimitiveSerializer<${state.prefix}$identifier>'))
..fields.addAll([
Field(
(final b) => b
..name = 'types'
..modifier = FieldModifier.final$
..type = refer('Iterable<Type>')
..annotations.add(refer('override'))
..assignment = Code('const [${state.prefix}$identifier, _\$${state.prefix}$identifier]'),
),
Field(
(final b) => b
..name = 'wireName'
..modifier = FieldModifier.final$
..type = refer('String')
..annotations.add(refer('override'))
..assignment = Code("r'${state.prefix}$identifier'"),
)
])
..methods.addAll([
Method((final b) {
b
..name = 'serialize'
..returns = refer('Object')
..annotations.add(refer('override'))
..requiredParameters.addAll([
Parameter(
(final b) => b
..name = 'serializers'
..type = refer('Serializers'),
),
Parameter(
(final b) => b
..name = 'object'
..type = refer('${state.prefix}$identifier'),
),
])
..optionalParameters.add(
Parameter(
(final b) => b
..name = 'specifiedType'
..type = refer('FullType')
..named = true
..defaultTo = const Code('FullType.unspecified'),
),
)
..body = const Code('return object.data.value;');
}),
Method((final b) {
b
..name = 'deserialize'
..returns = refer('${state.prefix}$identifier')
..annotations.add(refer('override'))
..requiredParameters.addAll([
Parameter(
(final b) => b
..name = 'serializers'
..type = refer('Serializers'),
),
Parameter(
(final b) => b
..name = 'data'
..type = refer('Object'),
),
])
..optionalParameters.add(
Parameter(
(final b) => b
..name = 'specifiedType'
..type = refer('FullType')
..named = true
..defaultTo = const Code('FullType.unspecified'),
), ),
) )
..body = Code( ..body = Code(
<String>[ <String>[
'final result = new ${state.prefix}${identifier}Builder()',
'..data = JsonObject(data);',
if (schema.allOf != null) ...[ if (schema.allOf != null) ...[
'return ${state.prefix}$identifier(',
'data,',
for (final result in results) ...[ for (final result in results) ...[
'${fields[result.name]!}: ${result.deserialize('data')},', 'result.${fields[result.name]!} = ${result.deserialize('data', toBuilder: true)};',
], ],
');',
] else ...[ ] else ...[
for (final result in results) ...[ if (schema.discriminator != null) ...[
'${_makeNullable(result.name, true)} ${fields[result.name]!};', 'if (data is! Map<String, dynamic>) {',
"throw StateError('discriminator is only supported for serializing Json like data.');",
'}',
], ],
for (final result in results) ...[ for (final result in results) ...[
if (schema.discriminator != null) ...[ if (schema.discriminator != null) ...[
"if (data['${schema.discriminator!.propertyName}'] == '${result.name.replaceFirst(state.prefix, '')}'", "if (data['${schema.discriminator!.propertyName}'] == '${result.name.replaceFirst(state.prefix, '')}'",
if (schema.discriminator!.mapping != null && if (schema.discriminator!.mapping != null && schema.discriminator!.mapping!.isNotEmpty) ...[
schema.discriminator!.mapping!.isNotEmpty) ...[
for (final key in schema.discriminator!.mapping!.entries for (final key in schema.discriminator!.mapping!.entries
.where( .where(
(final entry) => (final entry) =>
@ -1613,11 +1747,11 @@ TypeResult resolveType(
.map((final entry) => entry.key)) ...[ .map((final entry) => entry.key)) ...[
" || data['${schema.discriminator!.propertyName}'] == '$key'", " || data['${schema.discriminator!.propertyName}'] == '$key'",
], ],
],
') {', ') {',
], ],
],
'try {', 'try {',
'${fields[result.name]!} = ${result.deserialize('data')};', 'result.${fields[result.name]!} = ${result.deserialize('data', toBuilder: true)};',
'} catch (_) {', '} catch (_) {',
if (schema.discriminator != null) ...[ if (schema.discriminator != null) ...[
'rethrow;', 'rethrow;',
@ -1628,66 +1762,19 @@ TypeResult resolveType(
], ],
], ],
if (schema.oneOf != null) ...[ if (schema.oneOf != null) ...[
"assert([${fields.values.join(',')}].where((final x) => x != null).length >= 1, 'Need oneOf for \$data');", "assert([${fields.values.map((final e) => 'result._$e').join(',')}].where((final x) => x != null).length >= 1, 'Need oneOf for \${result._data}');",
], ],
if (schema.anyOf != null) ...[ if (schema.anyOf != null) ...[
"assert([${fields.values.join(',')}].where((final x) => x != null).length >= 1, 'Need anyOf for \$data');", "assert([${fields.values.map((final e) => 'result._$e').join(',')}].where((final x) => x != null).length >= 1, 'Need anyOf for \${result._data}');",
], ],
'return ${state.prefix}$identifier(',
'data,',
for (final result in results) ...[
'${fields[result.name]!}: ${fields[result.name]!},',
],
');',
], ],
'return result.build();',
].join(), ].join(),
); );
}, }),
), ]),
Constructor(
(final b) {
b
..factory = true
..lambda = true
..name = 'fromJsonString'
..requiredParameters.add(
Parameter(
(final b) => b
..name = 'data'
..type = refer('String'),
),
)
..body = Code('${state.prefix}$identifier.fromJson(json.decode(data))');
},
),
])
..methods.addAll([
Method(
(final b) => b
..name = 'toJson'
..returns = refer('dynamic')
..lambda = true
..body = const Code('_data'),
),
Method(
(final b) => b
..name = 'toJsonString'
..returns = refer('String')
..lambda = true
..static = true
..requiredParameters.add(
Parameter(
(final b) => b
..name = 'data'
..type = refer('dynamic'),
),
)
..body = const Code('json.encode(data)'),
), ),
]); ]);
},
),
);
} }
result = TypeResultObject('${state.prefix}$identifier'); result = TypeResultObject('${state.prefix}$identifier');

2
packages/dynamite/lib/src/type_result/object.dart

@ -37,7 +37,7 @@ class TypeResultObject extends TypeResult {
if (fromContentString) { if (fromContentString) {
return '$name.fromJsonString($object as String)${toBuilder ? '.toBuilder()' : ''}'; return '$name.fromJsonString($object as String)${toBuilder ? '.toBuilder()' : ''}';
} }
return '$name.fromJson($object as Map<String, dynamic>)${toBuilder ? '.toBuilder()' : ''}'; return '$name.fromJson($object as Object)${toBuilder ? '.toBuilder()' : ''}';
} }
@override @override

Loading…
Cancel
Save