@@ -129,3 +129,61 @@ external stringify: t -> string = "stringify"
129
129
[@@ bs.val] [@@ bs.scope "JSON" ]
130
130
external stringifyWithSpace : t -> (_ [@ bs.as {json| null| json}]) -> int -> string = " stringify"
131
131
[@@ bs.val] [@@ bs.scope "JSON" ]
132
+
133
+
134
+ (* in memory modification does not work until your root is
135
+ actually None, so we need wrap it as `[v]` and
136
+ return the first element instead *)
137
+
138
+ let patch : _ -> _ = [% raw{| function (json) {
139
+ var x = [json];
140
+ var q = [{ kind : 0 , i : 0 , parent : x }];
141
+ while (q.length != = 0 ) {
142
+ // begin pop the stack
143
+ var cur = q[q.length - 1 ];
144
+ if (cur.kind === 0 ) {
145
+ cur.val = cur.parent[cur.i]; // patch the undefined value for array
146
+ if (++ cur.i === cur.parent.length) {
147
+ q.pop() ;
148
+ }
149
+ } else {
150
+ q.pop() ;
151
+ }
152
+ // finish
153
+ var task = cur.val;
154
+ if (typeof task === " object" ) {
155
+ if (Array. isArray(task) && task.length != = 0 ) {
156
+ q.push({ kind : 0 , i : 0 , parent : task , val : undefined });
157
+ } else {
158
+ for (var k in task) {
159
+ if (k === " RE_PRIVATE_NONE" ) {
160
+ if (cur.kind === 0 ) {
161
+ cur.parent[cur.i - 1 ] = undefined;
162
+ } else {
163
+ cur.parent[cur.i] = undefined;
164
+ }
165
+ continue;
166
+ }
167
+ q.push({ kind : 1 , i : k , parent : task , val : task [k] });
168
+ }
169
+ }
170
+ }
171
+ }
172
+ return x[0 ];
173
+ }
174
+ | }]
175
+
176
+
177
+ let serialize (type t ) (x : t ) : string option = [% raw{| function(obj){
178
+ return JSON. stringify(obj,function(_,value){
179
+ if (value=== undefined){
180
+ return {RE_PRIVATE_NONE : true }
181
+ }
182
+ return value
183
+ })
184
+ }
185
+ | }] x
186
+
187
+ let deserializeExn (s : string ) : 'a =
188
+ patch (parseExn s)
189
+
0 commit comments