json-as 1.0.0-beta.9 → 1.0.1
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.
- package/.github/workflows/{nodejs.yml → tests.yml} +1 -1
- package/{CHANGELOG → CHANGELOG.md} +45 -0
- package/README.md +147 -93
- package/assembly/__benches__/abc.bench.ts +21 -0
- package/assembly/__benches__/large.bench.ts +174 -0
- package/assembly/__benches__/lib/index.ts +26 -0
- package/assembly/__benches__/medium.bench.ts +46 -0
- package/assembly/__benches__/small.bench.ts +33 -0
- package/assembly/__benches__/vec3.bench.ts +72 -0
- package/assembly/__tests__/array.spec.ts +42 -0
- package/assembly/__tests__/float.spec.ts +3 -3
- package/assembly/__tests__/map.spec.ts +7 -0
- package/assembly/__tests__/raw.spec.ts +4 -5
- package/assembly/__tests__/struct.spec.ts +2 -2
- package/assembly/deserialize/simple/arbitrary.ts +8 -4
- package/assembly/deserialize/simple/array/arbitrary.ts +6 -6
- package/assembly/deserialize/simple/array/array.ts +4 -3
- package/assembly/deserialize/simple/array/bool.ts +7 -7
- package/assembly/deserialize/simple/array/float.ts +2 -2
- package/assembly/deserialize/simple/array/integer.ts +1 -1
- package/assembly/deserialize/simple/array/map.ts +1 -1
- package/assembly/deserialize/simple/array/string.ts +3 -3
- package/assembly/deserialize/simple/array/struct.ts +14 -3
- package/assembly/deserialize/simple/array.ts +3 -0
- package/assembly/deserialize/simple/map.ts +93 -75
- package/assembly/deserialize/simple/object.ts +26 -16
- package/assembly/deserialize/simple/struct.ts +31 -19
- package/assembly/index.ts +14 -11
- package/assembly/serialize/simple/array.ts +1 -0
- package/assembly/serialize/simple/bool.ts +1 -0
- package/assembly/serialize/simple/date.ts +1 -0
- package/assembly/serialize/simple/float.ts +1 -0
- package/assembly/serialize/simple/integer.ts +1 -0
- package/assembly/serialize/simple/map.ts +1 -0
- package/assembly/serialize/simple/object.ts +1 -0
- package/assembly/serialize/simple/raw.ts +1 -0
- package/assembly/serialize/simple/string.ts +1 -0
- package/assembly/test.ts +18 -0
- package/bench/abc.bench.ts +20 -0
- package/bench/large.bench.ts +126 -0
- package/bench/medium.bench.ts +43 -0
- package/bench/small.bench.ts +30 -0
- package/bench/vec3.bench.ts +26 -0
- package/index.ts +1 -1
- package/package.json +24 -26
- package/run-bench.as.sh +27 -0
- package/run-bench.js.sh +12 -0
- package/run-tests.sh +14 -2
- package/transform/lib/index.js +29 -69
- package/transform/lib/index.js.map +1 -1
- package/transform/src/index.ts +55 -71
- package/.gitmodules +0 -0
- package/assembly/__benches__/misc.bench.ts +0 -47
- package/assembly/__benches__/schemas.ts +0 -25
- package/assembly/__benches__/string.bench.ts +0 -23
- package/assembly/__benches__/struct.bench.ts +0 -21
- package/assembly/as-bs.d.ts +0 -53
- package/bench/schemas.ts +0 -5
- package/bench/string.bench.ts +0 -16
- /package/bench/{bench.ts → lib/bench.ts} +0 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { JSON } from "..";
|
|
2
|
+
import { bench } from "../custom/bench";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@json
|
|
6
|
+
class Vec3 {
|
|
7
|
+
public x!: i32;
|
|
8
|
+
public y!: i32;
|
|
9
|
+
public z!: i32;
|
|
10
|
+
|
|
11
|
+
@inline __SERIALIZE(ptr: usize): void {
|
|
12
|
+
bs.proposeSize(98);
|
|
13
|
+
store<u64>(bs.offset, 9570664606466171, 0); // {"x"
|
|
14
|
+
store<u16>(bs.offset, 58, 8); // :
|
|
15
|
+
bs.offset += 10;
|
|
16
|
+
JSON.__serialize<i32>(load<i32>(ptr, offsetof<this>("x")));
|
|
17
|
+
store<u64>(bs.offset, 9570668901433388, 0); // ,"y"
|
|
18
|
+
store<u16>(bs.offset, 58, 8); // :
|
|
19
|
+
bs.offset += 10;
|
|
20
|
+
JSON.__serialize<i32>(load<i32>(ptr, offsetof<this>("y")));
|
|
21
|
+
store<u64>(bs.offset, 9570673196400684, 0); // ,"z"
|
|
22
|
+
store<u16>(bs.offset, 58, 8); // :
|
|
23
|
+
bs.offset += 10;
|
|
24
|
+
JSON.__serialize<i32>(load<i32>(ptr, offsetof<this>("z")));
|
|
25
|
+
store<u16>(bs.offset, 125, 0); // }
|
|
26
|
+
bs.offset += 2;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@inline __INITIALIZE(): this {
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@inline __DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {
|
|
34
|
+
switch (load<u16>(keyStart)) {
|
|
35
|
+
case 120: {
|
|
36
|
+
// x
|
|
37
|
+
store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("x"));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
case 121: {
|
|
41
|
+
// y
|
|
42
|
+
store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("y"));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
case 122: {
|
|
46
|
+
// z
|
|
47
|
+
store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("z"));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@json
|
|
57
|
+
class LargeJSON {
|
|
58
|
+
public id!: i32;
|
|
59
|
+
public name!: string;
|
|
60
|
+
public age!: i32;
|
|
61
|
+
public email!: string;
|
|
62
|
+
public street!: string;
|
|
63
|
+
public city!: string;
|
|
64
|
+
public state!: string;
|
|
65
|
+
public zip!: string;
|
|
66
|
+
public tags!: string[];
|
|
67
|
+
public theme!: string;
|
|
68
|
+
public notifications!: boolean;
|
|
69
|
+
public language!: string;
|
|
70
|
+
public movement!: Vec3[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const v1: LargeJSON = {
|
|
74
|
+
id: 2,
|
|
75
|
+
name: "Medium Object",
|
|
76
|
+
age: 18,
|
|
77
|
+
email: "me@jairus.dev",
|
|
78
|
+
street: "I don't want to say my street",
|
|
79
|
+
city: "I don't want to say this either",
|
|
80
|
+
state: "It really depends",
|
|
81
|
+
zip: "I forget what it is",
|
|
82
|
+
tags: ["me", "dogs", "mountains", "bar", "foo"],
|
|
83
|
+
theme: "Hyper Term Black",
|
|
84
|
+
notifications: true,
|
|
85
|
+
language: "en-US",
|
|
86
|
+
movement: [
|
|
87
|
+
{ x: 1, y: 2, z: 3 },
|
|
88
|
+
{ x: 1, y: 2, z: 3 },
|
|
89
|
+
{ x: 1, y: 2, z: 3 },
|
|
90
|
+
{ x: 1, y: 2, z: 3 },
|
|
91
|
+
{ x: 1, y: 2, z: 3 },
|
|
92
|
+
{ x: 1, y: 2, z: 3 },
|
|
93
|
+
{ x: 1, y: 2, z: 3 },
|
|
94
|
+
{ x: 1, y: 2, z: 3 },
|
|
95
|
+
{ x: 1, y: 2, z: 3 },
|
|
96
|
+
{ x: 1, y: 2, z: 3 },
|
|
97
|
+
{ x: 1, y: 2, z: 3 },
|
|
98
|
+
{ x: 1, y: 2, z: 3 },
|
|
99
|
+
{ x: 1, y: 2, z: 3 },
|
|
100
|
+
{ x: 1, y: 2, z: 3 },
|
|
101
|
+
{ x: 1, y: 2, z: 3 },
|
|
102
|
+
{ x: 1, y: 2, z: 3 },
|
|
103
|
+
{ x: 1, y: 2, z: 3 },
|
|
104
|
+
{ x: 1, y: 2, z: 3 },
|
|
105
|
+
{ x: 1, y: 2, z: 3 },
|
|
106
|
+
{ x: 1, y: 2, z: 3 },
|
|
107
|
+
{ x: 1, y: 2, z: 3 },
|
|
108
|
+
{ x: 1, y: 2, z: 3 },
|
|
109
|
+
{ x: 1, y: 2, z: 3 },
|
|
110
|
+
{ x: 1, y: 2, z: 3 },
|
|
111
|
+
{ x: 1, y: 2, z: 3 },
|
|
112
|
+
{ x: 1, y: 2, z: 3 },
|
|
113
|
+
{ x: 1, y: 2, z: 3 },
|
|
114
|
+
{ x: 1, y: 2, z: 3 },
|
|
115
|
+
{ x: 1, y: 2, z: 3 },
|
|
116
|
+
{ x: 1, y: 2, z: 3 },
|
|
117
|
+
{ x: 1, y: 2, z: 3 },
|
|
118
|
+
{ x: 1, y: 2, z: 3 },
|
|
119
|
+
{ x: 1, y: 2, z: 3 },
|
|
120
|
+
{ x: 1, y: 2, z: 3 },
|
|
121
|
+
{ x: 1, y: 2, z: 3 },
|
|
122
|
+
{ x: 1, y: 2, z: 3 },
|
|
123
|
+
{ x: 1, y: 2, z: 3 },
|
|
124
|
+
{ x: 1, y: 2, z: 3 },
|
|
125
|
+
{ x: 1, y: 2, z: 3 },
|
|
126
|
+
{ x: 1, y: 2, z: 3 },
|
|
127
|
+
{ x: 1, y: 2, z: 3 },
|
|
128
|
+
{ x: 1, y: 2, z: 3 },
|
|
129
|
+
{ x: 1, y: 2, z: 3 },
|
|
130
|
+
{ x: 1, y: 2, z: 3 },
|
|
131
|
+
{ x: 1, y: 2, z: 3 },
|
|
132
|
+
{ x: 1, y: 2, z: 3 },
|
|
133
|
+
{ x: 1, y: 2, z: 3 },
|
|
134
|
+
{ x: 1, y: 2, z: 3 },
|
|
135
|
+
{ x: 1, y: 2, z: 3 },
|
|
136
|
+
{ x: 1, y: 2, z: 3 },
|
|
137
|
+
{ x: 1, y: 2, z: 3 },
|
|
138
|
+
{ x: 1, y: 2, z: 3 },
|
|
139
|
+
{ x: 1, y: 2, z: 3 },
|
|
140
|
+
{ x: 1, y: 2, z: 3 },
|
|
141
|
+
{ x: 1, y: 2, z: 3 },
|
|
142
|
+
{ x: 1, y: 2, z: 3 },
|
|
143
|
+
{ x: 1, y: 2, z: 3 },
|
|
144
|
+
{ x: 1, y: 2, z: 3 },
|
|
145
|
+
{ x: 1, y: 2, z: 3 },
|
|
146
|
+
{ x: 1, y: 2, z: 3 },
|
|
147
|
+
{ x: 1, y: 2, z: 3 },
|
|
148
|
+
{ x: 1, y: 2, z: 3 },
|
|
149
|
+
{ x: 1, y: 2, z: 3 },
|
|
150
|
+
{ x: 1, y: 2, z: 3 },
|
|
151
|
+
{ x: 1, y: 2, z: 3 },
|
|
152
|
+
{ x: 1, y: 2, z: 3 },
|
|
153
|
+
{ x: 1, y: 2, z: 3 },
|
|
154
|
+
{ x: 1, y: 2, z: 3 },
|
|
155
|
+
],
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
const v2 = `{"id":2,"name":"Medium Object","age":18,"email":"me@jairus.dev","street":"I don't want to say my street","city":"I don't want to say this either","state":"It really depends","zip":"I forget what it is","tags":["me","dogs","mountains","bar","foo"],"theme":"Hyper Term Black","notifications":true,"language":"en-US","movement":[{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3}]}`;
|
|
159
|
+
|
|
160
|
+
bench(
|
|
161
|
+
"Serialize Medium Object",
|
|
162
|
+
() => {
|
|
163
|
+
JSON.stringify(v1);
|
|
164
|
+
},
|
|
165
|
+
3_000_00,
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
bench(
|
|
169
|
+
"Deserialize Medium Object",
|
|
170
|
+
() => {
|
|
171
|
+
JSON.parse<LargeJSON>(v2);
|
|
172
|
+
},
|
|
173
|
+
3_000_00,
|
|
174
|
+
);
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export function describe(description: string, routine: () => void): void {
|
|
2
|
+
routine();
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function it(description: string, routine: () => void): void {
|
|
6
|
+
routine();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function expect(left: string): Expectation {
|
|
10
|
+
return new Expectation(left);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
class Expectation {
|
|
14
|
+
public left: string;
|
|
15
|
+
|
|
16
|
+
constructor(left: string) {
|
|
17
|
+
this.left = left;
|
|
18
|
+
}
|
|
19
|
+
toBe(right: string): void {
|
|
20
|
+
if (this.left != right) {
|
|
21
|
+
console.log(" (expected) -> " + right);
|
|
22
|
+
console.log(" (received) -> " + this.left);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { JSON } from "..";
|
|
2
|
+
import { bench } from "../custom/bench";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@json
|
|
6
|
+
class MediumJSON {
|
|
7
|
+
public id!: i32;
|
|
8
|
+
public name!: string;
|
|
9
|
+
public age!: i32;
|
|
10
|
+
public email!: string;
|
|
11
|
+
public street!: string;
|
|
12
|
+
public city!: string;
|
|
13
|
+
public state!: string;
|
|
14
|
+
public zip!: string;
|
|
15
|
+
public tags!: string[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const v1: MediumJSON = {
|
|
19
|
+
id: 2,
|
|
20
|
+
name: "Medium Object",
|
|
21
|
+
age: 18,
|
|
22
|
+
email: "me@jairus.dev",
|
|
23
|
+
street: "I don't want to say my street",
|
|
24
|
+
city: "I don't want to say this either",
|
|
25
|
+
state: "It really depends",
|
|
26
|
+
zip: "I forget what it is",
|
|
27
|
+
tags: ["me", "dogs", "mountains", "bar", "foo"],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const v2 = `{"id":2,"name":"Medium Object","age":18,"email":"me@jairus.dev","street":"I don't want to say my street","city":"I don't want to say this either","state":"It really depends","zip":"I forget what it is","tags":["me","dogs","mountains","bar","foo"]}`;
|
|
31
|
+
|
|
32
|
+
bench(
|
|
33
|
+
"Serialize Medium Object",
|
|
34
|
+
() => {
|
|
35
|
+
JSON.stringify(v1);
|
|
36
|
+
},
|
|
37
|
+
8_000_00,
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
bench(
|
|
41
|
+
"Deserialize Medium Object",
|
|
42
|
+
() => {
|
|
43
|
+
JSON.parse<MediumJSON>(v2);
|
|
44
|
+
},
|
|
45
|
+
8_000_00,
|
|
46
|
+
);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { JSON } from "..";
|
|
2
|
+
import { bench } from "../custom/bench";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@json
|
|
6
|
+
class SmallJSON {
|
|
7
|
+
public id!: i32;
|
|
8
|
+
public name!: string;
|
|
9
|
+
public active!: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const v1: SmallJSON = {
|
|
13
|
+
id: 1,
|
|
14
|
+
name: "Small Object",
|
|
15
|
+
active: true,
|
|
16
|
+
};
|
|
17
|
+
const v2 = '{"id":1,"name":"Small Object","active":true}';
|
|
18
|
+
|
|
19
|
+
bench(
|
|
20
|
+
"Serialize Small Object",
|
|
21
|
+
() => {
|
|
22
|
+
JSON.stringify(v1);
|
|
23
|
+
},
|
|
24
|
+
16_000_00,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
bench(
|
|
28
|
+
"Deserialize Small Object",
|
|
29
|
+
() => {
|
|
30
|
+
JSON.parse<SmallJSON>(v2);
|
|
31
|
+
},
|
|
32
|
+
16_000_00,
|
|
33
|
+
);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { JSON } from "..";
|
|
2
|
+
import { bench } from "../custom/bench";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@json
|
|
6
|
+
class Vec3 {
|
|
7
|
+
public x!: i32;
|
|
8
|
+
public y!: i32;
|
|
9
|
+
public z!: i32;
|
|
10
|
+
|
|
11
|
+
@inline __SERIALIZE(ptr: usize): void {
|
|
12
|
+
bs.proposeSize(98);
|
|
13
|
+
store<u64>(bs.offset, 9570664606466171, 0); // {"x"
|
|
14
|
+
store<u16>(bs.offset, 58, 8); // :
|
|
15
|
+
bs.offset += 10;
|
|
16
|
+
JSON.__serialize<i32>(load<i32>(ptr, offsetof<this>("x")));
|
|
17
|
+
store<u64>(bs.offset, 9570668901433388, 0); // ,"y"
|
|
18
|
+
store<u16>(bs.offset, 58, 8); // :
|
|
19
|
+
bs.offset += 10;
|
|
20
|
+
JSON.__serialize<i32>(load<i32>(ptr, offsetof<this>("y")));
|
|
21
|
+
store<u64>(bs.offset, 9570673196400684, 0); // ,"z"
|
|
22
|
+
store<u16>(bs.offset, 58, 8); // :
|
|
23
|
+
bs.offset += 10;
|
|
24
|
+
JSON.__serialize<i32>(load<i32>(ptr, offsetof<this>("z")));
|
|
25
|
+
store<u16>(bs.offset, 125, 0); // }
|
|
26
|
+
bs.offset += 2;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@inline __INITIALIZE(): this {
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@inline __DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {
|
|
34
|
+
switch (load<u16>(keyStart)) {
|
|
35
|
+
case 120: {
|
|
36
|
+
// x
|
|
37
|
+
store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("x"));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
case 121: {
|
|
41
|
+
// y
|
|
42
|
+
store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("y"));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
case 122: {
|
|
46
|
+
// z
|
|
47
|
+
store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("z"));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const v1: Vec3 = { x: 1, y: 2, z: 3 };
|
|
56
|
+
const v2 = '{"x":1,"y":2,"z":3}';
|
|
57
|
+
|
|
58
|
+
bench(
|
|
59
|
+
"Serialize Vec3",
|
|
60
|
+
() => {
|
|
61
|
+
JSON.stringify(v1);
|
|
62
|
+
},
|
|
63
|
+
16_000_00,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
bench(
|
|
67
|
+
"Deserialize Vec3",
|
|
68
|
+
() => {
|
|
69
|
+
JSON.parse<Vec3>(v2);
|
|
70
|
+
},
|
|
71
|
+
16_000_00,
|
|
72
|
+
);
|
|
@@ -58,6 +58,48 @@ describe("Should serialize object arrays", () => {
|
|
|
58
58
|
).toBe('[{"x":3.4,"y":1.2,"z":8.3},{"x":3.4,"y":-2.1,"z":9.3}]');
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
+
describe("Should deserialize integer arrays", () => {
|
|
62
|
+
expect(JSON.stringify(JSON.parse<u32[]>("[0,100,101]"))).toBe('[0,100,101]');
|
|
63
|
+
expect(JSON.stringify(JSON.parse<u64[]>("[0,100,101]"))).toBe('[0,100,101]');
|
|
64
|
+
expect(JSON.stringify(JSON.parse<i32[]>("[0,100,101,-100,-101]"))).toBe("[0,100,101,-100,-101]");
|
|
65
|
+
expect(JSON.stringify(JSON.parse<i64[]>("[0,100,101,-100,-101]"))).toBe("[0,100,101,-100,-101]");
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe("Should deserialize float arrays", () => {
|
|
69
|
+
expect(JSON.stringify(JSON.parse<f64[]>("[7.23,1000.0,1000.0,1.23456,1.23456,0.0,7.23]"))).toBe("[7.23,1000.0,1000.0,1.23456,1.23456,0.0,7.23]");
|
|
70
|
+
expect(JSON.stringify(JSON.parse<f64[]>("[1e+21,1e+22,1e-7,1e-8,1e-9]"))).toBe("[1e+21,1e+22,1e-7,1e-8,1e-9]");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe("Should deserialize boolean arrays", () => {
|
|
74
|
+
expect(JSON.stringify(JSON.parse<bool[]>("[true,false]"))).toBe("[true,false]");
|
|
75
|
+
expect(JSON.stringify(JSON.parse<boolean[]>("[true,false]"))).toBe("[true,false]");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
describe("Should deserialize string arrays", () => {
|
|
79
|
+
expect(JSON.stringify(JSON.parse<string[]>("[\"string \\\"with random spa\\nces and \\nnewlines\\n\\n\\n\"]"))).toBe("[\"string \\\"with random spa\\nces and \\nnewlines\\n\\n\\n\"]");
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
describe("Should deserialize nested integer arrays", () => {
|
|
83
|
+
expect(JSON.stringify(JSON.parse<i64[][]>("[[100,101],[-100,-101],[0]]"))).toBe("[[100,101],[-100,-101],[0]]");
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
describe("Should deserialize nested float arrays", () => {
|
|
87
|
+
expect(JSON.stringify(JSON.parse<f64[][]>("[[7.23],[1000.0],[1000.0],[1.23456],[1.23456],[0.0],[7.23]]"))).toBe("[[7.23],[1000.0],[1000.0],[1.23456],[1.23456],[0.0],[7.23]]");
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe("Should deserialize nested boolean arrays", () => {
|
|
91
|
+
expect(JSON.stringify(JSON.parse<bool[][]>("[[true],[false]]"))).toBe("[[true],[false]]");
|
|
92
|
+
expect(JSON.stringify(JSON.parse<boolean[][]>("[[true],[false]]"))).toBe("[[true],[false]]");
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe("Should deserialize object arrays", () => {
|
|
96
|
+
expect(
|
|
97
|
+
JSON.stringify(JSON.parse<Vec3[]>(
|
|
98
|
+
'[{"x":3.4,"y":1.2,"z":8.3},{"x":3.4,"y":-2.1,"z":9.3}]'
|
|
99
|
+
)
|
|
100
|
+
)).toBe('[{"x":3.4,"y":1.2,"z":8.3},{"x":3.4,"y":-2.1,"z":9.3}]');
|
|
101
|
+
});
|
|
102
|
+
|
|
61
103
|
@json
|
|
62
104
|
class Vec3 {
|
|
63
105
|
x: f64 = 0.0;
|
|
@@ -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
|
-
|
|
37
|
+
expect(JSON.parse<f64>("1e-7").toString()).toBe(1e-7.toString());
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
expect(JSON.parse<f64>("100000000000000000000.0").toString()).toBe(1e20.toString());
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
expect(JSON.parse<f64>("1e+21").toString()).toBe(1e21.toString());
|
|
42
42
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { JSON } from "..";
|
|
2
|
+
import { describe, expect } from "./lib";
|
|
3
|
+
|
|
4
|
+
describe("Should deserialize complex objects", () => {
|
|
5
|
+
const input = '{"a":{"b":{"c":[{"d":"random value 1"},{"e":["value 2","value 3"]}],"f":{"g":{"h":[1,2,3],"i":{"j":"nested value"}}}},"k":"simple value"},"l":[{"m":"another value","n":{"o":"deep nested","p":[{"q":"even deeper"},"final value"]}}],"r":null}';
|
|
6
|
+
expect(JSON.stringify(JSON.parse<Map<string, JSON.Raw>>(input))).toBe(input);
|
|
7
|
+
})
|
|
@@ -17,8 +17,7 @@ describe("Should serialize Map<string, JSON.Raw>", () => {
|
|
|
17
17
|
expect(JSON.stringify(m1)).toBe('{"hello":"world","pos":{"x":1.0,"y":2.0,"z":3.0}}');
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
// });
|
|
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
|
+
});
|
|
@@ -64,9 +64,9 @@ describe("Should deserialize structs with whitespace", () => {
|
|
|
64
64
|
).toBe('{"x":3.4,"y":1.2,"z":8.3}');
|
|
65
65
|
});
|
|
66
66
|
|
|
67
|
-
describe("Should serialize Suite struct", () => {
|
|
67
|
+
// describe("Should serialize Suite struct", () => {
|
|
68
68
|
|
|
69
|
-
});
|
|
69
|
+
// });
|
|
70
70
|
|
|
71
71
|
@json
|
|
72
72
|
class BaseObject {
|
|
@@ -4,14 +4,18 @@ import { deserializeBoolean } from "./bool";
|
|
|
4
4
|
import { deserializeFloat } from "./float";
|
|
5
5
|
import { deserializeString } from "./string";
|
|
6
6
|
import { deserializeObject } from "./object";
|
|
7
|
+
import { BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE } from "../../custom/chars";
|
|
7
8
|
|
|
8
9
|
export function deserializeArbitrary(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value {
|
|
9
10
|
const firstChar = load<u16>(srcStart);
|
|
10
|
-
if (firstChar ==
|
|
11
|
-
else if (firstChar ==
|
|
11
|
+
if (firstChar == QUOTE) return JSON.Value.from(deserializeString(srcStart, srcEnd, 0));
|
|
12
|
+
else if (firstChar == BRACE_LEFT) return JSON.Value.from(deserializeObject(srcStart, srcEnd, 0));
|
|
12
13
|
else if (firstChar - 48 <= 9 || firstChar == 45) return JSON.Value.from(deserializeFloat<f64>(srcStart, srcEnd));
|
|
13
|
-
else if (firstChar ==
|
|
14
|
-
return JSON.Value.from(deserializeArray<JSON.Value[]>(srcStart, srcEnd,
|
|
14
|
+
else if (firstChar == BRACKET_LEFT) {
|
|
15
|
+
return JSON.Value.from(deserializeArray<JSON.Value[]>(srcStart, srcEnd, 0));
|
|
15
16
|
} else if (firstChar == 116 || firstChar == 102) return JSON.Value.from(deserializeBoolean(srcStart, srcEnd));
|
|
17
|
+
else if (firstChar == CHAR_N) {
|
|
18
|
+
return JSON.Value.from(null);
|
|
19
|
+
}
|
|
16
20
|
return unreachable();
|
|
17
21
|
}
|
|
@@ -4,7 +4,7 @@ import { isSpace } from "util/string";
|
|
|
4
4
|
import { ptrToStr } from "../../../util/ptrToStr";
|
|
5
5
|
|
|
6
6
|
export function deserializeArbitraryArray(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value[] {
|
|
7
|
-
const out =
|
|
7
|
+
const out = changetype<JSON.Value[]>(dst || changetype<usize>(instantiate<JSON.Value[]>()));
|
|
8
8
|
let lastIndex: usize = 0;
|
|
9
9
|
let depth: u32 = 0;
|
|
10
10
|
// if (load<u16>(srcStart) != BRACKET_LEFT)
|
|
@@ -121,12 +121,12 @@ export function deserializeArbitraryArray(srcStart: usize, srcEnd: usize, dst: u
|
|
|
121
121
|
}
|
|
122
122
|
} else if (code == CHAR_N) {
|
|
123
123
|
if (load<u64>(srcStart) == 30399761348886638) {
|
|
124
|
+
console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
|
|
124
125
|
// @ts-ignore: type
|
|
125
|
-
out.push(JSON.__deserialize<JSON.Value>(
|
|
126
|
-
//
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}
|
|
126
|
+
out.push(JSON.__deserialize<JSON.Value>(srcStart, (srcStart += 8)));
|
|
127
|
+
// while (isSpace(load<u16>((srcStart += 2)))) {
|
|
128
|
+
// /* empty */
|
|
129
|
+
// }
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
132
|
srcStart += 2;
|
|
@@ -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
|
|
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
|
+
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
|
|
2
|
+
const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
|
|
3
|
+
srcStart += 2; // skip [
|
|
5
4
|
while (srcStart < srcEnd) {
|
|
6
|
-
const
|
|
7
|
-
if (
|
|
5
|
+
const block = load<u64>(srcStart);
|
|
6
|
+
if (block == 28429475166421108) {
|
|
8
7
|
out.push(true);
|
|
9
8
|
srcStart += 10;
|
|
10
|
-
} else if (
|
|
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
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { isSpace } from "../../../util";
|
|
2
|
-
import { COMMA,
|
|
2
|
+
import { COMMA, 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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
}
|