73 lines
2.2 KiB
Nim
73 lines
2.2 KiB
Nim
|
# SPDX-FileCopyrightText: 2021 ☭ Emery Hemingway
|
||
|
# SPDX-License-Identifier: ISC
|
||
|
|
||
|
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.dict[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.pairs:
|
||
|
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")
|