Skip to content

Commit d5eb1a8

Browse files
committed
provide a generic serialization mechanism
reasonably fast, best effort
1 parent 6f29ca8 commit d5eb1a8

File tree

6 files changed

+461
-221
lines changed

6 files changed

+461
-221
lines changed

jscomp/others/js_json.ml

+58
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,61 @@ external stringify: t -> string = "stringify"
129129
[@@bs.val] [@@bs.scope "JSON"]
130130
external stringifyWithSpace: t -> (_ [@bs.as {json|null|json}]) -> int -> string = "stringify"
131131
[@@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+

jscomp/others/js_json.mli

+5
Original file line numberDiff line numberDiff line change
@@ -237,3 +237,8 @@ Js.log \@\@ Js.Json.stringifyAny [| "foo"; "bar" |]
237237

238238

239239

240+
241+
val deserializeExn : string -> 'a
242+
243+
(** Best-effort serialization, it tries to seralize as many objects as possible and deserialize it back*)
244+
val serialize : 'a -> string option

0 commit comments

Comments
 (0)