Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use of Unit type in server event stream creates non-compiling code #2546

Open
dbgilley opened this issue Apr 4, 2023 · 1 comment
Open
Labels
bug Something isn't working client server Rust server SDK

Comments

@dbgilley
Copy link

dbgilley commented Apr 4, 2023

When attempting to generate server code that returns an event stream, an event type referencing smithy.api#Unit generates code that fails to compile, instead producing an error.

smithy-rs version appears to be 0.54.4

A reproducible example is:

$version: "2"
namespace com.example
use aws.protocols#restJson1
use smithy.framework#ValidationException


@restJson1 @title("Test Service") service TestService { version: "0.1", operations: [ TestOperation ] }

@http(uri: "/test", method: "POST")
operation TestOperation {
    input := { payload: String },
    output := {
        @httpPayload
        events: TestEvent,
    },
    errors: [ValidationException],
}

@streaming
union TestEvent {
    KeepAlive: Unit,
    Response: TestResponseEvent,
}

structure TestResponseEvent { data: String }

The error produced is:

---> test/src/event_stream_serde.rs:56:13
   |
56 |             Self::Input::KeepAlive(inner) => {
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a tuple variant or struct
@jdisanti jdisanti added bug Something isn't working server Rust server SDK labels Apr 4, 2023
@rcoh
Copy link
Collaborator

rcoh commented Mar 15, 2024

Note that this also applies to any union, streaming or not

@drganjoo drganjoo added the client label Apr 3, 2024
github-merge-queue bot pushed a commit that referenced this issue Apr 9, 2024
## Motivation and Context

Unions that have a [unit target member
shape](https://smithy.io/2.0/spec/model.html#unit-type) do not have an
associated data in the generated Rust enum.

Closes Issue:
[2546](#2546)

## Description

On the **server** side, when the union has constrained members, the code
generated for the conversion from the `Unconstrained` type to the
`Constrained` type incorrectly assumed that each Rust enum would have
associated data.

```
rust-server-codegen/src/unconstrained.rs:31:129
  |
  |               crate::unconstrained::some_union_with_unit_unconstrained::SomeUnionWithUnitUnconstrained::Option1(unconstrained) => Self::Option1(
    |                                                                                                                                   -^^^^^^^^^^^^- help: consider using a semicolon here to finish the statement: `;`
    |  _________________________________________________________________________________________________________________________________|
  | |
  | |                 unconstrained
  | |             ),
  | |_____________- call expression requires function
    |
   ::: rust-server-codegen/src/model.rs:152:5
    |
    |       Option1,
    |       ------- `SomeUnionWithUnit::Option1` defined here
```

The marshaling code for event streams with unit target types incorrectly
assumed that the variant would have associated data.

```
rust-server-codegen/src/event_stream_serde.rs

impl ::aws_smithy_eventstream::frame::MarshallMessage for TestEventMarshaller {
        fn marshal() {
            let payload = match input {
                Self::Input::KeepAlive(inner) => {
```

On the **client** side, the `event_stream_serde` code incorrectly
assumes that a union member, which has the `@streaming` trait applied to
it, takes a `model::Unit` type.

```
rust-client-codegen/src/event_stream_serde.rs:
    |
    |                     crate::types::TestEvent::KeepAlive(crate::types::Unit::builder().build()),
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---------------------------------------
    |                     |
    |                     call expression requires function
    |
   ::: rust-client-codegen/src/types/_test_event.rs
    |
    |     KeepAlive,
    |     --------- `TestEvent::KeepAlive` defined here
```

## Testing

A unit test has been added that tests the following model:

```
            $version: "2"
            namespace com.example
            use aws.protocols#restJson1
            use smithy.framework#ValidationException
            
            @restJson1 @title("Test Service") 
            service TestService { 
                version: "0.1", 
                operations: [ 
                    TestOperation
                    TestSimpleUnionWithUnit
                ] 
            }
            
            @http(uri: "/testunit", method: "POST")
            operation TestSimpleUnionWithUnit {
                input := {
                    @required
                    request: SomeUnionWithUnit
                }
                output := {
                    result : SomeUnionWithUnit
                }
                errors: [
                    ValidationException
                ]
            }
            
            @Length(min: 13)
            string StringRestricted
            
            union SomeUnionWithUnit {
                Option1: Unit
                Option2: StringRestricted
            }

            @http(uri: "/test", method: "POST")
            operation TestOperation {
                input := { payload: String }
                output := {
                    @httpPayload
                    events: TestEvent
                },
                errors: [ValidationException]
            }
            
            @streaming
            union TestEvent {
                KeepAlive: Unit,
                Response: TestResponseEvent,
            }
            
            structure TestResponseEvent { 
                data: String 
            }            

```

---------

Co-authored-by: Fahad Zubair <fahadzub@amazon.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working client server Rust server SDK
Projects
None yet
Development

No branches or pull requests

4 participants