# 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 toJsonHook*(prs: Preserve): JsonNode = case prs.kind: of pkBoolean: result = newJBool(prs.bool) of pkFloat: result = newJFloat(prs.float) of pkDouble: result = newJFloat(prs.double) of pkSignedInteger: result = newJInt(prs.int) of pkBigInteger: raise newException(ValueError, "cannot convert big integer to JSON") of pkString: result = newJString(prs.string) of pkByteString: raise newException(ValueError, "cannot convert bytes to JSON") of pkSymbol: case prs.symbol of "false": result = newJBool(false) of "true": result = newJBool(true) of "null": result = newJNull() else: raise newException(ValueError, "cannot convert symbol to JSON") of pkRecord: raise newException(ValueError, "cannot convert record to JSON") of pkSequence: result = newJArray() for val in prs.sequence: result.add(toJsonHook(val)) of pkSet: raise newException(ValueError, "cannot convert set to JSON") of pkDictionary: result = newJObject() for (key, val) in prs.dict.items: if key.kind != pkString: raise newException(ValueError, "cannot convert non-string dictionary key to JSON") result[key.string] = toJsonHook(val) of pkEmbedded: raise newException(ValueError, "cannot convert embedded value to JSON")