Skip to content

Commit 66b2311

Browse files
authored
Fix serde on constrained blobs (#3893)
## Motivation and Context #3890 ## Description Replace the computed type (which will be a constrained shape, not what we want!) with an absolute type. ## Testing - [x] New unit test that fails without this fix applied. ## Checklist <!--- If a checkbox below is not applicable, then please DELETE it rather than leaving it unchecked --> - [x] For changes to the smithy-rs codegen or runtime crates, I have created a changelog entry Markdown file in the `.changelog` directory, specifying "client," "server," or both in the `applies_to` key. ---- _By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice._
1 parent c7b1038 commit 66b2311

File tree

3 files changed

+63
-11
lines changed

3 files changed

+63
-11
lines changed

.changelog/1729878769.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
applies_to: ["server"]
3+
authors: ["rcoh"]
4+
references: ["smithy-rs#3890"]
5+
breaking: false
6+
new_feature: false
7+
bug_fix: true
8+
---
9+
Fix bug in `serde` decorator that generated non-compiling code on some models

codegen-serde/src/main/kotlin/software/amazon/smithy/rust/codegen/serde/SerializeImplGenerator.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,8 @@ class SerializeImplGenerator(private val codegenContext: CodegenContext) {
462462
}
463463

464464
private fun serializeBlob(shape: BlobShape): RuntimeType =
465-
RuntimeType.forInlineFun("SerializeBlob", Companion.PrimitiveShapesModule) {
466-
implSerializeConfigured(codegenContext.symbolProvider.toSymbol(shape)) {
465+
RuntimeType.forInlineFun("SerializeBlob", PrimitiveShapesModule) {
466+
implSerializeConfigured(RuntimeType.blob(codegenContext.runtimeConfig).toSymbol()) {
467467
rustTemplate(
468468
"""
469469
if serializer.is_human_readable() {
@@ -478,7 +478,7 @@ class SerializeImplGenerator(private val codegenContext: CodegenContext) {
478478
}
479479

480480
private fun serializeByteStream(shape: BlobShape): RuntimeType =
481-
RuntimeType.forInlineFun("SerializeByteStream", Companion.PrimitiveShapesModule) {
481+
RuntimeType.forInlineFun("SerializeByteStream", PrimitiveShapesModule) {
482482
implSerializeConfigured(RuntimeType.byteStream(codegenContext.runtimeConfig).toSymbol()) {
483483
// This doesn't work yet—there is no way to get data out of a ByteStream from a sync context
484484
rustTemplate(
@@ -498,7 +498,7 @@ class SerializeImplGenerator(private val codegenContext: CodegenContext) {
498498
}
499499

500500
private fun serializeDocument(shape: DocumentShape): RuntimeType =
501-
RuntimeType.forInlineFun("SerializeDocument", Companion.PrimitiveShapesModule) {
501+
RuntimeType.forInlineFun("SerializeDocument", PrimitiveShapesModule) {
502502
implSerializeConfigured(codegenContext.symbolProvider.toSymbol(shape)) {
503503
rustTemplate(
504504
"""

codegen-serde/src/test/kotlin/software/amazon/smithy/rust/codegen/serde/SerdeDecoratorTest.kt

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package software.amazon.smithy.rust.codegen.serde
77

88
import org.junit.jupiter.api.Test
9+
import software.amazon.smithy.model.node.Node
910
import software.amazon.smithy.rust.codegen.client.testutil.clientIntegrationTest
1011
import software.amazon.smithy.rust.codegen.core.rustlang.Attribute
1112
import software.amazon.smithy.rust.codegen.core.rustlang.Attribute.Companion.cfg
@@ -190,22 +191,22 @@ class SerdeDecoratorTest {
190191
namespace com.example
191192
use smithy.rust#serde
192193
use aws.protocols#awsJson1_0
193-
194+
194195
@awsJson1_0
195196
@serde
196197
service MyResourceService {
197198
resources: [MyResource]
198199
}
199-
200+
200201
resource MyResource {
201202
read: ReadMyResource
202203
}
203-
204+
204205
@readonly
205206
operation ReadMyResource {
206207
input := { }
207208
}
208-
""".asSmithyModel(smithyVersion = "2")
209+
""".asSmithyModel(smithyVersion = "2")
209210

210211
val params =
211212
IntegrationTestParams(cargoCommand = "cargo test --all-features", service = "com.example#MyResourceService")
@@ -241,14 +242,14 @@ class SerdeDecoratorTest {
241242
"""
242243
namespace com.example
243244
use aws.protocols#awsJson1_0
244-
245+
245246
@awsJson1_0
246247
service MyService {
247248
operations: [MyOperation]
248249
}
249-
250+
250251
operation MyOperation { }
251-
""".asSmithyModel(smithyVersion = "2")
252+
""".asSmithyModel(smithyVersion = "2")
252253

253254
val params =
254255
IntegrationTestParams(cargoCommand = "cargo test --all-features", service = "com.example#MyService")
@@ -261,6 +262,48 @@ class SerdeDecoratorTest {
261262
}
262263
}
263264

265+
val onlyConstrained =
266+
"""
267+
namespace com.example
268+
use smithy.rust#serde
269+
use aws.protocols#awsJson1_0
270+
use smithy.framework#ValidationException
271+
@awsJson1_0
272+
service HelloService {
273+
operations: [SayHello],
274+
version: "1"
275+
}
276+
@serde
277+
operation SayHello {
278+
input: TestInput
279+
errors: [ValidationException]
280+
}
281+
structure TestInput {
282+
@length(max: 10)
283+
shortBlob: Blob
284+
}
285+
""".asSmithyModel(smithyVersion = "2")
286+
287+
// There is a "race condition" where if the first blob shape serialized is constrained, it triggered unexpected
288+
// behavior where the constrained shape was used instead. This test verifies the fix.
289+
// Fixes https://github.com/smithy-lang/smithy-rs/issues/3890
290+
@Test
291+
fun compilesOnlyConstrainedModel() {
292+
val constrainedShapesSettings =
293+
Node.objectNodeBuilder().withMember(
294+
"codegen",
295+
Node.objectNodeBuilder()
296+
.withMember("publicConstrainedTypes", true)
297+
.withMember("includeFluentClient", false)
298+
.build(),
299+
).build()
300+
serverIntegrationTest(
301+
onlyConstrained,
302+
params.copy(additionalSettings = constrainedShapesSettings),
303+
) { clientCodegenContext, rustCrate ->
304+
}
305+
}
306+
264307
@Test
265308
fun generateSerializersThatWorkServer() {
266309
serverIntegrationTest(simpleModel, params = params) { ctx, crate ->

0 commit comments

Comments
 (0)