Skip to content

Commit 84382a3

Browse files
authored
Fixing bug with enums as eventHeaders (#4337)
## Motivation and Context <!--- Why is this change required? What problem does it solve? --> <!--- If it fixes an open issue, please link to the issue here --> Fixing a bug that was discovered with smithy `enum` and `intEnum` shapes that are marked as `@eventHeader`. This came up in an internal investigation around a failed preview build. ## Description <!--- Describe your changes in detail --> Added handling of `EnumShape` in `EventStreamUnmarshallerGenerator` and `EventStreamMarshallerGenerator`. ## Testing <!--- Please describe in detail how you tested your changes --> <!--- Include details of your testing environment, and the tests you ran to --> <!--- see how your change affects other areas of the code, etc. --> Added new `enum` and `intEnum` shapes to the evenstream test model. They are only included in client tests since the server throws a validation error on enums in event streams (see smithy-lang/smithy#1388 for more info). Also tested against the model from the failed preview build and a `cargo test --all-features` was successful. ---- _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 4a4cbc4 commit 84382a3

File tree

4 files changed

+38
-3
lines changed

4 files changed

+38
-3
lines changed

codegen-client/src/test/kotlin/software/amazon/smithy/rust/codegen/client/smithy/protocols/eventstream/ClientEventStreamMarshallerGeneratorTest.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,11 @@ class ClientEventStreamMarshallerGeneratorTest {
155155
.is_some());
156156
assert_eq!(
157157
msg.payload(),
158-
&bytes::Bytes::from_static(${testCase.generateRustPayloadInitializer(rpcEventStreamTestCase.expectedInInitialRequest)})
158+
&bytes::Bytes::from_static(${
159+
testCase.generateRustPayloadInitializer(
160+
rpcEventStreamTestCase.expectedInInitialRequest,
161+
)
162+
})
159163
);
160164
""",
161165
)
@@ -178,7 +182,7 @@ class ClientEventStreamMarshallerGeneratorTest {
178182

179183
class TestCasesProvider : ArgumentsProvider {
180184
override fun provideArguments(context: ExtensionContext?): Stream<out Arguments> =
181-
EventStreamTestModels.TEST_CASES.map { Arguments.of(it) }.stream()
185+
EventStreamTestModels.TEST_CASES.map { Arguments.of(it.withEnumMembers()) }.stream()
182186
}
183187

184188
/**

codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/parse/EventStreamUnmarshallerGenerator.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import software.amazon.smithy.codegen.core.Symbol
99
import software.amazon.smithy.model.shapes.BlobShape
1010
import software.amazon.smithy.model.shapes.BooleanShape
1111
import software.amazon.smithy.model.shapes.ByteShape
12+
import software.amazon.smithy.model.shapes.EnumShape
1213
import software.amazon.smithy.model.shapes.IntegerShape
1314
import software.amazon.smithy.model.shapes.LongShape
1415
import software.amazon.smithy.model.shapes.MemberShape
@@ -261,6 +262,7 @@ class EventStreamUnmarshallerGenerator(
261262
is IntegerShape -> rustTemplate("#{expect_fns}::expect_int32(header)?", *codegenScope)
262263
is LongShape -> rustTemplate("#{expect_fns}::expect_int64(header)?", *codegenScope)
263264
is BlobShape -> rustTemplate("#{expect_fns}::expect_byte_array(header)?", *codegenScope)
265+
is EnumShape -> rustTemplate("#{expect_fns}::expect_string(header)?.as_str().into()", *codegenScope)
264266
is StringShape -> rustTemplate("#{expect_fns}::expect_string(header)?", *codegenScope)
265267
is TimestampShape -> rustTemplate("#{expect_fns}::expect_timestamp(header)?", *codegenScope)
266268
else -> throw IllegalStateException("unsupported event stream header shape type: $target")
@@ -383,7 +385,8 @@ class EventStreamUnmarshallerGenerator(
383385
"builder", target,
384386
mapErr = {
385387
rustTemplate(
386-
"""|err|#{Error}::unmarshalling(format!("{}", err))""", *codegenScope,
388+
"""|err|#{Error}::unmarshalling(format!("{}", err))""",
389+
*codegenScope,
387390
)
388391
},
389392
),

codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/serialize/EventStreamMarshallerGenerator.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import software.amazon.smithy.model.Model
1010
import software.amazon.smithy.model.shapes.BlobShape
1111
import software.amazon.smithy.model.shapes.BooleanShape
1212
import software.amazon.smithy.model.shapes.ByteShape
13+
import software.amazon.smithy.model.shapes.EnumShape
1314
import software.amazon.smithy.model.shapes.IntegerShape
1415
import software.amazon.smithy.model.shapes.LongShape
1516
import software.amazon.smithy.model.shapes.MemberShape
@@ -243,6 +244,7 @@ open class EventStreamMarshallerGenerator(
243244
is IntegerShape -> "Int32($inputName)"
244245
is LongShape -> "Int64($inputName)"
245246
is BlobShape -> "ByteArray($inputName.into_inner().into())"
247+
is EnumShape -> "String($inputName.to_string().into())"
246248
is StringShape -> "String($inputName.into())"
247249
is TimestampShape -> "Timestamp($inputName)"
248250
else -> throw IllegalStateException("unsupported event stream header shape type: $target")

codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/testutil/EventStreamTestModels.kt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ private fun fillInBaseModel(
2121
namespacedProtocolName: String,
2222
extraServiceAnnotations: String = "",
2323
nonEventStreamMembers: String = "",
24+
extraEventHeaderMembers: String = "",
25+
extraShapes: String = "",
2426
): String =
2527
"""
28+
${"\$version: \"2\""}
2629
namespace test
2730
2831
use smithy.framework#ValidationException
@@ -42,6 +45,8 @@ private fun fillInBaseModel(
4245
Message: String,
4346
}
4447
48+
$extraShapes
49+
4550
structure MessageWithBlob { @eventPayload data: Blob }
4651
structure MessageWithString { @eventPayload data: String }
4752
structure MessageWithStruct { @eventPayload someStruct: TestStruct }
@@ -55,6 +60,7 @@ private fun fillInBaseModel(
5560
@eventHeader short: Short,
5661
@eventHeader string: String,
5762
@eventHeader timestamp: Timestamp,
63+
$extraEventHeaderMembers
5864
}
5965
structure MessageWithHeaderAndPayload {
6066
@eventHeader header: String,
@@ -129,6 +135,26 @@ object EventStreamTestModels {
129135

130136
fun withNonEventStreamMembers(nonEventStreamMembers: String): TestCase =
131137
this.copy(model = fillInBaseModel(this.protocolShapeId, "", nonEventStreamMembers).asSmithyModel())
138+
139+
// Server doesn't support enum members in event streams, so this util allows Clients to test with those shapes
140+
fun withEnumMembers(): TestCase =
141+
this.copy(
142+
model =
143+
fillInBaseModel(
144+
this.protocolShapeId,
145+
extraEventHeaderMembers = "@eventHeader enum: TheEnum,\n@eventHeader intEnum: FaceCard,",
146+
extraShapes = """ enum TheEnum {
147+
FOO
148+
BAR
149+
}
150+
151+
intEnum FaceCard {
152+
JACK = 1
153+
QUEEN = 2
154+
KING = 3
155+
}""",
156+
).asSmithyModel(),
157+
)
132158
}
133159

134160
private fun base64Encode(input: ByteArray): String {

0 commit comments

Comments
 (0)