From 68328d957380de11b79ab4063ea76205e4a95390 Mon Sep 17 00:00:00 2001 From: Fahad Zubair Date: Thu, 12 Feb 2026 23:14:17 +0000 Subject: [PATCH 1/2] Handle implicit event stream payload members --- .../HttpBoundProtocolPayloadGenerator.kt | 7 ++++++- .../parse/EventStreamUnmarshallerGenerator.kt | 19 +++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/HttpBoundProtocolPayloadGenerator.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/HttpBoundProtocolPayloadGenerator.kt index 6ee4284452e..819da5dccb5 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/HttpBoundProtocolPayloadGenerator.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/HttpBoundProtocolPayloadGenerator.kt @@ -95,7 +95,12 @@ class HttpBoundProtocolPayloadGenerator( // need to take ownership. return if (payloadMemberName == null) { ProtocolPayloadGenerator.PayloadMetadata(takesOwnership = false) - } else if (operationShape.isInputEventStream(model)) { + } else if ( + when (httpMessageType) { + HttpMessageType.REQUEST -> operationShape.isInputEventStream(model) + HttpMessageType.RESPONSE -> operationShape.isOutputEventStream(model) + } + ) { ProtocolPayloadGenerator.PayloadMetadata(takesOwnership = true) } else { val member = shape.expectMember(payloadMemberName) diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/parse/EventStreamUnmarshallerGenerator.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/parse/EventStreamUnmarshallerGenerator.kt index 39fcb5dfc61..4509ebf52f1 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/parse/EventStreamUnmarshallerGenerator.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/parse/EventStreamUnmarshallerGenerator.kt @@ -243,6 +243,25 @@ class EventStreamUnmarshallerGenerator( } } } + // Handle implicit payload members: members with neither @eventPayload nor @eventHeader. + // Per the Smithy spec, these are collectively serialized as a protocol-specific document + // in the message body. + val implicitMembers = unionStruct.members().filter { + !it.hasTrait() && !it.hasTrait() + } + if (implicitMembers.isNotEmpty() && payloadMember == null) { + val parser = protocol.structuredDataParser().errorParser(unionStruct) + if (parser != null) { + rustTemplate( + """ + builder = #{parser}(&message.payload()[..], builder) + .map_err(|err| #{Error}::unmarshalling(format!("failed to unmarshall: {err}")))?; + """, + "parser" to parser, + *codegenScope, + ) + } + } rustTemplate( "Ok(#{UnmarshalledMessage}::Event(#{Output}::$unionMemberName(builder.build())))", "Output" to unionSymbol, From 2613e17baabf9f07b5b1870ece26ed14bd4a641b Mon Sep 17 00:00:00 2001 From: Fahad Zubair Date: Fri, 13 Feb 2026 14:35:23 +0000 Subject: [PATCH 2/2] Lint format --- .../protocols/parse/EventStreamUnmarshallerGenerator.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/parse/EventStreamUnmarshallerGenerator.kt b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/parse/EventStreamUnmarshallerGenerator.kt index 4509ebf52f1..4b00d1e1633 100644 --- a/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/parse/EventStreamUnmarshallerGenerator.kt +++ b/codegen-core/src/main/kotlin/software/amazon/smithy/rust/codegen/core/smithy/protocols/parse/EventStreamUnmarshallerGenerator.kt @@ -246,9 +246,10 @@ class EventStreamUnmarshallerGenerator( // Handle implicit payload members: members with neither @eventPayload nor @eventHeader. // Per the Smithy spec, these are collectively serialized as a protocol-specific document // in the message body. - val implicitMembers = unionStruct.members().filter { - !it.hasTrait() && !it.hasTrait() - } + val implicitMembers = + unionStruct.members().filter { + !it.hasTrait() && !it.hasTrait() + } if (implicitMembers.isNotEmpty() && payloadMember == null) { val parser = protocol.structuredDataParser().errorParser(unionStruct) if (parser != null) {