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