Skip to content

Commit f67c210

Browse files
authored
fix: Just emit a comment for validating SDK output structures in Rust (#752)
See #751 Also bumps the Rust toolchain version since the SDKs require 1.81 now.
1 parent fc8abc1 commit f67c210

File tree

2 files changed

+58
-38
lines changed

2 files changed

+58
-38
lines changed

Diff for: .github/workflows/test_models_rust_tests.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jobs:
5959
- name: Set up Rust
6060
uses: actions-rust-lang/setup-rust-toolchain@v1
6161
with:
62-
toolchain: "1.80.0"
62+
toolchain: "1.81.0"
6363
rustflags: ""
6464
components: rustfmt
6565

Diff for: codegen/smithy-dafny-codegen/src/main/java/software/amazon/polymorph/smithyrust/generator/RustLibraryShimGenerator.java

+57-37
Original file line numberDiff line numberDiff line change
@@ -1049,45 +1049,65 @@ private String generateValidationFunction(
10491049
);
10501050
}
10511051
} else if (shape instanceof StructureShape structureShape) {
1052-
var isPositionalOutput =
1053-
(operation == null ||
1054-
operation.getOutputShape().equals(shape.getId())) &&
1055-
structureShape.hasTrait(PositionalTrait.class);
1056-
for (final var memberShape : structureShape.getAllMembers().values()) {
1057-
final var memberVariables = structureMemberVariables(memberShape);
1058-
memberVariables.put(
1059-
"memberValidationFunctionName",
1060-
shapeValidationFunctionName(null, null, memberShape)
1052+
// If this is a response shape for an AWS SDK,
1053+
// make validation a no-op for now.
1054+
// This is because the SDKs will produce values that violate constraints,
1055+
// such as a `Some({})` on an optional map with @length(min: 1).
1056+
// This could be considered an SDK bug since information is lost,
1057+
// SDKs are also not supposed to validate constraints
1058+
// which makes it harder to argue it should be fixed.
1059+
// See https://github.com/smithy-lang/smithy-dafny/issues/751
1060+
var generator = mergedGenerator.generatorForShape(shape);
1061+
if (
1062+
generator instanceof RustAwsSdkShimGenerator &&
1063+
operationIndex.isOutputStructure(shape)
1064+
) {
1065+
validationBlocks.add(
1066+
"// Validation intentionally suppressed for AWS SDK response structures"
10611067
);
1062-
1063-
if (isPositionalOutput) {
1064-
validationBlocks.add(
1065-
evalTemplate(
1066-
"$memberValidationFunctionName:L(&Some(input.clone()))?;",
1067-
memberVariables
1068-
)
1069-
);
1070-
} else if (
1071-
mergedGenerator
1072-
.generatorForShape(structureShape)
1073-
.isRustFieldRequired(structureShape, memberShape) &&
1074-
// TODO: This may be more correct than the current isRustFieldRequired in general
1075-
!(operationIndex.isOutputStructure(structureShape) &&
1076-
model.expectShape(memberShape.getTarget()).isListShape())
1077-
) {
1078-
validationBlocks.add(
1079-
evalTemplate(
1080-
"$memberValidationFunctionName:L(&Some(input.$fieldName:L.clone()))?;",
1081-
memberVariables
1082-
)
1083-
);
1084-
} else {
1085-
validationBlocks.add(
1086-
evalTemplate(
1087-
"$memberValidationFunctionName:L(&input.$fieldName:L)?;",
1088-
memberVariables
1089-
)
1068+
} else {
1069+
var isPositionalOutput =
1070+
(operation == null ||
1071+
operation.getOutputShape().equals(shape.getId())) &&
1072+
structureShape.hasTrait(PositionalTrait.class);
1073+
for (final var memberShape : structureShape
1074+
.getAllMembers()
1075+
.values()) {
1076+
final var memberVariables = structureMemberVariables(memberShape);
1077+
memberVariables.put(
1078+
"memberValidationFunctionName",
1079+
shapeValidationFunctionName(null, null, memberShape)
10901080
);
1081+
1082+
if (isPositionalOutput) {
1083+
validationBlocks.add(
1084+
evalTemplate(
1085+
"$memberValidationFunctionName:L(&Some(input.clone()))?;",
1086+
memberVariables
1087+
)
1088+
);
1089+
} else if (
1090+
mergedGenerator
1091+
.generatorForShape(structureShape)
1092+
.isRustFieldRequired(structureShape, memberShape) &&
1093+
// TODO: This may be more correct than the current isRustFieldRequired in general
1094+
!(operationIndex.isOutputStructure(structureShape) &&
1095+
model.expectShape(memberShape.getTarget()).isListShape())
1096+
) {
1097+
validationBlocks.add(
1098+
evalTemplate(
1099+
"$memberValidationFunctionName:L(&Some(input.$fieldName:L.clone()))?;",
1100+
memberVariables
1101+
)
1102+
);
1103+
} else {
1104+
validationBlocks.add(
1105+
evalTemplate(
1106+
"$memberValidationFunctionName:L(&input.$fieldName:L)?;",
1107+
memberVariables
1108+
)
1109+
);
1110+
}
10911111
}
10921112
}
10931113
} else if (shape instanceof UnionShape unionShape) {

0 commit comments

Comments
 (0)