Skip to content

Commit

Permalink
event streams and operation errors not necessarily disjoint
Browse files Browse the repository at this point in the history
Signed-off-by: Daniele Ahmed <[email protected]>
  • Loading branch information
82marbag authored and Daniele Ahmed committed Jul 8, 2022
1 parent 2c4db07 commit 0a150ba
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 13 deletions.
10 changes: 9 additions & 1 deletion codegen-server-test/model/pokemon.smithy
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ resource PokemonSpecies {
operation CapturePokemonOperation {
input: CapturePokemonOperationEventsInput,
output: CapturePokemonOperationEventsOutput,
errors: [UnsupportedRegionError, MasterBallUnsuccessful]
errors: [UnsupportedRegionError, ThrottlingError]
}

@input
Expand All @@ -53,6 +53,7 @@ union AttemptCapturingPokemonEvent {
}

structure CapturingEvent {
@eventPayload
payload: CapturingPayload,
}

Expand All @@ -65,12 +66,17 @@ structure CapturingPayload {
union CapturePokemonEvents {
event: CaptureEvent,
invalid_pokeball: InvalidPokeballError,
throttlingError: ThrottlingError,
}

structure CaptureEvent {
@eventHeader
name: String,
@eventHeader
captured: Boolean,
@eventHeader
shiny: Boolean,
@eventPayload
pokedex_update: Blob,
}

Expand All @@ -89,6 +95,8 @@ structure MasterBallUnsuccessful {
@required
message: String,
}
@error("client")
structure ThrottlingError {}

/// Retrieve information about a Pokémon species.
@readonly
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,28 +21,31 @@ import software.amazon.smithy.rust.codegen.smithy.traits.SyntheticEventStreamUni
import software.amazon.smithy.rust.codegen.util.expectTrait
import software.amazon.smithy.rust.codegen.util.hasTrait
import software.amazon.smithy.rust.codegen.util.isEventStream
import kotlin.streams.toList

/**
* Generates synthetic unions to replace the modeled unions for Event Stream types.
* This allows us to strip out all the error union members once up-front, instead of in each
* place that does codegen with the unions.
*/
object EventStreamNormalizer {
fun transform(model: Model): Model = ModelTransformer.create().mapShapes(model) { shape ->
if (shape is OperationShape) {
val newErrors = shape.errors
fun transform(model: Model): Model {
val transformer = ModelTransformer.create()
val operations = model.shapes(OperationShape::class.java).toList()
val newShapes = operations.flatMap { operation ->
operation.errors
.map { model.expectShape(it, StructureShape::class.java) }
.map { it.toBuilder().addTrait(SyntheticOperationErrorTrait()).build() }
val newShape = shape.toBuilder().errors(newErrors.map { it.id }).build()
if (newShape.isEventStream(model)) {
addStreamErrorsToOperationErrors(model, newShape)
}
val modelWithSyntheticErrors = model.toBuilder().addShapes(newShapes).build()
return transformer.mapShapes(modelWithSyntheticErrors) { shape ->
if (shape is OperationShape && shape.isEventStream(modelWithSyntheticErrors)) {
addStreamErrorsToOperationErrors(modelWithSyntheticErrors, shape)
} else if (shape is UnionShape && shape.isEventStream()) {
syntheticEquivalentEventStreamUnion(modelWithSyntheticErrors, shape)
} else {
newShape
shape
}
} else if (shape is UnionShape && shape.isEventStream()) {
syntheticEquivalentEventStreamUnion(model, shape)
} else {
shape
}
}

Expand Down Expand Up @@ -107,6 +110,6 @@ fun OperationShape.allErrors(model: Model): List<Shape> {

class SyntheticOperationErrorTrait : AnnotationTrait(ID, Node.objectNode()) {
companion object {
val ID = ShapeId.from("smithy.api.internal#syntheticOperationErrorTrait")
val ID: ShapeId = ShapeId.from("smithy.api.internal#syntheticOperationErrorTrait")
}
}

0 comments on commit 0a150ba

Please sign in to comment.