json-as 1.0.0-alpha.4 → 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.
- package/.trunk/configs/.markdownlint.yaml +2 -0
- package/.trunk/configs/.shellcheckrc +7 -0
- package/.trunk/configs/.yamllint.yaml +7 -0
- package/.trunk/trunk.yaml +37 -0
- package/CHANGELOG +60 -0
- package/README.md +303 -48
- package/assembly/__benches__/misc.bench.ts +47 -0
- package/assembly/__benches__/schemas.ts +25 -0
- package/assembly/__benches__/string.bench.ts +23 -0
- package/assembly/__benches__/struct.bench.ts +21 -0
- package/assembly/__tests__/arbitrary.spec.ts +19 -0
- package/assembly/__tests__/array.spec.ts +42 -1
- package/assembly/__tests__/bool.spec.ts +1 -1
- package/assembly/__tests__/box.spec.ts +1 -1
- package/assembly/__tests__/custom.spec.ts +42 -0
- package/assembly/__tests__/date.spec.ts +1 -1
- package/assembly/__tests__/float.spec.ts +4 -4
- package/assembly/__tests__/integer.spec.ts +1 -1
- package/assembly/__tests__/null.spec.ts +1 -1
- package/assembly/__tests__/raw.spec.ts +23 -0
- package/assembly/__tests__/string.spec.ts +1 -1
- package/assembly/__tests__/{obj.spec.ts → struct.spec.ts} +18 -4
- package/assembly/__tests__/test.spec.ts +1 -1
- package/assembly/__tests__/types.ts +3 -3
- package/assembly/as-bs.d.ts +53 -0
- package/assembly/custom/bench.ts +26 -0
- package/assembly/deserialize/simd/string.ts +1 -1
- package/assembly/deserialize/simple/arbitrary.ts +1 -1
- package/assembly/deserialize/simple/array/arbitrary.ts +46 -24
- 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 +1 -1
- 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 +29 -0
- package/assembly/deserialize/simple/array.ts +7 -9
- package/assembly/deserialize/simple/integer.ts +2 -1
- package/assembly/deserialize/simple/map.ts +92 -67
- package/assembly/deserialize/simple/object.ts +14 -19
- package/assembly/deserialize/simple/raw.ts +6 -0
- package/assembly/deserialize/simple/struct.ts +171 -0
- package/assembly/index.d.ts +15 -1
- package/assembly/index.ts +202 -25
- package/assembly/serialize/simd/string.ts +0 -1
- package/assembly/serialize/simple/arbitrary.ts +15 -2
- package/assembly/serialize/simple/array.ts +0 -1
- package/assembly/serialize/simple/bool.ts +0 -2
- package/assembly/serialize/simple/date.ts +0 -1
- package/assembly/serialize/simple/float.ts +0 -1
- package/assembly/serialize/simple/integer.ts +0 -1
- package/assembly/serialize/simple/map.ts +0 -1
- package/assembly/serialize/simple/object.ts +42 -6
- package/assembly/serialize/simple/raw.ts +14 -0
- package/assembly/serialize/simple/string.ts +0 -1
- package/assembly/serialize/simple/struct.ts +7 -0
- package/assembly/test.ts +80 -13
- package/assembly/util/atoi.ts +1 -1
- package/bench/bench.ts +15 -0
- package/bench/schemas.ts +5 -0
- package/bench/string.bench.ts +16 -0
- package/bench.js +11 -2
- package/index.ts +1 -1
- package/{modules/as-bs/assembly/index.ts → lib/as-bs.ts} +3 -3
- package/lib/tsconfig.json +8 -0
- package/package.json +10 -6
- package/run-tests.sh +1 -1
- package/transform/lib/index.js +124 -55
- package/transform/lib/index.js.map +1 -1
- package/transform/src/index.ts +141 -62
- package/.gitmodules +0 -0
- package/as-test.config.json +0 -18
- package/assembly/deserialize/simple/array/object.ts +0 -18
- package/modules/as-bs/LICENSE +0 -21
- package/modules/as-bs/README.md +0 -95
- package/modules/as-bs/assembly/tsconfig.json +0 -97
- package/modules/as-bs/index.ts +0 -1
- package/modules/as-bs/package.json +0 -32
- /package/{modules/test/assembly → assembly/__tests__/lib}/index.ts +0 -0
package/assembly/index.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/// <reference path="./index.d.ts" />
|
|
2
|
-
import { bs } from "../modules/as-bs";
|
|
3
2
|
|
|
4
3
|
import { serializeString } from "./serialize/simple/string";
|
|
5
4
|
import { serializeArray } from "./serialize/simple/array";
|
|
@@ -7,7 +6,7 @@ import { serializeMap } from "./serialize/simple/map";
|
|
|
7
6
|
import { deserializeBoolean } from "./deserialize/simple/bool";
|
|
8
7
|
import { deserializeArray } from "./deserialize/simple/array";
|
|
9
8
|
import { deserializeFloat } from "./deserialize/simple/float";
|
|
10
|
-
import {
|
|
9
|
+
import { deserializeStruct } from "./deserialize/simple/struct";
|
|
11
10
|
import { deserializeMap } from "./deserialize/simple/map";
|
|
12
11
|
import { deserializeDate } from "./deserialize/simple/date";
|
|
13
12
|
import { deserializeInteger } from "./deserialize/simple/integer";
|
|
@@ -20,11 +19,14 @@ import { dtoa_buffered, itoa_buffered } from "util/number";
|
|
|
20
19
|
import { serializeBool } from "./serialize/simple/bool";
|
|
21
20
|
import { serializeInteger } from "./serialize/simple/integer";
|
|
22
21
|
import { serializeFloat } from "./serialize/simple/float";
|
|
23
|
-
import {
|
|
22
|
+
import { serializeStruct } from "./serialize/simple/struct";
|
|
24
23
|
import { ptrToStr } from "./util/ptrToStr";
|
|
25
|
-
import { bytes } from "./util";
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
import { atoi, bytes } from "./util";
|
|
25
|
+
import { deserializeArbitrary } from "./deserialize/simple/arbitrary";
|
|
26
|
+
import { serializeObject } from "./serialize/simple/object";
|
|
27
|
+
import { deserializeObject } from "./deserialize/simple/object";
|
|
28
|
+
import { serializeRaw } from "./serialize/simple/raw";
|
|
29
|
+
import { deserializeRaw } from "./deserialize/simple/raw";
|
|
28
30
|
|
|
29
31
|
/**
|
|
30
32
|
* Offset of the 'storage' property in the JSON.Value class.
|
|
@@ -49,7 +51,8 @@ export namespace JSON {
|
|
|
49
51
|
* @param data T
|
|
50
52
|
* @returns string
|
|
51
53
|
*/
|
|
52
|
-
|
|
54
|
+
// @ts-ignore: inline
|
|
55
|
+
@inline export function stringify<T>(data: T, out: string | null = null): string {
|
|
53
56
|
if (isBoolean<T>()) {
|
|
54
57
|
if (out) {
|
|
55
58
|
if (<bool>data == true) {
|
|
@@ -112,6 +115,11 @@ export namespace JSON {
|
|
|
112
115
|
serializeString(changetype<string>(data));
|
|
113
116
|
return bs.out<string>();
|
|
114
117
|
// @ts-ignore: Supplied by transform
|
|
118
|
+
} else if (isDefined(data.__SERIALIZE_CUSTOM)) {
|
|
119
|
+
// @ts-ignore
|
|
120
|
+
data.__SERIALIZE_CUSTOM(changetype<usize>(data));
|
|
121
|
+
return bs.out<string>();
|
|
122
|
+
// @ts-ignore: Supplied by transform
|
|
115
123
|
} else if (isDefined(data.__SERIALIZE)) {
|
|
116
124
|
// @ts-ignore
|
|
117
125
|
data.__SERIALIZE(changetype<usize>(data));
|
|
@@ -132,9 +140,15 @@ export namespace JSON {
|
|
|
132
140
|
// @ts-ignore
|
|
133
141
|
serializeMap(changetype<nonnull<T>>(data));
|
|
134
142
|
return bs.out<string>();
|
|
143
|
+
} else if (data instanceof JSON.Raw) {
|
|
144
|
+
serializeRaw(data);
|
|
145
|
+
return bs.out<string>();
|
|
135
146
|
} else if (data instanceof JSON.Value) {
|
|
136
147
|
serializeArbitrary(data);
|
|
137
148
|
return bs.out<string>();
|
|
149
|
+
} else if (data instanceof JSON.Obj) {
|
|
150
|
+
serializeObject(data);
|
|
151
|
+
return bs.out<string>();
|
|
138
152
|
} else if (data instanceof JSON.Box) {
|
|
139
153
|
return JSON.stringify(data.value);
|
|
140
154
|
} else {
|
|
@@ -150,7 +164,8 @@ export namespace JSON {
|
|
|
150
164
|
* @param data string
|
|
151
165
|
* @returns T
|
|
152
166
|
*/
|
|
153
|
-
|
|
167
|
+
// @ts-ignore: inline
|
|
168
|
+
@inline export function parse<T>(data: string): T {
|
|
154
169
|
const dataSize = bytes(data);
|
|
155
170
|
const dataPtr = changetype<usize>(data);
|
|
156
171
|
if (isBoolean<T>()) {
|
|
@@ -171,18 +186,34 @@ export namespace JSON {
|
|
|
171
186
|
}
|
|
172
187
|
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
173
188
|
// @ts-ignore: Defined by transform
|
|
174
|
-
if (isDefined(type.
|
|
175
|
-
const out =
|
|
189
|
+
if (isDefined(type.__DESERIALIZE_CUSTOM)) {
|
|
190
|
+
const out = changetype<nonnull<T>>(0);
|
|
191
|
+
// @ts-ignore: Defined by transform
|
|
192
|
+
if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
|
|
176
193
|
// @ts-ignore
|
|
177
|
-
|
|
194
|
+
return out.__DESERIALIZE_CUSTOM(ptrToStr(dataPtr, dataPtr + dataSize));
|
|
195
|
+
// @ts-ignore: Defined by transform
|
|
196
|
+
} else if (isDefined(type.__DESERIALIZE)) {
|
|
197
|
+
const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
|
|
198
|
+
// @ts-ignore: Defined by transform
|
|
199
|
+
if (isDefined(type.__INITIALIZE)) changetype<nonnull<T>>(out).__INITIALIZE();
|
|
178
200
|
// @ts-ignore
|
|
179
|
-
return
|
|
201
|
+
return deserializeStruct<nonnull<T>>(dataPtr, dataPtr + dataSize, out);
|
|
180
202
|
} else if (type instanceof Map) {
|
|
181
203
|
// @ts-ignore
|
|
182
|
-
return deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize);
|
|
204
|
+
return deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize, 0);
|
|
183
205
|
} else if (type instanceof Date) {
|
|
184
206
|
// @ts-ignore
|
|
185
207
|
return deserializeDate(dataPtr, dataPtr + dataSize);
|
|
208
|
+
} else if (type instanceof JSON.Raw) {
|
|
209
|
+
// @ts-ignore: type
|
|
210
|
+
return deserializeRaw(dataPtr, dataPtr + dataSize);
|
|
211
|
+
} else if (type instanceof JSON.Value) {
|
|
212
|
+
// @ts-ignorew
|
|
213
|
+
return deserializeArbitrary(dataPtr, dataPtr + dataSize, 0);
|
|
214
|
+
} else if (type instanceof JSON.Obj) {
|
|
215
|
+
// @ts-ignore
|
|
216
|
+
return deserializeObject(dataPtr, dataPtr + dataSize, 0);
|
|
186
217
|
} else if (type instanceof JSON.Box) {
|
|
187
218
|
// @ts-ignore
|
|
188
219
|
return new JSON.Box(parseBox(data, changetype<nonnull<T>>(0).value));
|
|
@@ -209,19 +240,41 @@ export namespace JSON {
|
|
|
209
240
|
Struct = 11,
|
|
210
241
|
}
|
|
211
242
|
|
|
212
|
-
export
|
|
243
|
+
export class Raw {
|
|
244
|
+
public data: string;
|
|
245
|
+
constructor(data: string) {
|
|
246
|
+
this.data = data;
|
|
247
|
+
}
|
|
248
|
+
set(data: string): void {
|
|
249
|
+
this.data = data;
|
|
250
|
+
}
|
|
251
|
+
toString(): string {
|
|
252
|
+
return this.data;
|
|
253
|
+
}
|
|
254
|
+
// @ts-ignore: inline
|
|
255
|
+
@inline static from(data: string): JSON.Raw {
|
|
256
|
+
return new JSON.Raw(data);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
213
259
|
|
|
214
260
|
export class Value {
|
|
215
261
|
static METHODS: Map<u32, u32> = new Map<u32, u32>();
|
|
216
262
|
public type: i32;
|
|
217
263
|
|
|
218
|
-
// @ts-ignore
|
|
219
264
|
private storage: u64;
|
|
220
265
|
|
|
221
266
|
private constructor() {
|
|
222
267
|
unreachable();
|
|
223
268
|
}
|
|
224
269
|
|
|
270
|
+
/**
|
|
271
|
+
* Creates an JSON.Value instance with no set value.
|
|
272
|
+
* @returns An instance of JSON.Value.
|
|
273
|
+
*/
|
|
274
|
+
@inline static empty(): JSON.Value {
|
|
275
|
+
return changetype<JSON.Value>(__new(offsetof<JSON.Value>(), idof<JSON.Value>()));
|
|
276
|
+
}
|
|
277
|
+
|
|
225
278
|
/**
|
|
226
279
|
* Creates an JSON.Value instance from a given value.
|
|
227
280
|
* @param value - The value to be encapsulated.
|
|
@@ -257,7 +310,7 @@ export namespace JSON {
|
|
|
257
310
|
this.type = JSON.Types.U64;
|
|
258
311
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
259
312
|
} else if (value instanceof f32) {
|
|
260
|
-
this.type = JSON.Types.
|
|
313
|
+
this.type = JSON.Types.F32;
|
|
261
314
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
262
315
|
} else if (value instanceof f64) {
|
|
263
316
|
this.type = JSON.Types.F64;
|
|
@@ -265,18 +318,31 @@ export namespace JSON {
|
|
|
265
318
|
} else if (isString<T>()) {
|
|
266
319
|
this.type = JSON.Types.String;
|
|
267
320
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
321
|
+
} else if (value instanceof JSON.Raw) {
|
|
322
|
+
this.type = JSON.Types.Raw;
|
|
323
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
268
324
|
} else if (value instanceof Map) {
|
|
269
325
|
if (idof<T>() !== idof<Map<string, JSON.Value>>()) {
|
|
270
326
|
abort("Maps must be of type Map<string, JSON.Value>!");
|
|
271
327
|
}
|
|
272
328
|
this.type = JSON.Types.Struct;
|
|
273
329
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
330
|
+
// @ts-ignore: supplied by transform
|
|
331
|
+
} else if (isDefined(value.__SERIALIZE_CUSTOM)) {
|
|
332
|
+
this.type = idof<T>() + JSON.Types.Struct;
|
|
274
333
|
// @ts-ignore
|
|
334
|
+
if (!JSON.Value.METHODS.has(idof<T>())) JSON.Value.METHODS.set(idof<T>(), value.__SERIALIZE_CUSTOM.index);
|
|
335
|
+
// @ts-ignore
|
|
336
|
+
store<usize>(changetype<usize>(this), changetype<usize>(value), STORAGE);
|
|
337
|
+
// @ts-ignore: supplied by transform
|
|
275
338
|
} else if (isDefined(value.__SERIALIZE)) {
|
|
276
339
|
this.type = idof<T>() + JSON.Types.Struct;
|
|
277
340
|
// @ts-ignore
|
|
278
341
|
if (!JSON.Value.METHODS.has(idof<T>())) JSON.Value.METHODS.set(idof<T>(), value.__SERIALIZE.index);
|
|
279
342
|
// @ts-ignore
|
|
343
|
+
store<usize>(changetype<usize>(this), changetype<usize>(value), STORAGE);
|
|
344
|
+
} else if (value instanceof JSON.Obj) {
|
|
345
|
+
this.type = JSON.Types.Object;
|
|
280
346
|
store<T>(changetype<usize>(this), value, STORAGE);
|
|
281
347
|
// @ts-ignore
|
|
282
348
|
} else if (isArray<T>() && idof<valueof<T>>() == idof<JSON.Value>()) {
|
|
@@ -308,10 +374,17 @@ export namespace JSON {
|
|
|
308
374
|
return this.get<u32>().toString();
|
|
309
375
|
case JSON.Types.U64:
|
|
310
376
|
return this.get<u64>().toString();
|
|
377
|
+
case JSON.Types.F32:
|
|
378
|
+
return this.get<f32>().toString();
|
|
379
|
+
case JSON.Types.F64:
|
|
380
|
+
return this.get<f64>().toString();
|
|
311
381
|
case JSON.Types.String:
|
|
312
382
|
return '"' + this.get<string>() + '"';
|
|
313
383
|
case JSON.Types.Bool:
|
|
314
384
|
return this.get<boolean>() ? "true" : "false";
|
|
385
|
+
case JSON.Types.Raw: {
|
|
386
|
+
return this.get<JSON.Raw>().toString();
|
|
387
|
+
}
|
|
315
388
|
case JSON.Types.Array: {
|
|
316
389
|
const arr = this.get<JSON.Value[]>();
|
|
317
390
|
if (!arr.length) return "[]";
|
|
@@ -329,15 +402,81 @@ export namespace JSON {
|
|
|
329
402
|
out.write("]");
|
|
330
403
|
return out.toString();
|
|
331
404
|
}
|
|
405
|
+
case JSON.Types.Object: {
|
|
406
|
+
return JSON.stringify(this.get<JSON.Obj>());
|
|
407
|
+
}
|
|
332
408
|
default: {
|
|
333
409
|
const fn = JSON.Value.METHODS.get(this.type - JSON.Types.Struct);
|
|
334
410
|
const value = this.get<usize>();
|
|
335
|
-
|
|
411
|
+
call_indirect<void>(fn, 0, value);
|
|
412
|
+
return bs.out<string>();
|
|
336
413
|
}
|
|
337
414
|
}
|
|
338
415
|
}
|
|
339
416
|
}
|
|
340
417
|
|
|
418
|
+
export class Obj {
|
|
419
|
+
// When accessing stackSize, subtract 2
|
|
420
|
+
// @ts-ignore: type
|
|
421
|
+
private stackSize: u32 = 6;
|
|
422
|
+
// @ts-ignore: type
|
|
423
|
+
private storage: Map<string, JSON.Value> = new Map<string, JSON.Value>();
|
|
424
|
+
|
|
425
|
+
constructor() { }
|
|
426
|
+
|
|
427
|
+
// @ts-ignore: decorator
|
|
428
|
+
@inline get size(): i32 {
|
|
429
|
+
return this.storage.size;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// @ts-ignore: decorator
|
|
433
|
+
@inline set<T>(key: string, value: T): void {
|
|
434
|
+
if (!this.storage.has(key)) this.stackSize += bytes(key) + 8;
|
|
435
|
+
this.storage.set(key, JSON.Value.from<T>(value));
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// @ts-ignore: decorator
|
|
439
|
+
@inline get(key: string): JSON.Value | null {
|
|
440
|
+
if (!this.storage.has(key)) return null;
|
|
441
|
+
return this.storage.get(key);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
// @ts-ignore: decorator
|
|
445
|
+
@inline has(key: string): bool {
|
|
446
|
+
return this.storage.has(key);
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// @ts-ignore: decorator
|
|
450
|
+
@inline delete(key: string): bool {
|
|
451
|
+
return this.storage.delete(key);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// @ts-ignore: decorator
|
|
455
|
+
@inline keys(): string[] {
|
|
456
|
+
return this.storage.keys();
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// @ts-ignore: decorator
|
|
460
|
+
@inline values(): JSON.Value[] {
|
|
461
|
+
return this.storage.values();
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
// @ts-ignore: decorator
|
|
465
|
+
@inline toString(): string {
|
|
466
|
+
return JSON.stringify(this);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
// @ts-ignore: decorator
|
|
470
|
+
@inline static from<T>(value: T): JSON.Obj {
|
|
471
|
+
if (value instanceof JSON.Obj) return value;
|
|
472
|
+
const out = changetype<JSON.Obj>(__new(offsetof<JSON.Obj>(), idof<JSON.Obj>()));
|
|
473
|
+
|
|
474
|
+
if (value instanceof Map) {
|
|
475
|
+
|
|
476
|
+
}
|
|
477
|
+
return out;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
341
480
|
/**
|
|
342
481
|
* Box for primitive types
|
|
343
482
|
*/
|
|
@@ -345,6 +484,15 @@ export namespace JSON {
|
|
|
345
484
|
constructor(public value: T) {
|
|
346
485
|
if (!isInteger<T>() && !isFloat<T>()) ERROR("JSON.Box should only hold primitive types!");
|
|
347
486
|
}
|
|
487
|
+
/**
|
|
488
|
+
* Set the internal value of Box to new value
|
|
489
|
+
* @param value T
|
|
490
|
+
* @returns this
|
|
491
|
+
*/
|
|
492
|
+
@inline set(value: T): Box<T> {
|
|
493
|
+
this.value = value;
|
|
494
|
+
return this;
|
|
495
|
+
}
|
|
348
496
|
/**
|
|
349
497
|
* Creates a reference to a primitive type
|
|
350
498
|
* This means that it can create a nullable primitive
|
|
@@ -366,7 +514,8 @@ export namespace JSON {
|
|
|
366
514
|
}
|
|
367
515
|
}
|
|
368
516
|
|
|
369
|
-
|
|
517
|
+
// @ts-ignore: inline
|
|
518
|
+
@inline export function __serialize<T>(src: T): void {
|
|
370
519
|
if (isBoolean<T>()) {
|
|
371
520
|
serializeBool(src as bool);
|
|
372
521
|
} else if (isInteger<T>() && nameof<T>() == "usize" && src == 0) {
|
|
@@ -387,9 +536,13 @@ export namespace JSON {
|
|
|
387
536
|
} else if (isString<nonnull<T>>()) {
|
|
388
537
|
serializeString(src as string);
|
|
389
538
|
// @ts-ignore: Supplied by transform
|
|
539
|
+
} else if (isDefined(src.__SERIALIZE_CUSTOM)) {
|
|
540
|
+
// @ts-ignore
|
|
541
|
+
return src.__SERIALIZE_CUSTOM(changetype<nonnull<T>>(src));
|
|
542
|
+
// @ts-ignore: Supplied by transform
|
|
390
543
|
} else if (isDefined(src.__SERIALIZE)) {
|
|
391
544
|
// @ts-ignore
|
|
392
|
-
|
|
545
|
+
serializeStruct(changetype<nonnull<T>>(src));
|
|
393
546
|
} else if (src instanceof Date) {
|
|
394
547
|
// @ts-ignore
|
|
395
548
|
serializeDate(changetype<nonnull<T>>(src));
|
|
@@ -399,20 +552,26 @@ export namespace JSON {
|
|
|
399
552
|
} else if (src instanceof Map) {
|
|
400
553
|
// @ts-ignore
|
|
401
554
|
serializeMap(changetype<nonnull<T>>(src));
|
|
555
|
+
} else if (src instanceof JSON.Raw) {
|
|
556
|
+
serializeRaw(src);
|
|
402
557
|
} else if (src instanceof JSON.Value) {
|
|
403
558
|
serializeArbitrary(src);
|
|
559
|
+
} else if (src instanceof JSON.Obj) {
|
|
560
|
+
serializeObject(src);
|
|
404
561
|
} else if (src instanceof JSON.Box) {
|
|
405
562
|
__serialize(src.value);
|
|
406
563
|
} else {
|
|
407
564
|
throw new Error(`Could not serialize provided data. Make sure to add the correct decorators to classes.`);
|
|
408
565
|
}
|
|
409
566
|
}
|
|
410
|
-
|
|
567
|
+
|
|
568
|
+
// @ts-ignore: inline
|
|
569
|
+
@inline export function __deserialize<T>(srcStart: usize, srcEnd: usize, dst: usize = 0): T {
|
|
411
570
|
if (isBoolean<T>()) {
|
|
412
571
|
// @ts-ignore: type
|
|
413
572
|
return deserializeBoolean(srcStart, srcEnd);
|
|
414
573
|
} else if (isInteger<T>()) {
|
|
415
|
-
return
|
|
574
|
+
return atoi<T>(srcStart, srcEnd);
|
|
416
575
|
} else if (isFloat<T>()) {
|
|
417
576
|
return deserializeFloat<T>(srcStart, srcEnd);
|
|
418
577
|
} else if (isString<T>()) {
|
|
@@ -423,15 +582,28 @@ export namespace JSON {
|
|
|
423
582
|
return deserializeArray<T>(srcStart, srcEnd, dst);
|
|
424
583
|
} else {
|
|
425
584
|
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
426
|
-
// @ts-ignore:
|
|
427
|
-
if (isDefined(type.
|
|
428
|
-
|
|
585
|
+
// @ts-ignore: Defined by transform
|
|
586
|
+
if (isDefined(type.__DESERIALIZE_CUSTOM)) {
|
|
587
|
+
const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
|
|
588
|
+
// @ts-ignore: Defined by transform
|
|
589
|
+
if (isDefined(type.__INITIALIZE)) changetype<nonnull<T>>(out).__INITIALIZE();
|
|
590
|
+
// @ts-ignore
|
|
591
|
+
return changetype<nonnull<T>>(out).__DESERIALIZE_CUSTOM(ptrToStr(dataPtr, dataPtr + dataSize));
|
|
592
|
+
// @ts-ignore: Defined by transform
|
|
593
|
+
} else if (isDefined(type.__DESERIALIZE)) {
|
|
594
|
+
return deserializeStruct<T>(srcStart, srcEnd, dst);
|
|
429
595
|
} else if (type instanceof Map) {
|
|
430
596
|
// @ts-ignore: type
|
|
431
597
|
return deserializeMap<T>(srcStart, srcEnd, dst);
|
|
432
598
|
} else if (type instanceof Date) {
|
|
433
599
|
// @ts-ignore: type
|
|
434
600
|
return deserializeDate(srcStart, srcEnd);
|
|
601
|
+
} else if (type instanceof JSON.Raw) {
|
|
602
|
+
// @ts-ignore: type
|
|
603
|
+
return deserializeRaw(srcStart, srcEnd);
|
|
604
|
+
} else if (type instanceof JSON.Value) {
|
|
605
|
+
// @ts-ignore: type
|
|
606
|
+
return deserializeArbitrary(srcStart, srcEnd, 0);
|
|
435
607
|
} else if (type instanceof JSON.Box) {
|
|
436
608
|
// @ts-ignore: type
|
|
437
609
|
return new JSON.Box(deserializeBox(srcStart, srcEnd, dst, changetype<nonnull<T>>(0).value));
|
|
@@ -448,4 +620,9 @@ export namespace JSON {
|
|
|
448
620
|
|
|
449
621
|
function deserializeBox<T>(srcStart: usize, srcEnd: usize, dst: usize, ty: T): T {
|
|
450
622
|
return JSON.__deserialize<T>(srcStart, srcEnd, dst);
|
|
451
|
-
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
export function toRaw(data: string): JSON.Raw { return new JSON.Raw(data) }
|
|
626
|
+
export function fromRaw(data: JSON.Raw): string { return data.data }
|
|
627
|
+
|
|
628
|
+
export function toBox<T>(data: T): JSON.Box<T> { return new JSON.Box<T>(data) }
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { JSON } from "../..";
|
|
2
2
|
import { serializeArray } from "./array";
|
|
3
3
|
import { serializeBool } from "./bool";
|
|
4
|
+
import { serializeFloat } from "./float";
|
|
4
5
|
import { serializeInteger } from "./integer";
|
|
6
|
+
import { serializeObject } from "./object";
|
|
5
7
|
import { serializeString } from "./string";
|
|
6
8
|
|
|
7
9
|
export function serializeArbitrary(src: JSON.Value): void {
|
|
@@ -18,19 +20,30 @@ export function serializeArbitrary(src: JSON.Value): void {
|
|
|
18
20
|
case JSON.Types.U64:
|
|
19
21
|
serializeInteger<u64>(src.get<u64>());
|
|
20
22
|
break;
|
|
23
|
+
case JSON.Types.F32:
|
|
24
|
+
serializeFloat<f32>(src.get<f32>());
|
|
25
|
+
break;
|
|
26
|
+
case JSON.Types.F64:
|
|
27
|
+
serializeFloat<f64>(src.get<f64>());
|
|
28
|
+
break;
|
|
21
29
|
case JSON.Types.String:
|
|
22
30
|
serializeString(src.get<string>());
|
|
23
31
|
break;
|
|
24
32
|
case JSON.Types.Bool:
|
|
25
33
|
serializeBool(src.get<bool>());
|
|
34
|
+
break;
|
|
26
35
|
case JSON.Types.Array: {
|
|
27
36
|
serializeArray(src.get<JSON.Value[]>());
|
|
28
37
|
break;
|
|
29
38
|
}
|
|
39
|
+
case JSON.Types.Object: {
|
|
40
|
+
serializeObject(src.get<JSON.Obj>());
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
30
43
|
default: {
|
|
31
44
|
const fn = JSON.Value.METHODS.get(src.type - JSON.Types.Struct);
|
|
32
|
-
const
|
|
33
|
-
call_indirect<
|
|
45
|
+
const ptr = src.get<usize>();
|
|
46
|
+
call_indirect<void>(fn, 0, ptr);
|
|
34
47
|
}
|
|
35
48
|
}
|
|
36
49
|
}
|
|
@@ -1,7 +1,43 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
}
|
|
1
|
+
import { JSON } from "../..";
|
|
2
|
+
import { BRACE_LEFT, BRACE_RIGHT, QUOTE } from "../../custom/chars";
|
|
3
|
+
import { bytes } from "../../util";
|
|
4
4
|
|
|
5
|
-
export function serializeObject
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
export function serializeObject(data: JSON.Obj): void {
|
|
6
|
+
if (!data.size) {
|
|
7
|
+
store<u32>(bs.offset, 0);
|
|
8
|
+
bs.offset += 4;
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// This grabs `JSON.Obj.stackSize` which is private
|
|
13
|
+
bs.ensureSize(load<u32>(changetype<usize>(data), offsetof<JSON.Obj>("stackSize")) - 2);
|
|
14
|
+
const keys = data.keys();
|
|
15
|
+
const values = data.values();
|
|
16
|
+
|
|
17
|
+
// console.log(" Keys " + keys.join(" "));
|
|
18
|
+
// console.log(" Values " + values.map<string>(v => v.toString()).join(" "))
|
|
19
|
+
|
|
20
|
+
store<u16>(bs.offset, BRACE_LEFT);
|
|
21
|
+
bs.offset += 2;
|
|
22
|
+
|
|
23
|
+
const firstKey = unchecked(keys[0]);
|
|
24
|
+
const keySize = bytes(firstKey);
|
|
25
|
+
store<u16>(bs.offset, QUOTE);
|
|
26
|
+
memory.copy(bs.offset + 2, changetype<usize>(firstKey), keySize);
|
|
27
|
+
store<u32>(bs.offset += keySize + 2, 3801122); // ":
|
|
28
|
+
bs.offset += 4;
|
|
29
|
+
JSON.__serialize(unchecked(values[0]));
|
|
30
|
+
|
|
31
|
+
for (let i = 1; i < keys.length; i++) {
|
|
32
|
+
const key = unchecked(keys[i]);
|
|
33
|
+
const keySize = bytes(key);
|
|
34
|
+
store<u32>(bs.offset, 2228268); // ,"
|
|
35
|
+
memory.copy(bs.offset + 4, changetype<usize>(key), keySize);
|
|
36
|
+
store<u32>(bs.offset += keySize + 4, 3801122); // ":
|
|
37
|
+
bs.offset += 4;
|
|
38
|
+
JSON.__serialize(unchecked(values[i]));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
store<u16>(bs.offset, BRACE_RIGHT);
|
|
42
|
+
bs.offset += 2;
|
|
43
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { JSON } from "../..";
|
|
2
|
+
import { bytes } from "../../util";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Serialize raw data to itself
|
|
6
|
+
* @param data data to serialize
|
|
7
|
+
* @returns void
|
|
8
|
+
*/
|
|
9
|
+
export function serializeRaw(data: JSON.Raw): void {
|
|
10
|
+
const dataSize = bytes(data.data);
|
|
11
|
+
bs.proposeSize(dataSize);
|
|
12
|
+
memory.copy(changetype<usize>(bs.offset), changetype<usize>(data.data), dataSize);
|
|
13
|
+
bs.offset += dataSize;
|
|
14
|
+
}
|