From 8d1f4143bd68c8669bd344b728b0921ac1fc1399 Mon Sep 17 00:00:00 2001 From: Nikolas Rimikis Date: Thu, 18 May 2023 15:02:45 +0200 Subject: [PATCH] dynamite: unify serialization and encoding --- .../dynamite/lib/src/openapi_builder.dart | 28 +++++++++++----- .../dynamite/lib/src/type_result/base.dart | 2 +- .../dynamite/lib/src/type_result/enum.dart | 14 ++++---- .../dynamite/lib/src/type_result/list.dart | 19 +---------- .../dynamite/lib/src/type_result/map.dart | 28 +--------------- .../dynamite/lib/src/type_result/object.dart | 32 ++----------------- .../lib/src/type_result/type_result.dart | 29 ++++++++++++++--- 7 files changed, 56 insertions(+), 96 deletions(-) diff --git a/packages/dynamite/dynamite/lib/src/openapi_builder.dart b/packages/dynamite/dynamite/lib/src/openapi_builder.dart index be020277..f3fe09d4 100644 --- a/packages/dynamite/dynamite/lib/src/openapi_builder.dart +++ b/packages/dynamite/dynamite/lib/src/openapi_builder.dart @@ -779,7 +779,7 @@ class OpenAPIBuilder implements Builder { code.write('if (${_toDartName(parameter.name)} != null) {'); } final value = result.encode( - result.serialize(_toDartName(parameter.name)), + _toDartName(parameter.name), onlyChildren: result is TypeResultList && parameter.in_ == 'query', // Objects inside the query always have to be interpreted in some way mimeType: 'application/json', @@ -858,7 +858,7 @@ class OpenAPIBuilder implements Builder { code.write('if ($parameterName != null) {'); } code.write( - 'body = Uint8List.fromList(utf8.encode(${result.encode(result.serialize(parameterName), mimeType: mimeType)}));', + 'body = Uint8List.fromList(utf8.encode(${result.encode(parameterName, mimeType: mimeType)}));', ); if (dartParameterNullable) { code.write('}'); @@ -1493,9 +1493,13 @@ TypeResult resolveObject( return [ Code("case '$propertyName':"), if (result.className != 'String') ...[ - Code( - 'result.${_toDartName(propertyName)} = ${result.deserialize('jsonDecode(value!)', toBuilder: true)};', - ), + if (result is TypeResultBase || result is TypeResultEnum) ...[ + Code('result.${_toDartName(propertyName)} = ${result.deserialize(result.decode('value!'))};'), + ] else ...[ + Code( + 'result.${_toDartName(propertyName)}.replace(${result.deserialize(result.decode('value!'))});', + ), + ], ] else ...[ Code( 'result.${_toDartName(propertyName)} = value!;', @@ -1512,7 +1516,7 @@ TypeResult resolveObject( const Code('while (iterator.moveNext()) {'), const Code('final key = iterator.current! as String;'), const Code('iterator.moveNext();'), - const Code('final value = iterator.current as String?;'), + const Code('final value = iterator.current! as String;'), const Code('switch (key) {'), for (final propertyName in schema.properties!.keys) ...[ ...deserializeProperty(propertyName), @@ -1749,7 +1753,11 @@ TypeResult resolveType( '..data = JsonObject(data);', if (schema.allOf != null) ...[ for (final result in results) ...[ - 'result.${fields[result.name]!} = ${result.deserialize('data', toBuilder: true)};', + if (result is TypeResultBase || result is TypeResultEnum) ...[ + 'result.${fields[result.name]!} = ${result.deserialize('data')};', + ] else ...[ + 'result.${fields[result.name]!}.replace(${result.deserialize('data')});', + ], ], ] else ...[ if (schema.discriminator != null) ...[ @@ -1786,7 +1794,11 @@ TypeResult resolveType( ], ], 'try {', - 'result.${fields[result.name]!} = ${result.deserialize('data', toBuilder: true)};', + if (result is TypeResultBase || result is TypeResultEnum) ...[ + 'result._${fields[result.name]!} = ${result.deserialize('data')};', + ] else ...[ + 'result._${fields[result.name]!} = ${result.deserialize('data')}.toBuilder();', + ], '} catch (_) {', if (schema.discriminator != null) ...[ 'rethrow;', diff --git a/packages/dynamite/dynamite/lib/src/type_result/base.dart b/packages/dynamite/dynamite/lib/src/type_result/base.dart index 924c98f3..e78a1a1c 100644 --- a/packages/dynamite/dynamite/lib/src/type_result/base.dart +++ b/packages/dynamite/dynamite/lib/src/type_result/base.dart @@ -26,7 +26,7 @@ class TypeResultBase extends TypeResult { return 'JsonObject($object)${nullable ? '?' : ''}'; } - return '($object as $name ${nullable ? '?' : ''})'; + return '($object as $nullableName)'; } @override diff --git a/packages/dynamite/dynamite/lib/src/type_result/enum.dart b/packages/dynamite/dynamite/lib/src/type_result/enum.dart index 742b8217..54e59a70 100644 --- a/packages/dynamite/dynamite/lib/src/type_result/enum.dart +++ b/packages/dynamite/dynamite/lib/src/type_result/enum.dart @@ -12,20 +12,18 @@ class TypeResultEnum extends TypeResult { @override String? get _builderFactory => null; - @override - String serialize(final String object) => '$object.name'; - @override String encode( final String object, { final bool onlyChildren = false, final String? mimeType, - }) => - subType.encode(object); + }) { + if (subType.name == 'String') { + return '$object.name'; + } - @override - String deserialize(final String object, {final bool toBuilder = false}) => - '$name.valueOf($object as ${subType.name})'; + return super.encode(object, mimeType: mimeType); + } @override String decode(final String object) => subType.decode(object); diff --git a/packages/dynamite/dynamite/lib/src/type_result/list.dart b/packages/dynamite/dynamite/lib/src/type_result/list.dart index 944603ba..db00cff9 100644 --- a/packages/dynamite/dynamite/lib/src/type_result/list.dart +++ b/packages/dynamite/dynamite/lib/src/type_result/list.dart @@ -12,9 +12,6 @@ class TypeResultList extends TypeResult { @override String? get _builderFactory => '..addBuilderFactory($fullType, ListBuilder<${subType.className}>.new)'; - @override - String serialize(final String object) => '$object.map((final e) => ${subType.serialize('e')})'; - @override String encode( final String object, { @@ -25,23 +22,9 @@ class TypeResultList extends TypeResult { return '$object.map((final e) => ${subType.encode('e', mimeType: mimeType)})'; } - switch (mimeType) { - case 'application/json': - return 'json.encode($object)'; - case 'application/x-www-form-urlencoded': - return 'Uri(queryParameters: $object).query'; - default: - throw Exception('Can not encode mime type "$mimeType"'); - } + return super.encode(object, mimeType: mimeType); } - @override - String deserialize(final String object, {final bool toBuilder = false}) => - '$name(($object as List).map((final e) => ${subType.deserialize('e')}))${toBuilder ? '.toBuilder()' : ''}'; - - @override - String decode(final String object) => 'json.decode($object as String)'; - @override TypeResultList get dartType => TypeResultList('List', subType, nullable: nullable); } diff --git a/packages/dynamite/dynamite/lib/src/type_result/map.dart b/packages/dynamite/dynamite/lib/src/type_result/map.dart index 599daeff..6e0efdcc 100644 --- a/packages/dynamite/dynamite/lib/src/type_result/map.dart +++ b/packages/dynamite/dynamite/lib/src/type_result/map.dart @@ -10,33 +10,7 @@ class TypeResultMap extends TypeResult { TypeResult get subType => generics[1]; @override - String? get _builderFactory => '..addBuilderFactory($fullType, ListBuilder.new)'; - - @override - String serialize(final String object) => object; - - @override - String encode( - final String object, { - final bool onlyChildren = false, - final String? mimeType, - }) { - switch (mimeType) { - case 'application/json': - return 'json.encode($object)'; - case 'application/x-www-form-urlencoded': - return 'Uri(queryParameters: $object).query'; - default: - throw Exception('Can not encode mime type "$mimeType"'); - } - } - - @override - String deserialize(final String object, {final bool toBuilder = false}) => - '($object as $className)${toBuilder ? '.toBuilder()' : ''}'; - - @override - String decode(final String object) => 'json.decode($object as String)'; + String? get _builderFactory => '..addBuilderFactory($fullType, MapBuilder.new)'; @override TypeResultMap get dartType => TypeResultMap('Map', subType, nullable: nullable); diff --git a/packages/dynamite/dynamite/lib/src/type_result/object.dart b/packages/dynamite/dynamite/lib/src/type_result/object.dart index 85a96823..c93c049c 100644 --- a/packages/dynamite/dynamite/lib/src/type_result/object.dart +++ b/packages/dynamite/dynamite/lib/src/type_result/object.dart @@ -15,15 +15,6 @@ class TypeResultObject extends TypeResult { @override String? get _builderFactory => '..addBuilderFactory($fullType, $name.new)'; - @override - String serialize(final String object) { - if (className == _contentString) { - return 'jsonSerializers.serialize(messages, specifiedType: const $fullType)'; - } - - return '$object.toJson()'; - } - @override String encode( final String object, { @@ -32,28 +23,9 @@ class TypeResultObject extends TypeResult { }) { if (className == _contentString) { assert(mimeType == 'application/json', '$_contentString should have a mimeType of application/json'); - return object; - } - - switch (mimeType) { - case 'application/json': - return 'json.encode($object)'; - case 'application/x-www-form-urlencoded': - return 'Uri(queryParameters: $object).query'; - default: - throw Exception('Can not encode mime type "$mimeType"'); + return serialize(object); } - } - @override - String deserialize(final String object, {final bool toBuilder = false}) { - if (className == 'ContentString') { - return 'jsonSerializers.deserialize(messages, specifiedType: const $fullType)! as $name${nullable ? '?' : ''}'; - } - - return '$name.fromJson($object as Object${nullable ? '?' : ''})${nullable && toBuilder ? '?' : ''}${toBuilder ? '.toBuilder()' : ''}'; + return super.encode(object, onlyChildren: onlyChildren, mimeType: mimeType); } - - @override - String decode(final String object) => 'json.decode($object as String)'; } diff --git a/packages/dynamite/dynamite/lib/src/type_result/type_result.dart b/packages/dynamite/dynamite/lib/src/type_result/type_result.dart index 6c6b6931..950fb70e 100644 --- a/packages/dynamite/dynamite/lib/src/type_result/type_result.dart +++ b/packages/dynamite/dynamite/lib/src/type_result/type_result.dart @@ -46,18 +46,39 @@ abstract class TypeResult { String? get _builderFactory; - String serialize(final String object); + /// Serializes the variable named [object]. + /// + /// The serialized result is an [Object]? + String serialize(final String object) => 'jsonSerializers.serialize($object, specifiedType: const $fullType)'; - String deserialize(final String object, {final bool toBuilder = false}); + /// Deserializes the variable named [object]. + /// + /// The serialized result will be of [name]. + String deserialize(final String object) => + '(jsonSerializers.deserialize($object, specifiedType: const $fullType)! as $name)'; - String decode(final String object); + /// Decodes the variable named [object]. + String decode(final String object) => 'json.decode($object as String)'; + /// Encodes the variable named [object]. String encode( final String object, { final bool onlyChildren = false, final String? mimeType, - }); + }) { + final serialized = serialize(object); + switch (mimeType) { + case 'application/json': + return 'json.encode($serialized)'; + case 'application/x-www-form-urlencoded': + return 'Uri(queryParameters: $serialized! as Map).query'; + default: + throw Exception('Can not encode mime type "$mimeType"'); + } + } + + /// Nullable TypeName String get nullableName => nullable ? '$name?' : name; /// Native dart type equivalent