diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index b785b2e4c0..31f396ac92 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -263,3 +263,9 @@ message = "Add more client re-exports. Specifically, it re-exports `aws_smithy_h references = ["smithy-rs#2437", "aws-sdk-rust#600"] meta = { "breaking" = false, "tada" = false, "bug" = false, "target" = "client" } author = "ysaito1001" + +[[smithy-rs]] +message = "Smithy members named `send` were previously renamed to `send_value` at codegen time. These will now be called `send` in the generated code." +references = ["smithy-rs#2382"] +meta = { "breaking" = true, "tada" = false, "bug" = true, "target" = "server" } +author = "jdisanti" diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientReservedWords.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientReservedWords.kt new file mode 100644 index 0000000000..add9f53f6d --- /dev/null +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/ClientReservedWords.kt @@ -0,0 +1,35 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rust.codegen.client.smithy + +import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWordConfig +import software.amazon.smithy.rust.codegen.core.smithy.generators.StructureGenerator +import software.amazon.smithy.rust.codegen.core.smithy.generators.UnionGenerator + +val ClientReservedWords = RustReservedWordConfig( + structureMemberMap = StructureGenerator.structureMemberNameMap + + mapOf( + "send" to "send_value", + // To avoid conflicts with the `make_operation` and `presigned` functions on generated inputs + "make_operation" to "make_operation_value", + "presigned" to "presigned_value", + "customize" to "customize_value", + // To avoid conflicts with the error metadata `meta` field + "meta" to "meta_value", + ), + unionMemberMap = mapOf( + // Unions contain an `Unknown` variant. This exists to support parsing data returned from the server + // that represent union variants that have been added since this SDK was generated. + UnionGenerator.UnknownVariantName to "${UnionGenerator.UnknownVariantName}Value", + "${UnionGenerator.UnknownVariantName}Value" to "${UnionGenerator.UnknownVariantName}Value_", + ), + enumMemberMap = mapOf( + // Unknown is used as the name of the variant containing unexpected values + "Unknown" to "UnknownValue", + // Real models won't end in `_` so it's safe to stop here + "UnknownValue" to "UnknownValue_", + ), +) diff --git a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/RustClientCodegenPlugin.kt b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/RustClientCodegenPlugin.kt index 517bcf32e0..f8852a700d 100644 --- a/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/RustClientCodegenPlugin.kt +++ b/codegen-client/src/main/kotlin/software/amazon/smithy/rust/codegen/client/smithy/RustClientCodegenPlugin.kt @@ -92,7 +92,7 @@ class RustClientCodegenPlugin : ClientDecoratableBuildPlugin() { .let { StreamingShapeMetadataProvider(it) } // Rename shapes that clash with Rust reserved words & and other SDK specific features e.g. `send()` cannot // be the name of an operation input - .let { RustReservedWordSymbolProvider(it) } + .let { RustReservedWordSymbolProvider(it, ClientReservedWords) } // Allows decorators to inject a custom symbol provider .let { codegenDecorator.symbolProvider(it) } } diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWords.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWords.kt index 3879167383..c9fdbafb13 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWords.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWords.kt @@ -16,12 +16,23 @@ import software.amazon.smithy.model.shapes.UnionShape import software.amazon.smithy.model.traits.EnumTrait import software.amazon.smithy.rust.codegen.core.smithy.RustSymbolProvider import software.amazon.smithy.rust.codegen.core.smithy.WrappingSymbolProvider -import software.amazon.smithy.rust.codegen.core.smithy.generators.UnionGenerator import software.amazon.smithy.rust.codegen.core.smithy.renamedFrom import software.amazon.smithy.rust.codegen.core.util.hasTrait import software.amazon.smithy.rust.codegen.core.util.letIf -class RustReservedWordSymbolProvider(private val base: RustSymbolProvider) : WrappingSymbolProvider(base) { +data class RustReservedWordConfig( + /** Map of struct member names that should get renamed */ + val structureMemberMap: Map, + /** Map of union member names that should get renamed */ + val unionMemberMap: Map, + /** Map of enum member names that should get renamed */ + val enumMemberMap: Map, +) + +class RustReservedWordSymbolProvider( + private val base: RustSymbolProvider, + private val reservedWordConfig: RustReservedWordConfig, +) : WrappingSymbolProvider(base) { private val internal = ReservedWordSymbolProvider.builder().symbolProvider(base) .nameReservedWords(RustReservedWords) @@ -33,35 +44,14 @@ class RustReservedWordSymbolProvider(private val base: RustSymbolProvider) : Wra val reservedWordReplacedName = internal.toMemberName(shape) val container = model.expectShape(shape.container) return when { - container is StructureShape -> when (baseName) { - "build" -> "build_value" - "builder" -> "builder_value" - "default" -> "default_value" - "send" -> "send_value" - // To avoid conflicts with the `make_operation` and `presigned` functions on generated inputs - "make_operation" -> "make_operation_value" - "presigned" -> "presigned_value" - "customize" -> "customize_value" - // To avoid conflicts with the error metadata `meta` field - "meta" -> "meta_value" - else -> reservedWordReplacedName - } + container is StructureShape -> + reservedWordConfig.structureMemberMap.getOrDefault(baseName, reservedWordReplacedName) - container is UnionShape -> when (baseName) { - // Unions contain an `Unknown` variant. This exists to support parsing data returned from the server - // that represent union variants that have been added since this SDK was generated. - UnionGenerator.UnknownVariantName -> "${UnionGenerator.UnknownVariantName}Value" - "${UnionGenerator.UnknownVariantName}Value" -> "${UnionGenerator.UnknownVariantName}Value_" - else -> reservedWordReplacedName - } + container is UnionShape -> + reservedWordConfig.unionMemberMap.getOrDefault(baseName, reservedWordReplacedName) - container is EnumShape || container.hasTrait() -> when (baseName) { - // Unknown is used as the name of the variant containing unexpected values - "Unknown" -> "UnknownValue" - // Real models won't end in `_` so it's safe to stop here - "UnknownValue" -> "UnknownValue_" - else -> reservedWordReplacedName - } + container is EnumShape || container.hasTrait() -> + reservedWordConfig.enumMemberMap.getOrDefault(baseName, reservedWordReplacedName) else -> error("unexpected container: $container") } diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/StructureGenerator.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/StructureGenerator.kt index e91bf3b871..6905058d46 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/StructureGenerator.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/StructureGenerator.kt @@ -60,6 +60,15 @@ open class StructureGenerator( private val shape: StructureShape, private val customizations: List, ) { + companion object { + /** Reserved struct member names */ + val structureMemberNameMap: Map = mapOf( + "build" to "build_value", + "builder" to "builder_value", + "default" to "default_value", + ) + } + private val errorTrait = shape.getTrait() protected val members: List = shape.allMembers.values.toList() private val accessorMembers: List = when (errorTrait) { diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/TestHelpers.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/TestHelpers.kt index 8524fc38b4..b80f211c76 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/TestHelpers.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/TestHelpers.kt @@ -17,6 +17,7 @@ import software.amazon.smithy.model.shapes.UnionShape import software.amazon.smithy.model.traits.ErrorTrait import software.amazon.smithy.rust.codegen.core.rustlang.Attribute import software.amazon.smithy.rust.codegen.core.rustlang.RustModule +import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWordConfig import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWordSymbolProvider import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWords import software.amazon.smithy.rust.codegen.core.rustlang.Visibility @@ -138,13 +139,21 @@ fun String.asSmithyModel(sourceLocation: String? = null, smithyVersion: String = } // Intentionally only visible to codegen-core since the other modules have their own symbol providers -internal fun testSymbolProvider(model: Model): RustSymbolProvider = SymbolVisitor( +internal fun testSymbolProvider( + model: Model, + rustReservedWordConfig: RustReservedWordConfig? = null, +): RustSymbolProvider = SymbolVisitor( testRustSettings(), model, ServiceShape.builder().version("test").id("test#Service").build(), TestRustSymbolProviderConfig, ).let { BaseSymbolMetadataProvider(it, additionalAttributes = listOf(Attribute.NonExhaustive)) } - .let { RustReservedWordSymbolProvider(it) } + .let { + RustReservedWordSymbolProvider( + it, + rustReservedWordConfig ?: RustReservedWordConfig(emptyMap(), emptyMap(), emptyMap()), + ) + } // Intentionally only visible to codegen-core since the other modules have their own contexts internal fun testCodegenContext( diff --git a/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWordsTest.kt b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWordsTest.kt index 0cbd3fcbb1..25e47e0963 100644 --- a/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWordsTest.kt +++ b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/rustlang/RustReservedWordsTest.kt @@ -22,6 +22,7 @@ import software.amazon.smithy.rust.codegen.core.util.lookup internal class RustReservedWordSymbolProviderTest { private class TestSymbolProvider(model: Model) : WrappingSymbolProvider(SymbolVisitor(testRustSettings(), model, null, TestRustSymbolProviderConfig)) + private val emptyConfig = RustReservedWordConfig(emptyMap(), emptyMap(), emptyMap()) @Test fun `structs are escaped`() { @@ -29,11 +30,100 @@ internal class RustReservedWordSymbolProviderTest { namespace test structure Self {} """.asSmithyModel() - val provider = RustReservedWordSymbolProvider(TestSymbolProvider(model)) + val provider = RustReservedWordSymbolProvider(TestSymbolProvider(model), emptyConfig) val symbol = provider.toSymbol(model.lookup("test#Self")) symbol.name shouldBe "SelfValue" } + private fun mappingTest(config: RustReservedWordConfig, model: Model, id: String, test: (String) -> Unit) { + val provider = RustReservedWordSymbolProvider(TestSymbolProvider(model), config) + val symbol = provider.toMemberName(model.lookup("test#Container\$$id")) + test(symbol) + } + + @Test + fun `structs member names are mapped via config`() { + val config = emptyConfig.copy( + structureMemberMap = mapOf( + "name_to_map" to "mapped_name", + "NameToMap" to "MappedName", + ), + ) + var model = """ + namespace test + structure Container { + name_to_map: String + } + """.asSmithyModel() + mappingTest(config, model, "name_to_map") { memberName -> + memberName shouldBe "mapped_name" + } + + model = """ + namespace test + enum Container { + NameToMap = "NameToMap" + } + """.asSmithyModel(smithyVersion = "2.0") + mappingTest(config, model, "NameToMap") { memberName -> + // Container was not a struct, so the field keeps its old name + memberName shouldBe "NameToMap" + } + + model = """ + namespace test + union Container { + NameToMap: String + } + """.asSmithyModel() + mappingTest(config, model, "NameToMap") { memberName -> + // Container was not a struct, so the field keeps its old name + memberName shouldBe "NameToMap" + } + } + + @Test + fun `union member names are mapped via config`() { + val config = emptyConfig.copy( + unionMemberMap = mapOf( + "name_to_map" to "mapped_name", + "NameToMap" to "MappedName", + ), + ) + + var model = """ + namespace test + union Container { + NameToMap: String + } + """.asSmithyModel() + mappingTest(config, model, "NameToMap") { memberName -> + memberName shouldBe "MappedName" + } + + model = """ + namespace test + structure Container { + name_to_map: String + } + """.asSmithyModel() + mappingTest(config, model, "name_to_map") { memberName -> + // Container was not a union, so the field keeps its old name + memberName shouldBe "name_to_map" + } + + model = """ + namespace test + enum Container { + NameToMap = "NameToMap" + } + """.asSmithyModel(smithyVersion = "2.0") + mappingTest(config, model, "NameToMap") { memberName -> + // Container was not a union, so the field keeps its old name + memberName shouldBe "NameToMap" + } + } + @Test fun `member names are escaped`() { val model = """ @@ -42,7 +132,7 @@ internal class RustReservedWordSymbolProviderTest { async: String } """.asSmithyModel() - val provider = RustReservedWordSymbolProvider(TestSymbolProvider(model)) + val provider = RustReservedWordSymbolProvider(TestSymbolProvider(model), emptyConfig) provider.toMemberName( MemberShape.builder().id("namespace#container\$async").target("namespace#Integer").build(), ) shouldBe "r##async" @@ -58,7 +148,15 @@ internal class RustReservedWordSymbolProviderTest { namespace foo @enum([{ name: "dontcare", value: "dontcare" }]) string Container """.asSmithyModel() - val provider = RustReservedWordSymbolProvider(TestSymbolProvider(model)) + val provider = RustReservedWordSymbolProvider( + TestSymbolProvider(model), + reservedWordConfig = emptyConfig.copy( + enumMemberMap = mapOf( + "Unknown" to "UnknownValue", + "UnknownValue" to "UnknownValue_", + ), + ), + ) fun expectEnumRename(original: String, expected: MaybeRenamed) { val symbol = provider.toSymbol( diff --git a/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/EnumGeneratorTest.kt b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/EnumGeneratorTest.kt index 2da87e1d45..b233a763bd 100644 --- a/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/EnumGeneratorTest.kt +++ b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/EnumGeneratorTest.kt @@ -14,6 +14,7 @@ import software.amazon.smithy.model.Model import software.amazon.smithy.model.shapes.StringShape import software.amazon.smithy.model.traits.EnumTrait import software.amazon.smithy.rust.codegen.core.rustlang.Attribute.Companion.AllowDeprecated +import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWordConfig import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter import software.amazon.smithy.rust.codegen.core.rustlang.Writable import software.amazon.smithy.rust.codegen.core.rustlang.rust @@ -30,6 +31,12 @@ import software.amazon.smithy.rust.codegen.core.util.lookup import software.amazon.smithy.rust.codegen.core.util.orNull class EnumGeneratorTest { + private val rustReservedWordConfig = RustReservedWordConfig( + enumMemberMap = mapOf("Unknown" to "UnknownValue"), + structureMemberMap = emptyMap(), + unionMemberMap = emptyMap(), + ) + @Nested inner class EnumMemberModelTests { private val testModel = """ @@ -47,7 +54,7 @@ class EnumGeneratorTest { ]) string EnumWithUnknown """.asSmithyModel() - private val symbolProvider = testSymbolProvider(testModel) + private val symbolProvider = testSymbolProvider(testModel, rustReservedWordConfig = rustReservedWordConfig) private val enumTrait = testModel.lookup("test#EnumWithUnknown").expectTrait() @@ -276,7 +283,7 @@ class EnumGeneratorTest { """.asSmithyModel() val shape = model.lookup("test#SomeEnum") - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) val project = TestWorkspace.testProject(provider) project.moduleFor(shape) { renderEnum(model, provider, shape) diff --git a/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/StructureGeneratorTest.kt b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/StructureGeneratorTest.kt index e6be7eee97..86e81c45f9 100644 --- a/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/StructureGeneratorTest.kt +++ b/codegen-core/src/test/kotlin/software/amazon/smithy/rust/codegen/core/smithy/generators/StructureGeneratorTest.kt @@ -12,6 +12,7 @@ import org.junit.jupiter.api.Test import software.amazon.smithy.model.shapes.StructureShape import software.amazon.smithy.rust.codegen.core.rustlang.Attribute import software.amazon.smithy.rust.codegen.core.rustlang.RustModule +import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWordConfig import software.amazon.smithy.rust.codegen.core.rustlang.RustWriter import software.amazon.smithy.rust.codegen.core.rustlang.rust import software.amazon.smithy.rust.codegen.core.rustlang.rustBlock @@ -85,11 +86,17 @@ class StructureGeneratorTest { val secretStructure = model.lookup("com.test#SecretStructure") val structWithInnerSecretStructure = model.lookup("com.test#StructWithInnerSecretStructure") val error = model.lookup("com.test#MyError") + + val rustReservedWordConfig: RustReservedWordConfig = RustReservedWordConfig( + structureMemberMap = StructureGenerator.structureMemberNameMap, + enumMemberMap = emptyMap(), + unionMemberMap = emptyMap(), + ) } @Test fun `generate basic structures`() { - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) val project = TestWorkspace.testProject(provider) project.useShapeWriter(inner) { StructureGenerator(model, provider, this, inner, emptyList()).render() @@ -110,7 +117,7 @@ class StructureGeneratorTest { @Test fun `generate structures with public fields`() { - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) val project = TestWorkspace.testProject(provider) project.lib { Attribute.AllowDeprecated.render(this) } @@ -140,7 +147,7 @@ class StructureGeneratorTest { @Test fun `generate a custom debug implementation when the sensitive trait is applied to some members`() { - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) val writer = RustWriter.forModule("lib") val generator = StructureGenerator(model, provider, writer, credentials, emptyList()) generator.render() @@ -160,7 +167,7 @@ class StructureGeneratorTest { @Test fun `generate a custom debug implementation when the sensitive trait is applied to the struct`() { - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) val writer = RustWriter.forModule("lib") val generator = StructureGenerator(model, provider, writer, secretStructure, emptyList()) generator.render() @@ -178,7 +185,7 @@ class StructureGeneratorTest { @Test fun `generate a custom debug implementation when the sensitive trait is applied to an inner struct`() { - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) val project = TestWorkspace.testProject(provider) project.useShapeWriter(inner) { val secretGenerator = StructureGenerator(model, provider, this, secretStructure, emptyList()) @@ -219,7 +226,7 @@ class StructureGeneratorTest { nested2: Inner }""".asSmithyModel() - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) val project = TestWorkspace.testProject(provider) project.lib { Attribute.DenyMissingDocs.render(this) @@ -234,7 +241,7 @@ class StructureGeneratorTest { @Test fun `documents are optional in structs`() { - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) val writer = RustWriter.forModule("lib") StructureGenerator(model, provider, writer, structWithDoc, emptyList()).render() @@ -265,7 +272,7 @@ class StructureGeneratorTest { @deprecated(message: "Fly, you fools!", since: "1.2.3") structure Qux {} """.asSmithyModel() - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) val project = TestWorkspace.testProject(provider) project.lib { rust("##![allow(deprecated)]") } project.moduleFor(model.lookup("test#Foo")) { @@ -298,7 +305,7 @@ class StructureGeneratorTest { @deprecated structure Bar {} """.asSmithyModel() - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) val project = TestWorkspace.testProject(provider) project.lib { rust("##![allow(deprecated)]") } project.moduleFor(model.lookup("test#Nested")) { @@ -347,7 +354,7 @@ class StructureGeneratorTest { } """.asSmithyModel(), ) - val provider = testSymbolProvider(testModel) + val provider = testSymbolProvider(testModel, rustReservedWordConfig = rustReservedWordConfig) val project = TestWorkspace.testProject(provider) project.useShapeWriter(inner) { @@ -407,7 +414,7 @@ class StructureGeneratorTest { """.asSmithyModel() val struct = model.lookup("com.test#MyStruct") - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) RustWriter.forModule("test").let { StructureGenerator(model, provider, it, struct, emptyList()).render() assertEquals(6, it.toString().split("#[doc(hidden)]").size, "there should be 5 doc-hiddens") @@ -423,7 +430,7 @@ class StructureGeneratorTest { """.asSmithyModel() val struct = model.lookup("com.test#MyStruct") - val provider = testSymbolProvider(model) + val provider = testSymbolProvider(model, rustReservedWordConfig = rustReservedWordConfig) RustWriter.forModule("test").let { writer -> StructureGenerator(model, provider, writer, struct, emptyList()).render() writer.toString().shouldNotContain("#[doc(hidden)]") diff --git a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/RustServerCodegenPythonPlugin.kt b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/RustServerCodegenPythonPlugin.kt index ce96020205..169106f305 100644 --- a/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/RustServerCodegenPythonPlugin.kt +++ b/codegen-server/python/src/main/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/RustServerCodegenPythonPlugin.kt @@ -19,6 +19,7 @@ import software.amazon.smithy.rust.codegen.server.python.smithy.customizations.D import software.amazon.smithy.rust.codegen.server.smithy.ConstrainedShapeSymbolMetadataProvider import software.amazon.smithy.rust.codegen.server.smithy.ConstrainedShapeSymbolProvider import software.amazon.smithy.rust.codegen.server.smithy.DeriveEqAndHashSymbolMetadataProvider +import software.amazon.smithy.rust.codegen.server.smithy.ServerReservedWords import software.amazon.smithy.rust.codegen.server.smithy.ServerRustSettings import software.amazon.smithy.rust.codegen.server.smithy.customizations.CustomValidationExceptionWithReasonDecorator import software.amazon.smithy.rust.codegen.server.smithy.customizations.ServerRequiredCustomizations @@ -98,7 +99,7 @@ class RustServerCodegenPythonPlugin : SmithyBuildPlugin { .let { DeriveEqAndHashSymbolMetadataProvider(it) } // Rename shapes that clash with Rust reserved words & and other SDK specific features e.g. `send()` cannot // be the name of an operation input - .let { RustReservedWordSymbolProvider(it) } + .let { RustReservedWordSymbolProvider(it, ServerReservedWords) } // Allows decorators to inject a custom symbol provider .let { codegenDecorator.symbolProvider(it) } } diff --git a/codegen-server/python/src/test/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerTypesTest.kt b/codegen-server/python/src/test/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerTypesTest.kt index e17c058d77..9c38d34395 100644 --- a/codegen-server/python/src/test/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerTypesTest.kt +++ b/codegen-server/python/src/test/kotlin/software/amazon/smithy/rust/codegen/server/python/smithy/generators/PythonServerTypesTest.kt @@ -191,9 +191,9 @@ internal class PythonServerTypesTest { use pyo3::{types::IntoPyDict, IntoPy, Python}; use hyper::{Body, Request, body}; use crate::{input, output, python_types}; - + pyo3::prepare_freethreaded_python(); - + let mut service = Service::builder_without_plugins() .echo(|input: input::EchoInput| async { Ok(Python::with_gil(|py| { @@ -202,10 +202,10 @@ internal class PythonServerTypesTest { ("DateTime", py.get_type::()), ].into_py_dict(py); let locals = [("input", input.into_py(py))].into_py_dict(py); - + py.run("assert input.value.secs() == 1676298520", Some(globals), Some(locals)).unwrap(); py.run("output = EchoOutput(value=input.value, opt_value=DateTime.from_secs(1677771678))", Some(globals), Some(locals)).unwrap(); - + locals .get_item("output") .unwrap() diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/RustServerCodegenPlugin.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/RustServerCodegenPlugin.kt index 2a150ab4be..aa310ccc71 100644 --- a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/RustServerCodegenPlugin.kt +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/RustServerCodegenPlugin.kt @@ -90,7 +90,7 @@ class RustServerCodegenPlugin : ServerDecoratableBuildPlugin() { .let { DeriveEqAndHashSymbolMetadataProvider(it) } // Rename shapes that clash with Rust reserved words & and other SDK specific features e.g. `send()` cannot // be the name of an operation input - .let { RustReservedWordSymbolProvider(it) } + .let { RustReservedWordSymbolProvider(it, ServerReservedWords) } // Allows decorators to inject a custom symbol provider .let { codegenDecorator.symbolProvider(it) } } diff --git a/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerReservedWords.kt b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerReservedWords.kt new file mode 100644 index 0000000000..64d9ea04f4 --- /dev/null +++ b/codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ServerReservedWords.kt @@ -0,0 +1,15 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rust.codegen.server.smithy + +import software.amazon.smithy.rust.codegen.core.rustlang.RustReservedWordConfig +import software.amazon.smithy.rust.codegen.core.smithy.generators.StructureGenerator + +val ServerReservedWords = RustReservedWordConfig( + structureMemberMap = StructureGenerator.structureMemberNameMap, + unionMemberMap = emptyMap(), + enumMemberMap = emptyMap(), +) diff --git a/rust-runtime/aws-smithy-http-server-python/Cargo.toml b/rust-runtime/aws-smithy-http-server-python/Cargo.toml index b0cba12b71..8db4973cca 100644 --- a/rust-runtime/aws-smithy-http-server-python/Cargo.toml +++ b/rust-runtime/aws-smithy-http-server-python/Cargo.toml @@ -57,7 +57,7 @@ hyper-rustls = { version = "0.23.1", features = ["http2"] } # PyO3 Asyncio tests cannot use Cargo's default testing harness because `asyncio` # wants to control the main thread. So we need to use testing harness provided by `pyo3_asyncio` -# for the async Python tests. For more detail see: +# for the async Python tests. For more detail see: # https://docs.rs/pyo3-asyncio/0.18.0/pyo3_asyncio/testing/index.html#pyo3-asyncio-testing-utilities [[test]] name = "middleware_tests" diff --git a/tools/ci-build/Dockerfile b/tools/ci-build/Dockerfile index 6a34cda1c7..4e2f72e8dc 100644 --- a/tools/ci-build/Dockerfile +++ b/tools/ci-build/Dockerfile @@ -16,8 +16,8 @@ FROM bare_base_image as musl_toolchain RUN yum -y install tar gzip gcc make RUN curl https://musl.libc.org/releases/musl-1.2.3.tar.gz -o musl-1.2.3.tar.gz \ && ls \ - && tar xvzf musl-1.2.3.tar.gz \ - && (cd musl-1.2.3 && ./configure && make install) + && tar xvzf musl-1.2.3.tar.gz \ + && (cd musl-1.2.3 && ./configure && make install) # # Rust & Tools Installation Stage