json-as 0.8.2 → 0.8.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/.github/workflows/nodejs.yml +0 -3
- package/CHANGELOG +2 -1
- package/README.md +1 -1
- package/assembly/__tests__/as-json.spec.ts +5 -0
- package/assembly/src/json.ts +109 -28
- package/assembly/test.ts +5 -21
- package/package.json +1 -1
- package/transform/lib/index.js +6 -6
- package/transform/package.json +1 -1
- package/transform/src/index.ts +6 -6
package/CHANGELOG
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
v0.8.2 - Properties starting with `static` or `private` would be ignored
|
|
1
|
+
v0.8.2 - Properties starting with `static` or `private` would be ignored
|
|
2
|
+
v0.8.3 - Dirty fix to issue #68. Add __JSON_Stringify callable to global scope.
|
package/README.md
CHANGED
|
@@ -102,6 +102,11 @@ describe("Ser/de Array", () => {
|
|
|
102
102
|
|
|
103
103
|
canSerde<i32[]>([0, 100, 101, -100, -101]);
|
|
104
104
|
canSerde<i64[]>([0, 100, 101, -100, -101]);
|
|
105
|
+
canDeser<i32[]>(`[
|
|
106
|
+
1,
|
|
107
|
+
2,
|
|
108
|
+
3
|
|
109
|
+
]`, [1,2,3]);
|
|
105
110
|
});
|
|
106
111
|
|
|
107
112
|
it("should ser/de float arrays", () => {
|
package/assembly/src/json.ts
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
tabCode,
|
|
28
28
|
formFeedCode,
|
|
29
29
|
newLineCode,
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
commaWord,
|
|
32
32
|
quoteWord,
|
|
33
33
|
|
|
@@ -50,7 +50,7 @@ export namespace JSON {
|
|
|
50
50
|
/**
|
|
51
51
|
* Stringifies valid JSON data.
|
|
52
52
|
* ```js
|
|
53
|
-
*
|
|
53
|
+
* __JSON_Stringify<T>(data)
|
|
54
54
|
* ```
|
|
55
55
|
* @param data T
|
|
56
56
|
* @returns string
|
|
@@ -104,11 +104,11 @@ export namespace JSON {
|
|
|
104
104
|
// @ts-ignore
|
|
105
105
|
for (let i = 0; i < data.length - 1; i++) {
|
|
106
106
|
// @ts-ignore
|
|
107
|
-
result.write(
|
|
107
|
+
result.write(__JSON_Stringify(unchecked(data[i])));
|
|
108
108
|
result.writeCodePoint(commaCode);
|
|
109
109
|
}
|
|
110
110
|
// @ts-ignore
|
|
111
|
-
result.write(
|
|
111
|
+
result.write(__JSON_Stringify(unchecked(data[data.length - 1])));
|
|
112
112
|
result.writeCodePoint(rightBracketCode);
|
|
113
113
|
return result.toString();
|
|
114
114
|
}
|
|
@@ -116,14 +116,17 @@ export namespace JSON {
|
|
|
116
116
|
let result = new StringSink(leftBraceWord);
|
|
117
117
|
let keys = data.keys();
|
|
118
118
|
let values = data.values();
|
|
119
|
-
|
|
119
|
+
const end = data.size - 1;
|
|
120
|
+
for (let i = 0; i < end; i++) {
|
|
120
121
|
result.write(serializeString(unchecked(keys[i]).toString()));
|
|
121
122
|
result.writeCodePoint(colonCode);
|
|
122
|
-
result.write(
|
|
123
|
-
|
|
124
|
-
result.writeCodePoint(commaCode);
|
|
125
|
-
}
|
|
123
|
+
result.write(__JSON_Stringify(unchecked(values[i])));
|
|
124
|
+
result.writeCodePoint(commaCode);
|
|
126
125
|
}
|
|
126
|
+
result.write(serializeString(unchecked(keys[end]).toString()));
|
|
127
|
+
result.writeCodePoint(colonCode);
|
|
128
|
+
result.write(__JSON_Stringify(unchecked(values[end])));
|
|
129
|
+
|
|
127
130
|
result.writeCodePoint(rightBraceCode);
|
|
128
131
|
return result.toString();
|
|
129
132
|
} else {
|
|
@@ -135,7 +138,7 @@ export namespace JSON {
|
|
|
135
138
|
/**
|
|
136
139
|
* Stringifies valid JSON data.
|
|
137
140
|
* ```js
|
|
138
|
-
*
|
|
141
|
+
* __JSON_Stringify<T>(data)
|
|
139
142
|
* ```
|
|
140
143
|
* @param data T
|
|
141
144
|
* @returns string
|
|
@@ -198,11 +201,11 @@ export namespace JSON {
|
|
|
198
201
|
// @ts-ignore
|
|
199
202
|
for (let i = 0; i < data.length - 1; i++) {
|
|
200
203
|
// @ts-ignore
|
|
201
|
-
result.write(
|
|
204
|
+
result.write(__JSON_Stringify(unchecked(data[i])));
|
|
202
205
|
result.writeCodePoint(commaCode);
|
|
203
206
|
}
|
|
204
207
|
// @ts-ignore
|
|
205
|
-
result.write(
|
|
208
|
+
result.write(__JSON_Stringify(unchecked(data[data.length - 1])));
|
|
206
209
|
result.writeCodePoint(rightBracketCode);
|
|
207
210
|
out = result.toString();
|
|
208
211
|
return;
|
|
@@ -350,7 +353,7 @@ export namespace JSON {
|
|
|
350
353
|
|
|
351
354
|
// @ts-ignore: Decorator
|
|
352
355
|
@inline function parseString(data: string, start: i32 = 0, end: i32 = 0): string {
|
|
353
|
-
end = end || data.length - 1;
|
|
356
|
+
end = end || data.length - 1;
|
|
354
357
|
let result = StringSink.withCapacity(end - start - 1);
|
|
355
358
|
let last = start + 1;
|
|
356
359
|
for (let i = last; i < end; i++) {
|
|
@@ -444,7 +447,7 @@ export namespace JSON {
|
|
|
444
447
|
const schema: nonnull<T> = changetype<nonnull<T>>(
|
|
445
448
|
__new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
|
|
446
449
|
);
|
|
447
|
-
|
|
450
|
+
|
|
448
451
|
// @ts-ignore
|
|
449
452
|
if (initializeDefaultValues) schema.__JSON_Initialize();
|
|
450
453
|
|
|
@@ -579,7 +582,7 @@ export namespace JSON {
|
|
|
579
582
|
const map: nonnull<T> = changetype<nonnull<T>>(
|
|
580
583
|
__new(offsetof<nonnull<T>>(), idof<nonnull<T>>())
|
|
581
584
|
);
|
|
582
|
-
|
|
585
|
+
|
|
583
586
|
if (!isDefined(map.set)) {
|
|
584
587
|
return unreachable();
|
|
585
588
|
}
|
|
@@ -652,7 +655,7 @@ export namespace JSON {
|
|
|
652
655
|
key.reinst(data, outerLoopIndex, stringValueIndex);
|
|
653
656
|
}
|
|
654
657
|
isKey = true;
|
|
655
|
-
} else {
|
|
658
|
+
} else {
|
|
656
659
|
if (isString<valueof<T>>()) {
|
|
657
660
|
const value = parseString(data, outerLoopIndex - 1, stringValueIndex);
|
|
658
661
|
map.set(parseMapKey<indexof<T>>(key), value);
|
|
@@ -702,7 +705,7 @@ export namespace JSON {
|
|
|
702
705
|
if (char === colonCode || char === commaCode || char === rightBraceCode || isSpace(char)) {
|
|
703
706
|
if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
|
|
704
707
|
map.set(parseMapKey<indexof<T>>(key), parseNumber<valueof<T>>(data.slice(outerLoopIndex - 1, numberValueIndex)));
|
|
705
|
-
}
|
|
708
|
+
}
|
|
706
709
|
outerLoopIndex = numberValueIndex;
|
|
707
710
|
isKey = false;
|
|
708
711
|
break;
|
|
@@ -754,7 +757,7 @@ export namespace JSON {
|
|
|
754
757
|
return parseObjectArray<T>(data);
|
|
755
758
|
}
|
|
756
759
|
}
|
|
757
|
-
|
|
760
|
+
|
|
758
761
|
return unreachable();
|
|
759
762
|
}
|
|
760
763
|
|
|
@@ -805,22 +808,18 @@ export namespace JSON {
|
|
|
805
808
|
const result = instantiate<T>();
|
|
806
809
|
let lastPos = 0;
|
|
807
810
|
let i = 1;
|
|
808
|
-
|
|
811
|
+
let awaitingParse = false;
|
|
812
|
+
for (; i < data.length; i++) {
|
|
809
813
|
const char = unsafeCharCodeAt(data, i);
|
|
810
814
|
if (lastPos === 0 && ((char >= 48 && char <= 57) || char === 45)) {
|
|
815
|
+
awaitingParse = true;
|
|
811
816
|
lastPos = i;
|
|
812
|
-
} else if ((isSpace(char) || char == commaCode) && lastPos > 0) {
|
|
817
|
+
} else if (awaitingParse && (isSpace(char) || char == commaCode || char == rightBracketCode) && lastPos > 0) {
|
|
818
|
+
awaitingParse = false;
|
|
813
819
|
result.push(parseNumber<valueof<T>>(data.slice(lastPos, i)));
|
|
814
820
|
lastPos = 0;
|
|
815
821
|
}
|
|
816
822
|
}
|
|
817
|
-
for (; i > lastPos - 1; i--) {
|
|
818
|
-
const char = unsafeCharCodeAt(data, i);
|
|
819
|
-
if (char !== rightBracketCode) {
|
|
820
|
-
result.push(parseNumber<valueof<T>>(data.slice(lastPos, i + 1)));
|
|
821
|
-
break;
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
823
|
return result;
|
|
825
824
|
}
|
|
826
825
|
|
|
@@ -876,7 +875,7 @@ export namespace JSON {
|
|
|
876
875
|
return result;
|
|
877
876
|
}
|
|
878
877
|
|
|
879
|
-
function parseDate(dateTimeString: string): Date {
|
|
878
|
+
function parseDate(dateTimeString: string): Date {
|
|
880
879
|
// Use AssemblyScript's date parser
|
|
881
880
|
const d = Date.fromString(dateTimeString);
|
|
882
881
|
|
|
@@ -891,3 +890,85 @@ function parseDate(dateTimeString: string): Date {
|
|
|
891
890
|
let type = changetype<T>(0);
|
|
892
891
|
return type instanceof Map;
|
|
893
892
|
}
|
|
893
|
+
|
|
894
|
+
// Dirty fix
|
|
895
|
+
// @ts-ignore: Decorator
|
|
896
|
+
@global @inline function __JSON_Stringify<T>(data: T): string {
|
|
897
|
+
// String
|
|
898
|
+
if (isString<T>() && data != null) {
|
|
899
|
+
return serializeString(data as string);
|
|
900
|
+
} else if (isBoolean<T>()) {
|
|
901
|
+
return data ? "true" : "false";
|
|
902
|
+
} else if (isNullable<T>() && data == null) {
|
|
903
|
+
return nullWord;
|
|
904
|
+
// @ts-ignore
|
|
905
|
+
} else if ((isInteger<T>() || isFloat<T>()) && isFinite(data)) {
|
|
906
|
+
// @ts-ignore
|
|
907
|
+
return data.toString();
|
|
908
|
+
// @ts-ignore: Hidden function
|
|
909
|
+
} else if (isDefined(data.__JSON_Serialize)) {
|
|
910
|
+
// @ts-ignore: Hidden function
|
|
911
|
+
return data.__JSON_Serialize();
|
|
912
|
+
} else if (data instanceof Date) {
|
|
913
|
+
return `"${data.toISOString()}"`;
|
|
914
|
+
} else if (isArrayLike<T>()) {
|
|
915
|
+
// @ts-ignore
|
|
916
|
+
if (data.length == 0) {
|
|
917
|
+
return emptyArrayWord;
|
|
918
|
+
// @ts-ignore
|
|
919
|
+
} else if (isString<valueof<T>>()) {
|
|
920
|
+
let result = leftBracketWord;
|
|
921
|
+
// @ts-ignore
|
|
922
|
+
for (let i = 0; i < data.length - 1; i++) {
|
|
923
|
+
// @ts-ignore
|
|
924
|
+
result += serializeString(unchecked(data[i]));
|
|
925
|
+
result += commaWord;
|
|
926
|
+
}
|
|
927
|
+
// @ts-ignore
|
|
928
|
+
result += serializeString(unchecked(data[data.length - 1]));
|
|
929
|
+
result += rightBracketWord;
|
|
930
|
+
return result;
|
|
931
|
+
// @ts-ignore
|
|
932
|
+
} else if (isBoolean<valueof<T>>()) {
|
|
933
|
+
// @ts-ignore
|
|
934
|
+
return leftBracketWord + data.join(commaWord) + rightBracketWord;
|
|
935
|
+
// @ts-ignore
|
|
936
|
+
} else if (isFloat<valueof<T>>() || isInteger<valueof<T>>()) {
|
|
937
|
+
// @ts-ignore
|
|
938
|
+
return leftBracketWord + data.join(commaWord) + rightBracketWord;
|
|
939
|
+
} else {
|
|
940
|
+
let result = new StringSink(leftBracketWord);
|
|
941
|
+
// @ts-ignore
|
|
942
|
+
for (let i = 0; i < data.length - 1; i++) {
|
|
943
|
+
// @ts-ignore
|
|
944
|
+
result.write(__JSON_Stringify(unchecked(data[i])));
|
|
945
|
+
result.writeCodePoint(commaCode);
|
|
946
|
+
}
|
|
947
|
+
// @ts-ignore
|
|
948
|
+
result.write(__JSON_Stringify(unchecked(data[data.length - 1])));
|
|
949
|
+
result.writeCodePoint(rightBracketCode);
|
|
950
|
+
return result.toString();
|
|
951
|
+
}
|
|
952
|
+
} else if (data instanceof Map) {
|
|
953
|
+
let result = new StringSink(leftBraceWord);
|
|
954
|
+
let keys = data.keys();
|
|
955
|
+
let values = data.values();
|
|
956
|
+
const end = data.size - 1;
|
|
957
|
+
for (let i = 0; i < end; i++) {
|
|
958
|
+
result.write(serializeString(unchecked(keys[i]).toString()));
|
|
959
|
+
result.writeCodePoint(colonCode);
|
|
960
|
+
result.write(__JSON_Stringify(unchecked(values[i])));
|
|
961
|
+
result.writeCodePoint(commaCode);
|
|
962
|
+
}
|
|
963
|
+
result.write(serializeString(unchecked(keys[end]).toString()));
|
|
964
|
+
result.writeCodePoint(colonCode);
|
|
965
|
+
result.write(__JSON_Stringify(unchecked(values[end])));
|
|
966
|
+
|
|
967
|
+
result.writeCodePoint(rightBraceCode);
|
|
968
|
+
return result.toString();
|
|
969
|
+
} else {
|
|
970
|
+
throw new Error(
|
|
971
|
+
`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
972
|
+
);
|
|
973
|
+
}
|
|
974
|
+
}
|
package/assembly/test.ts
CHANGED
|
@@ -1,23 +1,7 @@
|
|
|
1
1
|
import { JSON } from "./src/json";
|
|
2
|
-
@json
|
|
3
|
-
class Person {
|
|
4
|
-
staticprng: i32 = 23;
|
|
5
|
-
public country: string = '';
|
|
6
2
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
// temp method, returns hard-coded string for now
|
|
14
|
-
private getCountry(): string {
|
|
15
|
-
return "USA";
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const person = new Person(1);
|
|
20
|
-
person.staticprng = 32
|
|
21
|
-
let result = JSON.stringify<Person>(person);
|
|
22
|
-
console.log(JSON.stringify(JSON.parse<Person>(result)));
|
|
23
|
-
console.log(result);
|
|
3
|
+
console.log(JSON.stringify(JSON.parse<f64[]>(`[
|
|
4
|
+
1,
|
|
5
|
+
2,
|
|
6
|
+
3
|
|
7
|
+
]`)));
|
package/package.json
CHANGED
package/transform/lib/index.js
CHANGED
|
@@ -123,7 +123,7 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
125
|
else {
|
|
126
|
-
this.currentClass.encodeStmts.push(`${encodeKey(aliasName)}:\${
|
|
126
|
+
this.currentClass.encodeStmts.push(`${encodeKey(aliasName)}:\${__JSON_Stringify<${type}>(this.${name})},`);
|
|
127
127
|
// @ts-ignore
|
|
128
128
|
this.currentClass.setDataStmts.push(`if (key.equals(${JSON.stringify(aliasName)})) {
|
|
129
129
|
this.${name} = __parseObjectValue<${type}>(val_start ? data.slice(val_start, val_end) : data, initializeDefaultValues);
|
|
@@ -194,11 +194,11 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
194
194
|
//
|
|
195
195
|
// const stmt = SimpleParser.parseTopLevelStatement('import { Virtual as __Virtual } from "as-virtual/assembly";');
|
|
196
196
|
// ... So we have to do it the long way:
|
|
197
|
-
const
|
|
198
|
-
const
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
const stmt =
|
|
197
|
+
const txt = 'import { Virtual as __Virtual } from "as-virtual/assembly";';
|
|
198
|
+
const tokenizer = new Tokenizer(new Source(0 /* SourceKind.User */, node.normalizedPath, txt));
|
|
199
|
+
const parser = new Parser();
|
|
200
|
+
parser.currentSource = tokenizer.source;
|
|
201
|
+
const stmt = parser.parseTopLevelStatement(tokenizer);
|
|
202
202
|
// Add the import statement to the top of the source.
|
|
203
203
|
node.statements.unshift(stmt);
|
|
204
204
|
}
|
package/transform/package.json
CHANGED
package/transform/src/index.ts
CHANGED
|
@@ -156,7 +156,7 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
156
156
|
}
|
|
157
157
|
} else {
|
|
158
158
|
this.currentClass.encodeStmts.push(
|
|
159
|
-
`${encodeKey(aliasName)}:\${
|
|
159
|
+
`${encodeKey(aliasName)}:\${__JSON_Stringify<${type}>(this.${name})},`
|
|
160
160
|
);
|
|
161
161
|
// @ts-ignore
|
|
162
162
|
this.currentClass.setDataStmts.push(
|
|
@@ -246,11 +246,11 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
246
246
|
// const stmt = SimpleParser.parseTopLevelStatement('import { Virtual as __Virtual } from "as-virtual/assembly";');
|
|
247
247
|
|
|
248
248
|
// ... So we have to do it the long way:
|
|
249
|
-
const
|
|
250
|
-
const
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
const stmt =
|
|
249
|
+
const txt = 'import { Virtual as __Virtual } from "as-virtual/assembly";'
|
|
250
|
+
const tokenizer = new Tokenizer(new Source(SourceKind.User, node.normalizedPath, txt));
|
|
251
|
+
const parser = new Parser();
|
|
252
|
+
parser.currentSource = tokenizer.source;
|
|
253
|
+
const stmt = parser.parseTopLevelStatement(tokenizer)!;
|
|
254
254
|
|
|
255
255
|
// Add the import statement to the top of the source.
|
|
256
256
|
node.statements.unshift(stmt);
|