Skip to content

Commit 4a29a39

Browse files
chore: add helpers
1 parent 17072b1 commit 4a29a39

File tree

5 files changed

+83
-1
lines changed

5 files changed

+83
-1
lines changed

packages/smithy-client/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export * from "./get-array-if-single-item";
77
export * from "./get-value-from-text-node";
88
export * from "./lazy-json";
99
export * from "./parse-utils";
10+
export * from "./ser-utils";
1011
export * from "./date-utils";
1112
export * from "./split-every";
1213
export * from "./constants";

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

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { parseBoolean } from "./parse-utils";
1+
import { handleFloat, parseBoolean } from "./parse-utils";
22
import { expectBoolean, expectNumber, expectString } from "./parse-utils";
33

44
describe("parseBoolean", () => {
@@ -111,3 +111,26 @@ describe("expectString", () => {
111111
expect(() => expectString({})).toThrowError();
112112
});
113113
});
114+
115+
describe("handleFloat", () => {
116+
it("accepts non-numeric floats as strings", () => {
117+
expect(handleFloat("NaN")).toEqual(NaN);
118+
expect(handleFloat("Infinity")).toEqual(Infinity);
119+
expect(handleFloat("-Infinity")).toEqual(-Infinity);
120+
});
121+
122+
it("rejects numeric strings", () => {
123+
expect(() => handleFloat("1")).toThrowError();
124+
expect(() => handleFloat("1.1")).toThrowError();
125+
});
126+
127+
it("accepts numbers", () => {
128+
expect(expectNumber(1)).toEqual(1);
129+
expect(expectNumber(1.1)).toEqual(1.1);
130+
expect(expectNumber(Infinity)).toEqual(Infinity);
131+
expect(expectNumber(-Infinity)).toEqual(-Infinity);
132+
expect(expectNumber(NaN)).toEqual(NaN);
133+
expect(expectNumber(null)).toEqual(undefined);
134+
expect(expectNumber(undefined)).toEqual(undefined);
135+
});
136+
});

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,27 @@ export const expectString = (value: any): string | undefined => {
6565
}
6666
throw new TypeError(`Expected string, got ${typeof value}`);
6767
};
68+
69+
/**
70+
* Asserts a value is a number and returns it, and also converts string
71+
* representations of non-numeric floats into Numbers.
72+
*
73+
* @param value A number or string representation of a non-numeric float.
74+
* @returns The value as a number, undefined if it's null/undefined,
75+
* otherwise an error is thrown.
76+
*/
77+
export const handleFloat = (value: string | number): number | undefined => {
78+
if (typeof value == "string") {
79+
switch (value) {
80+
case "NaN":
81+
return NaN;
82+
case "Infinity":
83+
return Infinity;
84+
case "-Infinity":
85+
return -Infinity;
86+
default:
87+
throw new Error(`Unable to parse float value: ${value}`);
88+
}
89+
}
90+
return expectNumber(value);
91+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { serializeFloat } from "./ser-utils";
2+
3+
describe("serializeFloat", () => {
4+
it("handles non-numerics", () => {
5+
expect(serializeFloat(NaN)).toEqual("NaN");
6+
expect(serializeFloat(Infinity)).toEqual("Infinity");
7+
expect(serializeFloat(-Infinity)).toEqual("-Infinity");
8+
});
9+
10+
it("handles normal numbers", () => {
11+
expect(serializeFloat(1)).toEqual(1);
12+
expect(serializeFloat(1.1)).toEqual(1.1);
13+
});
14+
});
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Serializes a number, turning non-numeric values into strings.
3+
*
4+
* @param value The number to serialize.
5+
* @returns A number, or a string if the given number was non-numeric.
6+
*/
7+
export const serializeFloat = (value: number): string | number => {
8+
// NaN is not equal to everything, including itself.
9+
if (value !== value) {
10+
return "NaN";
11+
}
12+
switch (value) {
13+
case Infinity:
14+
return "Infinity";
15+
case -Infinity:
16+
return "-Infinity";
17+
default:
18+
return value;
19+
}
20+
};

0 commit comments

Comments
 (0)