95 lines
2.4 KiB
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)
|