preserves-nim/src/preserves/jsonhooks.nim

73 lines
1.9 KiB
Nim

# SPDX-FileCopyrightText: 2021 ☭ Emery Hemingway
# SPDX-License-Identifier: Unlicense
import std/[json, tables]
import preserves
proc toPreserveHook*(js: JsonNode): Preserve =
case js.kind
of JString:
result = Preserve(kind: pkString, string: js.str)
of JInt:
result = Preserve(kind: pkSignedInteger, int: js.num)
of JFloat:
result = Preserve(kind: pkDouble, double: js.fnum)
of JBool:
result = case js.bval
of false: symbol"false"
of true: symbol"true"
of JNull:
result = symbol"null"
of JObject:
result = Preserve(kind: pkDictionary)
for key, val in js.fields.pairs:
result[Preserve(kind: pkString, string: key)] = toPreserveHook(val)
of JArray:
result = Preserve(kind: pkSequence,
sequence: newSeq[Preserve](js.elems.len))
for i, e in js.elems:
result.sequence[i] = toPreserveHook(e)
proc fromPreserveHook*(js: var JsonNode; prs: Preserve): bool =
case prs.kind:
of pkBoolean:
js = newJBool(prs.bool)
of pkFloat:
js = newJFloat(prs.float)
of pkDouble:
js = newJFloat(prs.double)
of pkSignedInteger:
js = newJInt(prs.int)
of pkString:
js = newJString(prs.string)
of pkSymbol:
case prs.symbol
of "false":
js = newJBool(false)
of "true":
js = newJBool(true)
of "null":
js = newJNull()
else:
return false
of pkSequence:
js = newJArray()
js.elems.setLen(prs.sequence.len)
for i, val in prs.sequence:
if not fromPreserve(js.elems[i], val):
return false
of pkDictionary:
js = newJObject()
for (key, val) in prs.dict.items:
if key.kind != pkString:
return false
var jsVal: JsonNode
if not fromPreserve(jsVal, val): return false
js[key.string] = jsVal
else: return false
true
proc toJsonHook*(pr: Preserve): JsonNode =
if not fromPreserve(result, pr):
raise newException(ValueError, "cannot convert Preserves value to JSON")