preserves-nim/src/preserves/jsonhooks.nim

95 lines
2.4 KiB
Nim

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