# 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)