diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index a99b8c59a8..789c340c3b 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -28,3 +28,9 @@ message = "The `AssumeRoleBuilder::policy_arns` now accepts strings instead of a references = ["smithy-rs#3205"] meta = { "breaking" = true, "tada" = false, "bug" = false } author = "rcoh" + +[[aws-sdk-rust]] +message = "Fix optional types in S3. Many types in S3 were modeled as non-optional but this causes serialization issues." +references = ["smithy-rs#3213"] +meta = { "breaking" = true, "tada" = false, "bug" = false } +author = "rcoh" diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/MakeS3BoolsAndNumbersOptional.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/MakeS3BoolsAndNumbersOptional.kt new file mode 100644 index 0000000000..b8bd4056aa --- /dev/null +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/MakeS3BoolsAndNumbersOptional.kt @@ -0,0 +1,38 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +package software.amazon.smithy.rustsdk.customize.s3 + +import software.amazon.smithy.model.Model +import software.amazon.smithy.model.shapes.AbstractShapeBuilder +import software.amazon.smithy.model.shapes.BooleanShape +import software.amazon.smithy.model.shapes.NumberShape +import software.amazon.smithy.model.shapes.Shape +import software.amazon.smithy.model.traits.DefaultTrait +import software.amazon.smithy.model.transform.ModelTransformer + +/** + * The s3 model is being updated but if we consume that model update, then we'll run into an issue with examples compilation + * + * This "pre-updates" the model so we can fix examples without requiring complex coordination + */ +class MakeS3BoolsAndNumbersOptional { + fun processModel(model: Model): Model { + val updates = arrayListOf() + for (struct in model.structureShapes) { + for (member in struct.allMembers.values) { + val target = model.expectShape(member.target) + val boolTarget = target as? BooleanShape + val numberTarget = target as? NumberShape + if (boolTarget != null || numberTarget != null) { + updates.add(member.toBuilder().removeTrait(DefaultTrait.ID).build()) + val builder: AbstractShapeBuilder<*, *> = Shape.shapeToBuilder(target) + updates.add(builder.removeTrait(DefaultTrait.ID).build()) + } + } + } + return ModelTransformer.create().replaceShapes(model, updates) + } +} diff --git a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/S3Decorator.kt b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/S3Decorator.kt index 0cf1c196ff..3a00339811 100644 --- a/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/S3Decorator.kt +++ b/aws/sdk-codegen/src/main/kotlin/software/amazon/smithy/rustsdk/customize/s3/S3Decorator.kt @@ -88,6 +88,7 @@ class S3Decorator : ClientCodegenDecorator { ) // enable optional auth for operations commonly used with public buckets .let(AddOptionalAuth()::transform) + .let(MakeS3BoolsAndNumbersOptional()::processModel) override fun endpointCustomizations(codegenContext: ClientCodegenContext): List { return listOf( diff --git a/aws/sdk/integration-tests/s3/tests/select-object-content.rs b/aws/sdk/integration-tests/s3/tests/select-object-content.rs index 4ba1e49163..d9eb6d6df4 100644 --- a/aws/sdk/integration-tests/s3/tests/select-object-content.rs +++ b/aws/sdk/integration-tests/s3/tests/select-object-content.rs @@ -67,7 +67,9 @@ async fn test_success() { let stats = stats.details.unwrap(); received.push(format!( "scanned:{},processed:{},returned:{}", - stats.bytes_scanned, stats.bytes_processed, stats.bytes_returned + stats.bytes_scanned.unwrap(), + stats.bytes_processed.unwrap(), + stats.bytes_returned.unwrap() )) } SelectObjectContentEventStream::End(_) => {} diff --git a/aws/sdk/integration-tests/s3/tests/size-type.rs b/aws/sdk/integration-tests/s3/tests/size-type.rs index d790b0a622..5179fb0387 100644 --- a/aws/sdk/integration-tests/s3/tests/size-type.rs +++ b/aws/sdk/integration-tests/s3/tests/size-type.rs @@ -12,5 +12,5 @@ fn size_type() { // Should only compile if the type is correctly customized let object = Object::builder().size(size).build(); - assert_eq!(size, object.size); + assert_eq!(Some(size), object.size); }