Skip to content

Commit 2ba57f9

Browse files
authored
fix: Provide an encoding customization that allows empty lists to be serialized (#457)
* Adds the ability to serialize empty lists for Form URL encoding * Updates ec2 tests * Adds missing case for handling empty lists
1 parent ace9ef9 commit 2ba57f9

File tree

4 files changed

+32
-5
lines changed

4 files changed

+32
-5
lines changed

smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/serde/formurl/FormURLEncodeCustomizable.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ import software.amazon.smithy.model.shapes.Shape
1010
interface FormURLEncodeCustomizable {
1111
fun alwaysUsesFlattenedCollections(): Boolean
1212
fun customNameTraitGenerator(memberShape: Shape, defaultName: String): String
13+
fun shouldSerializeEmptyLists(): Boolean
1314
}

smithy-swift-codegen/src/main/kotlin/software/amazon/smithy/swift/codegen/integration/serde/formurl/MemberShapeEncodeFormURLGenerator.kt

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,19 @@ abstract class MemberShapeEncodeFormURLGenerator(
4040
val resolvedMemberName = customizations.customNameTraitGenerator(member, member.memberName)
4141
val nestedContainer = "${memberName}Container"
4242
writer.openBlock("if let $memberName = $memberName {", "}") {
43-
if (member.hasTrait(XmlFlattenedTrait::class.java) || customizations.alwaysUsesFlattenedCollections()) {
44-
writer.openBlock("if !$memberName.isEmpty {", "}") {
43+
writer.openBlock("if !$memberName.isEmpty {", "}") {
44+
if (member.hasTrait(XmlFlattenedTrait::class.java) || customizations.alwaysUsesFlattenedCollections()) {
4545
renderFlattenedListMemberItems(memberName, member, memberTarget, containerName)
46+
} else {
47+
writer.write("var $nestedContainer = $containerName.nestedContainer(keyedBy: \$N.self, forKey: \$N(\"$resolvedMemberName\"))", ClientRuntimeTypes.Serde.Key, ClientRuntimeTypes.Serde.Key)
48+
renderListMemberItems(memberName, memberTarget, nestedContainer)
49+
}
50+
}
51+
if (customizations.shouldSerializeEmptyLists()) {
52+
writer.openBlock("else {", "}") {
53+
writer.write("var $nestedContainer = $containerName.nestedContainer(keyedBy: \$N.self, forKey: \$N(\"$resolvedMemberName\"))", ClientRuntimeTypes.Serde.Key, ClientRuntimeTypes.Serde.Key)
54+
writer.write("try $nestedContainer.encode(\"\", forKey: \$N(\"\"))", ClientRuntimeTypes.Serde.Key)
4655
}
47-
} else {
48-
writer.write("var $nestedContainer = $containerName.nestedContainer(keyedBy: \$N.self, forKey: \$N(\"$resolvedMemberName\"))", ClientRuntimeTypes.Serde.Key, ClientRuntimeTypes.Serde.Key)
49-
renderListMemberItems(memberName, memberTarget, nestedContainer)
5056
}
5157
}
5258
}

smithy-swift-codegen/src/test/kotlin/mocks/MockHttpEC2QueryProtocolGenerator.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ class MockEc2QueryFormURLEncodeCustomizations : FormURLEncodeCustomizable {
6060
override fun customNameTraitGenerator(shape: Shape, defaultName: String): String {
6161
return Ec2QueryNameTraitGenerator.construct(shape, defaultName).toString()
6262
}
63+
64+
override fun shouldSerializeEmptyLists(): Boolean {
65+
return true
66+
}
6367
}
6468

6569
class MockHttpEC2QueryProtocolGenerator : HttpBindingProtocolGenerator() {

smithy-swift-codegen/src/test/kotlin/serde/ec2/OnlyFlattenedListEncodeFormURLGeneratorTests.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class OnlyFlattenedListEncodeFormURLGeneratorTests {
3232
try complexListArgContainer0.encode(greetingstruct0, forKey: ClientRuntime.Key(""))
3333
}
3434
}
35+
else {
36+
var complexListArgContainer = container.nestedContainer(keyedBy: ClientRuntime.Key.self, forKey: ClientRuntime.Key("ComplexListArg"))
37+
try complexListArgContainer.encode("", forKey: ClientRuntime.Key(""))
38+
}
3539
}
3640
if let listArg = listArg {
3741
if !listArg.isEmpty {
@@ -40,6 +44,10 @@ class OnlyFlattenedListEncodeFormURLGeneratorTests {
4044
try listArgContainer0.encode(string0, forKey: ClientRuntime.Key(""))
4145
}
4246
}
47+
else {
48+
var listArgContainer = container.nestedContainer(keyedBy: ClientRuntime.Key.self, forKey: ClientRuntime.Key("ListArg"))
49+
try listArgContainer.encode("", forKey: ClientRuntime.Key(""))
50+
}
4351
}
4452
if let listArgWithXmlName = listArgWithXmlName {
4553
if !listArgWithXmlName.isEmpty {
@@ -48,6 +56,10 @@ class OnlyFlattenedListEncodeFormURLGeneratorTests {
4856
try listArgWithXmlNameContainer0.encode(string0, forKey: ClientRuntime.Key(""))
4957
}
5058
}
59+
else {
60+
var listArgWithXmlNameContainer = container.nestedContainer(keyedBy: ClientRuntime.Key.self, forKey: ClientRuntime.Key("Hi"))
61+
try listArgWithXmlNameContainer.encode("", forKey: ClientRuntime.Key(""))
62+
}
5163
}
5264
if let listArgWithXmlNameMember = listArgWithXmlNameMember {
5365
if !listArgWithXmlNameMember.isEmpty {
@@ -56,6 +68,10 @@ class OnlyFlattenedListEncodeFormURLGeneratorTests {
5668
try listArgWithXmlNameMemberContainer0.encode(string0, forKey: ClientRuntime.Key(""))
5769
}
5870
}
71+
else {
72+
var listArgWithXmlNameMemberContainer = container.nestedContainer(keyedBy: ClientRuntime.Key.self, forKey: ClientRuntime.Key("ListArgWithXmlNameMember"))
73+
try listArgWithXmlNameMemberContainer.encode("", forKey: ClientRuntime.Key(""))
74+
}
5975
}
6076
try container.encode("Ec2QueryLists", forKey:ClientRuntime.Key("Action"))
6177
try container.encode("2020-01-08", forKey:ClientRuntime.Key("Version"))

0 commit comments

Comments
 (0)