json-as 1.0.0-beta.1 → 1.0.0-beta.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/.trunk/configs/.markdownlint.yaml +2 -0
  2. package/.trunk/configs/.shellcheckrc +7 -0
  3. package/.trunk/configs/.yamllint.yaml +7 -0
  4. package/.trunk/trunk.yaml +37 -0
  5. package/CHANGELOG +60 -0
  6. package/README.md +275 -25
  7. package/assembly/__benches__/misc.bench.ts +0 -1
  8. package/assembly/__benches__/string.bench.ts +23 -0
  9. package/assembly/__benches__/struct.bench.ts +21 -0
  10. package/assembly/__tests__/arbitrary.spec.ts +1 -1
  11. package/assembly/__tests__/array.spec.ts +42 -1
  12. package/assembly/__tests__/bool.spec.ts +1 -1
  13. package/assembly/__tests__/box.spec.ts +1 -1
  14. package/assembly/__tests__/custom.spec.ts +42 -0
  15. package/assembly/__tests__/date.spec.ts +1 -1
  16. package/assembly/__tests__/float.spec.ts +4 -4
  17. package/assembly/__tests__/integer.spec.ts +1 -1
  18. package/assembly/__tests__/null.spec.ts +1 -1
  19. package/assembly/__tests__/raw.spec.ts +23 -0
  20. package/assembly/__tests__/string.spec.ts +1 -1
  21. package/assembly/__tests__/{obj.spec.ts → struct.spec.ts} +18 -4
  22. package/assembly/__tests__/test.spec.ts +1 -1
  23. package/assembly/as-bs.d.ts +53 -0
  24. package/assembly/custom/bench.ts +26 -0
  25. package/assembly/deserialize/simple/array/arbitrary.ts +1 -2
  26. package/assembly/deserialize/simple/array/array.ts +4 -3
  27. package/assembly/deserialize/simple/array/bool.ts +7 -7
  28. package/assembly/deserialize/simple/array/float.ts +1 -1
  29. package/assembly/deserialize/simple/array/integer.ts +1 -1
  30. package/assembly/deserialize/simple/array/map.ts +1 -1
  31. package/assembly/deserialize/simple/array/string.ts +3 -3
  32. package/assembly/deserialize/simple/array/struct.ts +14 -3
  33. package/assembly/deserialize/simple/array.ts +3 -0
  34. package/assembly/deserialize/simple/map.ts +92 -67
  35. package/assembly/deserialize/simple/object.ts +3 -2
  36. package/assembly/deserialize/simple/raw.ts +6 -0
  37. package/assembly/deserialize/simple/struct.ts +29 -16
  38. package/assembly/index.d.ts +15 -1
  39. package/assembly/index.ts +94 -13
  40. package/assembly/serialize/simd/string.ts +0 -1
  41. package/assembly/serialize/simple/array.ts +0 -1
  42. package/assembly/serialize/simple/bool.ts +0 -2
  43. package/assembly/serialize/simple/date.ts +0 -1
  44. package/assembly/serialize/simple/float.ts +0 -1
  45. package/assembly/serialize/simple/integer.ts +0 -1
  46. package/assembly/serialize/simple/map.ts +0 -1
  47. package/assembly/serialize/simple/object.ts +0 -1
  48. package/assembly/serialize/simple/raw.ts +14 -0
  49. package/assembly/serialize/simple/string.ts +0 -1
  50. package/assembly/test.ts +69 -28
  51. package/bench/bench.ts +15 -0
  52. package/bench/schemas.ts +5 -0
  53. package/bench/string.bench.ts +16 -0
  54. package/index.ts +1 -1
  55. package/lib/tsconfig.json +8 -0
  56. package/package.json +9 -6
  57. package/run-tests.sh +1 -1
  58. package/transform/lib/index.js +120 -46
  59. package/transform/lib/index.js.map +1 -1
  60. package/transform/src/index.ts +137 -54
  61. package/.gitmodules +0 -0
  62. package/as-test.config.json +0 -18
  63. package/modules/as-bs/LICENSE +0 -21
  64. package/modules/as-bs/README.md +0 -95
  65. package/modules/as-bs/assembly/state.ts +0 -8
  66. package/modules/as-bs/assembly/tsconfig.json +0 -97
  67. package/modules/as-bs/index.ts +0 -1
  68. package/modules/as-bs/package.json +0 -32
  69. /package/{modules/test/assembly → assembly/__tests__/lib}/index.ts +0 -0
  70. /package/{modules/as-bs/assembly/index.ts → lib/as-bs.ts} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize Date", () => {
5
5
  expect(JSON.stringify<Date>(new Date(0)))
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize floats", () => {
5
5
  expect(JSON.stringify<f64>(7.23)).toBe("7.23");
@@ -34,9 +34,9 @@ describe("Should deserialize floats", () => {
34
34
 
35
35
  expect(JSON.parse<f64>("0.000001").toString()).toBe("0.000001");
36
36
 
37
- // expect(JSON.parse<f64>("1e-7")).toBe(1e-7);
37
+ expect(JSON.parse<f64>("1e-7").toString()).toBe(1e-7.toString());
38
38
 
39
- // expect(JSON.parse<f64>("100000000000000000000.0").toString()).toBe(1e20);
39
+ expect(JSON.parse<f64>("100000000000000000000.0").toString()).toBe(1e20.toString());
40
40
 
41
- // expect(JSON.parse<f64>("1e+21")).toBe(1e21);
41
+ expect(JSON.parse<f64>("1e+21").toString()).toBe(1e21.toString());
42
42
  });
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize integers", () => {
5
5
  expect(JSON.stringify(0)).toBe("0");
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize null", () => {
5
5
  expect(JSON.stringify(null)).toBe("null");
@@ -0,0 +1,23 @@
1
+ import { JSON } from "..";
2
+ import { describe, expect } from "./lib";
3
+
4
+ describe("Should serialize JSON.Raw", () => {
5
+ expect(JSON.stringify<JSON.Raw>(JSON.Raw.from('{"x":1.0,"y":2.0,"z":3.0}'))).toBe('{"x":1.0,"y":2.0,"z":3.0}');
6
+ });
7
+
8
+ describe("Should deserialize JSON.Raw", () => {
9
+ expect(JSON.parse<JSON.Raw>('{"x":1.0,"y":2.0,"z":3.0}').toString()).toBe('{"x":1.0,"y":2.0,"z":3.0}');
10
+ });
11
+
12
+ describe("Should serialize Map<string, JSON.Raw>", () => {
13
+ const m1 = new Map<string, JSON.Raw>();
14
+ m1.set("hello", new JSON.Raw("\"world\""));
15
+ m1.set("pos", new JSON.Raw("{\"x\":1.0,\"y\":2.0,\"z\":3.0}"));
16
+
17
+ expect(JSON.stringify(m1)).toBe('{"hello":"world","pos":{"x":1.0,"y":2.0,"z":3.0}}');
18
+ });
19
+
20
+ describe("Should deserialize Map<string, JSON.Raw>", () => {
21
+ const m1 = JSON.parse<Map<string, JSON.Raw>>('{"hello":"world","pos":{"x":1.0,"y":2.0,"z":3.0}}');
22
+ expect(JSON.stringify(m1)).toBe('{"hello":"world","pos":{"x":1.0,"y":2.0,"z":3.0}}');
23
+ });
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize strings", () => {
5
5
  expect(JSON.stringify("abcdefg")).toBe('"abcdefg"');
@@ -1,7 +1,7 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
- describe("Should serialize objects", () => {
4
+ describe("Should serialize structs", () => {
5
5
  expect(
6
6
  JSON.stringify<Vec3>({
7
7
  x: 3.4,
@@ -38,7 +38,7 @@ describe("Should serialize objects", () => {
38
38
  expect(JSON.stringify<ObjWithStrangeKey<string>>({ data: "foo" })).toBe('{"a\\\\\\t\\"\\u0002b`c":"foo"}');
39
39
  });
40
40
 
41
- describe("Should serialize objects with inheritance", () => {
41
+ describe("Should serialize structs with inheritance", () => {
42
42
  const obj = new DerivedObject("1", "2");
43
43
 
44
44
  expect(JSON.stringify(obj)).toBe('{"a":"1","b":"2"}');
@@ -52,6 +52,21 @@ describe("Should ignore properties decorated with @omit", () => {
52
52
  ).toBe('{"y":1,"x":1,"z":1}');
53
53
  });
54
54
 
55
+ describe("Should deserialize structs", () => {
56
+ expect(
57
+ JSON.stringify(JSON.parse<Vec3>('{"x":3.4,"y":1.2,"z":8.3}')),
58
+ ).toBe('{"x":3.4,"y":1.2,"z":8.3}');
59
+ });
60
+
61
+ describe("Should deserialize structs with whitespace", () => {
62
+ expect(
63
+ JSON.stringify(JSON.parse<Vec3>(' { "x" : 3.4 , "y" : 1.2 , "z" : 8.3 } ')),
64
+ ).toBe('{"x":3.4,"y":1.2,"z":8.3}');
65
+ });
66
+
67
+ // describe("Should serialize Suite struct", () => {
68
+
69
+ // });
55
70
 
56
71
  @json
57
72
  class BaseObject {
@@ -99,7 +114,6 @@ class ObjWithString {
99
114
 
100
115
  @json
101
116
  class ObjWithStrangeKey<T> {
102
-
103
117
  @alias('a\\\t"\x02b`c')
104
118
  data!: T;
105
119
  }
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "../";
2
- import { describe, expect } from "../../modules/test/assembly/index";
2
+ import { describe, expect } from "./lib";
3
3
  import { DerivedObject, Null, ObjWithStrangeKey, ObjectWithFloat, OmitIf, Player, Vec3 } from "./types";
4
4
 
5
5
  // describe("Should serialize objects", () => {
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Central buffer namespace for managing memory operations.
3
+ */
4
+ declare namespace bs {
5
+ /** Current buffer pointer. */
6
+ export let buffer: ArrayBuffer;
7
+
8
+ /** Current offset within the buffer. */
9
+ export let offset: usize;
10
+
11
+ /** Proposed size of output. */
12
+ export let stackSize: usize;
13
+
14
+ /**
15
+ * Ensures the buffer size is at least the proposed size.
16
+ * If necessary, reallocates the buffer to the exact new size.
17
+ * @param size - The size to propose.
18
+ */
19
+ export function ensureSize(size: u32): void;
20
+
21
+ /**
22
+ * Proposes that the buffer size should be at least the given size.
23
+ * If necessary, reallocates the buffer to the exact new size.
24
+ * @param size - The size to propose.
25
+ */
26
+ export function proposeSize(size: u32): void;
27
+
28
+ /**
29
+ * Increases the proposed size by nextPowerOf2(n + 64) if necessary.
30
+ * If necessary, reallocates the buffer to the exact new size.
31
+ * @param size - The size to grow by.
32
+ */
33
+ export function growSize(size: u32): void;
34
+
35
+ /**
36
+ * Resizes the buffer to the specified size.
37
+ * @param newSize - The new buffer size.
38
+ */
39
+ export function resize(newSize: u32): void;
40
+
41
+ /**
42
+ * Copies the buffer's content to a new object of a specified type.
43
+ * @returns The new object containing the buffer's content.
44
+ */
45
+ export function out<T>(): T;
46
+
47
+ /**
48
+ * Copies the buffer's content to a given destination pointer.
49
+ * @param dst - The destination pointer.
50
+ * @returns The destination pointer cast to the specified type.
51
+ */
52
+ export function outTo<T>(dst: usize): T;
53
+ }
@@ -0,0 +1,26 @@
1
+ export function bench(description: string, routine: () => void, ops: u64 = 1_000_000): void {
2
+ console.log(" - Benchmarking " + description);
3
+ const start = Date.now();
4
+ let count = ops;
5
+ while (count != 0) {
6
+ routine();
7
+ count--;
8
+ }
9
+ const elapsed = Date.now() - start;
10
+
11
+ let opsPerSecond = (ops * 1000) / elapsed;
12
+
13
+ console.log(` Completed benchmark in ${formatNumber(elapsed)}ms at ${formatNumber(opsPerSecond)} ops/s\n`);
14
+ }
15
+
16
+ function formatNumber(n: u64): string {
17
+ let str = n.toString();
18
+ let len = str.length;
19
+ let result = "";
20
+ let commaOffset = len % 3;
21
+ for (let i = 0; i < len; i++) {
22
+ if (i > 0 && (i - commaOffset) % 3 == 0) result += ",";
23
+ result += str.charAt(i);
24
+ }
25
+ return result;
26
+ }
@@ -1,10 +1,9 @@
1
1
  import { BACK_SLASH, BRACE_LEFT, BRACE_RIGHT, BRACKET_LEFT, BRACKET_RIGHT, CHAR_F, CHAR_N, CHAR_T, COMMA, QUOTE } from "../../../custom/chars";
2
2
  import { JSON } from "../../../";
3
3
  import { isSpace } from "util/string";
4
- import { ptrToStr } from "../../../util/ptrToStr";
5
4
 
6
5
  export function deserializeArbitraryArray(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value[] {
7
- const out = dst ? changetype<JSON.Value[]>(dst) : instantiate<JSON.Value[]>();
6
+ const out = changetype<JSON.Value[]>(dst || changetype<usize>(instantiate<JSON.Value[]>()));
8
7
  let lastIndex: usize = 0;
9
8
  let depth: u32 = 0;
10
9
  // if (load<u16>(srcStart) != BRACKET_LEFT)
@@ -2,15 +2,16 @@ import { BRACKET_LEFT, BRACKET_RIGHT } from "../../../custom/chars";
2
2
  import { JSON } from "../../../";
3
3
 
4
4
  export function deserializeArrayArray<T extends unknown[][]>(srcStart: usize, srcEnd: usize, dst: usize): T {
5
- const out = dst ? changetype<T>(dst) : instantiate<T>();
5
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
6
6
  let lastIndex: usize = 0;
7
7
  let depth: u32 = 0;
8
- while (srcStart < srcEnd) {
8
+ srcStart += 2;
9
+ while (srcStart < srcEnd - 2) {
9
10
  const code = load<u16>(srcStart);
10
11
  if (code == BRACKET_LEFT && depth++ == 0) {
11
12
  lastIndex = srcStart;
12
13
  } else if (code == BRACKET_RIGHT && --depth == 0) {
13
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
14
+ out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart + 2));
14
15
  }
15
16
  srcStart += 2;
16
17
  }
@@ -1,17 +1,17 @@
1
- import { CHAR_E, CHAR_F, CHAR_T } from "../../../custom/chars";
2
-
3
1
  export function deserializeBooleanArray<T extends boolean[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
4
- const out = dst ? changetype<T>(dst) : instantiate<T>();
2
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
3
+ srcStart += 2; // skip [
5
4
  while (srcStart < srcEnd) {
6
- const code = load<u16>(srcStart);
7
- if (code == CHAR_T && load<u16>(srcStart, 8) == CHAR_E) {
5
+ const block = load<u64>(srcStart);
6
+ if (block == 28429475166421108) {
8
7
  out.push(true);
9
8
  srcStart += 10;
10
- } else if (code == CHAR_F && load<u16>(srcStart, 10) == CHAR_E) {
9
+ } else if (block == 32370086184550502 && load<u16>(srcStart, 8) == 101) {
11
10
  out.push(false);
12
11
  srcStart += 12;
12
+ } else {
13
+ srcStart += 2;
13
14
  }
14
- srcStart += 2;
15
15
  }
16
16
  return out;
17
17
  }
@@ -3,7 +3,7 @@ import { COMMA, BRACE_RIGHT, BRACKET_RIGHT } from "../../../custom/chars";
3
3
  import { JSON } from "../../..";
4
4
 
5
5
  export function deserializeFloatArray<T extends number[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
6
- const out = dst ? changetype<T>(dst) : instantiate<T>();
6
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
7
7
  let lastIndex: usize = 0;
8
8
  while (srcStart < srcEnd) {
9
9
  const code = load<u16>(srcStart);
@@ -2,7 +2,7 @@ import { atoi, isSpace } from "../../../util";
2
2
  import { COMMA, BRACKET_RIGHT } from "../../../custom/chars";
3
3
 
4
4
  export function deserializeIntegerArray<T extends number[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
5
- const out: T = dst ? changetype<T>(dst) : instantiate<T>();
5
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
6
6
  let lastIndex: usize = 0;
7
7
  while (srcStart < srcEnd) {
8
8
  const code = load<u16>(srcStart);
@@ -2,7 +2,7 @@ import { BRACE_LEFT, BRACE_RIGHT } from "../../../custom/chars";
2
2
  import { JSON } from "../../..";
3
3
 
4
4
  export function deserializeMapArray<T extends Map<any, any>[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
5
- const out = dst ? changetype<T>(dst) : instantiate<T>();
5
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
6
6
  let lastIndex: usize = 0;
7
7
  let depth: u32 = 0;
8
8
  while (srcStart < srcEnd) {
@@ -2,8 +2,8 @@ import { JSON } from "../../..";
2
2
  import { BACK_SLASH, QUOTE } from "../../../custom/chars";
3
3
 
4
4
  export function deserializeStringArray(srcStart: usize, srcEnd: usize, dst: usize): string[] {
5
- const out = dst ? changetype<string[]>(dst) : new Array<string>();
6
- let lastPos = 2;
5
+ const out = changetype<string[]>(dst || changetype<usize>(instantiate<string[]>()));
6
+ let lastPos: usize = 2;
7
7
  let inString = false;
8
8
  while (srcStart < srcEnd) {
9
9
  const code = load<u16>(srcStart);
@@ -12,7 +12,7 @@ export function deserializeStringArray(srcStart: usize, srcEnd: usize, dst: usiz
12
12
  inString = true;
13
13
  lastPos = srcStart;
14
14
  } else if (load<u16>(srcStart - 2) != BACK_SLASH) {
15
- out.push(JSON.__deserialize<string>(lastPos, srcStart));
15
+ out.push(JSON.__deserialize<string>(lastPos, srcStart + 2));
16
16
  inString = false;
17
17
  }
18
18
  }
@@ -1,16 +1,27 @@
1
- import { BRACE_LEFT, BRACE_RIGHT } from "../../../custom/chars";
1
+ import { BRACE_LEFT, BRACE_RIGHT, BRACKET_LEFT, BRACKET_RIGHT } from "../../../custom/chars";
2
2
  import { JSON } from "../../..";
3
+ import { isSpace } from "util/string";
3
4
 
4
5
  export function deserializeStructArray<T extends unknown[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
5
- const out = dst ? changetype<T>(dst) : instantiate<T>();
6
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
6
7
  let lastIndex: usize = 0;
7
8
  let depth: u32 = 0;
9
+
10
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
11
+ while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
12
+
13
+ if (srcStart - srcEnd == 0)
14
+ throw new Error("Input string had zero length or was all whitespace");
15
+
16
+ if (load<u16>(srcStart) != BRACKET_LEFT) throw new Error("Expected '[' at start of object at position " + (srcEnd - srcStart).toString());
17
+ if (load<u16>(srcEnd - 2) != BRACKET_RIGHT) throw new Error("Expected ']' at end of object at position " + (srcEnd - srcStart).toString());
18
+
8
19
  while (srcStart < srcEnd) {
9
20
  const code = load<u16>(srcStart);
10
21
  if (code == BRACE_LEFT && depth++ == 0) {
11
22
  lastIndex = srcStart;
12
23
  } else if (code == BRACE_RIGHT && --depth == 0) {
13
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
24
+ out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart += 2));
14
25
  }
15
26
  srcStart += 2;
16
27
  }
@@ -33,6 +33,9 @@ export function deserializeArray<T extends unknown[]>(srcStart: usize, srcEnd: u
33
33
  // @ts-ignore: type
34
34
  return deserializeMapArray<T>(srcStart, srcEnd, dst);
35
35
  // @ts-ignore: defined by transform
36
+ } else if (isDefined(type.__DESERIALIZE_CUSTOM)) {
37
+ return deserializeStructArray<T>(srcStart, srcEnd, dst);
38
+ // @ts-ignore: defined by transform
36
39
  } else if (isDefined(type.__DESERIALIZE)) {
37
40
  return deserializeStructArray<T>(srcStart, srcEnd, dst);
38
41
  }
@@ -1,145 +1,170 @@
1
1
  import { JSON } from "../..";
2
2
  import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T, COLON } from "../../custom/chars";
3
3
  import { isSpace } from "../../util";
4
+ import { ptrToStr } from "../../util/ptrToStr";
4
5
 
5
6
  export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd: usize, dst: usize): T {
6
- const out = changetype<T>(dst || __new(offsetof<T>(), idof<T>()));
7
+ const out = changetype<nonnull<T>>(dst || __new(offsetof<T>(), idof<T>()));
7
8
  // @ts-ignore: type
8
9
  if (!isString<indexof<T>>() && !isInteger<indexof<T>>() && !isFloat<indexof<T>>()) throw new Error("Map key must also be a valid JSON key!");
9
10
 
10
- const srcPtr = srcStart;
11
- let key: string | null = null;
11
+ let keyStart: usize = 0;
12
+ let keyEnd: usize = 0;
12
13
  let isKey = false;
13
14
  let depth = 0;
14
- let lastIndex = 0;
15
+ let lastIndex: usize = 0;
15
16
 
16
- // while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
17
- // while (srcEnd > srcStart && isSpace(load<u16>(srcEnd))) srcEnd -= 2;
17
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
18
+ while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2; // would like to optimize this later
18
19
 
20
+ if (srcStart - srcEnd == 0)
21
+ throw new Error("Input string had zero length or was all whitespace");
22
+ if (load<u16>(srcStart) != BRACE_LEFT) throw new Error("Expected '{' at start of object at position " + (srcEnd - srcStart).toString());
23
+ if (load<u16>(srcEnd - 2) != BRACE_RIGHT) throw new Error("Expected '}' at end of object at position " + (srcEnd - srcStart).toString());
24
+
25
+ srcStart += 2;
19
26
  while (srcStart < srcEnd) {
20
27
  let code = load<u16>(srcStart); // while (isSpace(code)) code = load<u16>(srcStart += 2);
21
- if (key == null) {
28
+ if (keyStart == 0) {
22
29
  if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
23
30
  if (isKey) {
24
- key = sliceTo(lastIndex, srcStart);
25
- while (isSpace((code = load<u16>((srcStart += 2))))) {
26
- /* empty */
27
- }
28
- if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcStart - srcPtr).toString());
31
+ keyStart = lastIndex;
32
+ keyEnd = srcStart;
33
+ // console.log("Key: " + ptrToStr(lastIndex, srcStart));
34
+ // console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
35
+ while (isSpace((code = load<u16>((srcStart += 2))))) { }
36
+ if (code !== COLON) throw new Error("Expected ':' after key at position " + (srcEnd - srcStart).toString());
29
37
  isKey = false;
30
38
  } else {
31
- isKey = true;
39
+ // console.log("Got key start");
40
+ isKey = true; // i don't like this
32
41
  lastIndex = srcStart + 2;
33
42
  }
34
43
  }
35
44
  // isKey = !isKey;
36
45
  srcStart += 2;
37
46
  } else {
38
- // @ts-ignore: type
39
- if (isString<valueof<T>>() && code == QUOTE) {
47
+ if (code == QUOTE) {
40
48
  lastIndex = srcStart;
41
49
  srcStart += 2;
42
50
  while (srcStart < srcEnd) {
43
51
  const code = load<u16>(srcStart);
44
52
  if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
45
- while (isSpace(load<u16>((srcStart += 2)))) {
46
- /* empty */
47
- }
53
+ // console.log("Value (string): " + ptrToStr(lastIndex, srcStart + 2));
48
54
  // @ts-ignore: type
49
- out.set(key, JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
50
- key = null;
55
+ out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, srcStart + 2));
56
+ // while (isSpace(load<u16>(srcStart))) srcStart += 2;
57
+ srcStart += 4;
58
+ // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
59
+ keyStart = 0;
51
60
  break;
52
61
  }
53
62
  srcStart += 2;
54
63
  }
55
- // @ts-ignore: type
56
- } else if ((!isBoolean<valueof<T>>() && isInteger<valueof<T>>() && code - 48 <= 9) || code == 45) {
64
+ } else if (code - 48 <= 9 || code == 45) {
57
65
  lastIndex = srcStart;
58
66
  srcStart += 2;
59
67
  while (srcStart < srcEnd) {
60
68
  const code = load<u16>(srcStart);
61
- if (code == COMMA || isSpace(code) || code == BRACE_RIGHT) {
69
+ if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
70
+ // console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
62
71
  // @ts-ignore: type
63
- out.set(key, JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
64
- while (isSpace(load<u16>((srcStart += 2)))) {
65
- /* empty */
66
- }
67
- key = null;
72
+ out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
73
+ // while (isSpace(load<u16>((srcStart += 2)))) {
74
+ // /* empty */
75
+ // }
76
+ srcStart += 2;
77
+ // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
78
+ keyStart = 0;
68
79
  break;
69
80
  }
70
81
  srcStart += 2;
71
82
  }
72
- // @ts-ignore: type
73
- } else if (isArray<valueof<T>>() && code == BRACKET_LEFT) {
83
+ } else if (code == BRACE_LEFT) {
74
84
  lastIndex = srcStart;
75
85
  depth++;
76
86
  srcStart += 2;
77
87
  while (srcStart < srcEnd) {
78
88
  const code = load<u16>(srcStart);
79
- if (code == BRACKET_RIGHT) {
89
+ if (code == QUOTE) {
90
+ srcStart += 2;
91
+ while (!(load<u16>(srcStart) == QUOTE && load<u16>(srcStart - 2) != BACK_SLASH)) srcStart += 2;
92
+ } else if (code == BRACE_RIGHT) {
80
93
  if (--depth == 0) {
94
+ // console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
81
95
  // @ts-ignore: type
82
- out.set(key, JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
83
- while (isSpace(load<u16>((srcStart += 2)))) {
84
- /* empty */
85
- }
86
- key = null;
96
+ out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 2)));
97
+ // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
98
+ keyStart = 0;
99
+ // while (isSpace(load<u16>(srcStart))) {
100
+ // /* empty */
101
+ // }
87
102
  break;
88
103
  }
89
- } else if (code == BRACKET_LEFT) depth++;
104
+ } else if (code == BRACE_LEFT) depth++;
90
105
  srcStart += 2;
91
106
  }
92
- // @ts-ignore: type
93
- } else if (isDefined(changetype<nonnull<valueof<T>>>(0).__DESERIALIZE) && code == BRACE_LEFT) {
107
+ } else if (code == BRACKET_LEFT) {
94
108
  lastIndex = srcStart;
95
109
  depth++;
96
110
  srcStart += 2;
97
111
  while (srcStart < srcEnd) {
98
112
  const code = load<u16>(srcStart);
99
- if (code == BRACE_RIGHT) {
113
+ if (code == BRACKET_RIGHT) {
100
114
  if (--depth == 0) {
115
+ // console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
101
116
  // @ts-ignore: type
102
- out.set(key, JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
103
- while (isSpace(load<u16>((srcStart += 2)))) {
104
- /* empty */
105
- }
106
- key = null;
117
+ out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 2)));
118
+ // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
119
+ keyStart = 0;
120
+ // while (isSpace(load<u16>((srcStart += 2)))) {
121
+ // /* empty */
122
+ // }
107
123
  break;
108
124
  }
109
- } else if (code == BRACE_LEFT) depth++;
125
+ } else if (code == BRACKET_LEFT) depth++;
110
126
  srcStart += 2;
111
127
  }
112
- // @ts-ignore: type
113
- } else if (isBoolean<valueof<T>>() && code == CHAR_T) {
128
+ } else if (code == CHAR_T) {
114
129
  if (load<u64>(srcStart) == 28429475166421108) {
130
+ // console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
115
131
  // @ts-ignore: type
116
- out.set(key, JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 8)));
117
- while (isSpace(load<u16>((srcStart += 2)))) {
118
- /* empty */
119
- }
120
- key = null;
132
+ out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 8)));
133
+ // while (isSpace(load<u16>((srcStart += 2)))) {
134
+ // /* empty */
135
+ // }
136
+ srcStart += 2;
137
+ // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)) + " " + (srcStart < srcEnd).toString());
138
+ keyStart = 0;
121
139
  }
122
- // @ts-ignore: type
123
- } else if (isBoolean<valueof<T>>() && code == CHAR_F) {
140
+ } else if (code == CHAR_F) {
124
141
  if (load<u64>(srcStart, 2) == 28429466576093281) {
142
+ // console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
125
143
  // @ts-ignore: type
126
- out.set(key, JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 10)));
127
- while (isSpace(load<u16>((srcStart += 2)))) {
128
- /* empty */
129
- }
130
- key = null;
144
+ out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 10)));
145
+ // while (isSpace(load<u16>((srcStart += 2)))) {
146
+ // /* empty */
147
+ // }
148
+ srcStart += 2;
149
+ // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
150
+ keyStart = 0;
131
151
  }
132
- } else if ((isNullable<T>() || nameof<T>() == "usize") && code == CHAR_N) {
152
+ } else if (code == CHAR_N) {
133
153
  if (load<u64>(srcStart) == 30399761348886638) {
154
+ // console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
134
155
  // @ts-ignore: type
135
- out.set(key, JSON.__deserialize<valueof<T>>(srcStart, (srcStart += 8)));
136
- while (isSpace(load<u16>((srcStart += 2)))) {
137
- /* empty */
138
- }
156
+ out.set(ptrToStr(keyStart, keyEnd), JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 8)));
157
+ // while (isSpace(load<u16>((srcStart += 2)))) {
158
+ /* empty */
159
+ // }
160
+ srcStart += 2;
161
+ // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
162
+ keyStart = 0;
139
163
  }
164
+ } else if (isSpace(code)) {
165
+ srcStart += 2;
140
166
  } else {
141
- // @ts-ignore: type
142
- throw new Error("Unexpected character " + String.fromCharCode(code) + " or type " + nameof<valueof<T>>() + " does not match found type!");
167
+ throw new Error("Unexpected character in JSON object '" + String.fromCharCode(code) + "' at position " + (srcEnd - srcStart).toString());
143
168
  }
144
169
  }
145
170
  }
@@ -13,8 +13,9 @@ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): J
13
13
  let depth = 0;
14
14
  let lastIndex: usize = 0;
15
15
 
16
- // while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
17
- // while (srcEnd > srcStart && isSpace(load<u16>(srcEnd))) srcEnd -= 2;
16
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
17
+ while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
18
+
18
19
  srcStart += 2;
19
20
  while (srcStart < srcEnd) {
20
21
  let code = load<u16>(srcStart); // while (isSpace(code)) code = load<u16>(srcStart += 2);
@@ -0,0 +1,6 @@
1
+ import { JSON } from "../..";
2
+ import { ptrToStr } from "../../util/ptrToStr";
3
+
4
+ export function deserializeRaw(srcStart: usize, srcEnd: usize): JSON.Raw {
5
+ return JSON.Raw.from(ptrToStr(srcStart, srcEnd));
6
+ }