json-as 1.1.7 → 1.1.8
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.md +4 -0
- package/README.md +1 -1
- package/assembly/index.ts +137 -2
- package/assembly/test.ts +233 -159
- package/lib/as-bs.ts +55 -0
- package/package.json +2 -2
- package/transform/lib/index.js +38 -4
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/types.js +1 -0
- package/transform/lib/types.js.map +1 -1
- package/transform/lib/util.js +69 -0
- package/transform/lib/util.js.map +1 -1
- package/transform/src/index.ts +95 -7
- package/transform/src/types.ts +1 -0
- package/transform/src/util.ts +78 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 2025-05-27 - 1.1.8
|
|
4
|
+
|
|
5
|
+
- feat: add support for calling `JSON.stringify/JSON.parse` methods inside of custom serializers, but not yet deserializers
|
|
6
|
+
|
|
3
7
|
## 2025-05-27 - 1.1.7
|
|
4
8
|
|
|
5
9
|
- fix: bad boolean logic to decide whether to add 2nd break statement
|
package/README.md
CHANGED
package/assembly/index.ts
CHANGED
|
@@ -424,7 +424,7 @@ export namespace JSON {
|
|
|
424
424
|
// @ts-ignore: type
|
|
425
425
|
private storage: Map<string, JSON.Value> = new Map<string, JSON.Value>();
|
|
426
426
|
|
|
427
|
-
constructor() {}
|
|
427
|
+
constructor() { }
|
|
428
428
|
|
|
429
429
|
// @ts-ignore: decorator
|
|
430
430
|
@inline get size(): i32 {
|
|
@@ -515,6 +515,12 @@ export namespace JSON {
|
|
|
515
515
|
}
|
|
516
516
|
}
|
|
517
517
|
|
|
518
|
+
/**
|
|
519
|
+
* Serializes JSON data but writes directly to the buffer.
|
|
520
|
+
* Should only be used if you know what you are doing.
|
|
521
|
+
* @param src - T
|
|
522
|
+
* @returns void
|
|
523
|
+
*/
|
|
518
524
|
export function __serialize<T>(src: T): void {
|
|
519
525
|
if (isBoolean<T>()) {
|
|
520
526
|
serializeBool(src as bool);
|
|
@@ -565,6 +571,14 @@ export namespace JSON {
|
|
|
565
571
|
}
|
|
566
572
|
}
|
|
567
573
|
|
|
574
|
+
/**
|
|
575
|
+
* Deserializes JSON data directly from the buffer.
|
|
576
|
+
* Should only be used if you know what you are doing.
|
|
577
|
+
* @param srcStart - usize
|
|
578
|
+
* @param srcEnd - usize
|
|
579
|
+
* @param dst - usize
|
|
580
|
+
* @returns void
|
|
581
|
+
*/
|
|
568
582
|
export function __deserialize<T>(srcStart: usize, srcEnd: usize, dst: usize = 0): T {
|
|
569
583
|
if (isBoolean<T>()) {
|
|
570
584
|
// @ts-ignore: type
|
|
@@ -612,7 +626,7 @@ export namespace JSON {
|
|
|
612
626
|
}
|
|
613
627
|
throw new Error(`Could not deserialize data '${ptrToStr(srcStart, srcEnd).slice(0, 100)}' to type. Make sure to add the correct decorators to classes.`);
|
|
614
628
|
}
|
|
615
|
-
|
|
629
|
+
namespace Util {
|
|
616
630
|
// @ts-ignore: decorator
|
|
617
631
|
@inline export function isSpace(code: u16): boolean {
|
|
618
632
|
return code == 0x20 || code - 9 <= 4;
|
|
@@ -625,6 +639,127 @@ export namespace JSON {
|
|
|
625
639
|
return changetype<string>(out);
|
|
626
640
|
}
|
|
627
641
|
}
|
|
642
|
+
/**
|
|
643
|
+
* Methods for use when using JSON methods inside another JSON method or custom serializer/deserializer.
|
|
644
|
+
*/
|
|
645
|
+
export namespace internal {
|
|
646
|
+
/**
|
|
647
|
+
* Serializes JSON data. Don't use this directly, use `JSON.stringify` instead.
|
|
648
|
+
* @param data - T
|
|
649
|
+
* @param out - string | null
|
|
650
|
+
* @returns - string
|
|
651
|
+
*/
|
|
652
|
+
// @ts-ignore: inline
|
|
653
|
+
@inline export function stringify<T>(data: T, out: string | null = null): string {
|
|
654
|
+
if (isBoolean<T>()) {
|
|
655
|
+
if (out) {
|
|
656
|
+
if (<bool>data == true) {
|
|
657
|
+
out = changetype<string>(__renew(changetype<usize>(out), 8));
|
|
658
|
+
store<u64>(changetype<usize>(out), 28429475166421108);
|
|
659
|
+
} else {
|
|
660
|
+
out = changetype<string>(__renew(changetype<usize>(out), 10));
|
|
661
|
+
store<u64>(changetype<usize>(out), 32370086184550502);
|
|
662
|
+
store<u16>(changetype<usize>(out), 101, 8);
|
|
663
|
+
}
|
|
664
|
+
return out;
|
|
665
|
+
}
|
|
666
|
+
return data ? "true" : "false";
|
|
667
|
+
} else if (isInteger<T>() && !isSigned<T>() && nameof<T>() == "usize" && data == 0) {
|
|
668
|
+
if (out) {
|
|
669
|
+
out = changetype<string>(__renew(changetype<usize>(out), 8));
|
|
670
|
+
store<u64>(changetype<usize>(out), 30399761348886638);
|
|
671
|
+
return out;
|
|
672
|
+
}
|
|
673
|
+
return NULL_WORD;
|
|
674
|
+
} else if (isInteger<T>(data)) {
|
|
675
|
+
if (out) {
|
|
676
|
+
out = changetype<string>(__renew(changetype<usize>(out), sizeof<T>() << 3));
|
|
677
|
+
|
|
678
|
+
// @ts-ignore
|
|
679
|
+
const bytes = itoa_buffered(changetype<usize>(out), data) << 1;
|
|
680
|
+
return (out = changetype<string>(__renew(changetype<usize>(out), bytes)));
|
|
681
|
+
}
|
|
682
|
+
return data.toString();
|
|
683
|
+
} else if (isFloat<T>(data)) {
|
|
684
|
+
if (out) {
|
|
685
|
+
out = changetype<string>(__renew(changetype<usize>(out), 64));
|
|
686
|
+
|
|
687
|
+
// @ts-ignore
|
|
688
|
+
const bytes = dtoa_buffered(changetype<usize>(out), data) << 1;
|
|
689
|
+
return (out = changetype<string>(__renew(changetype<usize>(out), bytes)));
|
|
690
|
+
}
|
|
691
|
+
return data.toString();
|
|
692
|
+
// @ts-ignore: Function is generated by transform
|
|
693
|
+
} else if (isNullable<T>() && changetype<usize>(data) == <usize>0) {
|
|
694
|
+
if (out) {
|
|
695
|
+
out = changetype<string>(__renew(changetype<usize>(out), 8));
|
|
696
|
+
store<u64>(changetype<usize>(out), 30399761348886638);
|
|
697
|
+
return out;
|
|
698
|
+
}
|
|
699
|
+
return NULL_WORD;
|
|
700
|
+
// @ts-ignore
|
|
701
|
+
} else if (isString<nonnull<T>>()) {
|
|
702
|
+
// if (out) {
|
|
703
|
+
// out = changetype<string>(__renew(changetype<usize>(out), bytes(data) + 4));
|
|
704
|
+
// // const oldSize = bs.byteLength;
|
|
705
|
+
// const oldBuf = bs.buffer;
|
|
706
|
+
// const newSize = bytes(data) + 4;
|
|
707
|
+
// const newBuf = __new(newSize, idof<string>());
|
|
708
|
+
// bs.setBuffer(newBuf);
|
|
709
|
+
// serializeString(changetype<string>(data));
|
|
710
|
+
// bs.setBuffer(oldBuf);
|
|
711
|
+
// return changetype<string>(newBuf);
|
|
712
|
+
// }
|
|
713
|
+
// if (ASC_FEATURE_SIMD) {
|
|
714
|
+
// serializeString_SIMD(data as string);
|
|
715
|
+
// } else {
|
|
716
|
+
bs.saveState();
|
|
717
|
+
serializeString(data as string);
|
|
718
|
+
// }
|
|
719
|
+
return bs.cpyOut<string>();
|
|
720
|
+
// @ts-ignore: Supplied by transform
|
|
721
|
+
} else if (isDefined(data.__SERIALIZE)) {
|
|
722
|
+
bs.saveState();
|
|
723
|
+
// @ts-ignore
|
|
724
|
+
inline.always(data.__SERIALIZE(changetype<usize>(data)));
|
|
725
|
+
return bs.cpyOut<string>();
|
|
726
|
+
// @ts-ignore: Supplied by transform
|
|
727
|
+
} else if (data instanceof Date) {
|
|
728
|
+
out = out ? changetype<string>(__renew(changetype<usize>(out), 52)) : changetype<string>(__new(52, idof<string>()));
|
|
729
|
+
|
|
730
|
+
store<u16>(changetype<usize>(out), QUOTE);
|
|
731
|
+
memory.copy(changetype<usize>(out) + 2, changetype<usize>(data.toISOString()), 48);
|
|
732
|
+
store<u16>(changetype<usize>(out), QUOTE, 50);
|
|
733
|
+
return changetype<string>(out);
|
|
734
|
+
} else if (data instanceof Array) {
|
|
735
|
+
bs.saveState();
|
|
736
|
+
// @ts-ignore
|
|
737
|
+
inline.always(serializeArray(changetype<nonnull<T>>(data)));
|
|
738
|
+
return bs.cpyOut<string>();
|
|
739
|
+
} else if (data instanceof Map) {
|
|
740
|
+
bs.saveState();
|
|
741
|
+
// @ts-ignore
|
|
742
|
+
inline.always(serializeMap(changetype<nonnull<T>>(data)));
|
|
743
|
+
return bs.cpyOut<string>();
|
|
744
|
+
} else if (data instanceof JSON.Raw) {
|
|
745
|
+
bs.saveState();
|
|
746
|
+
serializeRaw(data);
|
|
747
|
+
return bs.cpyOut<string>();
|
|
748
|
+
} else if (data instanceof JSON.Value) {
|
|
749
|
+
bs.saveState();
|
|
750
|
+
inline.always(serializeArbitrary(data));
|
|
751
|
+
return bs.cpyOut<string>();
|
|
752
|
+
} else if (data instanceof JSON.Obj) {
|
|
753
|
+
bs.saveState();
|
|
754
|
+
inline.always(serializeObject(data));
|
|
755
|
+
return bs.cpyOut<string>();
|
|
756
|
+
} else if (data instanceof JSON.Box) {
|
|
757
|
+
return JSON.internal.stringify(data.value);
|
|
758
|
+
} else {
|
|
759
|
+
throw new Error(`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
}
|
|
628
763
|
}
|
|
629
764
|
|
|
630
765
|
// @ts-ignore: decorator
|
package/assembly/test.ts
CHANGED
|
@@ -1,218 +1,292 @@
|
|
|
1
1
|
import { JSON } from ".";
|
|
2
2
|
import { bytes } from "./util";
|
|
3
3
|
|
|
4
|
-
@json
|
|
5
|
-
class Obj {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
4
|
+
// @json
|
|
5
|
+
// class Obj {
|
|
6
|
+
// public a: string = "hello";
|
|
7
|
+
// public b: string = "world";
|
|
8
|
+
// public c: string = '"\t\f\u0000\u0001';
|
|
9
|
+
// }
|
|
10
|
+
|
|
11
|
+
// @json
|
|
12
|
+
// class Vec3 {
|
|
13
|
+
// x: f32 = 0.0;
|
|
14
|
+
// y: f32 = 0.0;
|
|
15
|
+
// z: f32 = 0.0;
|
|
16
|
+
// }
|
|
17
|
+
|
|
18
|
+
// @json
|
|
19
|
+
// class Player {
|
|
20
|
+
// @alias("first name")
|
|
21
|
+
// firstName!: string;
|
|
22
|
+
// lastName!: string;
|
|
23
|
+
// lastActive!: i32[];
|
|
24
|
+
// // Drop in a code block, function, or expression that evaluates to a boolean
|
|
25
|
+
// @omitif((self: Player) => self.age < 18)
|
|
26
|
+
// age!: i32;
|
|
27
|
+
|
|
28
|
+
// @omitnull()
|
|
29
|
+
// pos!: Vec3 | null;
|
|
30
|
+
// isVerified!: boolean;
|
|
31
|
+
// }
|
|
32
|
+
|
|
33
|
+
// @json
|
|
34
|
+
// class Point { }
|
|
35
|
+
|
|
36
|
+
// @json
|
|
37
|
+
// class NewPoint {
|
|
38
|
+
// x: f64 = 0.0;
|
|
39
|
+
// y: f64 = 0.0;
|
|
40
|
+
// constructor(x: f64, y: f64) {
|
|
41
|
+
// this.x = x;
|
|
42
|
+
// this.y = y;
|
|
43
|
+
// }
|
|
10
44
|
|
|
11
|
-
@
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
z: f32 = 0.0;
|
|
16
|
-
}
|
|
45
|
+
// @serializer
|
|
46
|
+
// serializer(self: NewPoint): string {
|
|
47
|
+
// return `x=${self.x},y=${self.y}`;
|
|
48
|
+
// }
|
|
17
49
|
|
|
18
|
-
@
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
firstName!: string;
|
|
22
|
-
lastName!: string;
|
|
23
|
-
lastActive!: i32[];
|
|
24
|
-
// Drop in a code block, function, or expression that evaluates to a boolean
|
|
25
|
-
@omitif((self: Player) => self.age < 18)
|
|
26
|
-
age!: i32;
|
|
27
|
-
|
|
28
|
-
@omitnull()
|
|
29
|
-
pos!: Vec3 | null;
|
|
30
|
-
isVerified!: boolean;
|
|
31
|
-
}
|
|
50
|
+
// @deserializer
|
|
51
|
+
// deserializer(data: string): NewPoint {
|
|
52
|
+
// const dataSize = bytes(data);
|
|
32
53
|
|
|
33
|
-
|
|
34
|
-
|
|
54
|
+
// const c = data.indexOf(",");
|
|
55
|
+
// const x = data.slice(2, c);
|
|
56
|
+
// const y = data.slice(c + 3);
|
|
35
57
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
y: f64 = 0.0;
|
|
40
|
-
constructor(x: f64, y: f64) {
|
|
41
|
-
this.x = x;
|
|
42
|
-
this.y = y;
|
|
43
|
-
}
|
|
58
|
+
// return new NewPoint(f64.parse(x), f64.parse(y));
|
|
59
|
+
// }
|
|
60
|
+
// }
|
|
44
61
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
62
|
+
// @json
|
|
63
|
+
// class InnerObj<T> {
|
|
64
|
+
// obj: T = instantiate<T>();
|
|
65
|
+
// }
|
|
49
66
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
67
|
+
// @json
|
|
68
|
+
// class ObjWithBracketString {
|
|
69
|
+
// data: string = "";
|
|
70
|
+
// }
|
|
53
71
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
72
|
+
// const player: Player = {
|
|
73
|
+
// firstName: "Jairus",
|
|
74
|
+
// lastName: "Tanaka",
|
|
75
|
+
// lastActive: [2, 7, 2025],
|
|
76
|
+
// age: 18,
|
|
77
|
+
// pos: {
|
|
78
|
+
// x: 3.4,
|
|
79
|
+
// y: 1.2,
|
|
80
|
+
// z: 8.3,
|
|
81
|
+
// },
|
|
82
|
+
// isVerified: true,
|
|
83
|
+
// };
|
|
57
84
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
85
|
+
// const a1 = JSON.stringify("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f\u000f\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f");
|
|
86
|
+
// // console.log("Bytes " + bytes(a1).toString());
|
|
87
|
+
// console.log("a1: " + a1);
|
|
61
88
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
89
|
+
// const obj = new Obj();
|
|
90
|
+
// const a2 = JSON.stringify(obj);
|
|
91
|
+
// // console.log("Bytes " + bytes(a2).toString());
|
|
92
|
+
// console.log("a2: " + a2);
|
|
66
93
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
94
|
+
// const a3 = JSON.stringify(player);
|
|
95
|
+
// // console.log("Bytes " + bytes(a3).toString());
|
|
96
|
+
// console.log("a3: " + a3);
|
|
71
97
|
|
|
72
|
-
const
|
|
73
|
-
firstName: "Jairus",
|
|
74
|
-
lastName: "Tanaka",
|
|
75
|
-
lastActive: [2, 7, 2025],
|
|
76
|
-
age: 18,
|
|
77
|
-
pos: {
|
|
78
|
-
x: 3.4,
|
|
79
|
-
y: 1.2,
|
|
80
|
-
z: 8.3,
|
|
81
|
-
},
|
|
82
|
-
isVerified: true,
|
|
83
|
-
};
|
|
98
|
+
// const a4 = new JSON.Obj();
|
|
84
99
|
|
|
85
|
-
|
|
86
|
-
//
|
|
87
|
-
|
|
100
|
+
// a4.set("x", 1.5);
|
|
101
|
+
// a4.set("y", 5.4);
|
|
102
|
+
// a4.set("z", 9.8);
|
|
103
|
+
// a4.set("obj", obj);
|
|
104
|
+
// a4.set<boolean>("bool", false);
|
|
105
|
+
|
|
106
|
+
// console.log("a4: " + JSON.stringify(a4));
|
|
107
|
+
|
|
108
|
+
// const a5 = JSON.parse<JSON.Obj>('{"foo":"bar"}');
|
|
88
109
|
|
|
89
|
-
|
|
90
|
-
const a2 = JSON.stringify(obj);
|
|
91
|
-
// console.log("Bytes " + bytes(a2).toString());
|
|
92
|
-
console.log("a2: " + a2);
|
|
110
|
+
// console.log("a5: " + JSON.stringify(a5));
|
|
93
111
|
|
|
94
|
-
const
|
|
95
|
-
// console.log("Bytes " + bytes(a3).toString());
|
|
96
|
-
console.log("a3: " + a3);
|
|
112
|
+
// const a6 = JSON.parse<JSON.Obj>('{"x":1.5,"y":5.4,"z":9.8,"obj":{"foo":"bar"}}');
|
|
97
113
|
|
|
98
|
-
|
|
114
|
+
// console.log("a6: " + JSON.stringify(a6));
|
|
99
115
|
|
|
100
|
-
|
|
101
|
-
a4.set("y", 5.4);
|
|
102
|
-
a4.set("z", 9.8);
|
|
103
|
-
a4.set("obj", obj);
|
|
104
|
-
a4.set<boolean>("bool", false);
|
|
116
|
+
// const a7 = JSON.parse<JSON.Value[]>('["string",true,3.14,{"x":1.0,"y":2.0,"z":3.0},[1,2,3,true]]');
|
|
105
117
|
|
|
106
|
-
console.log("
|
|
118
|
+
// console.log("a7: " + JSON.stringify(a7));
|
|
107
119
|
|
|
108
|
-
const
|
|
120
|
+
// const a8 = JSON.stringify(["hello", JSON.stringify("world"), "working?"]);
|
|
109
121
|
|
|
110
|
-
console.log("
|
|
122
|
+
// console.log("a8: " + a8);
|
|
111
123
|
|
|
112
|
-
const
|
|
124
|
+
// const a9 = JSON.stringify<JSON.Raw>(JSON.Raw.from('"hello world"'));
|
|
113
125
|
|
|
114
|
-
console.log("
|
|
126
|
+
// console.log("a9: " + a9);
|
|
115
127
|
|
|
116
|
-
const
|
|
128
|
+
// const m10 = new Map<string, JSON.Raw>();
|
|
129
|
+
// m10.set("hello", new JSON.Raw('"world"'));
|
|
130
|
+
// m10.set("pos", new JSON.Raw('{"x":1.0,"y":2.0,"z":3.0}'));
|
|
117
131
|
|
|
118
|
-
|
|
132
|
+
// const a10 = JSON.stringify(m10);
|
|
119
133
|
|
|
120
|
-
|
|
134
|
+
// console.log("a10: " + a10);
|
|
121
135
|
|
|
122
|
-
|
|
136
|
+
// const a11 = JSON.parse<JSON.Obj>(' { "x" : 3.4 , "y" : 1.2 , "z" : 8.3 } ');
|
|
123
137
|
|
|
124
|
-
|
|
138
|
+
// console.log("a11: " + JSON.stringify(a11));
|
|
125
139
|
|
|
126
|
-
|
|
140
|
+
// const a12 = JSON.parse<InnerObj<ObjWithBracketString>>('{"obj":{"data":"hello} world"}}');
|
|
127
141
|
|
|
128
|
-
|
|
129
|
-
m10.set("hello", new JSON.Raw('"world"'));
|
|
130
|
-
m10.set("pos", new JSON.Raw('{"x":1.0,"y":2.0,"z":3.0}'));
|
|
142
|
+
// console.log("a12: " + JSON.stringify(a12));
|
|
131
143
|
|
|
132
|
-
const
|
|
144
|
+
// const a13 = JSON.stringify<JSON.Obj>(new JSON.Obj());
|
|
133
145
|
|
|
134
|
-
console.log("
|
|
146
|
+
// console.log("a13: " + a13);
|
|
135
147
|
|
|
136
|
-
const
|
|
148
|
+
// const a14 = JSON.stringify(new Point());
|
|
149
|
+
// console.log("a14: " + a14);
|
|
137
150
|
|
|
138
|
-
|
|
151
|
+
// const a15 = JSON.parse<Point>(a14);
|
|
152
|
+
// console.log("a15: " + JSON.stringify(a15));
|
|
139
153
|
|
|
140
|
-
const
|
|
154
|
+
// const a16 = JSON.stringify(new NewPoint(1.0, 2.0));
|
|
155
|
+
// console.log("a16: " + a16);
|
|
141
156
|
|
|
142
|
-
|
|
157
|
+
// const a17 = JSON.parse<NewPoint>(a16);
|
|
158
|
+
// console.log("a17: " + JSON.stringify(a17));
|
|
143
159
|
|
|
144
|
-
const
|
|
160
|
+
// const a18 = JSON.parse<JSON.Obj[]>('[{"x":1.0,"y":2.0,"z":3.0},{"x":4.0,"y":5.0,"z":6.0},{"x":7.0,"y":8.0,"z":9.0}]');
|
|
161
|
+
// console.log("a18: " + JSON.stringify(a18));
|
|
145
162
|
|
|
146
|
-
|
|
163
|
+
// const a19 = JSON.stringify<JSON.Obj[]>(a18);
|
|
164
|
+
// console.log("a19: " + a19);
|
|
147
165
|
|
|
148
|
-
const
|
|
149
|
-
console.log("
|
|
166
|
+
// const a20 = JSON.parse<JSON.Box<f64>[]>("[1.3,4.7,9.5]");
|
|
167
|
+
// console.log("a20: " + JSON.stringify(a20));
|
|
150
168
|
|
|
151
|
-
const
|
|
152
|
-
console.log("
|
|
169
|
+
// const a21 = JSON.stringify<JSON.Box<f64>[]>(a20);
|
|
170
|
+
// console.log("a21: " + a21);
|
|
153
171
|
|
|
154
|
-
const
|
|
155
|
-
console.log("
|
|
172
|
+
// const a22 = JSON.parse<Foo>('{"id":"0xb8","firstName":"Jairus","lastName":"Tanaka"}');
|
|
173
|
+
// console.log("a22: " + JSON.stringify(a22));
|
|
156
174
|
|
|
157
|
-
const a17 = JSON.parse<NewPoint>(a16);
|
|
158
|
-
console.log("a17: " + JSON.stringify(a17));
|
|
159
175
|
|
|
160
|
-
|
|
161
|
-
|
|
176
|
+
// @json
|
|
177
|
+
// class Foo {
|
|
178
|
+
// id: string = "";
|
|
179
|
+
// firstName: string = "";
|
|
180
|
+
// lastName: string = "";
|
|
181
|
+
// }
|
|
162
182
|
|
|
163
|
-
|
|
164
|
-
|
|
183
|
+
// @json
|
|
184
|
+
// class SrvInfo {
|
|
185
|
+
// accessUrl: string = "https://example.com";
|
|
186
|
+
// cardTypes: i32[] = [1, 2, 3];
|
|
187
|
+
// customService: string = "Contact us at support@example.com";
|
|
188
|
+
// invoiceApplicationStatus: i32 = 1;
|
|
189
|
+
// isCertification: bool = true;
|
|
190
|
+
// isOnlineRecharge: bool = false;
|
|
191
|
+
// loginTypes: i32[] = [0, 1]; // e.g. 0 = password, 1 = OTP
|
|
192
|
+
// record: string = "ICP 12345678";
|
|
193
|
+
// regCompanyAudit: i32 = 2;
|
|
194
|
+
// regCompanyPipeline: i32[] = [101, 102, 103];
|
|
195
|
+
// regPwdLimit: i32 = 8; // min password length
|
|
196
|
+
// serverTime: i64 = 1650000000000; // dummy timestamp
|
|
197
|
+
// srvDescription: string = "A demo service for handling customer operations.";
|
|
198
|
+
// srvHiddenMenu: string[] = ["admin", "beta"];
|
|
199
|
+
// srvHost: string = "srv.example.com";
|
|
200
|
+
// srvId: i32 = 999;
|
|
201
|
+
// srvKeywords: string[] = ["finance", "payments", "online"];
|
|
202
|
+
// srvLogoImgUrl: string = "https://example.com/logo.png";
|
|
203
|
+
// srvName: string = "ExampleService";
|
|
204
|
+
// srvPageId: i32 = 5;
|
|
205
|
+
// thirdAuthUrl: string = "https://auth.example.com";
|
|
206
|
+
// userCenterStyle: i32 = 1; // e.g. 1 = modern, 0 = legacy
|
|
207
|
+
// }
|
|
165
208
|
|
|
166
|
-
const
|
|
167
|
-
console.log("
|
|
209
|
+
// const a23 = JSON.stringify(new SrvInfo());
|
|
210
|
+
// console.log("a23: " + a23);
|
|
168
211
|
|
|
169
|
-
const
|
|
170
|
-
console.log("
|
|
212
|
+
// const a24 = '{"accessUrl":"https://example.com","cardTypes":[1,2,3],"customService":"Contact us at support@example.com","invoiceApplicationStatus":1,"isCertification":true,"isOnlineRecharge":false,"loginTypes":[0,1],"record":"ICP 12345678","regCompanyAudit":2,"regCompanyPipeline":[101,102,103],"regPwdLimit":8,"serverTime":1650000000000,"srvDescription":"A demo service for handling customer operations.","srvHiddenMenu":["admin","beta"],"srvHost":"srv.example.com","srvId":999,"srvKeywords":["finance","payments","online"],"srvLogoImgUrl":"https://example.com/logo.png","srvName":"ExampleService","srvPageId":5,"thirdAuthUrl":"https://auth.example.com","userCenterStyle":1}';
|
|
213
|
+
// console.log("a25: " + (a24 == a23).toString());
|
|
171
214
|
|
|
172
|
-
const
|
|
173
|
-
console.log("
|
|
215
|
+
// const a26 = JSON.parse<SrvInfo>(a23);
|
|
216
|
+
// console.log("a26: " + JSON.stringify(a26));
|
|
174
217
|
|
|
218
|
+
// console.log("a27: " + (JSON.stringify(a26) == a23).toString())
|
|
219
|
+
import {
|
|
220
|
+
bs
|
|
221
|
+
} from "../lib/as-bs"
|
|
175
222
|
|
|
176
223
|
@json
|
|
177
|
-
class
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
224
|
+
class GenericEnum<T> {
|
|
225
|
+
private tag: string = ""
|
|
226
|
+
private value: T | null = null
|
|
227
|
+
|
|
228
|
+
constructor() {
|
|
229
|
+
this.tag = ""
|
|
230
|
+
this.value = null
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
static create<T>(tag: string, value: T): GenericEnum<T> {
|
|
234
|
+
const item = new GenericEnum<T>()
|
|
235
|
+
item.tag = tag
|
|
236
|
+
item.value = value
|
|
237
|
+
return item
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
getTag(): string {
|
|
241
|
+
return this.tag
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
getValue(): T | null {
|
|
245
|
+
return this.value
|
|
246
|
+
}
|
|
247
|
+
@serializer
|
|
248
|
+
serialize<T>(self: GenericEnum<T>): string {
|
|
249
|
+
const tagJson = JSON.stringify(self.tag);
|
|
250
|
+
const valueJson = JSON.stringify(self.value);
|
|
251
|
+
return `{${tagJson}:${valueJson}}`
|
|
252
|
+
}
|
|
253
|
+
@deserializer
|
|
254
|
+
deserialize(data: string): GenericEnum<T> {
|
|
255
|
+
const parsed = JSON.parse<Map<string, JSON.Raw>>(data);
|
|
256
|
+
const result = new GenericEnum<T>();
|
|
257
|
+
|
|
258
|
+
const keys = parsed.keys();
|
|
259
|
+
const values = parsed.values();
|
|
260
|
+
|
|
261
|
+
result.tag = keys[0];
|
|
262
|
+
result.value = JSON.parse<T>(values[0].data);
|
|
263
|
+
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
181
266
|
}
|
|
182
267
|
|
|
183
268
|
@json
|
|
184
|
-
class
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
regCompanyPipeline: i32[] = [101, 102, 103];
|
|
195
|
-
regPwdLimit: i32 = 8; // min password length
|
|
196
|
-
serverTime: i64 = 1650000000000; // dummy timestamp
|
|
197
|
-
srvDescription: string = "A demo service for handling customer operations.";
|
|
198
|
-
srvHiddenMenu: string[] = ["admin", "beta"];
|
|
199
|
-
srvHost: string = "srv.example.com";
|
|
200
|
-
srvId: i32 = 999;
|
|
201
|
-
srvKeywords: string[] = ["finance", "payments", "online"];
|
|
202
|
-
srvLogoImgUrl: string = "https://example.com/logo.png";
|
|
203
|
-
srvName: string = "ExampleService";
|
|
204
|
-
srvPageId: i32 = 5;
|
|
205
|
-
thirdAuthUrl: string = "https://auth.example.com";
|
|
206
|
-
userCenterStyle: i32 = 1; // e.g. 1 = modern, 0 = legacy
|
|
269
|
+
class Node<T> {
|
|
270
|
+
name: string
|
|
271
|
+
id: u32
|
|
272
|
+
data: T
|
|
273
|
+
|
|
274
|
+
constructor() {
|
|
275
|
+
this.name = ""
|
|
276
|
+
this.id = 0
|
|
277
|
+
this.data = changetype<T>(0);
|
|
278
|
+
}
|
|
207
279
|
}
|
|
208
280
|
|
|
209
|
-
const
|
|
210
|
-
console.log("a23: " + a23);
|
|
281
|
+
const enumValue = GenericEnum.create<string>("success", "Hello World")
|
|
211
282
|
|
|
212
|
-
const
|
|
213
|
-
|
|
283
|
+
const node = new Node<GenericEnum<string>>();
|
|
284
|
+
node.name = "test-node";
|
|
285
|
+
node.id = 42;
|
|
286
|
+
node.data = enumValue;
|
|
214
287
|
|
|
215
|
-
const
|
|
216
|
-
console.log("
|
|
288
|
+
const serialized = JSON.stringify(node);
|
|
289
|
+
console.log("Serialized Node: " + serialized);
|
|
217
290
|
|
|
218
|
-
|
|
291
|
+
const deserialized = JSON.parse<JSON.Obj>(serialized)
|
|
292
|
+
console.log("Deserialized Node: " + JSON.stringify(deserialized));
|