Skip to content

Commit b3be1af

Browse files
chore: reduce code for bools/numbers
1 parent 8ee1a0e commit b3be1af

File tree

3 files changed

+49
-20
lines changed

3 files changed

+49
-20
lines changed

codegen/smithy-aws-typescript-codegen/src/main/java/software/amazon/smithy/aws/typescript/codegen/JsonShapeDeserVisitor.java

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import software.amazon.smithy.model.shapes.DocumentShape;
2424
import software.amazon.smithy.model.shapes.MapShape;
2525
import software.amazon.smithy.model.shapes.MemberShape;
26+
import software.amazon.smithy.model.shapes.NumberShape;
2627
import software.amazon.smithy.model.shapes.Shape;
2728
import software.amazon.smithy.model.shapes.StructureShape;
2829
import software.amazon.smithy.model.shapes.UnionShape;
@@ -131,10 +132,16 @@ protected void deserializeStructure(GenerationContext context, StructureShape sh
131132
.orElse(memberName);
132133
Shape target = context.getModel().expectShape(memberShape.getTarget());
133134

134-
writer.write("$1L: (output.$2L !== undefined && output.$2L !== null)"
135-
+ " ? $3L: undefined,", memberName, locationName,
136-
// Dispatch to the output value provider for any additional handling.
137-
target.accept(getMemberVisitor("output." + locationName)));
135+
if (target.isBooleanShape() || target instanceof NumberShape) {
136+
// Booleans and numbers will call expectBoolean/expectNumber which will handle
137+
// null/undefined properly.
138+
writer.write("$L: $L,", memberName, target.accept(getMemberVisitor("output." + locationName)));
139+
} else {
140+
writer.write("$1L: (output.$2L !== undefined && output.$2L !== null)"
141+
+ " ? $3L: undefined,", memberName, locationName,
142+
// Dispatch to the output value provider for any additional handling.
143+
target.accept(getMemberVisitor("output." + locationName)));
144+
}
138145
});
139146
});
140147
}
@@ -152,13 +159,23 @@ protected void deserializeUnion(GenerationContext context, UnionShape shape) {
152159
String locationName = memberShape.getTrait(JsonNameTrait.class)
153160
.map(JsonNameTrait::getValue)
154161
.orElse(memberName);
155-
writer.openBlock("if (output.$L !== undefined && output.$L !== null) {", "}", locationName, locationName,
156-
() -> {
157-
writer.openBlock("return {", "};", () -> {
158-
// Dispatch to the output value provider for any additional handling.
159-
writer.write("$L: $L", memberName, target.accept(getMemberVisitor("output." + locationName)));
162+
163+
String memberValue = target.accept(getMemberVisitor("output." + locationName));
164+
if (target.isBooleanShape() || target instanceof NumberShape) {
165+
// Booleans and numbers will call expectBoolean/expectNumber which will handle
166+
// null/undefined properly.
167+
writer.openBlock("if ((val = $L) !== undefined) {", "}", memberValue, () -> {
168+
writer.write("return { $L: val }", memberName);
160169
});
161-
});
170+
} else {
171+
writer.openBlock("if (output.$L !== undefined && output.$L !== null) {", "}", locationName,
172+
locationName, () -> {
173+
writer.openBlock("return {", "};", () -> {
174+
// Dispatch to the output value provider for any additional handling.
175+
writer.write("$L: $L", memberName, memberValue);
176+
});
177+
});
178+
}
162179
});
163180
// Or write to the unknown member the element in the output.
164181
writer.write("return { $$unknown: Object.entries(output)[0] };");

packages/smithy-client/src/parse-utils.spec.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ describe("expectBoolean", () => {
5151
it("accepts booleans", () => {
5252
expect(expectBoolean(true)).toEqual(true);
5353
expect(expectBoolean(false)).toEqual(false);
54+
expect(expectBoolean(null)).toEqual(undefined);
55+
expect(expectBoolean(undefined)).toEqual(undefined);
5456
});
5557

5658
it("rejects non-booleans", () => {
@@ -64,8 +66,6 @@ describe("expectBoolean", () => {
6466
expect(() => expectBoolean(NaN)).toThrowError();
6567
expect(() => expectBoolean({})).toThrowError();
6668
expect(() => expectBoolean([])).toThrowError();
67-
expect(() => expectBoolean(null)).toThrowError();
68-
expect(() => expectBoolean(undefined)).toThrowError();
6969
});
7070
});
7171

@@ -76,6 +76,8 @@ describe("expectNumber", () => {
7676
expect(expectNumber(Infinity)).toEqual(Infinity);
7777
expect(expectNumber(-Infinity)).toEqual(-Infinity);
7878
expect(expectNumber(NaN)).toEqual(NaN);
79+
expect(expectNumber(null)).toEqual(undefined);
80+
expect(expectNumber(undefined)).toEqual(undefined);
7981
});
8082

8183
it("rejects non-numbers", () => {
@@ -88,14 +90,14 @@ describe("expectNumber", () => {
8890
expect(() => expectNumber(false)).toThrowError();
8991
expect(() => expectNumber([])).toThrowError();
9092
expect(() => expectNumber({})).toThrowError();
91-
expect(() => expectNumber(null)).toThrowError();
92-
expect(() => expectNumber(undefined)).toThrowError();
9393
});
9494
});
9595

9696
describe("expectString", () => {
9797
it("accepts strings", () => {
9898
expect(expectString("foo")).toEqual("foo");
99+
expect(expectString(null)).toEqual(undefined);
100+
expect(expectString(undefined)).toEqual(undefined);
99101
});
100102

101103
it("rejects non-strings", () => {
@@ -107,7 +109,5 @@ describe("expectString", () => {
107109
expect(() => expectString(false)).toThrowError();
108110
expect(() => expectString([])).toThrowError();
109111
expect(() => expectString({})).toThrowError();
110-
expect(() => expectString(null)).toThrowError();
111-
expect(() => expectString(undefined)).toThrowError();
112112
});
113113
});

packages/smithy-client/src/parse-utils.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ export const parseBoolean = (value: string): boolean => {
1919
* Asserts a value is a boolean and returns it.
2020
*
2121
* @param value A value that is expected to be a boolean.
22-
* @returns The value if it is a boolean, otherwise an error is thrown.
22+
* @returns The value if it's a boolean, undefined if it's null/undefined,
23+
* otherwise an error is thrown.
2324
*/
24-
export function expectBoolean(value: any): boolean {
25+
export function expectBoolean(value: any): boolean | undefined {
26+
if (value === null || value === undefined) {
27+
return undefined;
28+
}
2529
if (typeof value === "boolean") {
2630
return value;
2731
}
@@ -32,9 +36,13 @@ export function expectBoolean(value: any): boolean {
3236
* Asserts a value is a number and returns it.
3337
*
3438
* @param value A value that is expected to be a number.
35-
* @returns The value if it is a number, otherwise an error is thrown.
39+
* @returns The value if it's a number, undefined if it's null/undefined,
40+
* otherwise an error is thrown.
3641
*/
3742
export function expectNumber(value: any): number {
43+
if (value === null || value === undefined) {
44+
return undefined;
45+
}
3846
if (typeof value === "number") {
3947
return value;
4048
}
@@ -45,9 +53,13 @@ export function expectNumber(value: any): number {
4553
* Asserts a value is a string and returns it.
4654
*
4755
* @param value A value that is expected to be a string.
48-
* @returns The value if it is a string, otherwise an error is thrown.
56+
* @returns The value if it's a string, undefined if it's null/undefined,
57+
* otherwise an error is thrown.
4958
*/
5059
export function expectString(value: any): string {
60+
if (value === null || value === undefined) {
61+
return undefined;
62+
}
5163
if (typeof value === "string") {
5264
return value;
5365
}

0 commit comments

Comments
 (0)