json-as 0.8.6 → 0.8.7

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 (52) hide show
  1. package/.github/workflows/nodejs.yml +7 -1
  2. package/CHANGELOG +4 -1
  3. package/README.md +26 -16
  4. package/assembly/__tests__/deserialize.spec.ts +298 -0
  5. package/assembly/__tests__/serialize.spec.ts +375 -0
  6. package/assembly/deserialize/array/array.ts +31 -0
  7. package/assembly/deserialize/array/bool.ts +19 -0
  8. package/assembly/deserialize/array/float.ts +24 -0
  9. package/assembly/deserialize/array/integer.ts +24 -0
  10. package/assembly/deserialize/array/map.ts +27 -0
  11. package/assembly/deserialize/array/object.ts +27 -0
  12. package/assembly/deserialize/array/string.ts +29 -0
  13. package/assembly/deserialize/array.ts +37 -0
  14. package/assembly/deserialize/bool.ts +18 -0
  15. package/assembly/deserialize/box.ts +17 -0
  16. package/assembly/deserialize/date.ts +11 -0
  17. package/assembly/deserialize/float.ts +9 -0
  18. package/assembly/deserialize/integer.ts +7 -0
  19. package/assembly/deserialize/map.ts +182 -0
  20. package/assembly/deserialize/object.ts +136 -0
  21. package/assembly/deserialize/string.ts +88 -0
  22. package/assembly/index.d.ts +7 -1
  23. package/assembly/index.ts +129 -1
  24. package/assembly/serialize/array.ts +52 -0
  25. package/assembly/serialize/bool.ts +4 -0
  26. package/assembly/serialize/box.ts +10 -0
  27. package/assembly/serialize/date.ts +4 -0
  28. package/assembly/serialize/float.ts +4 -0
  29. package/assembly/serialize/integer.ts +5 -0
  30. package/assembly/serialize/map.ts +24 -0
  31. package/assembly/serialize/object.ts +7 -0
  32. package/assembly/serialize/string.ts +64 -0
  33. package/assembly/src/sink.ts +286 -0
  34. package/assembly/src/util.ts +6 -0
  35. package/assembly/test.ts +34 -16
  36. package/bench/benchmark.ts +7 -3
  37. package/bench.js +14 -3
  38. package/index.ts +1 -1
  39. package/package.json +6 -8
  40. package/transform/lib/index.js +301 -183
  41. package/transform/lib/index.old.js +257 -0
  42. package/transform/lib/types.js +17 -0
  43. package/transform/package.json +1 -1
  44. package/transform/src/index.old.ts +312 -0
  45. package/transform/src/index.ts +301 -215
  46. package/transform/tsconfig.json +2 -2
  47. package/tsconfig.json +94 -102
  48. package/assembly/__benches__/as-json.ts +0 -88
  49. package/assembly/__benches__/as-tral.d.ts +0 -1
  50. package/assembly/__tests__/as-json.spec.ts +0 -673
  51. package/assembly/__tests__/as-pect.d.ts +0 -1
  52. package/assembly/src/json.ts +0 -941
@@ -0,0 +1,182 @@
1
+ import { Virtual } from "as-virtual/assembly";
2
+ import { containsCodePoint, unsafeCharCodeAt } from "../src/util";
3
+ import {
4
+ aCode,
5
+ backSlashCode,
6
+ colonCode,
7
+ commaCode,
8
+ eCode,
9
+ fCode,
10
+ lCode,
11
+ leftBraceCode,
12
+ leftBracketCode,
13
+ nCode,
14
+ quoteCode,
15
+ rCode,
16
+ rightBraceCode,
17
+ rightBracketCode,
18
+ sCode,
19
+ tCode,
20
+ uCode
21
+ } from "../src/chars";
22
+ import { deserializeBoolean } from "./bool";
23
+ import { JSON } from "..";
24
+ import { deserializeString } from "./string";
25
+ import { isSpace } from "util/string";
26
+ import { deserializeInteger } from "./integer";
27
+ import { deserializeFloat } from "./float";
28
+
29
+ // @ts-ignore: Decorator
30
+ @inline export function deserializeMap<T extends Map>(data: string): T {
31
+
32
+ const map: nonnull<T> = changetype<nonnull<T>>(
33
+ __new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
34
+ );
35
+
36
+ const key = Virtual.createEmpty<string>();
37
+ let isKey = false;
38
+ let depth = 0;
39
+ let outerLoopIndex = 1;
40
+ for (; outerLoopIndex < data.length - 1; outerLoopIndex++) {
41
+ const char = unsafeCharCodeAt(data, outerLoopIndex);
42
+ if (char === leftBracketCode) {
43
+ for (
44
+ let arrayValueIndex = outerLoopIndex;
45
+ arrayValueIndex < data.length - 1;
46
+ arrayValueIndex++
47
+ ) {
48
+ const char = unsafeCharCodeAt(data, arrayValueIndex);
49
+ if (char === leftBracketCode) {
50
+ depth++;
51
+ } else if (char === rightBracketCode) {
52
+ depth--;
53
+ if (depth === 0) {
54
+ ++arrayValueIndex;
55
+ map.set(deserializeMapKey<indexof<T>>(key), JSON.parse<valueof<T>>(data.slice(outerLoopIndex, arrayValueIndex)));
56
+ outerLoopIndex = arrayValueIndex;
57
+ isKey = false;
58
+ break;
59
+ }
60
+ }
61
+ }
62
+ } else if (char === leftBraceCode) {
63
+ for (
64
+ let objectValueIndex = outerLoopIndex;
65
+ objectValueIndex < data.length - 1;
66
+ objectValueIndex++
67
+ ) {
68
+ const char = unsafeCharCodeAt(data, objectValueIndex);
69
+ if (char === leftBraceCode) {
70
+ depth++;
71
+ } else if (char === rightBraceCode) {
72
+ depth--;
73
+ if (depth === 0) {
74
+ ++objectValueIndex;
75
+ map.set(deserializeMapKey<indexof<T>>(key), JSON.parse<valueof<T>>(data.slice(outerLoopIndex, objectValueIndex)));
76
+ outerLoopIndex = objectValueIndex;
77
+ isKey = false;
78
+ break;
79
+ }
80
+ }
81
+ }
82
+ } else if (char === quoteCode) {
83
+ let escaping = false;
84
+ for (
85
+ let stringValueIndex = ++outerLoopIndex;
86
+ stringValueIndex < data.length - 1;
87
+ stringValueIndex++
88
+ ) {
89
+ const char = unsafeCharCodeAt(data, stringValueIndex);
90
+ if (char === backSlashCode && !escaping) {
91
+ escaping = true;
92
+ } else {
93
+ if (
94
+ char === quoteCode && !escaping
95
+ ) {
96
+ if (isKey === false) {
97
+ // perf: we can avoid creating a new string here if the key doesn't contain any escape sequences
98
+ if (containsCodePoint(data, backSlashCode, outerLoopIndex, stringValueIndex)) {
99
+ key.reinst(deserializeString(data, outerLoopIndex - 1, stringValueIndex));
100
+ } else {
101
+ key.reinst(data, outerLoopIndex, stringValueIndex);
102
+ }
103
+ isKey = true;
104
+ } else {
105
+ if (isString<valueof<T>>()) {
106
+ const value = deserializeString(data, outerLoopIndex - 1, stringValueIndex);
107
+ map.set(deserializeMapKey<indexof<T>>(key), value);
108
+ }
109
+ isKey = false;
110
+ }
111
+ outerLoopIndex = ++stringValueIndex;
112
+ break;
113
+ }
114
+ escaping = false;
115
+ }
116
+ }
117
+ } else if (
118
+ char == nCode &&
119
+ unsafeCharCodeAt(data, ++outerLoopIndex) === uCode &&
120
+ unsafeCharCodeAt(data, ++outerLoopIndex) === lCode &&
121
+ unsafeCharCodeAt(data, ++outerLoopIndex) === lCode) {
122
+ if (isNullable<valueof<T>>()) {
123
+ map.set(deserializeMapKey<indexof<T>>(key), null);
124
+ }
125
+ isKey = false;
126
+ } else if (
127
+ char === tCode &&
128
+ unsafeCharCodeAt(data, ++outerLoopIndex) === rCode &&
129
+ unsafeCharCodeAt(data, ++outerLoopIndex) === uCode &&
130
+ unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
131
+ ) {
132
+ if (isBoolean<valueof<T>>()) {
133
+ map.set(deserializeMapKey<indexof<T>>(key), true);
134
+ }
135
+ isKey = false;
136
+ } else if (
137
+ char === fCode &&
138
+ unsafeCharCodeAt(data, ++outerLoopIndex) === aCode &&
139
+ unsafeCharCodeAt(data, ++outerLoopIndex) === lCode &&
140
+ unsafeCharCodeAt(data, ++outerLoopIndex) === sCode &&
141
+ unsafeCharCodeAt(data, ++outerLoopIndex) === eCode
142
+ ) {
143
+ if (isBoolean<valueof<T>>()) {
144
+ map.set(deserializeMapKey<indexof<T>>(key), false);
145
+ }
146
+ isKey = false;
147
+ } else if ((char >= 48 && char <= 57) || char === 45) {
148
+ let numberValueIndex = ++outerLoopIndex;
149
+ for (; numberValueIndex < data.length; numberValueIndex++) {
150
+ const char = unsafeCharCodeAt(data, numberValueIndex);
151
+ if (char === colonCode || char === commaCode || char === rightBraceCode || isSpace(char)) {
152
+ if (isInteger<valueof<T>>()) {
153
+ map.set(deserializeMapKey<indexof<T>>(key), deserializeInteger<valueof<T>>(data.slice(outerLoopIndex - 1, numberValueIndex)));
154
+ } else if (isFloat<valueof<T>>()) {
155
+ map.set(deserializeMapKey<indexof<T>>(key), deserializeFloat<valueof<T>>(data.slice(outerLoopIndex - 1, numberValueIndex)));
156
+ }
157
+ outerLoopIndex = numberValueIndex;
158
+ isKey = false;
159
+ break;
160
+ }
161
+ }
162
+ }
163
+ }
164
+
165
+ return map;
166
+ }
167
+
168
+ //@ts-ignore: Decorator
169
+ @inline function deserializeMapKey<T>(key: Virtual<string>): T {
170
+ const k = key.copyOut();
171
+ if (isString<T>()) {
172
+ return k as T;
173
+ } else if (isBoolean<T>()) {
174
+ return deserializeBoolean(k) as T;
175
+ } else if (isInteger<T>()) {
176
+ return deserializeInteger<T>(k);
177
+ } else if (isFloat<T>()) {
178
+ return deserializeFloat<T>(k);
179
+ }
180
+
181
+ throw new Error(`JSON: Cannot parse JSON object to a Map with a key of type ${nameof<T>()}`);
182
+ }
@@ -0,0 +1,136 @@
1
+ import { containsCodePoint, unsafeCharCodeAt } from "../src/util";
2
+ import { aCode, backSlashCode, commaCode, eCode, fCode, lCode, leftBraceCode, leftBracketCode, nCode, quoteCode, rCode, rightBraceCode, rightBracketCode, sCode, tCode, uCode } from "../src/chars";
3
+ import { isSpace } from "util/string";
4
+
5
+ // @ts-ignore: Decorator
6
+ @inline export function deserializeObject<T>(data: string): T {
7
+ const schema: nonnull<T> = changetype<nonnull<T>>(
8
+ __new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
9
+ );
10
+
11
+ // @ts-ignore
12
+ schema.__INITIALIZE();
13
+
14
+ let key_start: i32 = 0;
15
+ let key_end: i32 = 0;
16
+ let isKey = false;
17
+ let depth = 0;
18
+ let outerLoopIndex = 1;
19
+ for (; outerLoopIndex < data.length - 1; outerLoopIndex++) {
20
+ const char = unsafeCharCodeAt(data, outerLoopIndex);
21
+ if (char === leftBracketCode) {
22
+ for (
23
+ let arrayValueIndex = outerLoopIndex;
24
+ arrayValueIndex < data.length - 1;
25
+ arrayValueIndex++
26
+ ) {
27
+ const char = unsafeCharCodeAt(data, arrayValueIndex);
28
+ if (char === leftBracketCode) {
29
+ depth++;
30
+ } else if (char === rightBracketCode) {
31
+ depth--;
32
+ if (depth === 0) {
33
+ ++arrayValueIndex;
34
+ // @ts-ignore
35
+ schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex, arrayValueIndex);
36
+ outerLoopIndex = arrayValueIndex;
37
+ isKey = false;
38
+ break;
39
+ }
40
+ }
41
+ }
42
+ } else if (char === leftBraceCode) {
43
+ for (
44
+ let objectValueIndex = outerLoopIndex;
45
+ objectValueIndex < data.length - 1;
46
+ objectValueIndex++
47
+ ) {
48
+ const char = unsafeCharCodeAt(data, objectValueIndex);
49
+ if (char === leftBraceCode) {
50
+ depth++;
51
+ } else if (char === rightBraceCode) {
52
+ depth--;
53
+ if (depth === 0) {
54
+ ++objectValueIndex;
55
+ // @ts-ignore
56
+ schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex, objectValueIndex);
57
+ outerLoopIndex = objectValueIndex;
58
+ isKey = false;
59
+ break;
60
+ }
61
+ }
62
+ }
63
+ } else if (char === quoteCode) {
64
+ let escaping = false;
65
+ for (
66
+ let stringValueIndex = ++outerLoopIndex;
67
+ stringValueIndex < data.length - 1;
68
+ stringValueIndex++
69
+ ) {
70
+ const char = unsafeCharCodeAt(data, stringValueIndex);
71
+ if (char === backSlashCode && !escaping) {
72
+ escaping = true;
73
+ } else {
74
+ if (char === quoteCode && !escaping) {
75
+ if (isKey === false) {
76
+ key_start = outerLoopIndex;
77
+ key_end = stringValueIndex;
78
+ isKey = true;
79
+ } else {
80
+ // @ts-ignore
81
+ schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex - 1, stringValueIndex + 1);
82
+ isKey = false;
83
+ }
84
+ outerLoopIndex = ++stringValueIndex;
85
+ break;
86
+ }
87
+ escaping = false;
88
+ }
89
+ }
90
+ } else if (
91
+ char == nCode &&
92
+ unsafeCharCodeAt(data, outerLoopIndex + 1) === uCode &&
93
+ unsafeCharCodeAt(data, outerLoopIndex + 2) === lCode &&
94
+ unsafeCharCodeAt(data, outerLoopIndex + 3) === lCode
95
+ ) {
96
+ // @ts-ignore
97
+ schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex, outerLoopIndex + 4);
98
+ outerLoopIndex += 3;
99
+ isKey = false;
100
+ } else if (
101
+ char === tCode &&
102
+ unsafeCharCodeAt(data, outerLoopIndex + 1) === rCode &&
103
+ unsafeCharCodeAt(data, outerLoopIndex + 2) === uCode &&
104
+ unsafeCharCodeAt(data, outerLoopIndex + 3) === eCode
105
+ ) {
106
+ // @ts-ignore
107
+ schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex, outerLoopIndex + 4);
108
+ outerLoopIndex += 3;
109
+ isKey = false;
110
+ } else if (
111
+ char === fCode &&
112
+ unsafeCharCodeAt(data, outerLoopIndex + 1) === aCode &&
113
+ unsafeCharCodeAt(data, outerLoopIndex + 2) === lCode &&
114
+ unsafeCharCodeAt(data, outerLoopIndex + 3) === sCode &&
115
+ unsafeCharCodeAt(data, outerLoopIndex + 4) === eCode
116
+ ) {
117
+ // @ts-ignore
118
+ schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex, outerLoopIndex + 5);
119
+ outerLoopIndex += 4;
120
+ isKey = false;
121
+ } else if ((char >= 48 && char <= 57) || char === 45) {
122
+ let numberValueIndex = ++outerLoopIndex;
123
+ for (; numberValueIndex < data.length; numberValueIndex++) {
124
+ const char = unsafeCharCodeAt(data, numberValueIndex);
125
+ if (char === commaCode || char === rightBraceCode || isSpace(char)) {
126
+ // @ts-ignore
127
+ schema.__DESERIALIZE(data, key_start, key_end, outerLoopIndex - 1, numberValueIndex);
128
+ outerLoopIndex = numberValueIndex;
129
+ isKey = false;
130
+ break;
131
+ }
132
+ }
133
+ }
134
+ }
135
+ return schema;
136
+ }
@@ -0,0 +1,88 @@
1
+ import {
2
+ bCode,
3
+ backSlashCode,
4
+ backspaceCode,
5
+ carriageReturnCode,
6
+ fCode,
7
+ formFeedCode,
8
+ forwardSlashCode,
9
+ nCode,
10
+ newLineCode,
11
+ quoteCode,
12
+ rCode,
13
+ tCode,
14
+ tabCode,
15
+ uCode
16
+ } from "../src/chars";
17
+ import { Sink } from "../src/sink";
18
+ import { unsafeCharCodeAt } from "../src/util";
19
+
20
+ // @ts-ignore: Decorator
21
+ @inline export function deserializeString(data: string, start: i32 = 0, end: i32 = 0): string {
22
+ end = end || data.length - 1;
23
+ let result = Sink.withCapacity(end - start - 1);
24
+ let last = start + 1;
25
+ for (let i = last; i < end; i++) {
26
+ if (unsafeCharCodeAt(data, i) !== backSlashCode) {
27
+ continue;
28
+ }
29
+ const char = unsafeCharCodeAt(data, ++i);
30
+ result.write(data, last, i - 1);
31
+ switch (char) {
32
+ case quoteCode: {
33
+ result.writeCodePoint(quoteCode);
34
+ last = i + 1;
35
+ break;
36
+ }
37
+ case backSlashCode: {
38
+ result.writeCodePoint(backSlashCode);
39
+ last = i + 1;
40
+ break;
41
+ }
42
+ case forwardSlashCode: {
43
+ result.writeCodePoint(forwardSlashCode);
44
+ last = i + 1;
45
+ break;
46
+ }
47
+ case bCode: {
48
+ result.writeCodePoint(backspaceCode);
49
+ last = i + 1;
50
+ break;
51
+ }
52
+ case fCode: {
53
+ result.writeCodePoint(formFeedCode);
54
+ last = i + 1;
55
+ break;
56
+ }
57
+ case nCode: {
58
+ result.writeCodePoint(newLineCode);
59
+ last = i + 1;
60
+ break;
61
+ }
62
+ case rCode: {
63
+ result.writeCodePoint(carriageReturnCode);
64
+ last = i + 1;
65
+ break;
66
+ }
67
+ case tCode: {
68
+ result.writeCodePoint(tabCode);
69
+ last = i + 1;
70
+ break;
71
+ }
72
+ case uCode: {
73
+ const code = u16.parse(data.slice(i + 1, i + 5), 16);
74
+ result.writeCodePoint(code);
75
+ i += 4;
76
+ last = i + 1;
77
+ break;
78
+ }
79
+ default: {
80
+ throw new Error(`JSON: Cannot parse "${data}" as string. Invalid escape sequence: \\${data.charAt(i)}`);
81
+ }
82
+ }
83
+ }
84
+ if (end > last) {
85
+ result.write(data, last, end);
86
+ }
87
+ return result.toString()
88
+ }
@@ -13,10 +13,16 @@ declare function serializable(target: any): void;
13
13
  */
14
14
  declare function alias(name: string): Function;
15
15
 
16
+ /**
17
+ * Property decorator that allows omits a field, making it be ignored.
18
+ */
19
+ declare function omit(): Function;
20
+
21
+
16
22
  /**
17
23
  * Property decorator that allows a field to be omitted when equal to an Expression.
18
24
  */
19
- declare function omitwhen(condition: string): Function;
25
+ declare function omitif(condition: string): Function;
20
26
 
21
27
  /**
22
28
  * Property decorator that allows a field to be omitted when a property is null.
package/assembly/index.ts CHANGED
@@ -1,3 +1,131 @@
1
1
  /// <reference path="./index.d.ts" />
2
2
 
3
- export { JSON } from "./src/json";
3
+ import { Box } from "as-container/assembly";
4
+
5
+ import { serializeString } from "./serialize/string";
6
+ import { serializeBool } from "./serialize/bool";
7
+ import { serializeBox } from "./serialize/box";
8
+ import { serializeInteger } from "./serialize/integer";
9
+ import { serializeFloat } from "./serialize/float";
10
+ import { serializeObject } from "./serialize/object";
11
+ import { serializeDate } from "./serialize/date";
12
+ import { serializeArray } from "./serialize/array";
13
+ import { serializeMap } from "./serialize/map";
14
+ import { deserializeBoolean } from "./deserialize/bool";
15
+ import { deserializeArray } from "./deserialize/array";
16
+ import { deserializeFloat } from "./deserialize/float";
17
+ import { deserializeBox } from "./deserialize/box";
18
+ import { deserializeObject } from "./deserialize/object";
19
+ import { deserializeMap } from "./deserialize/map";
20
+ import { deserializeDate } from "./deserialize/date";
21
+ import { nullWord } from "./src/chars";
22
+ import { deserializeInteger } from "./deserialize/integer";
23
+ import { deserializeString } from "./deserialize/string";
24
+
25
+ /**
26
+ * JSON Encoder/Decoder for AssemblyScript
27
+ */
28
+ export namespace JSON {
29
+ /**
30
+ * Stringifies valid JSON data.
31
+ * ```js
32
+ * JSON.stringify<T>(data)
33
+ * ```
34
+ * @param data T
35
+ * @returns string
36
+ */
37
+ // @ts-ignore: Decorator
38
+ @inline export function stringify<T>(data: T): string {
39
+ if (isNullable<T>() && changetype<usize>(data) == <usize>0) {
40
+ return nullWord;
41
+ // @ts-ignore
42
+ } else if (isString<T>()) {
43
+ return serializeString(data as string);
44
+ } else if (isBoolean<T>()) {
45
+ return serializeBool(data as bool);
46
+ } else if (data instanceof Box) {
47
+ return serializeBox(data);
48
+ } else if (isInteger<T>()) {
49
+ // @ts-ignore
50
+ return serializeInteger<T>(data);
51
+ } else if (isFloat<T>(data)) {
52
+ // @ts-ignore
53
+ return serializeFloat<T>(data);
54
+ // @ts-ignore: Function is generated by transform
55
+ } else if (isDefined(data.__SERIALIZE)) {
56
+ // @ts-ignore
57
+ return serializeObject(data);
58
+ } else if (data instanceof Date) {
59
+ return serializeDate(data);
60
+ } else if (data instanceof Array) {
61
+ return serializeArray(data);
62
+ } else if (data instanceof Map) {
63
+ return serializeMap(data);
64
+ } else {
65
+ throw new Error(
66
+ `Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
67
+ );
68
+ }
69
+ }
70
+ /**
71
+ * Parses valid JSON strings into their original format.
72
+ * ```js
73
+ * JSON.parse<T>(data)
74
+ * ```
75
+ * @param data string
76
+ * @returns T
77
+ */
78
+
79
+ // @ts-ignore: Decorator
80
+ @inline export function parse<T>(data: string): T {
81
+ if (isString<T>()) {
82
+ // @ts-ignore
83
+ return deserializeString(data);
84
+ } else if (isBoolean<T>()) {
85
+ return deserializeBoolean(data) as T;
86
+ } else if (isInteger<T>()) {
87
+ return deserializeInteger<T>(data);
88
+ } else if (isFloat<T>()) {
89
+ return deserializeFloat<T>(data);
90
+ } else if (isArray<T>()) {
91
+ // @ts-ignore
92
+ return deserializeArray<T>(data);
93
+ }
94
+ let type: nonnull<T> = changetype<nonnull<T>>(__new(offsetof<nonnull<T>>(), idof<nonnull<T>>()));
95
+ if (type instanceof Box) {
96
+ return deserializeBox<T>(data);
97
+ } else if (isNullable<T>() && data == nullWord) {
98
+ // @ts-ignore
99
+ return null;
100
+ // @ts-ignore
101
+ } else if (isDefined(type.__DESERIALIZE)) {
102
+ return deserializeObject<T>(data.trimStart());
103
+ } else if (type instanceof Map) {
104
+ return deserializeMap<T>(data.trimStart());
105
+ } else if (type instanceof Date) {
106
+ // @ts-ignore
107
+ return deserializeDate(data);
108
+ } else {
109
+ throw new Error(
110
+ `Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
111
+ );
112
+ }
113
+ }
114
+ }
115
+
116
+ // @ts-ignore: Decorator
117
+ @global @inline function __parseObjectValue<T>(data: string, initializeDefaultValues: boolean): T {
118
+ // @ts-ignore
119
+ if (isString<T>()) return data;
120
+ return JSON.parse<T>(data, initializeDefaultValues);
121
+ }
122
+
123
+ // Dirty fix
124
+ // @ts-ignore: Decorator
125
+ @global @inline function __SERIALIZE<T>(data: T): string {
126
+ return JSON.stringify(data);
127
+ }
128
+ // @ts-ignore: Decorator
129
+ @global @inline function __DESERIALIZE<T>(data: string): T {
130
+ return JSON.parse<T>(data);
131
+ }
@@ -0,0 +1,52 @@
1
+ import { JSON } from "..";
2
+ import {
3
+ commaCode,
4
+ commaWord,
5
+ emptyArrayWord,
6
+ leftBracketWord,
7
+ rightBracketCode,
8
+ rightBracketWord
9
+ } from "../src/chars";
10
+ import { Sink } from "../src/sink";
11
+ import { serializeString } from "./string";
12
+
13
+ // @ts-ignore
14
+ @inline export function serializeArray<T extends any[]>(data: T): string {
15
+ // @ts-ignore
16
+ if (data.length == 0) {
17
+ return emptyArrayWord;
18
+ // @ts-ignore
19
+ } else if (isString<valueof<T>>()) {
20
+ let result = leftBracketWord;
21
+ // @ts-ignore
22
+ for (let i = 0; i < data.length - 1; i++) {
23
+ // @ts-ignore
24
+ result += serializeString(unchecked(data[i]));
25
+ result += commaWord;
26
+ }
27
+ // @ts-ignore
28
+ result += serializeString(unchecked(data[data.length - 1]));
29
+ result += rightBracketWord;
30
+ return result;
31
+ // @ts-ignore
32
+ } else if (isBoolean<valueof<T>>()) {
33
+ // @ts-ignore
34
+ return leftBracketWord + data.join(commaWord) + rightBracketWord;
35
+ // @ts-ignore
36
+ } else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
37
+ // @ts-ignore
38
+ return leftBracketWord + data.join(commaWord) + rightBracketWord;
39
+ } else {
40
+ let result = Sink.fromString(leftBracketWord);
41
+ // @ts-ignore
42
+ for (let i = 0; i < data.length - 1; i++) {
43
+ // @ts-ignore
44
+ result.write(JSON.stringify(unchecked(data[i])));
45
+ result.writeCodePoint(commaCode);
46
+ }
47
+ // @ts-ignore
48
+ result.write(JSON.stringify(unchecked(data[data.length - 1])));
49
+ result.writeCodePoint(rightBracketCode);
50
+ return result.toString();
51
+ }
52
+ }
@@ -0,0 +1,4 @@
1
+ // @ts-ignore
2
+ @inline export function serializeBool(data: bool): string {
3
+ return data ? "true" : "false";
4
+ }
@@ -0,0 +1,10 @@
1
+ import { nullWord } from "../src/chars";
2
+ import { JSON } from "..";
3
+
4
+ // @ts-ignore
5
+ @inline export function serializeBox<T extends Box<any>>(data: T): string {
6
+ if (isNullable<T>() && changetype<usize>(data) == <usize>0) {
7
+ return nullWord;
8
+ }
9
+ return JSON.stringify(data.unwrap());
10
+ }
@@ -0,0 +1,4 @@
1
+ // @ts-ignore
2
+ @inline export function serializeDate(data: Date): string {
3
+ return `"${data.toISOString()}"`
4
+ }
@@ -0,0 +1,4 @@
1
+ // @ts-ignore
2
+ @inline export function serializeFloat<T extends number>(data: T): string {
3
+ return data.toString();
4
+ }
@@ -0,0 +1,5 @@
1
+ // @ts-ignore
2
+ @inline export function serializeInteger<T extends number>(data: T): string {
3
+ // I have a much faster implementation of itoa that I will port over later. Its ~4x faster
4
+ return data.toString();
5
+ }
@@ -0,0 +1,24 @@
1
+ import { colonCode, commaCode, leftBraceWord, rightBraceCode } from "../src/chars";
2
+ import { JSON } from "..";
3
+ import { Sink } from "../src/sink";
4
+ import { serializeString } from "./string";
5
+
6
+ // @ts-ignore
7
+ @inline export function serializeMap<T extends Map<any, any>>(data: T): string {
8
+ let result = Sink.fromString(leftBraceWord);
9
+ let keys = data.keys();
10
+ let values = data.values();
11
+ const end = data.size - 1;
12
+ for (let i = 0; i < end; i++) {
13
+ result.write(serializeString(unchecked(keys[i]).toString()));
14
+ result.writeCodePoint(colonCode);
15
+ result.write(JSON.stringify(unchecked(values[i])));
16
+ result.writeCodePoint(commaCode);
17
+ }
18
+ result.write(serializeString(unchecked(keys[end]).toString()));
19
+ result.writeCodePoint(colonCode);
20
+ result.write(JSON.stringify(unchecked(values[end])));
21
+
22
+ result.writeCodePoint(rightBraceCode);
23
+ return result.toString();
24
+ }
@@ -0,0 +1,7 @@
1
+ interface GeneratedInterface {
2
+ __SERIALIZE(): string;
3
+ }
4
+ // @ts-ignore
5
+ @inline export function serializeObject<T extends GeneratedInterface>(data: T): string {
6
+ return changetype<nonnull<T>>(data).__SERIALIZE();
7
+ }