json-as 0.4.4 → 0.4.5
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/LICENSE +0 -0
- package/README.md +9 -5
- package/as-pect.asconfig.json +23 -23
- package/as-pect.config.js +0 -0
- package/asconfig.json +1 -16
- package/assembly/__benches__/as-tral.d.ts +0 -0
- package/assembly/__benches__/benchmark.ts +33 -28
- package/assembly/__tests__/as-json.spec.ts +0 -0
- package/assembly/__tests__/as-pect.d.ts +0 -0
- package/assembly/chars.ts +2 -1
- package/assembly/index.ts +297 -156
- package/assembly/test.ts +64 -54
- package/assembly/tsconfig.json +0 -0
- package/assembly/util.ts +30 -21
- package/index.ts +0 -1
- package/package.json +4 -3
- package/tests/index.js +0 -0
- package/tests/test.js +0 -0
- package/transform/lib/index.js +74 -73
- package/transform/package.json +1 -2
- package/transform/src/index.old.js +0 -0
- package/transform/src/index.ts +109 -95
- package/transform/tsconfig.json +0 -0
- package/assembly/__tests__/example.spec.ts +0 -40
package/assembly/index.ts
CHANGED
|
@@ -1,22 +1,48 @@
|
|
|
1
1
|
import { StringSink } from "as-string-sink/assembly";
|
|
2
2
|
import { Variant } from "as-variant/assembly";
|
|
3
|
+
import { isSpace } from "assemblyscript/std/assembly/util/string";
|
|
4
|
+
import { stringify } from "as-console/assembly";
|
|
3
5
|
import {
|
|
4
6
|
backSlashCode,
|
|
5
7
|
colonCode,
|
|
6
8
|
commaCode,
|
|
9
|
+
eCode,
|
|
10
|
+
fCode,
|
|
11
|
+
forwardSlashCode,
|
|
7
12
|
leftBraceCode,
|
|
8
13
|
leftBracketCode,
|
|
9
14
|
quoteCode,
|
|
10
15
|
rightBraceCode,
|
|
11
|
-
rightBracketCode
|
|
16
|
+
rightBracketCode,
|
|
17
|
+
tCode,
|
|
12
18
|
} from "./chars";
|
|
13
|
-
import { removeWhitespace } from "./util";
|
|
19
|
+
import { removeWhitespace, unsafeCharCodeAt } from "./util";
|
|
14
20
|
|
|
15
21
|
/**
|
|
16
22
|
* JSON Encoder/Decoder for AssemblyScript
|
|
17
23
|
*/
|
|
18
|
-
export
|
|
19
|
-
|
|
24
|
+
export class JSON {
|
|
25
|
+
private static parseObjectValue<T>(data: string): T {
|
|
26
|
+
let type!: T;
|
|
27
|
+
if (isString<T>()) {
|
|
28
|
+
// @ts-ignore
|
|
29
|
+
return data.replaceAll('\\"', '"');
|
|
30
|
+
} else if (isBoolean<T>()) {
|
|
31
|
+
// @ts-ignore
|
|
32
|
+
return parseBoolean<T>(data);
|
|
33
|
+
} else if (isFloat<T>() || isInteger<T>()) {
|
|
34
|
+
return parseNumber<T>(data);
|
|
35
|
+
} else if (isArrayLike<T>()) {
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
return parseArray<T>(data);
|
|
38
|
+
// @ts-ignore
|
|
39
|
+
} else if (isDefined(type.__JSON_Deserialize)) {
|
|
40
|
+
return parseObject<T>(data);
|
|
41
|
+
} else {
|
|
42
|
+
// @ts-ignore
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
20
46
|
/**
|
|
21
47
|
* Stringifies valid JSON data.
|
|
22
48
|
* ```js
|
|
@@ -25,7 +51,7 @@ export namespace JSON {
|
|
|
25
51
|
* @param data T
|
|
26
52
|
* @returns string
|
|
27
53
|
*/
|
|
28
|
-
|
|
54
|
+
static stringify<T = Nullable | null>(data: T): string {
|
|
29
55
|
// String
|
|
30
56
|
if (isString<T>()) {
|
|
31
57
|
return '"' + (<string>data).replaceAll('"', '\\"') + '"';
|
|
@@ -77,8 +103,7 @@ export namespace JSON {
|
|
|
77
103
|
* @param data string
|
|
78
104
|
* @returns T
|
|
79
105
|
*/
|
|
80
|
-
|
|
81
|
-
data = removeWhitespace(data);
|
|
106
|
+
static parse<T = Variant>(data: string): T {
|
|
82
107
|
let type!: T;
|
|
83
108
|
if (isString<T>()) {
|
|
84
109
|
// @ts-ignore
|
|
@@ -89,53 +114,11 @@ export namespace JSON {
|
|
|
89
114
|
} else if (isFloat<T>() || isInteger<T>()) {
|
|
90
115
|
return parseNumber<T>(data);
|
|
91
116
|
} else if (isArrayLike<T>()) {
|
|
92
|
-
return parseArray<T>(data);
|
|
93
117
|
// @ts-ignore
|
|
94
|
-
|
|
95
|
-
const len: u32 = data.length - 1
|
|
96
|
-
let schema!: T
|
|
97
|
-
const result = new Map<string, string>()
|
|
98
|
-
let lastPos: u32 = 1
|
|
99
|
-
let key: string = ''
|
|
100
|
-
let instr: boolean = false
|
|
101
|
-
let char: u32 = 0
|
|
102
|
-
let depth: u32 = 0
|
|
103
|
-
let fdepth: u32 = 0
|
|
104
|
-
for (let i: u32 = 1; i < len; i++) {
|
|
105
|
-
char = data.charCodeAt(i);
|
|
106
|
-
if (instr === false && char === quoteCode) instr = true;
|
|
107
|
-
else if (instr === true && char === quoteCode && data.charCodeAt(i - 1) !== "/".charCodeAt(0)) instr = false;
|
|
108
|
-
if (instr === false) {
|
|
109
|
-
if (char === leftBraceCode || char === leftBracketCode) depth++
|
|
110
|
-
if (char === rightBraceCode || char === rightBracketCode) fdepth++
|
|
111
|
-
}
|
|
112
|
-
if (depth !== 0 && depth === fdepth) {
|
|
113
|
-
//console.log(`Found Struct: ${data.slice(lastPos + 1, i + 1)}`)
|
|
114
|
-
result.set(key, data.slice(lastPos + 1, i + 1))
|
|
115
|
-
// Reset the depth
|
|
116
|
-
depth = 0
|
|
117
|
-
fdepth = 0
|
|
118
|
-
// Set new lastPos
|
|
119
|
-
lastPos = i + 1
|
|
120
|
-
}
|
|
121
|
-
if (!instr && depth === 0) {
|
|
122
|
-
if (char === colonCode) {
|
|
123
|
-
key = data.slice(lastPos + 1, i - 1)
|
|
124
|
-
//console.log(`Found Key: ${data.slice(lastPos + 1, i - 1)}`)
|
|
125
|
-
lastPos = i
|
|
126
|
-
} else if (char === commaCode) {
|
|
127
|
-
//console.log(`Found Comma: ${data.slice(lastPos + 1, i)}`)
|
|
128
|
-
if ((i - lastPos) > 0) result.set(key, data.slice(lastPos + 1, i))
|
|
129
|
-
lastPos = i + 1
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if ((len - lastPos) > 1 && (len - lastPos) !== 0) {
|
|
135
|
-
result.set(key, data.slice(lastPos + 1, len))
|
|
136
|
-
}
|
|
118
|
+
return parseArray<T>(data.trimStart());
|
|
137
119
|
// @ts-ignore
|
|
138
|
-
|
|
120
|
+
} else if (isDefined(type.__JSON_Deserialize)) {
|
|
121
|
+
return parseObject<T>(data.trimStart());
|
|
139
122
|
} else {
|
|
140
123
|
// @ts-ignore
|
|
141
124
|
return null;
|
|
@@ -143,23 +126,23 @@ export namespace JSON {
|
|
|
143
126
|
}
|
|
144
127
|
}
|
|
145
128
|
|
|
146
|
-
|
|
147
129
|
// @ts-ignore
|
|
148
130
|
@inline
|
|
149
|
-
|
|
131
|
+
function parseString(data: string): string {
|
|
150
132
|
return data.slice(1, data.length - 1).replaceAll('\\"', '"');
|
|
151
133
|
}
|
|
152
134
|
|
|
153
135
|
// @ts-ignore
|
|
154
136
|
@inline
|
|
155
|
-
|
|
137
|
+
function parseBoolean<T extends boolean>(data: string): T {
|
|
156
138
|
if (data.length > 3 && data.startsWith("true")) return <T>true;
|
|
157
139
|
else if (data.length > 4 && data.startsWith("false")) return <T>false;
|
|
158
140
|
else throw new Error(`JSON: Cannot parse "${data}" as boolean`);
|
|
159
141
|
}
|
|
142
|
+
|
|
160
143
|
// @ts-ignore
|
|
161
144
|
@inline
|
|
162
|
-
|
|
145
|
+
function parseNumber<T>(data: string): T {
|
|
163
146
|
let type: T;
|
|
164
147
|
// @ts-ignore
|
|
165
148
|
if (type instanceof f64) return F64.parseFloat(data);
|
|
@@ -183,129 +166,287 @@ export namespace JSON {
|
|
|
183
166
|
);
|
|
184
167
|
}
|
|
185
168
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
let
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
169
|
+
export function parseObject<T>(data: string): T {
|
|
170
|
+
let schema!: T;
|
|
171
|
+
const result = new Map<string, string>();
|
|
172
|
+
let key: usize = 0;
|
|
173
|
+
let depth = 1;
|
|
174
|
+
let char = 0;
|
|
175
|
+
for (
|
|
176
|
+
let outerLoopIndex = 1;
|
|
177
|
+
outerLoopIndex < data.length - 1;
|
|
178
|
+
outerLoopIndex++
|
|
179
|
+
) {
|
|
180
|
+
char = unsafeCharCodeAt(data, outerLoopIndex);
|
|
181
|
+
if (char === leftBracketCode) {
|
|
182
|
+
for (
|
|
183
|
+
let arrayValueIndex = outerLoopIndex;
|
|
184
|
+
arrayValueIndex < data.length - 1;
|
|
185
|
+
arrayValueIndex++
|
|
186
|
+
) {
|
|
187
|
+
char = unsafeCharCodeAt(data, arrayValueIndex);
|
|
188
|
+
if (char === leftBracketCode) {
|
|
189
|
+
depth = depth << 1;
|
|
190
|
+
} else if (char === rightBracketCode) {
|
|
191
|
+
depth = depth >> 1;
|
|
192
|
+
if (depth === 1) {
|
|
193
|
+
++arrayValueIndex;
|
|
194
|
+
result.set(
|
|
195
|
+
changetype<string>(key),
|
|
196
|
+
data.slice(outerLoopIndex, arrayValueIndex)
|
|
197
|
+
);
|
|
198
|
+
outerLoopIndex = arrayValueIndex;
|
|
199
|
+
key = 0;
|
|
200
|
+
break;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
} else if (char === leftBraceCode) {
|
|
205
|
+
for (
|
|
206
|
+
let objectValueIndex = outerLoopIndex;
|
|
207
|
+
objectValueIndex < data.length - 1;
|
|
208
|
+
objectValueIndex++
|
|
209
|
+
) {
|
|
210
|
+
char = unsafeCharCodeAt(data, objectValueIndex);
|
|
211
|
+
if (char === leftBraceCode) {
|
|
212
|
+
depth = depth << 1;
|
|
213
|
+
} else if (char === rightBraceCode) {
|
|
214
|
+
depth = depth >> 1;
|
|
215
|
+
if (depth === 1) {
|
|
216
|
+
++objectValueIndex;
|
|
217
|
+
result.set(
|
|
218
|
+
changetype<string>(key),
|
|
219
|
+
data.slice(outerLoopIndex, objectValueIndex)
|
|
220
|
+
);
|
|
221
|
+
outerLoopIndex = objectValueIndex;
|
|
222
|
+
key = 0;
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
} else if (char === quoteCode) {
|
|
228
|
+
for (
|
|
229
|
+
let stringValueIndex = ++outerLoopIndex;
|
|
230
|
+
stringValueIndex < data.length - 1;
|
|
231
|
+
stringValueIndex++
|
|
232
|
+
) {
|
|
233
|
+
char = unsafeCharCodeAt(data, stringValueIndex);
|
|
234
|
+
if (
|
|
235
|
+
char === quoteCode &&
|
|
236
|
+
unsafeCharCodeAt(data, stringValueIndex - 1) !== backSlashCode
|
|
237
|
+
) {
|
|
238
|
+
if (key === 0) {
|
|
239
|
+
key = changetype<usize>(
|
|
240
|
+
data.slice(outerLoopIndex, stringValueIndex)
|
|
241
|
+
);
|
|
242
|
+
} else {
|
|
243
|
+
result.set(
|
|
244
|
+
changetype<string>(key),
|
|
245
|
+
data.slice(outerLoopIndex, stringValueIndex)
|
|
246
|
+
);
|
|
247
|
+
key = 0;
|
|
248
|
+
}
|
|
249
|
+
outerLoopIndex = ++stringValueIndex;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
} else if (
|
|
254
|
+
char === tCode &&
|
|
255
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "r".charCodeAt(0) &&
|
|
256
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "u".charCodeAt(0) &&
|
|
257
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
|
|
258
|
+
) {
|
|
259
|
+
result.set(changetype<string>(key), "true");
|
|
260
|
+
key = 0;
|
|
261
|
+
} else if (
|
|
262
|
+
char === fCode &&
|
|
263
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "a".charCodeAt(0) &&
|
|
264
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "l".charCodeAt(0) &&
|
|
265
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === "s".charCodeAt(0) &&
|
|
266
|
+
unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
|
|
267
|
+
) {
|
|
268
|
+
result.set(changetype<string>(key), "false");
|
|
269
|
+
key = 0;
|
|
270
|
+
} else if (char >= 48 && char <= 57) {
|
|
271
|
+
let numberValueIndex = ++outerLoopIndex;
|
|
272
|
+
for (; numberValueIndex < data.length - 1; numberValueIndex++) {
|
|
273
|
+
char = unsafeCharCodeAt(data, numberValueIndex);
|
|
274
|
+
if (
|
|
275
|
+
char === commaCode ||
|
|
276
|
+
isSpace(char) ||
|
|
277
|
+
numberValueIndex == data.length - 2
|
|
278
|
+
) {
|
|
279
|
+
result.set(
|
|
280
|
+
changetype<string>(key),
|
|
281
|
+
data.slice(outerLoopIndex - 1, numberValueIndex)
|
|
282
|
+
);
|
|
283
|
+
outerLoopIndex = numberValueIndex;
|
|
284
|
+
key = 0;
|
|
285
|
+
break;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
201
288
|
}
|
|
202
289
|
}
|
|
203
|
-
//console.log(data.slice(lastPos, data.length - 1))
|
|
204
290
|
// @ts-ignore
|
|
205
|
-
|
|
291
|
+
return schema.__JSON_Deserialize(result);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// @ts-ignore
|
|
295
|
+
@inline
|
|
296
|
+
// @ts-ignore
|
|
297
|
+
export function parseArray<T extends unknown[]>(data: string): T {
|
|
298
|
+
// TODO: Replace with opt
|
|
299
|
+
let type!: valueof<T>;
|
|
300
|
+
if (type instanceof String) {
|
|
301
|
+
return <T>parseStringArray(data);
|
|
302
|
+
} else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
|
|
303
|
+
// @ts-ignore
|
|
304
|
+
return parseNumberArray<T>(data);
|
|
305
|
+
} else if (isBoolean<valueof<T>>()) {
|
|
206
306
|
// @ts-ignore
|
|
207
|
-
|
|
208
|
-
)
|
|
307
|
+
return parseBooleanArray<T>(data);
|
|
308
|
+
} else if (isArrayLike<valueof<T>>()) {
|
|
309
|
+
// @ts-ignore
|
|
310
|
+
return parseArrayArray<T>(data);
|
|
311
|
+
// @ts-ignore
|
|
312
|
+
} else if (isDefined(type.__JSON_Deserialize)) {
|
|
313
|
+
// @ts-ignore
|
|
314
|
+
return parseObjectArray<T>(data);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// @ts-ignore
|
|
319
|
+
@inline
|
|
320
|
+
export function parseStringArray(data: string): string[] {
|
|
321
|
+
const result: string[] = [];
|
|
322
|
+
let lastPos = 0;
|
|
323
|
+
let instr = false;
|
|
324
|
+
for (let i = 1; i < data.length - 1; i++) {
|
|
325
|
+
if (unsafeCharCodeAt(data, i) === quoteCode) {
|
|
326
|
+
if (instr === false) {
|
|
327
|
+
instr = true;
|
|
328
|
+
lastPos = i;
|
|
329
|
+
} else if (unsafeCharCodeAt(data, i - 1) !== backSlashCode) {
|
|
330
|
+
instr = false;
|
|
331
|
+
result.push(data.slice(lastPos + 1, i).replaceAll('\\"', '"'));
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
209
335
|
return result;
|
|
210
336
|
}
|
|
211
337
|
|
|
212
338
|
// @ts-ignore
|
|
213
339
|
@inline
|
|
214
|
-
|
|
340
|
+
export function parseBooleanArray<T extends boolean[]>(data: string): T {
|
|
215
341
|
const result = instantiate<T>();
|
|
216
|
-
|
|
217
|
-
let
|
|
218
|
-
let i
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
char
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
342
|
+
let lastPos = 1;
|
|
343
|
+
let char = 0;
|
|
344
|
+
for (let i = 1; i < data.length - 1; i++) {
|
|
345
|
+
char = unsafeCharCodeAt(data, i);
|
|
346
|
+
/*// if char == "t" && i+3 == "e"
|
|
347
|
+
if (char === tCode && data.charCodeAt(i + 3) === eCode) {
|
|
348
|
+
//i += 3;
|
|
349
|
+
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+2)));
|
|
350
|
+
//i++;
|
|
351
|
+
} else if (char === fCode && data.charCodeAt(i + 4) === eCode) {
|
|
352
|
+
//i += 4;
|
|
353
|
+
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i+3)));
|
|
354
|
+
//i++;
|
|
355
|
+
}*/
|
|
356
|
+
if (char === tCode || char === fCode) {
|
|
357
|
+
lastPos = i;
|
|
358
|
+
} else if (char === eCode) {
|
|
359
|
+
i++;
|
|
360
|
+
result.push(parseBoolean<valueof<T>>(data.slice(lastPos, i)));
|
|
226
361
|
}
|
|
227
362
|
}
|
|
228
|
-
// @ts-ignore
|
|
229
|
-
result.push(
|
|
230
|
-
// @ts-ignore
|
|
231
|
-
parseBoolean<valueof<T>>(data.slice(lastPos, data.length - 1).trimStart())
|
|
232
|
-
);
|
|
233
363
|
return result;
|
|
234
364
|
}
|
|
235
365
|
|
|
236
366
|
// @ts-ignore
|
|
237
367
|
@inline
|
|
238
|
-
|
|
368
|
+
export function parseNumberArray<T extends number[]>(data: string): T {
|
|
239
369
|
const result = instantiate<T>();
|
|
240
|
-
|
|
241
|
-
let
|
|
242
|
-
let
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
let inDepth: u32 = 0;
|
|
251
|
-
let outDepth: u32 = 0;
|
|
252
|
-
for (; i < len; i++) {
|
|
253
|
-
char = data.charCodeAt(i);
|
|
254
|
-
if (char == quoteCode && data.charCodeAt(i - 1) != backSlashCode)
|
|
255
|
-
isStr = !isStr;
|
|
256
|
-
if (char == leftBraceCode || char == leftBracketCode) {
|
|
257
|
-
inDepth++;
|
|
258
|
-
isStruct = true;
|
|
259
|
-
} else if (char == rightBraceCode || char == rightBracketCode) {
|
|
260
|
-
outDepth++;
|
|
261
|
-
isStruct = true;
|
|
370
|
+
let lastPos = 0;
|
|
371
|
+
let char = 0;
|
|
372
|
+
let i = 1;
|
|
373
|
+
for (; i < data.length - 1; i++) {
|
|
374
|
+
char = unsafeCharCodeAt(data, i);
|
|
375
|
+
if (lastPos === 0 && char >= 48 && char <= 57) {
|
|
376
|
+
lastPos = i;
|
|
377
|
+
} else if ((isSpace(char) || char == commaCode) && lastPos > 0) {
|
|
378
|
+
result.push(parseNumber<valueof<T>>(data.slice(lastPos, i)));
|
|
379
|
+
lastPos = 0;
|
|
262
380
|
}
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
if (isSpace(char)) offset++;
|
|
270
|
-
}*/
|
|
271
|
-
// This checks to see if we are dealing with structures such as Objects and Arrays
|
|
272
|
-
if (char == commaCode) {
|
|
273
|
-
// @ts-ignore
|
|
274
|
-
result.push(JSON.parse<valueof<T>>(data.slice(lastPos, i).trim()));
|
|
275
|
-
//offset = 0;
|
|
276
|
-
lastPos = i + 1;
|
|
277
|
-
}
|
|
278
|
-
} else {
|
|
279
|
-
if (inDepth == outDepth) {
|
|
280
|
-
i++;
|
|
281
|
-
//console.log(`Struct-${data.slice(lastPos, i).trim()}-`)
|
|
282
|
-
lastPos = i + 1;
|
|
283
|
-
inDepth = 0;
|
|
284
|
-
outDepth = 0;
|
|
285
|
-
isStruct = false;
|
|
286
|
-
}
|
|
287
|
-
}
|
|
381
|
+
}
|
|
382
|
+
for (; i > lastPos; i--) {
|
|
383
|
+
char = unsafeCharCodeAt(data, i);
|
|
384
|
+
if (char !== rightBracketCode) {
|
|
385
|
+
result.push(parseNumber<valueof<T>>(data.slice(lastPos, i + 1)));
|
|
386
|
+
break;
|
|
288
387
|
}
|
|
289
388
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
389
|
+
return result;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// @ts-ignore
|
|
393
|
+
@inline
|
|
394
|
+
export function parseArrayArray<T extends unknown[][]>(data: string): T {
|
|
395
|
+
const result = instantiate<T>();
|
|
396
|
+
let char = 0;
|
|
397
|
+
let lastPos = 0;
|
|
398
|
+
let depth = 1;
|
|
399
|
+
let i = 1;
|
|
400
|
+
// Find start of bracket
|
|
401
|
+
//for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) {}
|
|
402
|
+
//i++;
|
|
403
|
+
for (; i < data.length - 1; i++) {
|
|
404
|
+
char = unsafeCharCodeAt(data, i);
|
|
405
|
+
if (char === leftBracketCode) {
|
|
406
|
+
if (depth === 1) {
|
|
407
|
+
lastPos = i;
|
|
408
|
+
}
|
|
409
|
+
// Shifting is 6% faster than incrementing
|
|
410
|
+
depth = depth << 1;
|
|
411
|
+
} else if (char === rightBracketCode) {
|
|
412
|
+
depth = depth >> 1;
|
|
413
|
+
if (depth === 1) {
|
|
414
|
+
i++;
|
|
415
|
+
result.push(JSON.parse<valueof<T>>(data.slice(lastPos, i)));
|
|
416
|
+
}
|
|
417
|
+
}
|
|
295
418
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
len--;
|
|
299
|
-
char = data.charCodeAt(len);
|
|
300
|
-
}*/
|
|
419
|
+
return result;
|
|
420
|
+
}
|
|
301
421
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
422
|
+
// @ts-ignore
|
|
423
|
+
@inline
|
|
424
|
+
export function parseObjectArray<T extends unknown[][]>(data: string): T {
|
|
425
|
+
const result = instantiate<T>();
|
|
426
|
+
let char = 0;
|
|
427
|
+
let lastPos = 1;
|
|
428
|
+
let depth = 1;
|
|
429
|
+
let i = 1;
|
|
430
|
+
// Find start of bracket
|
|
431
|
+
//for (; unsafeCharCodeAt(data, i) !== leftBracketCode; i++) { }
|
|
432
|
+
//i++;
|
|
433
|
+
for (; i < data.length - 1; i++) {
|
|
434
|
+
char = unsafeCharCodeAt(data, i);
|
|
435
|
+
if (char === leftBraceCode) {
|
|
436
|
+
if (depth === 1) {
|
|
437
|
+
lastPos = i;
|
|
438
|
+
}
|
|
439
|
+
// Shifting is 6% faster than incrementing
|
|
440
|
+
depth = depth << 1;
|
|
441
|
+
} else if (char === rightBraceCode) {
|
|
442
|
+
depth = depth >> 1;
|
|
443
|
+
if (depth === 1) {
|
|
444
|
+
i++;
|
|
445
|
+
result.push(JSON.parse<valueof<T>>(data.slice(lastPos, i)));
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
308
449
|
return result;
|
|
309
450
|
}
|
|
310
451
|
|
|
311
|
-
class Nullable {
|
|
452
|
+
class Nullable {}
|
package/assembly/test.ts
CHANGED
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
import "wasi";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
JSON,
|
|
4
|
+
parseArrayArray,
|
|
5
|
+
parseNumberArray,
|
|
6
|
+
parseObject,
|
|
7
|
+
parseObjectArray,
|
|
8
|
+
} from ".";
|
|
3
9
|
import { removeWhitespace } from "./util";
|
|
4
10
|
|
|
5
11
|
// @ts-ignore
|
|
6
12
|
@json
|
|
7
13
|
class Vec2 {
|
|
8
|
-
x: f32
|
|
9
|
-
y: f32
|
|
14
|
+
x: f32;
|
|
15
|
+
y: f32;
|
|
10
16
|
}
|
|
11
17
|
|
|
12
18
|
// @ts-ignore
|
|
13
19
|
@json
|
|
14
20
|
class Player {
|
|
15
|
-
firstName: string
|
|
16
|
-
lastName: string
|
|
17
|
-
lastActive: i32[]
|
|
18
|
-
age: i32
|
|
19
|
-
pos: Vec2
|
|
21
|
+
firstName: string;
|
|
22
|
+
lastName: string;
|
|
23
|
+
lastActive: i32[];
|
|
24
|
+
age: i32;
|
|
25
|
+
pos: Vec2;
|
|
26
|
+
isVerified: boolean;
|
|
20
27
|
}
|
|
21
28
|
|
|
22
29
|
const data: Player = {
|
|
@@ -26,50 +33,53 @@ const data: Player = {
|
|
|
26
33
|
age: 23,
|
|
27
34
|
pos: {
|
|
28
35
|
x: -3.4,
|
|
29
|
-
y: 1.2
|
|
30
|
-
}
|
|
31
|
-
|
|
36
|
+
y: 1.2,
|
|
37
|
+
},
|
|
38
|
+
isVerified: true,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const serialized = JSON.stringify<Player>(data);
|
|
42
|
+
console.log("Serialized: " + serialized);
|
|
43
|
+
const deserialized = JSON.parse<Player>(serialized);
|
|
44
|
+
console.log("Deserialized: " + JSON.stringify(deserialized));
|
|
45
|
+
/*
|
|
46
|
+
const parsed = JSON.parse<Player>(stringified);
|
|
47
|
+
console.log("Vec2 Parse: " + JSON.stringify<Player>(parsed));
|
|
48
|
+
console.log(
|
|
49
|
+
`Parsed String Array: ${JSON.stringify(
|
|
50
|
+
JSON.parse<string[]>(`\n[ "hello" , "world" ] `)
|
|
51
|
+
)}`
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
console.log(
|
|
55
|
+
`Parsed Boolean Array: ${JSON.stringify(
|
|
56
|
+
JSON.parse<boolean[]>(`\n[ false , true ] `)
|
|
57
|
+
)}`
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
console.log(
|
|
61
|
+
`Parsed Number Array: ${JSON.stringify(
|
|
62
|
+
JSON.parse<i32[]>(`[ 1 , 2\n ,3\n\t ]`)
|
|
63
|
+
)}`
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
console.log(
|
|
67
|
+
JSON.stringify<Vec2>(
|
|
68
|
+
load<Vec2>(changetype<usize>(data), offsetof<Player>("pos"))
|
|
69
|
+
)
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
console.log(
|
|
73
|
+
JSON.stringify<string[][]>(
|
|
74
|
+
parseArrayArray<string[][]>('[["a","b","c"],["d","e","f"]]')
|
|
75
|
+
)
|
|
76
|
+
);
|
|
32
77
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// "y": 1.2000000476837159
|
|
42
|
-
// }
|
|
43
|
-
// }
|
|
44
|
-
console.log(`Stringified: ${stringified}`);
|
|
45
|
-
console.log(`Whitespace: ${removeWhitespace(`{
|
|
46
|
-
"firstName": "Emmet",
|
|
47
|
-
"lastName": "West",
|
|
48
|
-
"lastActive": [8, 27, 2022],
|
|
49
|
-
"age": 23,
|
|
50
|
-
"pos": {
|
|
51
|
-
"x": -3.4000000953674318,
|
|
52
|
-
"y": 1.2000000476837159
|
|
53
|
-
}
|
|
54
|
-
}`)}`)
|
|
55
|
-
const parsed = JSON.parse<Player>(`{
|
|
56
|
-
"firstName": "Emmet",
|
|
57
|
-
"lastName": "West",
|
|
58
|
-
"lastActive": [8, 27, 2022],
|
|
59
|
-
"age": 23,
|
|
60
|
-
"pos": {
|
|
61
|
-
"x": -3.4000000953674318,
|
|
62
|
-
"y": 1.2000000476837159
|
|
63
|
-
}
|
|
64
|
-
}`);
|
|
65
|
-
// Player {
|
|
66
|
-
// firstName: "Emmet",
|
|
67
|
-
// lastName: "West",
|
|
68
|
-
// lastActive: [8, 27, 2022],
|
|
69
|
-
// age: 23,
|
|
70
|
-
// pos: {
|
|
71
|
-
// x: -3.4000000953674318,
|
|
72
|
-
// y: 1.2000000476837159
|
|
73
|
-
// }
|
|
74
|
-
// }
|
|
75
|
-
console.log(`Parsed: ${JSON.stringify(parsed)}`);
|
|
78
|
+
console.log(
|
|
79
|
+
JSON.stringify<Player[][]>(
|
|
80
|
+
parseObjectArray<Player[][]>(
|
|
81
|
+
'[{"firstName":"Emmet","lastName":"West","lastActive":[8,7],"age":23,"pos":{"x":-3.4000000953674318,"y":1.2000000476837159}}]'
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
);
|
|
85
|
+
*/
|
package/assembly/tsconfig.json
CHANGED
|
File without changes
|