Skip to content

Commit 5eeb5d7

Browse files
authored
Detect if the uniqueItems trait is used (#2001)
And act like in the rest of the unsupported constraint traits cases. I missed this in the implementation of #1342.
1 parent 0a610ec commit 5eeb5d7

File tree

5 files changed

+87
-20
lines changed

5 files changed

+87
-20
lines changed

codegen-core/common-test-models/constraints.smithy

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,10 @@ structure ConstrainedHttpBoundShapesOperationInputOutput {
154154
// @httpHeader("X-Length-MediaType")
155155
// lengthStringHeaderWithMediaType: MediaTypeLengthString,
156156

157-
@httpHeader("X-Length-Set")
158-
lengthStringSetHeader: SetOfLengthString,
157+
// TODO(https://github.com/awslabs/smithy-rs/issues/1401): a `set` shape is
158+
// just a `list` shape with `uniqueItems`, which hasn't been implemented yet.
159+
// @httpHeader("X-Length-Set")
160+
// lengthStringSetHeader: SetOfLengthString,
159161

160162
@httpHeader("X-Length-List")
161163
lengthStringListHeader: ListOfLengthString,
@@ -176,8 +178,10 @@ structure ConstrainedHttpBoundShapesOperationInputOutput {
176178
@httpQuery("lengthStringList")
177179
lengthStringListQuery: ListOfLengthString,
178180

179-
@httpQuery("lengthStringSet")
180-
lengthStringSetQuery: SetOfLengthString,
181+
// TODO(https://github.com/awslabs/smithy-rs/issues/1401): a `set` shape is
182+
// just a `list` shape with `uniqueItems`, which hasn't been implemented yet.
183+
// @httpQuery("lengthStringSet")
184+
// lengthStringSetQuery: SetOfLengthString,
181185

182186
@httpQuery("enumStringList")
183187
enumStringListQuery: ListOfEnumString,
@@ -277,7 +281,9 @@ structure ConA {
277281
conBList: ConBList,
278282
conBList2: ConBList2,
279283

280-
conBSet: ConBSet,
284+
// TODO(https://github.com/awslabs/smithy-rs/issues/1401): a `set` shape is
285+
// just a `list` shape with `uniqueItems`, which hasn't been implemented yet.
286+
// conBSet: ConBSet,
281287

282288
conBMap: ConBMap,
283289

@@ -287,7 +293,9 @@ structure ConA {
287293
enumString: EnumString,
288294

289295
listOfLengthString: ListOfLengthString,
290-
setOfLengthString: SetOfLengthString,
296+
// TODO(https://github.com/awslabs/smithy-rs/issues/1401): a `set` shape is
297+
// just a `list` shape with `uniqueItems`, which hasn't been implemented yet.
298+
// setOfLengthString: SetOfLengthString,
291299
mapOfLengthString: MapOfLengthString,
292300

293301
nonStreamingBlob: NonStreamingBlob
@@ -315,7 +323,10 @@ map MapOfListOfEnumString {
315323

316324
map MapOfSetOfLengthString {
317325
key: LengthString,
318-
value: SetOfLengthString,
326+
// TODO(https://github.com/awslabs/smithy-rs/issues/1401): a `set` shape is
327+
// just a `list` shape with `uniqueItems`, which hasn't been implemented yet.
328+
// value: SetOfLengthString,
329+
value: ListOfLengthString
319330
}
320331

321332
@length(min: 2, max: 8)
@@ -346,7 +357,9 @@ union ConstrainedUnion {
346357

347358
constrainedStructure: ConB,
348359
conBList: ConBList,
349-
conBSet: ConBSet,
360+
// TODO(https://github.com/awslabs/smithy-rs/issues/1401): a `set` shape is
361+
// just a `list` shape with `uniqueItems`, which hasn't been implemented yet.
362+
// conBSet: ConBSet,
350363
conBMap: ConBMap,
351364
}
352365

@@ -420,13 +433,15 @@ list NestedList {
420433
member: ConB
421434
}
422435

423-
set ConBSet {
424-
member: NestedSet
425-
}
426-
427-
set NestedSet {
428-
member: String
429-
}
436+
// TODO(https://github.com/awslabs/smithy-rs/issues/1401): a `set` shape is
437+
// just a `list` shape with `uniqueItems`, which hasn't been implemented yet.
438+
// set ConBSet {
439+
// member: NestedSet
440+
// }
441+
//
442+
// set NestedSet {
443+
// member: String
444+
// }
430445

431446
@length(min: 1, max: 69)
432447
map ConBMap {

codegen-core/common-test-models/misc.smithy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ list HeaderList {
255255
member: String
256256
}
257257

258-
set HeaderSet {
258+
@uniqueItems
259+
list HeaderSet {
259260
member: String
260261
}

codegen-server-test/build.gradle.kts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,12 @@ val allCodegenTests = "../codegen-core/common-test-models".let { commonModels ->
5454
"constraints",
5555
imports = listOf("$commonModels/constraints.smithy"),
5656
),
57-
CodegenTest("aws.protocoltests.restjson#RestJson", "rest_json"),
57+
CodegenTest(
58+
"aws.protocoltests.restjson#RestJson",
59+
"rest_json",
60+
// TODO(https://github.com/awslabs/smithy-rs/issues/1401) `@uniqueItems` is used.
61+
extraConfig = """, "codegen": { "ignoreUnsupportedConstraints": true } """,
62+
),
5863
CodegenTest(
5964
"aws.protocoltests.restjson#RestJsonExtras",
6065
"rest_json_extras",
@@ -65,8 +70,18 @@ val allCodegenTests = "../codegen-core/common-test-models".let { commonModels ->
6570
extraConfig = """, "codegen": { "ignoreUnsupportedConstraints": true } """,
6671
),
6772
CodegenTest("aws.protocoltests.json10#JsonRpc10", "json_rpc10"),
68-
CodegenTest("aws.protocoltests.json#JsonProtocol", "json_rpc11"),
69-
CodegenTest("aws.protocoltests.misc#MiscService", "misc", imports = listOf("$commonModels/misc.smithy")),
73+
CodegenTest(
74+
"aws.protocoltests.json#JsonProtocol",
75+
"json_rpc11",
76+
extraConfig = """, "codegen": { "ignoreUnsupportedConstraints": true } """,
77+
),
78+
CodegenTest(
79+
"aws.protocoltests.misc#MiscService",
80+
"misc",
81+
imports = listOf("$commonModels/misc.smithy"),
82+
// TODO(https://github.com/awslabs/smithy-rs/issues/1401) `@uniqueItems` is used.
83+
extraConfig = """, "codegen": { "ignoreUnsupportedConstraints": true } """,
84+
),
7085
CodegenTest(
7186
"com.amazonaws.ebs#Ebs", "ebs",
7287
imports = listOf("$commonModels/ebs.json"),

codegen-server/src/main/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ValidateUnsupportedConstraints.kt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ private sealed class UnsupportedConstraintMessageKind {
9494
level,
9595
buildMessageShapeHasUnsupportedConstraintTrait(shape, rangeTrait, constraintTraitsUberIssue),
9696
)
97+
is UnsupportedUniqueItemsTraitOnShape -> LogMessage(
98+
level,
99+
buildMessageShapeHasUnsupportedConstraintTrait(shape, uniqueItemsTrait, constraintTraitsUberIssue),
100+
)
97101
}
98102
}
99103
}
@@ -104,6 +108,7 @@ private data class UnsupportedLengthTraitOnStreamingBlobShape(val shape: BlobSha
104108
private data class UnsupportedLengthTraitOnCollectionOrOnBlobShape(val shape: Shape, val lengthTrait: LengthTrait) : UnsupportedConstraintMessageKind()
105109
private data class UnsupportedPatternTraitOnStringShape(val shape: Shape, val patternTrait: PatternTrait) : UnsupportedConstraintMessageKind()
106110
private data class UnsupportedRangeTraitOnShape(val shape: Shape, val rangeTrait: RangeTrait) : UnsupportedConstraintMessageKind()
111+
private data class UnsupportedUniqueItemsTraitOnShape(val shape: Shape, val uniqueItemsTrait: UniqueItemsTrait) : UnsupportedConstraintMessageKind()
107112

108113
data class LogMessage(val level: Level, val message: String)
109114
data class ValidationResult(val shouldAbort: Boolean, val messages: List<LogMessage>)
@@ -228,13 +233,23 @@ fun validateUnsupportedConstraints(model: Model, service: ServiceShape, codegenC
228233
.map { (shape, rangeTrait) -> UnsupportedRangeTraitOnShape(shape, rangeTrait as RangeTrait) }
229234
.toSet()
230235

236+
// 7. UniqueItems trait on any shape is used. It has not been implemented yet.
237+
// TODO(https://github.com/awslabs/smithy-rs/issues/1401)
238+
val unsupportedUniqueItemsTraitOnShapeSet = walker
239+
.walkShapes(service)
240+
.asSequence()
241+
.filterMapShapesToTraits(setOf(UniqueItemsTrait::class.java))
242+
.map { (shape, uniqueItemsTrait) -> UnsupportedUniqueItemsTraitOnShape(shape, uniqueItemsTrait as UniqueItemsTrait) }
243+
.toSet()
244+
231245
val messages =
232246
unsupportedConstraintOnMemberShapeSet.map { it.intoLogMessage(codegenConfig.ignoreUnsupportedConstraints) } +
233247
unsupportedLengthTraitOnStreamingBlobShapeSet.map { it.intoLogMessage(codegenConfig.ignoreUnsupportedConstraints) } +
234248
unsupportedConstraintOnShapeReachableViaAnEventStreamSet.map { it.intoLogMessage(codegenConfig.ignoreUnsupportedConstraints) } +
235249
unsupportedLengthTraitOnCollectionOrOnBlobShapeSet.map { it.intoLogMessage(codegenConfig.ignoreUnsupportedConstraints) } +
236250
unsupportedPatternTraitOnStringShapeSet.map { it.intoLogMessage(codegenConfig.ignoreUnsupportedConstraints) } +
237-
unsupportedRangeTraitOnShapeSet.map { it.intoLogMessage(codegenConfig.ignoreUnsupportedConstraints) }
251+
unsupportedRangeTraitOnShapeSet.map { it.intoLogMessage(codegenConfig.ignoreUnsupportedConstraints) } +
252+
unsupportedUniqueItemsTraitOnShapeSet.map { it.intoLogMessage(codegenConfig.ignoreUnsupportedConstraints) }
238253

239254
return ValidationResult(shouldAbort = messages.any { it.level == Level.SEVERE }, messages)
240255
}

codegen-server/src/test/kotlin/software/amazon/smithy/rust/codegen/server/smithy/ValidateUnsupportedConstraintsAreNotUsedTest.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,27 @@ internal class ValidateUnsupportedConstraintsAreNotUsedTest {
214214
validationResult.messages[0].message shouldContain "The integer shape `test#RangeInteger` has the constraint trait `smithy.api#range` attached"
215215
}
216216

217+
@Test
218+
fun `it should detect when the unique items trait is used`() {
219+
val model =
220+
"""
221+
$baseModel
222+
223+
structure TestInputOutput {
224+
uniqueItemsList: UniqueItemsList
225+
}
226+
227+
@uniqueItems
228+
list UniqueItemsList {
229+
member: String
230+
}
231+
""".asSmithyModel()
232+
val validationResult = validateModel(model)
233+
234+
validationResult.messages shouldHaveSize 1
235+
validationResult.messages[0].message shouldContain "The list shape `test#UniqueItemsList` has the constraint trait `smithy.api#uniqueItems` attached"
236+
}
237+
217238
@Test
218239
fun `it should abort when ignoreUnsupportedConstraints is false and unsupported constraints are used`() {
219240
val validationResult = validateModel(constraintTraitOnStreamingBlobShapeModel, ServerCodegenConfig())

0 commit comments

Comments
 (0)