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. 335
      packages/dynamite/lib/src/openapi_builder.dart
  2. 2
      packages/dynamite/lib/src/type_result/object.dart

335
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,174 +1520,261 @@ TypeResult resolveType(
), ),
) )
.toList(); .toList();
state.output.add(
final fields = <String, String>{};
for (final result in results) {
final dartName = _toDartName(result.name.replaceFirst(state.prefix, ''));
fields[result.name] = _toFieldName(dartName, result.name.replaceFirst(state.prefix, ''));
}
state.output.addAll([
Class( Class(
(final b) { (final b) {
final fields = <String, String>{};
for (final result in results) {
final dartName = _toDartName(result.name.replaceFirst(state.prefix, ''));
fields[result.name] = _toFieldName(dartName, result.name.replaceFirst(state.prefix, ''));
}
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) ...[
Parameter(
(final b) => b
..name = fields[result.name]!
..toThis = true
..named = true
..required = schema.allOf != null,
),
],
]),
), ),
Constructor( Method(
(final b) { (final b) => b
b ..static = true
..factory = true ..name = 'fromJsonString'
..name = 'fromJson' ..lambda = true
..requiredParameters.add( ..returns = refer('${state.prefix}$identifier')
Parameter( ..requiredParameters.add(
(final b) => b Parameter(
..name = 'data' (final b) => b
..type = refer('dynamic'), ..name = 'data'
), ..type = refer('String'),
) ),
..body = Code( )
<String>[ ..body = const Code('serializers.fromJson(serializer, data)!'),
if (schema.allOf != null) ...[
'return ${state.prefix}$identifier(',
'data,',
for (final result in results) ...[
'${fields[result.name]!}: ${result.deserialize('data')},',
],
');',
] else ...[
for (final result in results) ...[
'${_makeNullable(result.name, true)} ${fields[result.name]!};',
],
for (final result in results) ...[
if (schema.discriminator != null) ...[
"if (data['${schema.discriminator!.propertyName}'] == '${result.name.replaceFirst(state.prefix, '')}'",
if (schema.discriminator!.mapping != null &&
schema.discriminator!.mapping!.isNotEmpty) ...[
for (final key in schema.discriminator!.mapping!.entries
.where(
(final entry) =>
entry.value.endsWith('/${result.name.replaceFirst(state.prefix, '')}'),
)
.map((final entry) => entry.key)) ...[
" || data['${schema.discriminator!.propertyName}'] == '$key'",
],
],
') {',
],
'try {',
'${fields[result.name]!} = ${result.deserialize('data')};',
'} catch (_) {',
if (schema.discriminator != null) ...[
'rethrow;',
],
'}',
if (schema.discriminator != null) ...[
'}',
],
],
if (schema.oneOf != null) ...[
"assert([${fields.values.join(',')}].where((final x) => x != null).length >= 1, 'Need oneOf for \$data');",
],
if (schema.anyOf != null) ...[
"assert([${fields.values.join(',')}].where((final x) => x != null).length >= 1, 'Need anyOf for \$data');",
],
'return ${state.prefix}$identifier(',
'data,',
for (final result in results) ...[
'${fields[result.name]!}: ${fields[result.name]!},',
],
');',
],
].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( Method(
(final b) => b (final b) => b
..name = 'toJson' ..name = 'toJson'
..returns = refer('dynamic') ..returns = refer('Map<String, dynamic>')
..lambda = true ..lambda = true
..body = const Code('_data'), ..body = const Code('serializers.serializeWith(serializer, this)! as Map<String, dynamic>'),
), ),
Method( Method(
(final b) => b (final b) => b
..name = 'toJsonString' ..name = 'toJsonString'
..returns = refer('String') ..returns = refer('String?')
..lambda = true ..lambda = true
..static = 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('json.encode(data)'), ..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(
<String>[
'final result = new ${state.prefix}${identifier}Builder()',
'..data = JsonObject(data);',
if (schema.allOf != null) ...[
for (final result in results) ...[
'result.${fields[result.name]!} = ${result.deserialize('data', toBuilder: true)};',
],
] else ...[
if (schema.discriminator != null) ...[
'if (data is! Map<String, dynamic>) {',
"throw StateError('discriminator is only supported for serializing Json like data.');",
'}',
],
for (final result in results) ...[
if (schema.discriminator != null) ...[
"if (data['${schema.discriminator!.propertyName}'] == '${result.name.replaceFirst(state.prefix, '')}'",
if (schema.discriminator!.mapping != null && schema.discriminator!.mapping!.isNotEmpty) ...[
for (final key in schema.discriminator!.mapping!.entries
.where(
(final entry) =>
entry.value.endsWith('/${result.name.replaceFirst(state.prefix, '')}'),
)
.map((final entry) => entry.key)) ...[
" || data['${schema.discriminator!.propertyName}'] == '$key'",
],
') {',
],
],
'try {',
'result.${fields[result.name]!} = ${result.deserialize('data', toBuilder: true)};',
'} catch (_) {',
if (schema.discriminator != null) ...[
'rethrow;',
],
'}',
if (schema.discriminator != null) ...[
'}',
],
],
if (schema.oneOf != null) ...[
"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) ...[
"assert([${fields.values.map((final e) => 'result._$e').join(',')}].where((final x) => x != null).length >= 1, 'Need anyOf for \${result._data}');",
],
],
'return result.build();',
].join(),
);
}),
]),
),
]);
} }
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