From 0f9257aa12da00a79a109fdfcde8edfa193c148f Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Thu, 30 Jun 2022 19:51:29 +0100 Subject: [PATCH 1/6] Codegenerate Python application example. Explicitly call from complex types in JSON deserialization if the shape has been overriden by the symbol provider --- .../generators/PythonApplicationGenerator.kt | 75 ++++++++++++++++++- .../protocols/parse/JsonParserGenerator.kt | 20 ++++- .../smithy/protocols/parse/ParserUtil.kt | 33 ++++++++ 3 files changed, 121 insertions(+), 7 deletions(-) create mode 100644 codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt index cc4b1cbd7a..0dccdabb64 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt @@ -6,13 +6,21 @@ package software.amazon.smithy.rust.codegen.server.python.smithy.generators import software.amazon.smithy.model.shapes.OperationShape +import software.amazon.smithy.model.traits.DocumentationTrait import software.amazon.smithy.rust.codegen.rustlang.RustWriter import software.amazon.smithy.rust.codegen.rustlang.asType +import software.amazon.smithy.rust.codegen.rustlang.rust import software.amazon.smithy.rust.codegen.rustlang.rustBlockTemplate import software.amazon.smithy.rust.codegen.rustlang.rustTemplate import software.amazon.smithy.rust.codegen.server.python.smithy.PythonServerCargoDependency import software.amazon.smithy.rust.codegen.server.smithy.ServerCargoDependency import software.amazon.smithy.rust.codegen.smithy.CoreCodegenContext +import software.amazon.smithy.rust.codegen.smithy.Errors +import software.amazon.smithy.rust.codegen.smithy.Inputs +import software.amazon.smithy.rust.codegen.smithy.Outputs +import software.amazon.smithy.rust.codegen.util.getTrait +import software.amazon.smithy.rust.codegen.util.inputShape +import software.amazon.smithy.rust.codegen.util.outputShape import software.amazon.smithy.rust.codegen.util.toSnakeCase /** @@ -56,8 +64,10 @@ class PythonApplicationGenerator( coreCodegenContext: CoreCodegenContext, private val operations: List, ) { + private val crateName = coreCodegenContext.settings.moduleName private val symbolProvider = coreCodegenContext.symbolProvider private val runtimeConfig = coreCodegenContext.runtimeConfig + private val model = coreCodegenContext.model private val codegenScope = arrayOf( "SmithyPython" to PythonServerCargoDependency.SmithyHttpServerPython(runtimeConfig).asType(), @@ -73,10 +83,9 @@ class PythonApplicationGenerator( ) fun render(writer: RustWriter) { + renderPyApplicationRustDocs(writer) writer.rustTemplate( """ - /// Main Python application, used to register operations and context and start multiple - /// workers on the same shared socket. ##[#{pyo3}::pyclass] ##[derive(Debug, Clone)] pub struct App { @@ -127,7 +136,7 @@ class PythonApplicationGenerator( ) rustBlockTemplate( """ - /// Dynamically codegenerate the routes, allowing to build the Smithy [Router]. + /// Dynamically codegenerate the routes, allowing to build the Smithy [#{SmithyServer}::Router]. pub fn build_router(&mut self, py: #{pyo3}::Python) -> #{pyo3}::PyResult<()> """, *codegenScope @@ -179,4 +188,64 @@ class PythonApplicationGenerator( } } } + + private fun renderPyApplicationRustDocs(writer: RustWriter) { + writer.rust( + """ + ##[allow(clippy::tabs_in_doc_comments)] + /// Main Python application, used to register operations and context and start multiple + /// workers on the same shared socket. + /// + /// Here's a full example to get you started: + /// + /// ```python + ${ if (operations.any { it.errors.isNotEmpty() }) { + """/// from $crateName import ${Inputs.namespace} +/// from $crateName import ${Outputs.namespace} +/// from $crateName import ${Errors.namespace}""" + } else { +"""/// from $crateName import ${Inputs.namespace} +/// from $crateName import ${Outputs.namespace}""" + } } +/// from $crateName import App +/// +/// @dataclass +/// class Context: +/// counter: int = 0 +/// +/// app = App() +/// app.context(Context()) +/// +${operationImplementationStubs(operations)} +/// +/// app.run() +/// ``` + """ + ) + } + + private fun operationImplementationStubs(operations: List): String = + operations.joinToString("\n///\n") { + val operationDocumentation = it.getTrait()?.value + val ret = if (!operationDocumentation.isNullOrBlank()) { + operationDocumentation.replace("#", "##").prependIndent("/// ## ") + "\n" + } else "" + ret + + """ + /// ${it.signature()}: + /// raise NotImplementedError + """.trimIndent() + } + + /** + * Returns the function signature for an operation handler implementation. Used in the documentation. + */ + private fun OperationShape.signature(): String { + val inputSymbol = symbolProvider.toSymbol(inputShape(model)) + val outputSymbol = symbolProvider.toSymbol(outputShape(model)) + val inputT = "${Inputs.namespace}::${inputSymbol.name}" + val outputT = "${Outputs.namespace}::${outputSymbol.name}" + val operationName = symbolProvider.toSymbol(this).name.toSnakeCase() + return "@app.$operationName\n/// async def $operationName(input: $inputT, ctx: Context) -> $outputT" + } } diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/JsonParserGenerator.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/JsonParserGenerator.kt index 1bb82d09e3..7d0a5f9943 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/JsonParserGenerator.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/JsonParserGenerator.kt @@ -65,6 +65,7 @@ class JsonParserGenerator( private val target = coreCodegenContext.target private val smithyJson = CargoDependency.smithyJson(runtimeConfig).asType() private val jsonDeserModule = RustModule.private("json_deser") + private val util = ParserUtil(symbolProvider, runtimeConfig) private val codegenScope = arrayOf( "Error" to smithyJson.member("deserialize::Error"), "ErrorReason" to smithyJson.member("deserialize::ErrorReason"), @@ -221,8 +222,8 @@ class JsonParserGenerator( is StringShape -> deserializeString(target) is BooleanShape -> rustTemplate("#{expect_bool_or_null}(tokens.next())?", *codegenScope) is NumberShape -> deserializeNumber(target) - is BlobShape -> rustTemplate("#{expect_blob_or_null}(tokens.next())?", *codegenScope) - is TimestampShape -> deserializeTimestamp(memberShape) + is BlobShape -> deserializeBlob(target) + is TimestampShape -> deserializeTimestamp(target, memberShape) is CollectionShape -> deserializeCollection(target) is MapShape -> deserializeMap(target) is StructureShape -> deserializeStruct(target) @@ -236,6 +237,14 @@ class JsonParserGenerator( } } + private fun RustWriter.deserializeBlob(target: BlobShape) { + rustTemplate( + "#{expect_blob_or_null}(tokens.next())?#{ConvertFrom:W}", + "ConvertFrom" to util.convertViaFrom(target), + *codegenScope + ) + } + private fun RustWriter.deserializeStringInner(target: StringShape, escapedStrName: String) { withBlock("$escapedStrName.to_unescaped().map(|u|", ")") { when (target.hasTrait()) { @@ -266,14 +275,17 @@ class JsonParserGenerator( rustTemplate("#{expect_number_or_null}(tokens.next())?.map(|v| v.to_#{T}())", "T" to symbol, *codegenScope) } - private fun RustWriter.deserializeTimestamp(member: MemberShape) { + private fun RustWriter.deserializeTimestamp(shape: TimestampShape, member: MemberShape) { val timestampFormat = httpBindingResolver.timestampFormat( member, HttpLocation.DOCUMENT, TimestampFormatTrait.Format.EPOCH_SECONDS ) val timestampFormatType = RuntimeType.TimestampFormat(runtimeConfig, timestampFormat) - rustTemplate("#{expect_timestamp_or_null}(tokens.next(), #{T})?", "T" to timestampFormatType, *codegenScope) + rustTemplate( + "#{expect_timestamp_or_null}(tokens.next(), #{T})?#{ConvertFrom:W}", + "T" to timestampFormatType, "ConvertFrom" to util.convertViaFrom(shape), *codegenScope + ) } private fun RustWriter.deserializeCollection(shape: CollectionShape) { diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt new file mode 100644 index 0000000000..5cc6479b1e --- /dev/null +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt @@ -0,0 +1,33 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rust.codegen.smithy.protocols.parse + +import software.amazon.smithy.model.shapes.BlobShape +import software.amazon.smithy.model.shapes.Shape +import software.amazon.smithy.model.shapes.TimestampShape +import software.amazon.smithy.rust.codegen.rustlang.Writable +import software.amazon.smithy.rust.codegen.rustlang.rust +import software.amazon.smithy.rust.codegen.rustlang.writable +import software.amazon.smithy.rust.codegen.smithy.RuntimeConfig +import software.amazon.smithy.rust.codegen.smithy.RuntimeType +import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider +import software.amazon.smithy.rust.codegen.smithy.rustType + +class ParserUtil(private val symbolProvider: RustSymbolProvider, private val runtimeConfig: RuntimeConfig) { + fun convertViaFrom(shape: Shape): Writable = + writable { + val oldSymbol = when (shape) { + // TODO(understand what needs to be done for ByteStream) + is BlobShape -> RuntimeType.Blob(runtimeConfig).toSymbol() + is TimestampShape -> RuntimeType.DateTime(runtimeConfig).toSymbol() + else -> symbolProvider.toSymbol(shape) + } + val newSymbol = symbolProvider.toSymbol(shape) + if (oldSymbol.rustType() != newSymbol.rustType()) { + rust(".map($newSymbol::from)") + } + } +} From 1fbaf2d37d7d74ff0e5d25c4f9070117375a131e Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Thu, 30 Jun 2022 19:53:39 +0100 Subject: [PATCH 2/6] Fix indentation --- .../generators/PythonApplicationGenerator.kt | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt index 0dccdabb64..ae8c497547 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt @@ -190,23 +190,22 @@ class PythonApplicationGenerator( } private fun renderPyApplicationRustDocs(writer: RustWriter) { - writer.rust( - """ - ##[allow(clippy::tabs_in_doc_comments)] - /// Main Python application, used to register operations and context and start multiple - /// workers on the same shared socket. - /// - /// Here's a full example to get you started: - /// - /// ```python - ${ if (operations.any { it.errors.isNotEmpty() }) { - """/// from $crateName import ${Inputs.namespace} + writer.rust(""" +##[allow(clippy::tabs_in_doc_comments)] +/// Main Python application, used to register operations and context and start multiple +/// workers on the same shared socket. +/// +/// Here's a full example to get you started: +/// +/// ```python +${ if (operations.any { it.errors.isNotEmpty() }) { +"""/// from $crateName import ${Inputs.namespace} /// from $crateName import ${Outputs.namespace} /// from $crateName import ${Errors.namespace}""" - } else { +} else { """/// from $crateName import ${Inputs.namespace} /// from $crateName import ${Outputs.namespace}""" - } } +} } /// from $crateName import App /// /// @dataclass From 411d4d1f876b45fe7692e36178344af1bbad6f68 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Wed, 6 Jul 2022 13:59:04 +0100 Subject: [PATCH 3/6] Add documentation and server changelog --- CHANGELOG.next.toml | 8 ++++++++ .../generators/PythonApplicationGenerator.kt | 16 +++++++++++----- .../codegen/smithy/protocols/parse/ParserUtil.kt | 7 +++++++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index fed8585d71..0316d04d85 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -25,3 +25,11 @@ message = "Re-export aws_types::SdkConfig in aws_config" references = ["smithy-rs#1457"] meta = { "breaking" = false, "tada" = true, "bug" = false } author = "calavera" + +[[smithy-rs]] +message = """ +Codegenerate Python application example and add explicit cast during JSON deserialization. +""" +references = ["smithy-rs#1520"] +meta = { "breaking" = false, "tada" = false, "bug" = false, "sdk" = "both" } +author = "crisidev" diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt index ae8c497547..bdeb6c5d51 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt @@ -190,22 +190,25 @@ class PythonApplicationGenerator( } private fun renderPyApplicationRustDocs(writer: RustWriter) { - writer.rust(""" + writer.rust( +""" ##[allow(clippy::tabs_in_doc_comments)] /// Main Python application, used to register operations and context and start multiple /// workers on the same shared socket. /// -/// Here's a full example to get you started: +/// Operations can be registrered using the application object as a decorator (`@app.operation_name`). +/// +/// Here's a full example to get you started using coroutines: /// /// ```python ${ if (operations.any { it.errors.isNotEmpty() }) { """/// from $crateName import ${Inputs.namespace} /// from $crateName import ${Outputs.namespace} /// from $crateName import ${Errors.namespace}""" -} else { + } else { """/// from $crateName import ${Inputs.namespace} /// from $crateName import ${Outputs.namespace}""" -} } + } } /// from $crateName import App /// /// @dataclass @@ -219,6 +222,9 @@ ${operationImplementationStubs(operations)} /// /// app.run() /// ``` +/// +/// Any of operations above can be written as well prepending the `async` keyword and +/// the Python application will automatically handle it and schedule it on the even loop for you. """ ) } @@ -245,6 +251,6 @@ ${operationImplementationStubs(operations)} val inputT = "${Inputs.namespace}::${inputSymbol.name}" val outputT = "${Outputs.namespace}::${outputSymbol.name}" val operationName = symbolProvider.toSymbol(this).name.toSnakeCase() - return "@app.$operationName\n/// async def $operationName(input: $inputT, ctx: Context) -> $outputT" + return "@app.$operationName\n/// def $operationName(input: $inputT, ctx: Context) -> $outputT" } } diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt index 5cc6479b1e..3d66eb2ac5 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt @@ -16,6 +16,13 @@ import software.amazon.smithy.rust.codegen.smithy.RuntimeType import software.amazon.smithy.rust.codegen.smithy.RustSymbolProvider import software.amazon.smithy.rust.codegen.smithy.rustType +/* + * Utility class used to force casting a non primitive type into one overriden by a new symbol provider, + * by explicitly calling `from()`. + * + * For example we use this in the server Python implementation, where we override types like [Blob] and [DateTime] + * with wrappers compatibile with Python, without touching the original implementation coming from `aws-smithy-types`. + */ class ParserUtil(private val symbolProvider: RustSymbolProvider, private val runtimeConfig: RuntimeConfig) { fun convertViaFrom(shape: Shape): Writable = writable { From b1a8475a6b135e66f9f13549262ad048992529a9 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Wed, 13 Jul 2022 15:57:03 +0100 Subject: [PATCH 4/6] Fix codegeneration example --- .../python/smithy/generators/PythonApplicationGenerator.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt index bdeb6c5d51..12e1dcaf65 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonApplicationGenerator.kt @@ -198,7 +198,7 @@ class PythonApplicationGenerator( /// /// Operations can be registrered using the application object as a decorator (`@app.operation_name`). /// -/// Here's a full example to get you started using coroutines: +/// Here's a full example to get you started: /// /// ```python ${ if (operations.any { it.errors.isNotEmpty() }) { @@ -224,7 +224,7 @@ ${operationImplementationStubs(operations)} /// ``` /// /// Any of operations above can be written as well prepending the `async` keyword and -/// the Python application will automatically handle it and schedule it on the even loop for you. +/// the Python application will automatically handle it and schedule it on the event loop for you. """ ) } From 90958c792a62428ca887c382dffb5b2e5a123f18 Mon Sep 17 00:00:00 2001 From: Matteo Bigoi <1781140+crisidev@users.noreply.github.com> Date: Thu, 21 Jul 2022 09:32:17 +0100 Subject: [PATCH 5/6] Update codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt Co-authored-by: John DiSanti --- .../smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt index 3d66eb2ac5..e4136ebecb 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt @@ -21,7 +21,7 @@ import software.amazon.smithy.rust.codegen.smithy.rustType * by explicitly calling `from()`. * * For example we use this in the server Python implementation, where we override types like [Blob] and [DateTime] - * with wrappers compatibile with Python, without touching the original implementation coming from `aws-smithy-types`. + * with wrappers compatible with Python, without touching the original implementation coming from `aws-smithy-types`. */ class ParserUtil(private val symbolProvider: RustSymbolProvider, private val runtimeConfig: RuntimeConfig) { fun convertViaFrom(shape: Shape): Writable = From 468bdfd9afe33aeb06f1787331d854a2f837afc5 Mon Sep 17 00:00:00 2001 From: Bigo <1781140+crisidev@users.noreply.github.com> Date: Tue, 26 Jul 2022 10:23:14 +0100 Subject: [PATCH 6/6] Follow PR suggestions --- CHANGELOG.next.toml | 6 +++--- .../codegen/smithy/protocols/parse/JsonParserGenerator.kt | 6 +++--- .../parse/{ParserUtil.kt => TypeConversionGenerator.kt} | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) rename codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/{ParserUtil.kt => TypeConversionGenerator.kt} (93%) diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index 360049e87f..ab8220945d 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -151,8 +151,8 @@ author = "jdisanti" [[smithy-rs]] message = """ -Codegenerate Python application example and add explicit cast during JSON deserialization. +Add explicit cast during JSON deserialization in case of custom Symbol providers. """ references = ["smithy-rs#1520"] -meta = { "breaking" = false, "tada" = false, "bug" = false, "sdk" = "all" } -author = "crisidev" \ No newline at end of file +meta = { "breaking" = false, "tada" = false, "bug" = false } +author = "crisidev" diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/JsonParserGenerator.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/JsonParserGenerator.kt index 7d0a5f9943..04502a6577 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/JsonParserGenerator.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/JsonParserGenerator.kt @@ -65,7 +65,7 @@ class JsonParserGenerator( private val target = coreCodegenContext.target private val smithyJson = CargoDependency.smithyJson(runtimeConfig).asType() private val jsonDeserModule = RustModule.private("json_deser") - private val util = ParserUtil(symbolProvider, runtimeConfig) + private val typeConversionGenerator = TypeConversionGenerator(symbolProvider, runtimeConfig) private val codegenScope = arrayOf( "Error" to smithyJson.member("deserialize::Error"), "ErrorReason" to smithyJson.member("deserialize::ErrorReason"), @@ -240,7 +240,7 @@ class JsonParserGenerator( private fun RustWriter.deserializeBlob(target: BlobShape) { rustTemplate( "#{expect_blob_or_null}(tokens.next())?#{ConvertFrom:W}", - "ConvertFrom" to util.convertViaFrom(target), + "ConvertFrom" to typeConversionGenerator.convertViaFrom(target), *codegenScope ) } @@ -284,7 +284,7 @@ class JsonParserGenerator( val timestampFormatType = RuntimeType.TimestampFormat(runtimeConfig, timestampFormat) rustTemplate( "#{expect_timestamp_or_null}(tokens.next(), #{T})?#{ConvertFrom:W}", - "T" to timestampFormatType, "ConvertFrom" to util.convertViaFrom(shape), *codegenScope + "T" to timestampFormatType, "ConvertFrom" to typeConversionGenerator.convertViaFrom(shape), *codegenScope ) } diff --git a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/TypeConversionGenerator.kt similarity index 93% rename from codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt rename to codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/TypeConversionGenerator.kt index e4136ebecb..b168a8e894 100644 --- a/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/ParserUtil.kt +++ b/codegen/src/main/kotlin/software/amazon/smithy/rust/codegen/smithy/protocols/parse/TypeConversionGenerator.kt @@ -23,7 +23,7 @@ import software.amazon.smithy.rust.codegen.smithy.rustType * For example we use this in the server Python implementation, where we override types like [Blob] and [DateTime] * with wrappers compatible with Python, without touching the original implementation coming from `aws-smithy-types`. */ -class ParserUtil(private val symbolProvider: RustSymbolProvider, private val runtimeConfig: RuntimeConfig) { +class TypeConversionGenerator(private val symbolProvider: RustSymbolProvider, private val runtimeConfig: RuntimeConfig) { fun convertViaFrom(shape: Shape): Writable = writable { val oldSymbol = when (shape) {