json-as 0.9.1 → 0.9.3
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/CHANGELOG +3 -1
- package/README.md +1 -1
- package/assembly/__tests__/deserialize.spec.ts +1 -1
- package/assembly/__tests__/serialize.spec.ts +21 -1
- package/assembly/deserialize/array/array.ts +4 -4
- package/assembly/deserialize/array/bool.ts +4 -4
- package/assembly/deserialize/array/float.ts +3 -3
- package/assembly/deserialize/array/integer.ts +3 -3
- package/assembly/deserialize/array/map.ts +4 -4
- package/assembly/deserialize/array/object.ts +4 -4
- package/assembly/deserialize/array/string.ts +4 -4
- package/assembly/deserialize/array.ts +1 -1
- package/assembly/deserialize/bool.ts +4 -4
- package/assembly/deserialize/box.ts +2 -2
- package/assembly/deserialize/date.ts +1 -1
- package/assembly/deserialize/float.ts +1 -1
- package/assembly/deserialize/integer.ts +1 -1
- package/assembly/deserialize/map.ts +43 -43
- package/assembly/deserialize/object.ts +25 -25
- package/assembly/deserialize/string.ts +33 -33
- package/assembly/index.ts +218 -36
- package/assembly/serialize/array.ts +16 -16
- package/assembly/serialize/bool.ts +6 -1
- package/assembly/serialize/box.ts +4 -3
- package/assembly/serialize/date.ts +1 -1
- package/assembly/serialize/float.ts +1 -1
- package/assembly/serialize/integer.ts +1 -1
- package/assembly/serialize/map.ts +7 -7
- package/assembly/serialize/object.ts +1 -1
- package/assembly/serialize/string.ts +19 -10
- package/assembly/src/chars.ts +37 -35
- package/assembly/src/sink.ts +17 -17
- package/assembly/src/util.ts +15 -15
- package/assembly/test.ts +2 -1
- package/package.json +3 -3
- package/transform/lib/index.js +31 -28
- package/transform/package.json +1 -1
- package/transform/src/index.ts +28 -24
|
@@ -1,75 +1,75 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
2
|
+
CHAR_B,
|
|
3
|
+
BACK_SLASH,
|
|
4
|
+
BACKSPACE,
|
|
5
|
+
CARRIAGE_RETURN,
|
|
6
|
+
CHAR_F,
|
|
7
|
+
FORM_FEED,
|
|
8
|
+
FWD_SLASH,
|
|
9
|
+
CHAR_N,
|
|
10
|
+
NEW_LINE,
|
|
11
|
+
QUOTE,
|
|
12
|
+
CHAR_R,
|
|
13
|
+
CHAR_T,
|
|
14
|
+
TAB,
|
|
15
|
+
CHAR_U
|
|
16
16
|
} from "../src/chars";
|
|
17
17
|
import { Sink } from "../src/sink";
|
|
18
18
|
import { unsafeCharCodeAt } from "../src/util";
|
|
19
19
|
|
|
20
20
|
// @ts-ignore: Decorator
|
|
21
|
-
|
|
21
|
+
export function deserializeString(data: string, start: i32 = 0, end: i32 = 0): string {
|
|
22
22
|
end = end || data.length - 1;
|
|
23
23
|
let result = Sink.withCapacity(end - start - 1);
|
|
24
24
|
let last = start + 1;
|
|
25
25
|
for (let i = last; i < end; i++) {
|
|
26
|
-
if (unsafeCharCodeAt(data, i) !==
|
|
26
|
+
if (unsafeCharCodeAt(data, i) !== BACK_SLASH) {
|
|
27
27
|
continue;
|
|
28
28
|
}
|
|
29
29
|
const char = unsafeCharCodeAt(data, ++i);
|
|
30
30
|
result.write(data, last, i - 1);
|
|
31
31
|
switch (char) {
|
|
32
|
-
case
|
|
33
|
-
result.writeCodePoint(
|
|
32
|
+
case QUOTE: {
|
|
33
|
+
result.writeCodePoint(QUOTE);
|
|
34
34
|
last = i + 1;
|
|
35
35
|
break;
|
|
36
36
|
}
|
|
37
|
-
case
|
|
38
|
-
result.writeCodePoint(
|
|
37
|
+
case BACK_SLASH: {
|
|
38
|
+
result.writeCodePoint(BACK_SLASH);
|
|
39
39
|
last = i + 1;
|
|
40
40
|
break;
|
|
41
41
|
}
|
|
42
|
-
case
|
|
43
|
-
result.writeCodePoint(
|
|
42
|
+
case FWD_SLASH: {
|
|
43
|
+
result.writeCodePoint(FWD_SLASH);
|
|
44
44
|
last = i + 1;
|
|
45
45
|
break;
|
|
46
46
|
}
|
|
47
|
-
case
|
|
48
|
-
result.writeCodePoint(
|
|
47
|
+
case CHAR_B: {
|
|
48
|
+
result.writeCodePoint(BACKSPACE);
|
|
49
49
|
last = i + 1;
|
|
50
50
|
break;
|
|
51
51
|
}
|
|
52
|
-
case
|
|
53
|
-
result.writeCodePoint(
|
|
52
|
+
case CHAR_F: {
|
|
53
|
+
result.writeCodePoint(FORM_FEED);
|
|
54
54
|
last = i + 1;
|
|
55
55
|
break;
|
|
56
56
|
}
|
|
57
|
-
case
|
|
58
|
-
result.writeCodePoint(
|
|
57
|
+
case CHAR_N: {
|
|
58
|
+
result.writeCodePoint(NEW_LINE);
|
|
59
59
|
last = i + 1;
|
|
60
60
|
break;
|
|
61
61
|
}
|
|
62
|
-
case
|
|
63
|
-
result.writeCodePoint(
|
|
62
|
+
case CHAR_R: {
|
|
63
|
+
result.writeCodePoint(CARRIAGE_RETURN);
|
|
64
64
|
last = i + 1;
|
|
65
65
|
break;
|
|
66
66
|
}
|
|
67
|
-
case
|
|
68
|
-
result.writeCodePoint(
|
|
67
|
+
case CHAR_T: {
|
|
68
|
+
result.writeCodePoint(TAB);
|
|
69
69
|
last = i + 1;
|
|
70
70
|
break;
|
|
71
71
|
}
|
|
72
|
-
case
|
|
72
|
+
case CHAR_U: {
|
|
73
73
|
const code = u16.parse(data.slice(i + 1, i + 5), 16);
|
|
74
74
|
result.writeCodePoint(code);
|
|
75
75
|
i += 4;
|
package/assembly/index.ts
CHANGED
|
@@ -18,14 +18,195 @@ import { deserializeBox } from "./deserialize/box";
|
|
|
18
18
|
import { deserializeObject } from "./deserialize/object";
|
|
19
19
|
import { deserializeMap } from "./deserialize/map";
|
|
20
20
|
import { deserializeDate } from "./deserialize/date";
|
|
21
|
-
import {
|
|
21
|
+
import { FALSE_WORD, NULL_WORD, TRUE_WORD } from "./src/chars";
|
|
22
22
|
import { deserializeInteger } from "./deserialize/integer";
|
|
23
23
|
import { deserializeString } from "./deserialize/string";
|
|
24
|
+
import { Sink } from "./src/sink";
|
|
25
|
+
import { Variant } from "as-variant/assembly";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Offset of the 'storage' property in the JSON.Value class.
|
|
29
|
+
*/
|
|
30
|
+
// @ts-ignore: Decorator valid here
|
|
31
|
+
const STORAGE = offsetof<JSON.Value>("storage");
|
|
24
32
|
|
|
25
33
|
/**
|
|
26
34
|
* JSON Encoder/Decoder for AssemblyScript
|
|
27
35
|
*/
|
|
28
36
|
export namespace JSON {
|
|
37
|
+
/**
|
|
38
|
+
* Enum representing the different types supported by JSON.
|
|
39
|
+
*/
|
|
40
|
+
export enum Types {
|
|
41
|
+
U8,
|
|
42
|
+
U16,
|
|
43
|
+
U32,
|
|
44
|
+
U64,
|
|
45
|
+
F32,
|
|
46
|
+
F64,
|
|
47
|
+
Bool,
|
|
48
|
+
String,
|
|
49
|
+
Struct,
|
|
50
|
+
Array
|
|
51
|
+
}
|
|
52
|
+
export class Value {
|
|
53
|
+
public type: i32;
|
|
54
|
+
public length: i32 = 0;
|
|
55
|
+
|
|
56
|
+
// @ts-ignore: storage is set directly through memory
|
|
57
|
+
private storage: u64;
|
|
58
|
+
|
|
59
|
+
private constructor() { unreachable(); }
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Creates an JSON.Value instance from a given value.
|
|
63
|
+
* @param value - The value to be encapsulated.
|
|
64
|
+
* @returns An instance of JSON.Value.
|
|
65
|
+
*/
|
|
66
|
+
static from<T>(value: T): JSON.Value {
|
|
67
|
+
if (value instanceof Variant) {
|
|
68
|
+
// Handle
|
|
69
|
+
} else if (value instanceof JSON.Value) {
|
|
70
|
+
return value;
|
|
71
|
+
}
|
|
72
|
+
const out = changetype<JSON.Value>(__new(offsetof<JSON.Value>(), idof<JSON.Value>()));
|
|
73
|
+
out.set<T>(value);
|
|
74
|
+
return out;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Sets the value of the JSON.Value instance.
|
|
79
|
+
* @param value - The value to be set.
|
|
80
|
+
*/
|
|
81
|
+
set<T>(value: T): void {
|
|
82
|
+
if (isBoolean<T>()) {
|
|
83
|
+
this.type = JSON.Types.Bool;
|
|
84
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
85
|
+
} else if (value instanceof u8 || value instanceof i8) {
|
|
86
|
+
this.type = JSON.Types.U8;
|
|
87
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
88
|
+
} else if (value instanceof u16 || value instanceof i16) {
|
|
89
|
+
this.type = JSON.Types.U16;
|
|
90
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
91
|
+
} else if (value instanceof u32 || value instanceof i32) {
|
|
92
|
+
this.type = JSON.Types.U32;
|
|
93
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
94
|
+
} else if (value instanceof u64 || value instanceof i64) {
|
|
95
|
+
this.type = JSON.Types.U64;
|
|
96
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
97
|
+
} else if (value instanceof f32) {
|
|
98
|
+
this.type = JSON.Types.F64;
|
|
99
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
100
|
+
} else if (value instanceof f64) {
|
|
101
|
+
this.type = JSON.Types.F64;
|
|
102
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
103
|
+
} else if (isString<T>()) {
|
|
104
|
+
this.type = JSON.Types.String;
|
|
105
|
+
this.length = String.UTF8.byteLength(value as string);
|
|
106
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
107
|
+
} else if (value instanceof Map) {
|
|
108
|
+
if (idof<T>() !== idof<Map<string, JSON.Value>>()) {
|
|
109
|
+
throw new Error("Maps must be of type Map<string, JSON.Value>!");
|
|
110
|
+
}
|
|
111
|
+
this.type = JSON.Types.Struct;
|
|
112
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
113
|
+
// @ts-ignore: __SERIALIZE is implemented by the transform
|
|
114
|
+
} else if (isDefined(value.__SERIALIZE)) {
|
|
115
|
+
this.type = JSON.Types.Struct;
|
|
116
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
117
|
+
} else if (isArray<T>()) {
|
|
118
|
+
// @ts-ignore: T satisfies constraints of any[]
|
|
119
|
+
this.type = JSON.Types.Array + getArrayDepth<T>(0);
|
|
120
|
+
// @ts-ignore
|
|
121
|
+
this.length = value.length;
|
|
122
|
+
store<T>(changetype<usize>(this), value, STORAGE);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Gets the value of the JSON.Value instance.
|
|
128
|
+
* @returns The encapsulated value.
|
|
129
|
+
*/
|
|
130
|
+
unwrap<T>(): T {
|
|
131
|
+
if (isManaged<T>()) {
|
|
132
|
+
if (this.type !== JSON.Types.Struct) throw new Error("Type mismatch");
|
|
133
|
+
if (idof<T>() !== load<u32>(changetype<usize>(this.storage), -8)) throw new Error("Type mismatch");
|
|
134
|
+
}
|
|
135
|
+
return load<T>(changetype<usize>(this), STORAGE);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Gets the value of the JSON.Value instance.
|
|
140
|
+
* @returns The encapsulated value.
|
|
141
|
+
*/
|
|
142
|
+
unwrapUnsafe<T>(): T {
|
|
143
|
+
return load<T>(changetype<usize>(this), STORAGE);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Gets the value of the JSON.Value instance.
|
|
148
|
+
* @returns The encapsulated value.
|
|
149
|
+
*/
|
|
150
|
+
get<T>(): T {
|
|
151
|
+
return load<T>(changetype<usize>(this), STORAGE);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Gets the value of the JSON.Value instance.
|
|
156
|
+
* @returns The encapsulated value.
|
|
157
|
+
*/
|
|
158
|
+
getUnsafe<T>(): T {
|
|
159
|
+
return load<T>(changetype<usize>(this), STORAGE);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Gets the value of the JSON.Value instance.
|
|
164
|
+
* @returns The encapsulated value.
|
|
165
|
+
*/
|
|
166
|
+
is<T>(): T {
|
|
167
|
+
return load<T>(changetype<usize>(this), STORAGE);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Gets the value of the JSON.Value instance.
|
|
172
|
+
* @returns The encapsulated value.
|
|
173
|
+
*/
|
|
174
|
+
clone<T>(): T {
|
|
175
|
+
return load<T>(changetype<usize>(this), STORAGE);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Converts the JSON.Value to a string representation.
|
|
180
|
+
* @param useString - If true, treats Buffer as a string.
|
|
181
|
+
* @returns The string representation of the JSON.Value.
|
|
182
|
+
*/
|
|
183
|
+
toString(useString: boolean = false): string {
|
|
184
|
+
switch (this.type) {
|
|
185
|
+
case JSON.Types.U8: return this.get<u8>().toString();
|
|
186
|
+
case JSON.Types.U16: return this.get<u16>().toString();
|
|
187
|
+
case JSON.Types.U32: return this.get<u32>().toString();
|
|
188
|
+
case JSON.Types.U64: return this.get<u64>().toString();
|
|
189
|
+
case JSON.Types.String: return "\"" + this.get<string>() + "\"";
|
|
190
|
+
case JSON.Types.Bool: return this.get<boolean>() ? TRUE_WORD : FALSE_WORD;
|
|
191
|
+
default: {
|
|
192
|
+
const arr = this.get<JSON.Value[]>();
|
|
193
|
+
if (!arr.length) return "[]";
|
|
194
|
+
const out = Sink.fromString("[");
|
|
195
|
+
for (let i = 0; i < arr.length - 1; i++) {
|
|
196
|
+
const element = unchecked(arr[i]);
|
|
197
|
+
out.write(element.toString(useString));
|
|
198
|
+
out.write(",");
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const element = unchecked(arr[arr.length - 1]);
|
|
202
|
+
out.write(element.toString(useString));
|
|
203
|
+
|
|
204
|
+
out.write("]");
|
|
205
|
+
return out.toString();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
29
210
|
/**
|
|
30
211
|
* Stringifies valid JSON data.
|
|
31
212
|
* ```js
|
|
@@ -35,16 +216,9 @@ export namespace JSON {
|
|
|
35
216
|
* @returns string
|
|
36
217
|
*/
|
|
37
218
|
// @ts-ignore: Decorator
|
|
38
|
-
|
|
39
|
-
if (
|
|
40
|
-
return nullWord;
|
|
41
|
-
// @ts-ignore
|
|
42
|
-
} else if (isString<T>()) {
|
|
43
|
-
return serializeString(data as string);
|
|
44
|
-
} else if (isBoolean<T>()) {
|
|
219
|
+
export function stringify<T>(data: T): string {
|
|
220
|
+
if (isBoolean<T>()) {
|
|
45
221
|
return serializeBool(data as bool);
|
|
46
|
-
} else if (data instanceof Box) {
|
|
47
|
-
return serializeBox(data);
|
|
48
222
|
} else if (isInteger<T>()) {
|
|
49
223
|
// @ts-ignore
|
|
50
224
|
return serializeInteger<T>(data);
|
|
@@ -52,15 +226,27 @@ export namespace JSON {
|
|
|
52
226
|
// @ts-ignore
|
|
53
227
|
return serializeFloat<T>(data);
|
|
54
228
|
// @ts-ignore: Function is generated by transform
|
|
229
|
+
} else if (isNullable<T>() && changetype<usize>(data) == <usize>0) {
|
|
230
|
+
return NULL_WORD;
|
|
231
|
+
// @ts-ignore
|
|
232
|
+
} else if (isString<nonnull<T>>()) {
|
|
233
|
+
return serializeString(changetype<string>(data));
|
|
234
|
+
} else if (data instanceof Box) {
|
|
235
|
+
// @ts-ignore
|
|
236
|
+
return serializeBox(changetype<nonnull<T>>(data));
|
|
237
|
+
// @ts-ignore
|
|
55
238
|
} else if (isDefined(data.__SERIALIZE)) {
|
|
56
239
|
// @ts-ignore
|
|
57
|
-
return serializeObject(data);
|
|
240
|
+
return serializeObject(changetype<nonnull<T>>(data));
|
|
58
241
|
} else if (data instanceof Date) {
|
|
59
|
-
|
|
242
|
+
// @ts-ignore
|
|
243
|
+
return serializeDate(changetype<nonnull<T>>(data));
|
|
60
244
|
} else if (data instanceof Array) {
|
|
61
|
-
|
|
245
|
+
// @ts-ignore
|
|
246
|
+
return serializeArray(changetype<nonnull<T>>(data));
|
|
62
247
|
} else if (data instanceof Map) {
|
|
63
|
-
|
|
248
|
+
// @ts-ignore
|
|
249
|
+
return serializeMap(changetype<nonnull<T>>(data));
|
|
64
250
|
} else {
|
|
65
251
|
throw new Error(
|
|
66
252
|
`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
@@ -77,31 +263,34 @@ export namespace JSON {
|
|
|
77
263
|
*/
|
|
78
264
|
|
|
79
265
|
// @ts-ignore: Decorator
|
|
80
|
-
|
|
81
|
-
if (
|
|
82
|
-
// @ts-ignore
|
|
83
|
-
return deserializeString(data);
|
|
84
|
-
} else if (isBoolean<T>()) {
|
|
266
|
+
export function parse<T>(data: string): T {
|
|
267
|
+
if (isBoolean<T>()) {
|
|
85
268
|
return deserializeBoolean(data) as T;
|
|
86
269
|
} else if (isInteger<T>()) {
|
|
87
270
|
return deserializeInteger<T>(data);
|
|
88
271
|
} else if (isFloat<T>()) {
|
|
89
272
|
return deserializeFloat<T>(data);
|
|
273
|
+
} else if (isNullable<T>() && data.length === 4 && data == "null") {
|
|
274
|
+
// @ts-ignore
|
|
275
|
+
return null;
|
|
276
|
+
} else if (isString<T>()) {
|
|
277
|
+
// @ts-ignore
|
|
278
|
+
return deserializeString(data);
|
|
90
279
|
} else if (isArray<T>()) {
|
|
91
280
|
// @ts-ignore
|
|
92
|
-
return deserializeArray<T
|
|
281
|
+
return deserializeArray<nonnull<T>>(data);
|
|
93
282
|
}
|
|
94
|
-
let type: nonnull<T> = changetype<nonnull<T>>(
|
|
283
|
+
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
95
284
|
if (type instanceof Box) {
|
|
96
|
-
return deserializeBox<T>(data);
|
|
97
|
-
} else if (isNullable<T>() && data == nullWord) {
|
|
98
285
|
// @ts-ignore
|
|
99
|
-
return
|
|
286
|
+
return deserializeBox<nonnull<T>>(data);
|
|
100
287
|
// @ts-ignore
|
|
101
288
|
} else if (isDefined(type.__DESERIALIZE)) {
|
|
102
|
-
|
|
289
|
+
// @ts-ignore
|
|
290
|
+
return deserializeObject<nonnull<T>>(data.trimStart());
|
|
103
291
|
} else if (type instanceof Map) {
|
|
104
|
-
|
|
292
|
+
// @ts-ignore
|
|
293
|
+
return deserializeMap<nonnull<T>>(data.trimStart());
|
|
105
294
|
} else if (type instanceof Date) {
|
|
106
295
|
// @ts-ignore
|
|
107
296
|
return deserializeDate(data);
|
|
@@ -113,19 +302,12 @@ export namespace JSON {
|
|
|
113
302
|
}
|
|
114
303
|
}
|
|
115
304
|
|
|
305
|
+
// This allows JSON.stringify and JSON.parse to be available globally through an alias
|
|
116
306
|
// @ts-ignore: Decorator
|
|
117
|
-
@global
|
|
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 {
|
|
307
|
+
@global function __SERIALIZE<T>(data: T): string {
|
|
126
308
|
return JSON.stringify(data);
|
|
127
309
|
}
|
|
128
310
|
// @ts-ignore: Decorator
|
|
129
|
-
@global
|
|
311
|
+
@global function __DESERIALIZE<T>(data: string): T {
|
|
130
312
|
return JSON.parse<T>(data);
|
|
131
313
|
}
|
|
@@ -1,52 +1,52 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
COMMA,
|
|
4
|
+
COMMA_WORD,
|
|
5
|
+
EMPTY_BRACKET_WORD,
|
|
6
|
+
BRACKET_LEFT_WORD,
|
|
7
|
+
BRACKET_RIGHT,
|
|
8
|
+
BRACKET_RIGHT_WORD
|
|
9
9
|
} from "../src/chars";
|
|
10
10
|
import { Sink } from "../src/sink";
|
|
11
11
|
import { serializeString } from "./string";
|
|
12
12
|
|
|
13
13
|
// @ts-ignore
|
|
14
|
-
|
|
14
|
+
export function serializeArray<T extends any[]>(data: T): string {
|
|
15
15
|
// @ts-ignore
|
|
16
16
|
if (data.length == 0) {
|
|
17
|
-
return
|
|
17
|
+
return EMPTY_BRACKET_WORD;
|
|
18
18
|
// @ts-ignore
|
|
19
19
|
} else if (isString<valueof<T>>()) {
|
|
20
|
-
let result =
|
|
20
|
+
let result = BRACKET_LEFT_WORD;
|
|
21
21
|
// @ts-ignore
|
|
22
22
|
for (let i = 0; i < data.length - 1; i++) {
|
|
23
23
|
// @ts-ignore
|
|
24
24
|
result += serializeString(unchecked(data[i]));
|
|
25
|
-
result +=
|
|
25
|
+
result += COMMA_WORD;
|
|
26
26
|
}
|
|
27
27
|
// @ts-ignore
|
|
28
28
|
result += serializeString(unchecked(data[data.length - 1]));
|
|
29
|
-
result +=
|
|
29
|
+
result += BRACKET_RIGHT_WORD;
|
|
30
30
|
return result;
|
|
31
31
|
// @ts-ignore
|
|
32
32
|
} else if (isBoolean<valueof<T>>()) {
|
|
33
33
|
// @ts-ignore
|
|
34
|
-
return
|
|
34
|
+
return BRACKET_LEFT_WORD + data.join(COMMA_WORD) + BRACKET_RIGHT_WORD;
|
|
35
35
|
// @ts-ignore
|
|
36
36
|
} else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
|
|
37
37
|
// @ts-ignore
|
|
38
|
-
return
|
|
38
|
+
return BRACKET_LEFT_WORD + data.join(COMMA_WORD) + BRACKET_RIGHT_WORD;
|
|
39
39
|
} else {
|
|
40
|
-
let result = Sink.fromString(
|
|
40
|
+
let result = Sink.fromString(BRACKET_LEFT_WORD);
|
|
41
41
|
// @ts-ignore
|
|
42
42
|
for (let i = 0; i < data.length - 1; i++) {
|
|
43
43
|
// @ts-ignore
|
|
44
44
|
result.write(JSON.stringify(unchecked(data[i])));
|
|
45
|
-
result.writeCodePoint(
|
|
45
|
+
result.writeCodePoint(COMMA);
|
|
46
46
|
}
|
|
47
47
|
// @ts-ignore
|
|
48
48
|
result.write(JSON.stringify(unchecked(data[data.length - 1])));
|
|
49
|
-
result.writeCodePoint(
|
|
49
|
+
result.writeCodePoint(BRACKET_RIGHT);
|
|
50
50
|
return result.toString();
|
|
51
51
|
}
|
|
52
52
|
}
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Serialize a bool to type string
|
|
3
|
+
* @param data data to serialize
|
|
4
|
+
* @returns string
|
|
5
|
+
*/
|
|
1
6
|
// @ts-ignore
|
|
2
|
-
|
|
7
|
+
export function serializeBool(data: bool): string {
|
|
3
8
|
return data ? "true" : "false";
|
|
4
9
|
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NULL_WORD } from "../src/chars";
|
|
2
2
|
import { JSON } from "..";
|
|
3
|
+
import { Box } from "as-container";
|
|
3
4
|
|
|
4
5
|
// @ts-ignore
|
|
5
|
-
|
|
6
|
+
export function serializeBox<T extends Box<any>>(data: T): string {
|
|
6
7
|
if (isNullable<T>() && changetype<usize>(data) == <usize>0) {
|
|
7
|
-
return
|
|
8
|
+
return NULL_WORD;
|
|
8
9
|
}
|
|
9
10
|
return JSON.stringify(data.unwrap());
|
|
10
11
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @ts-ignore
|
|
2
|
-
|
|
2
|
+
export function serializeInteger<T extends number>(data: T): string {
|
|
3
3
|
// I have a much faster implementation of itoa that I will port over later. Its ~4x faster
|
|
4
4
|
return data.toString();
|
|
5
5
|
}
|
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { COLON, COMMA, BRACE_LEFT_WORD, BRACE_RIGHT } from "../src/chars";
|
|
2
2
|
import { JSON } from "..";
|
|
3
3
|
import { Sink } from "../src/sink";
|
|
4
4
|
import { serializeString } from "./string";
|
|
5
5
|
|
|
6
6
|
// @ts-ignore
|
|
7
|
-
|
|
8
|
-
let result = Sink.fromString(
|
|
7
|
+
export function serializeMap<T extends Map<any, any>>(data: T): string {
|
|
8
|
+
let result = Sink.fromString(BRACE_LEFT_WORD);
|
|
9
9
|
let keys = data.keys();
|
|
10
10
|
let values = data.values();
|
|
11
11
|
const end = data.size - 1;
|
|
12
12
|
for (let i = 0; i < end; i++) {
|
|
13
13
|
result.write(serializeString(unchecked(keys[i]).toString()));
|
|
14
|
-
result.writeCodePoint(
|
|
14
|
+
result.writeCodePoint(COLON);
|
|
15
15
|
result.write(JSON.stringify(unchecked(values[i])));
|
|
16
|
-
result.writeCodePoint(
|
|
16
|
+
result.writeCodePoint(COMMA);
|
|
17
17
|
}
|
|
18
18
|
result.write(serializeString(unchecked(keys[end]).toString()));
|
|
19
|
-
result.writeCodePoint(
|
|
19
|
+
result.writeCodePoint(COLON);
|
|
20
20
|
result.write(JSON.stringify(unchecked(values[end])));
|
|
21
21
|
|
|
22
|
-
result.writeCodePoint(
|
|
22
|
+
result.writeCodePoint(BRACE_RIGHT);
|
|
23
23
|
return result.toString();
|
|
24
24
|
}
|
|
@@ -2,6 +2,6 @@ interface GeneratedInterface {
|
|
|
2
2
|
__SERIALIZE(): string;
|
|
3
3
|
}
|
|
4
4
|
// @ts-ignore
|
|
5
|
-
|
|
5
|
+
export function serializeObject<T extends GeneratedInterface>(data: T): string {
|
|
6
6
|
return changetype<nonnull<T>>(data).__SERIALIZE();
|
|
7
7
|
}
|
|
@@ -1,23 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
BACK_SLASH,
|
|
3
|
+
BACKSPACE,
|
|
4
|
+
CARRIAGE_RETURN,
|
|
5
|
+
FORM_FEED,
|
|
6
|
+
NEW_LINE,
|
|
7
|
+
QUOTE,
|
|
8
|
+
QUOTE_WORD,
|
|
9
|
+
TAB
|
|
10
|
+
} from "../src/chars";
|
|
2
11
|
import { Sink } from "../src/sink";
|
|
3
12
|
import { unsafeCharCodeAt } from "../src/util";
|
|
4
13
|
|
|
5
14
|
// @ts-ignore: Decorator
|
|
6
|
-
|
|
15
|
+
export function serializeString(data: string): string {
|
|
7
16
|
if (data.length === 0) {
|
|
8
|
-
return
|
|
17
|
+
return QUOTE_WORD + QUOTE_WORD;
|
|
9
18
|
}
|
|
10
19
|
|
|
11
|
-
let result = Sink.fromString(
|
|
20
|
+
let result = Sink.fromString(QUOTE_WORD, data.length);
|
|
12
21
|
|
|
13
22
|
let last: i32 = 0;
|
|
14
23
|
for (let i = 0; i < data.length; i++) {
|
|
15
24
|
const char = unsafeCharCodeAt(<string>data, i);
|
|
16
|
-
if (char ===
|
|
25
|
+
if (char === QUOTE || char === BACK_SLASH) {
|
|
17
26
|
result.write(<string>data, last, i);
|
|
18
|
-
result.writeCodePoint(
|
|
27
|
+
result.writeCodePoint(BACK_SLASH);
|
|
19
28
|
last = i;
|
|
20
|
-
} else if (
|
|
29
|
+
} else if (16 > char) {
|
|
21
30
|
result.write(<string>data, last, i);
|
|
22
31
|
last = i + 1;
|
|
23
32
|
switch (char) {
|
|
@@ -29,7 +38,7 @@ import { unsafeCharCodeAt } from "../src/util";
|
|
|
29
38
|
result.write("\\t");
|
|
30
39
|
break;
|
|
31
40
|
}
|
|
32
|
-
case
|
|
41
|
+
case NEW_LINE: {
|
|
33
42
|
result.write("\\n");
|
|
34
43
|
break;
|
|
35
44
|
}
|
|
@@ -49,7 +58,7 @@ import { unsafeCharCodeAt } from "../src/util";
|
|
|
49
58
|
break;
|
|
50
59
|
}
|
|
51
60
|
}
|
|
52
|
-
} else if (
|
|
61
|
+
} else if (32 > char) {
|
|
53
62
|
result.write(<string>data, last, i);
|
|
54
63
|
last = i + 1;
|
|
55
64
|
// all chars 0-31 must be encoded as a four digit unicode escape sequence
|
|
@@ -59,6 +68,6 @@ import { unsafeCharCodeAt } from "../src/util";
|
|
|
59
68
|
}
|
|
60
69
|
}
|
|
61
70
|
result.write(<string>data, last);
|
|
62
|
-
result.writeCodePoint(
|
|
71
|
+
result.writeCodePoint(QUOTE);
|
|
63
72
|
return result.toString();
|
|
64
73
|
}
|