json-as 0.9.28 → 1.0.0-alpha.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.
Files changed (110) hide show
  1. package/.github/workflows/nodejs.yml +0 -3
  2. package/.prettierrc.json +4 -1
  3. package/CHANGELOG +13 -0
  4. package/LICENSE +1 -1
  5. package/README.md +22 -7
  6. package/as-test.config.json +1 -1
  7. package/asconfig.json +2 -2
  8. package/assembly/__benches__/misc.bench.ts +17 -31
  9. package/assembly/__tests__/bool.spec.ts +1 -1
  10. package/assembly/__tests__/simd/string.spec.ts +32 -0
  11. package/assembly/__tests__/types.ts +17 -0
  12. package/assembly/custom/chars.ts +2 -2
  13. package/assembly/custom/memory.ts +25 -0
  14. package/assembly/custom/types.ts +1 -0
  15. package/assembly/custom/util.ts +59 -140
  16. package/assembly/deserialize/simd/string.ts +103 -0
  17. package/assembly/deserialize/simple/arbitrary.ts +17 -0
  18. package/assembly/deserialize/simple/array/arbitrary.ts +113 -0
  19. package/assembly/deserialize/simple/array/array.ts +18 -0
  20. package/assembly/deserialize/simple/array/bool.ts +17 -0
  21. package/assembly/deserialize/simple/array/float.ts +28 -0
  22. package/assembly/deserialize/simple/array/integer.ts +27 -0
  23. package/assembly/deserialize/simple/array/map.ts +18 -0
  24. package/assembly/deserialize/simple/array/object.ts +18 -0
  25. package/assembly/deserialize/simple/array/string.ts +22 -0
  26. package/assembly/deserialize/simple/array.ts +48 -0
  27. package/assembly/deserialize/simple/bool.ts +9 -0
  28. package/assembly/deserialize/simple/date.ts +11 -0
  29. package/assembly/deserialize/simple/float.ts +10 -0
  30. package/assembly/deserialize/simple/integer.ts +5 -0
  31. package/assembly/deserialize/simple/map.ts +154 -0
  32. package/assembly/deserialize/simple/object.ts +159 -0
  33. package/assembly/deserialize/simple/string.ts +48 -0
  34. package/assembly/globals/tables.ts +417 -0
  35. package/assembly/index.d.ts +9 -13
  36. package/assembly/index.ts +282 -158
  37. package/assembly/serialize/simd/string.ts +176 -0
  38. package/assembly/serialize/simple/arbitrary.ts +36 -0
  39. package/assembly/serialize/simple/array.ts +32 -0
  40. package/assembly/serialize/simple/bool.ts +19 -0
  41. package/assembly/serialize/simple/date.ts +13 -0
  42. package/assembly/serialize/simple/float.ts +7 -0
  43. package/assembly/serialize/simple/integer.ts +7 -0
  44. package/assembly/serialize/simple/map.ts +43 -0
  45. package/assembly/serialize/simple/object.ts +7 -0
  46. package/assembly/serialize/simple/string.ts +48 -0
  47. package/assembly/test.ts +43 -28
  48. package/assembly/tsconfig.json +2 -91
  49. package/assembly/types.ts +0 -0
  50. package/assembly/util/atoi.ts +35 -0
  51. package/assembly/util/bytes.ts +12 -0
  52. package/assembly/util/concat.ts +9 -0
  53. package/assembly/util/getArrayDepth.ts +17 -0
  54. package/assembly/util/index.ts +5 -0
  55. package/assembly/util/isSpace.ts +4 -0
  56. package/assembly/util/nextPowerOf2.ts +4 -0
  57. package/assembly/util/ptrToStr.ts +7 -0
  58. package/assembly/util/snp.ts +69 -0
  59. package/bench.js +5 -5
  60. package/modules/bs/index.ts +167 -0
  61. package/modules/tsconfig.json +8 -0
  62. package/package.json +42 -47
  63. package/transform/lib/builder.js +1353 -0
  64. package/transform/lib/builder.js.map +1 -0
  65. package/transform/lib/index.js +497 -395
  66. package/transform/lib/index.js.map +1 -1
  67. package/transform/lib/index.old.js +404 -0
  68. package/transform/lib/index.old.js.map +1 -0
  69. package/transform/lib/linker.js +18 -0
  70. package/transform/lib/linker.js.map +1 -0
  71. package/transform/lib/types.js +25 -0
  72. package/transform/lib/types.js.map +1 -0
  73. package/transform/lib/util.js +47 -0
  74. package/transform/lib/util.js.map +1 -0
  75. package/transform/lib/visitor.js +529 -446
  76. package/transform/lib/visitor.js.map +1 -0
  77. package/transform/package.json +1 -34
  78. package/transform/src/builder.ts +1371 -0
  79. package/transform/src/index.ts +571 -481
  80. package/transform/src/linker.ts +21 -0
  81. package/transform/src/types.ts +27 -0
  82. package/transform/src/util.ts +56 -0
  83. package/transform/src/visitor.ts +531 -0
  84. package/transform/tsconfig.json +3 -1
  85. package/assembly/__benches__/as-tral.d.ts +0 -1
  86. package/assembly/custom/bs.ts +0 -211
  87. package/assembly/deserialize/array/array.ts +0 -31
  88. package/assembly/deserialize/array/bool.ts +0 -19
  89. package/assembly/deserialize/array/float.ts +0 -24
  90. package/assembly/deserialize/array/integer.ts +0 -24
  91. package/assembly/deserialize/array/map.ts +0 -27
  92. package/assembly/deserialize/array/object.ts +0 -27
  93. package/assembly/deserialize/array/string.ts +0 -29
  94. package/assembly/deserialize/array.ts +0 -46
  95. package/assembly/deserialize/bool.ts +0 -34
  96. package/assembly/deserialize/date.ts +0 -19
  97. package/assembly/deserialize/float.ts +0 -21
  98. package/assembly/deserialize/integer.ts +0 -16
  99. package/assembly/deserialize/map.ts +0 -189
  100. package/assembly/deserialize/object.ts +0 -271
  101. package/assembly/deserialize/string.ts +0 -164
  102. package/assembly/serialize/array.ts +0 -51
  103. package/assembly/serialize/bool.ts +0 -10
  104. package/assembly/serialize/date.ts +0 -4
  105. package/assembly/serialize/float.ts +0 -4
  106. package/assembly/serialize/integer.ts +0 -5
  107. package/assembly/serialize/map.ts +0 -24
  108. package/assembly/serialize/object.ts +0 -13
  109. package/assembly/serialize/string.ts +0 -287
  110. package/logs/test.log.json +0 -1049
package/assembly/index.ts CHANGED
@@ -1,23 +1,31 @@
1
1
  /// <reference path="./index.d.ts" />
2
- import { serializeString } from "./serialize/string";
3
- import { serializeBool } from "./serialize/bool";
4
- import { serializeInteger } from "./serialize/integer";
5
- import { serializeFloat } from "./serialize/float";
6
- import { serializeObject } from "./serialize/object";
7
- import { serializeDate } from "./serialize/date";
8
- import { serializeArray } from "./serialize/array";
9
- import { serializeMap } from "./serialize/map";
10
- import { deserializeBoolean, deserializeBoolean_Safe } from "./deserialize/bool";
11
- import { deserializeArray, deserializeArray_Safe } from "./deserialize/array";
12
- import { deserializeFloat } from "./deserialize/float";
13
- import { deserializeObject, deserializeObject_Safe } from "./deserialize/object";
14
- import { deserializeMap, deserializeMap_Safe } from "./deserialize/map";
15
- import { deserializeDate } from "./deserialize/date";
16
- import { NULL_WORD } from "./custom/chars";
17
- import { deserializeInteger, deserializeInteger_Safe } from "./deserialize/integer";
18
- import { deserializeString, deserializeString_Safe } from "./deserialize/string";
2
+ import { bs } from "../modules/bs";
3
+
4
+ import { serializeString } from "./serialize/simple/string";
5
+ import { serializeArray } from "./serialize/simple/array";
6
+ import { serializeMap } from "./serialize/simple/map";
7
+ import { deserializeBoolean } from "./deserialize/simple/bool";
8
+ import { deserializeArray } from "./deserialize/simple/array";
9
+ import { deserializeFloat } from "./deserialize/simple/float";
10
+ import { deserializeObject } from "./deserialize/simple/object";
11
+ import { deserializeMap } from "./deserialize/simple/map";
12
+ import { deserializeDate } from "./deserialize/simple/date";
13
+ import { deserializeInteger } from "./deserialize/simple/integer";
14
+ import { deserializeString } from "./deserialize/simple/string";
15
+ import { serializeArbitrary } from "./serialize/simple/arbitrary";
16
+
19
17
  import { Sink } from "./custom/sink";
20
- import { getArrayDepth } from "./custom/util";
18
+ import { NULL_WORD, QUOTE } from "./custom/chars";
19
+ import { dtoa_buffered, itoa_buffered } from "util/number";
20
+ import { serializeBool } from "./serialize/simple/bool";
21
+ import { serializeInteger } from "./serialize/simple/integer";
22
+ import { serializeFloat } from "./serialize/simple/float";
23
+ import { serializeObject } from "./serialize/simple/object";
24
+ import { ptrToStr } from "./util/ptrToStr";
25
+ import { bytes } from "./util";
26
+ import { serializeString_SIMD } from "./serialize/simd/string";
27
+
28
+ export type Raw = string;
21
29
 
22
30
  /**
23
31
  * Offset of the 'storage' property in the JSON.Value class.
@@ -29,6 +37,158 @@ import { getArrayDepth } from "./custom/util";
29
37
  * JSON Encoder/Decoder for AssemblyScript
30
38
  */
31
39
  export namespace JSON {
40
+ /**
41
+ * Serializes valid JSON data
42
+ * ```js
43
+ * JSON.stringify<T>(data)
44
+ * ```
45
+ * @param data T
46
+ * @returns string
47
+ */
48
+ export function stringify<T>(data: T, out: string | null = null): string {
49
+ if (isBoolean<T>()) {
50
+ if (out) {
51
+ if (<bool>data == true) {
52
+ out = changetype<string>(__renew(changetype<usize>(out), 8));
53
+ store<u64>(changetype<usize>(out), 28429475166421108);
54
+ } else {
55
+ out = changetype<string>(__renew(changetype<usize>(out), 10));
56
+ store<u64>(changetype<usize>(out), 32370086184550502);
57
+ store<u16>(changetype<usize>(out), 101, 8);
58
+ }
59
+ return out;
60
+ }
61
+ return data ? "true" : "false";
62
+ } else if (isInteger<T>() && nameof<T>() == "usize" && data == 0) {
63
+ if (out) {
64
+ out = changetype<string>(__renew(changetype<usize>(out), 8));
65
+ store<u64>(changetype<usize>(out), 30399761348886638);
66
+ return out;
67
+ }
68
+ return NULL_WORD;
69
+ } else if (isInteger<T>(data)) {
70
+ if (out) {
71
+ out = changetype<string>(__renew(changetype<usize>(out), sizeof<T>() << 3));
72
+
73
+ // @ts-ignore
74
+ const bytes = itoa_buffered(changetype<usize>(out), data) << 1;
75
+ return (out = changetype<string>(__renew(changetype<usize>(out), bytes)));
76
+ }
77
+ return data.toString();
78
+ } else if (isFloat<T>(data)) {
79
+ if (out) {
80
+ out = changetype<string>(__renew(changetype<usize>(out), 64));
81
+
82
+ // @ts-ignore
83
+ const bytes = dtoa_buffered(changetype<usize>(out), data) << 1;
84
+ return (out = changetype<string>(__renew(changetype<usize>(out), bytes)));
85
+ }
86
+ return data.toString();
87
+ // @ts-ignore: Function is generated by transform
88
+ } else if (isNullable<T>() && changetype<usize>(data) == <usize>0) {
89
+ if (out) {
90
+ out = changetype<string>(__renew(changetype<usize>(out), 8));
91
+ store<u64>(changetype<usize>(out), 30399761348886638);
92
+ return out;
93
+ }
94
+ return NULL_WORD;
95
+ // @ts-ignore
96
+ } else if (isString<nonnull<T>>()) {
97
+ if (out) {
98
+ out = changetype<string>(__renew(changetype<usize>(out), bytes(data) + 4));
99
+ // const oldSize = bs.byteLength;
100
+ const oldBuf = bs.buffer;
101
+ const newSize = bytes(data) + 4;
102
+ const newBuf = __new(newSize, idof<string>());
103
+ bs.setBuffer(newBuf);
104
+ serializeString(changetype<string>(data));
105
+ bs.setBuffer(oldBuf);
106
+ return changetype<string>(newBuf);
107
+ }
108
+ serializeString(changetype<string>(data));
109
+ return bs.out<string>();
110
+ // @ts-ignore: Supplied by transform
111
+ } else if (isDefined(data.__SERIALIZE) && isDefined(data.__ALLOCATE)) {
112
+ // @ts-ignore
113
+ data.__ALLOCATE();
114
+ // @ts-ignore
115
+ data.__SERIALIZE(changetype<usize>(data));
116
+ return bs.out<string>();
117
+ // @ts-ignore: Supplied by transform
118
+ } else if (data instanceof Date) {
119
+ out = out ? changetype<string>(__renew(changetype<usize>(out), 52)) : changetype<string>(__new(52, idof<string>()));
120
+
121
+ store<u16>(changetype<usize>(out), QUOTE);
122
+ memory.copy(changetype<usize>(out) + 2, changetype<usize>(data.toISOString()), 48);
123
+ store<u16>(changetype<usize>(out), 50);
124
+ return out;
125
+ } else if (data instanceof Array) {
126
+ // @ts-ignore
127
+ serializeArray(changetype<nonnull<T>>(data));
128
+ return bs.out<string>();
129
+ } else if (data instanceof Map) {
130
+ // @ts-ignore
131
+ serializeMap(changetype<nonnull<T>>(data));
132
+ return bs.out<string>();
133
+ } else if (data instanceof JSON.Value) {
134
+ serializeArbitrary(data);
135
+ return bs.out<string>();
136
+ } else if (data instanceof JSON.Box) {
137
+ return JSON.stringify(data.value);
138
+ } else {
139
+ ERROR(`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
140
+ }
141
+ }
142
+
143
+ /**
144
+ * Parses valid JSON strings into their original format
145
+ * ```js
146
+ * JSON.parse<T>(data)
147
+ * ```
148
+ * @param data string
149
+ * @returns T
150
+ */
151
+ export function parse<T>(data: string): T {
152
+ const dataSize = bytes(data);
153
+ const dataPtr = changetype<usize>(data);
154
+ if (isBoolean<T>()) {
155
+ return deserializeBoolean(dataPtr, dataPtr + dataSize) as T;
156
+ } else if (isInteger<T>()) {
157
+ return deserializeInteger<T>(dataPtr, dataPtr + dataSize);
158
+ } else if (isFloat<T>()) {
159
+ return deserializeFloat<T>(dataPtr, dataPtr + dataSize);
160
+ } else if (isNullable<T>() && data.length == 4 && data == "null") {
161
+ // @ts-ignore
162
+ return null;
163
+ } else if (isString<T>()) {
164
+ // @ts-ignore
165
+ return deserializeString(dataPtr, dataPtr + dataSize);
166
+ } else if (isArray<T>()) {
167
+ // @ts-ignore
168
+ return deserializeArray<nonnull<T>>(dataPtr, dataPtr + dataSize, changetype<usize>(instantiate<T>()));
169
+ }
170
+ let type: nonnull<T> = changetype<nonnull<T>>(0);
171
+ // @ts-ignore: Defined by transform
172
+ if (isDefined(type.__DESERIALIZE) && isDefined(type.__INITIALIZE)) {
173
+ const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
174
+ // @ts-ignore
175
+ changetype<nonnull<T>>(out).__INITIALIZE();
176
+ // @ts-ignore
177
+ return deserializeObject<nonnull<T>>(dataPtr, dataPtr + dataSize, out);
178
+ } else if (type instanceof Map) {
179
+ // @ts-ignore
180
+ return deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize);
181
+ } else if (type instanceof Date) {
182
+ // @ts-ignore
183
+ return deserializeDate(dataPtr, dataPtr + dataSize);
184
+ } else if (type instanceof JSON.Box) {
185
+ // @ts-ignore
186
+ return new JSON.Box(JSON.parse<indexof<T>>(data));
187
+ } else {
188
+ ERROR(`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
189
+ }
190
+ }
191
+
32
192
  /**
33
193
  * Enum representing the different types supported by JSON.
34
194
  */
@@ -42,17 +202,23 @@ export namespace JSON {
42
202
  F64 = 6,
43
203
  Bool = 7,
44
204
  String = 8,
45
- Obj = 8,
46
- Array = 9
205
+ Object = 9,
206
+ Array = 10,
207
+ Struct = 11,
47
208
  }
209
+
48
210
  export type Raw = string;
211
+
49
212
  export class Value {
213
+ static METHODS: Map<u32, u32> = new Map<u32, u32>();
50
214
  public type: i32;
51
215
 
52
216
  // @ts-ignore
53
217
  private storage: u64;
54
218
 
55
- private constructor() { unreachable(); }
219
+ private constructor() {
220
+ unreachable();
221
+ }
56
222
 
57
223
  /**
58
224
  * Creates an JSON.Value instance from a given value.
@@ -101,11 +267,19 @@ export namespace JSON {
101
267
  if (idof<T>() !== idof<Map<string, JSON.Value>>()) {
102
268
  abort("Maps must be of type Map<string, JSON.Value>!");
103
269
  }
104
- this.type = JSON.Types.Obj;
270
+ this.type = JSON.Types.Struct;
271
+ store<T>(changetype<usize>(this), value, STORAGE);
272
+ // @ts-ignore
273
+ } else if (isDefined(value.__SERIALIZE)) {
274
+ this.type = idof<T>() + JSON.Types.Struct;
275
+ // @ts-ignore
276
+ if (!JSON.Value.METHODS.has(idof<T>())) JSON.Value.METHODS.set(idof<T>(), value.__SERIALIZE.index);
277
+ // @ts-ignore
105
278
  store<T>(changetype<usize>(this), value, STORAGE);
106
- } else if (isArray<T>()) {
279
+ // @ts-ignore
280
+ } else if (isArray<T>() && idof<valueof<T>>() == idof<JSON.Value>()) {
107
281
  // @ts-ignore: T satisfies constraints of any[]
108
- this.type = JSON.Types.Array + getArrayDepth<T>(0);
282
+ this.type = JSON.Types.Array;
109
283
  store<T>(changetype<usize>(this), value, STORAGE);
110
284
  }
111
285
  }
@@ -120,18 +294,23 @@ export namespace JSON {
120
294
 
121
295
  /**
122
296
  * Converts the JSON.Value to a string representation.
123
- * @param useString - If true, treats Buffer as a string.
124
297
  * @returns The string representation of the JSON.Value.
125
298
  */
126
299
  toString(): string {
127
300
  switch (this.type) {
128
- case JSON.Types.U8: return this.get<u8>().toString();
129
- case JSON.Types.U16: return this.get<u16>().toString();
130
- case JSON.Types.U32: return this.get<u32>().toString();
131
- case JSON.Types.U64: return this.get<u64>().toString();
132
- case JSON.Types.String: return "\"" + this.get<string>() + "\"";
133
- case JSON.Types.Bool: return this.get<boolean>() ? "true" : "false";
134
- default: {
301
+ case JSON.Types.U8:
302
+ return this.get<u8>().toString();
303
+ case JSON.Types.U16:
304
+ return this.get<u16>().toString();
305
+ case JSON.Types.U32:
306
+ return this.get<u32>().toString();
307
+ case JSON.Types.U64:
308
+ return this.get<u64>().toString();
309
+ case JSON.Types.String:
310
+ return '"' + this.get<string>() + '"';
311
+ case JSON.Types.Bool:
312
+ return this.get<boolean>() ? "true" : "false";
313
+ case JSON.Types.Array: {
135
314
  const arr = this.get<JSON.Value[]>();
136
315
  if (!arr.length) return "[]";
137
316
  const out = Sink.fromStringLiteral("[");
@@ -148,162 +327,107 @@ export namespace JSON {
148
327
  out.write("]");
149
328
  return out.toString();
150
329
  }
330
+ default: {
331
+ const fn = JSON.Value.METHODS.get(this.type - JSON.Types.Struct);
332
+ const value = this.get<usize>();
333
+ return call_indirect<string>(fn, 0, value);
334
+ }
151
335
  }
152
336
  }
153
337
  }
338
+
339
+ /**
340
+ * Box for primitive types
341
+ */
154
342
  export class Box<T> {
155
- constructor(public value: T) { }
343
+ constructor(public value: T) {}
344
+ /**
345
+ * Creates a reference to a primitive type
346
+ * This means that it can create a nullable primitive
347
+ * ```js
348
+ * JSON.stringify<Box<i32> | null>(null);
349
+ * // null
350
+ * ```
351
+ * @param from T
352
+ * @returns Box<T>
353
+ */
156
354
  @inline static from<T>(value: T): Box<T> {
157
355
  return new Box(value);
158
356
  }
159
357
  }
160
358
 
161
- /**
162
- * Stringifies valid JSON data.
163
- * ```js
164
- * JSON.stringify<T>(data)
165
- * ```
166
- * @param data T
167
- * @returns string
168
- */
169
- export function stringify<T>(data: T/*, options: SerializeOptions = DEFAULT_SERIALIZE_OPTIONS*/): string {
359
+ export function __serialize<T>(src: T): void {
170
360
  if (isBoolean<T>()) {
171
- return serializeBool(data as bool);
172
- } else if (isInteger<T>() && nameof<T>() == "usize" && data == 0) {
173
- return NULL_WORD;
361
+ serializeBool(src as bool);
362
+ } else if (isInteger<T>() && nameof<T>() == "usize" && src == 0) {
363
+ bs.ensureSize(8);
364
+ store<u64>(bs.offset, 30399761348886638);
365
+ bs.offset += 8;
174
366
  } else if (isInteger<T>()) {
175
367
  // @ts-ignore
176
- return serializeInteger<T>(data);
177
- } else if (isFloat<T>(data)) {
368
+ serializeInteger<T>(src);
369
+ } else if (isFloat<T>(src)) {
178
370
  // @ts-ignore
179
- return serializeFloat<T>(data);
371
+ serializeFloat<T>(src);
180
372
  // @ts-ignore: Function is generated by transform
181
- } else if (isNullable<T>() && changetype<usize>(data) == <usize>0) {
182
- return NULL_WORD;
183
- // @ts-ignore
373
+ } else if (isNullable<T>() && changetype<usize>(src) == <usize>0) {
374
+ bs.ensureSize(8);
375
+ store<u64>(bs.offset, 30399761348886638);
376
+ bs.offset += 8;
184
377
  } else if (isString<nonnull<T>>()) {
185
- return serializeString(changetype<string>(data));
378
+ if (ASC_FEATURE_SIMD) {
379
+ serializeString_SIMD(src as string);
380
+ } else {
381
+ serializeString(src as string);
382
+ }
186
383
  // @ts-ignore: Supplied by transform
187
- } else if (isDefined(data.__SERIALIZE)) {
188
- /*if (options.pretty) {
189
- // @ts-ignore
190
- return serializeObject_Pretty(changetype<nonnull<T>>(data));
191
- }*/
192
- // @ts-ignore
193
- return serializeObject(changetype<nonnull<T>>(data));
194
- } else if (data instanceof Date) {
195
- // @ts-ignore
196
- return serializeDate(changetype<nonnull<T>>(data));
197
- } else if (data instanceof Array) {
198
- // @ts-ignore
199
- return serializeArray(changetype<nonnull<T>>(data));
200
- } else if (data instanceof Map) {
201
- // @ts-ignore
202
- return serializeMap(changetype<nonnull<T>>(data));
203
- } else {
204
- throw new Error(
205
- `Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
206
- );
207
- }
208
- }
209
- /**
210
- * Parses valid JSON strings into their original format.
211
- * ```js
212
- * JSON.parse<T>(data)
213
- * ```
214
- * @param data string
215
- * @returns T
216
- */
217
- export function parse<T>(data: string): T {
218
- if (isBoolean<T>()) {
219
- return deserializeBoolean(data) as T;
220
- } else if (isInteger<T>()) {
221
- return deserializeInteger<T>(data);
222
- } else if (isFloat<T>()) {
223
- return deserializeFloat<T>(data);
224
- } else if (isNullable<T>() && data.length === 4 && data == "null") {
225
- // @ts-ignore
226
- return null;
227
- } else if (isString<T>()) {
228
- // @ts-ignore
229
- return deserializeString(data);
230
- } else if (isArray<T>()) {
384
+ } else if (isDefined(src.__SERIALIZE)) {
231
385
  // @ts-ignore
232
- return deserializeArray<nonnull<T>>(data);
233
- }
234
- let type: nonnull<T> = changetype<nonnull<T>>(0);
235
- // @ts-ignore: Defined by transform
236
- if (isDefined(type.__DESERIALIZE)) {
386
+ serializeObject(changetype<nonnull<T>>(src));
387
+ } else if (src instanceof Date) {
237
388
  // @ts-ignore
238
- return deserializeObject<nonnull<T>>(data.trimStart());
239
- } else if (type instanceof Map) {
389
+ serializeDate(changetype<nonnull<T>>(src));
390
+ } else if (src instanceof Array) {
240
391
  // @ts-ignore
241
- return deserializeMap<nonnull<T>>(data.trimStart());
242
- } else if (type instanceof Date) {
392
+ serializeArray(changetype<nonnull<T>>(src));
393
+ } else if (src instanceof Map) {
243
394
  // @ts-ignore
244
- return deserializeDate(data);
395
+ serializeMap(changetype<nonnull<T>>(src));
396
+ } else if (src instanceof JSON.Value) {
397
+ serializeArbitrary(src);
398
+ } else if (src instanceof JSON.Box) {
399
+ __serialize(src.value);
245
400
  } else {
246
- throw new Error(
247
- `Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
248
- );
401
+ ERROR(`Could not serialize provided data. Make sure to add the correct decorators to classes.`);
249
402
  }
250
403
  }
251
- /**
252
- * Parses valid JSON strings into their original format (safely).
253
- * ```js
254
- * JSON.parseSafe<T>(data)
255
- * ```
256
- * @param data string
257
- * @returns T
258
- */
259
-
260
- // @ts-ignore: Decorator
261
- @inline export function parseSafe<T>(data: string): T {
404
+ export function __deserialize<T>(srcStart: usize, srcEnd: usize, dst: usize = 0): T {
262
405
  if (isBoolean<T>()) {
263
- return deserializeBoolean_Safe(data) as T;
406
+ // @ts-ignore: type
407
+ return deserializeBoolean(srcStart, srcEnd);
264
408
  } else if (isInteger<T>()) {
265
- return deserializeInteger_Safe<T>(data);
409
+ return deserializeInteger<T>(srcStart, srcEnd);
266
410
  } else if (isFloat<T>()) {
267
- return deserializeFloat<T>(data);
268
- } else if (isNullable<T>() && data.length === 4 && data == "null") {
269
- // @ts-ignore
270
- return null;
411
+ return deserializeFloat<T>(srcStart, srcEnd);
271
412
  } else if (isString<T>()) {
272
- // @ts-ignore
273
- return deserializeString_Safe(data);
413
+ // @ts-ignore: type
414
+ return deserializeString(srcStart, srcEnd, dst);
274
415
  } else if (isArray<T>()) {
275
416
  // @ts-ignore
276
- return deserializeArray_Safe<nonnull<T>>(data);
277
- }
278
- let type: nonnull<T> = changetype<nonnull<T>>(0);
279
- // @ts-ignore: Defined by transform
280
- if (isDefined(type.__DESERIALIZE)) {
281
- // @ts-ignore
282
- return deserializeObject_Safe<nonnull<T>>(data.trimStart());
283
- } else if (type instanceof Map) {
284
- // @ts-ignore
285
- return deserializeMap_Safe<nonnull<T>>(data.trimStart());
286
- } else if (type instanceof Date) {
287
- // @ts-ignore
288
- return deserializeDate_Safe(data);
417
+ return deserializeArray<T>(srcStart, srcEnd, dst);
289
418
  } else {
290
- throw new Error(
291
- `Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
292
- );
419
+ let type: nonnull<T> = changetype<nonnull<T>>(0);
420
+ // @ts-ignore: declared by transform
421
+ if (isDefined(type.__DESERIALIZE)) {
422
+ return deserializeObject<T>(srcStart, srcEnd, dst);
423
+ } else if (type instanceof Map) {
424
+ // @ts-ignore: type
425
+ return deserializeMap<T>(srcStart, srcEnd, dst);
426
+ } else if (type instanceof Date) {
427
+ // @ts-ignore: type
428
+ return deserializeDate(srcStart, srcEnd);
429
+ }
293
430
  }
431
+ throw new Error(`Could not deserialize data '${ptrToStr(srcStart, srcEnd).slice(0, 100)}' to type. Make sure to add the correct decorators to classes.`);
294
432
  }
295
433
  }
296
-
297
- // This allows JSON.stringify and JSON.parse to be available globally through an alias
298
- // @ts-ignore: Decorator
299
- @global @inline function __SERIALIZE<T>(data: T): string {
300
- return JSON.stringify(data);
301
- }
302
- // @ts-ignore: Decorator
303
- @global @inline function __DESERIALIZE<T>(data: string): T {
304
- return JSON.parse<T>(data);
305
- }
306
- // @ts-ignore: Decorator
307
- @global @inline function __DESERIALIZE_SAFE<T>(data: string): T {
308
- return JSON.parseSafe<T>(data);
309
- }