59 lines
2.0 KiB
Nim
59 lines
2.0 KiB
Nim
# SPDX-FileCopyrightText: ☭ Emery Hemingway
|
|
# SPDX-License-Identifier: Unlicense
|
|
|
|
import std/[base64, json, parseutils, tables]
|
|
import preserves
|
|
|
|
proc toPreserveHook*(js: JsonNode; E: typedesc): Preserve[E] {.gcsafe.} =
|
|
case js.kind
|
|
of JString:
|
|
var off = js.str.skip("data:")
|
|
if off == 0:
|
|
result = Preserve[E](kind: pkString, string: js.str)
|
|
else:
|
|
var mime: string
|
|
off.inc js.str.parseUntil(mime, ';', off)
|
|
var dataOff = off + js.str.skip(";base64,", off)
|
|
if dataOff != off:
|
|
var data = cast[seq[byte]](substr(js.str, dataOff).decode)
|
|
result = initRecord("mime", mime.toSymbol(E), data.toPreserve(E))
|
|
else:
|
|
result = Preserve[E](kind: pkString, string: js.str)
|
|
of JInt:
|
|
result = Preserve[E](kind: pkSignedInteger, int: js.num)
|
|
of JFloat:
|
|
result = Preserve[E](kind: pkDouble, double: js.fnum)
|
|
of JBool:
|
|
result = case js.bval
|
|
of false: toSymbol("false", E)
|
|
of true: toSymbol("true", E)
|
|
of JNull:
|
|
result = toSymbol("null", E)
|
|
of JArray:
|
|
result = Preserve[E](kind: pkSequence,
|
|
sequence: newSeq[Preserve[E]](js.elems.len))
|
|
for i, e in js.elems:
|
|
result.sequence[i] = toPreserveHook(e, E)
|
|
of JObject:
|
|
if js.hasKey("type"):
|
|
var label = js.getOrDefault("type").getStr.toSymbol(E)
|
|
if js.len == 1:
|
|
result = initRecord(label)
|
|
elif js.len == 2:
|
|
for key, val in js.fields.pairs:
|
|
if key != "type":
|
|
result = initRecord(label, val.toPreserve(E))
|
|
else:
|
|
var dict = Preserve[E](kind: pkDictionary)
|
|
for key, val in js.fields.pairs:
|
|
if key != "type":
|
|
dict[Preserve[E](kind: pkString, string: key)] = toPreserveHook(val, E)
|
|
result = initRecord(label, dict)
|
|
elif js.len == 1:
|
|
for key, val in js.fields.pairs:
|
|
result = initRecord(key, val.toPreserve(E))
|
|
else:
|
|
result = Preserve[E](kind: pkDictionary)
|
|
for key, val in js.fields.pairs:
|
|
result[Preserve[E](kind: pkString, string: key)] = toPreserveHook(val, E)
|