Move JSON specifics to preserves/jsonhooks

This commit is contained in:
Emery Hemingway 2021-08-28 11:31:33 +02:00
parent 5aaac95ca1
commit 41b1328e4e
3 changed files with 75 additions and 70 deletions

View File

@ -4,8 +4,7 @@
import bigints
import std/[base64, endians, hashes, options, sets, streams, strutils, tables, typetraits]
import json except `%`, `%*`
from std/json import escapeJson, escapeJsonUnquoted
from std/macros import hasCustomPragma, getCustomPragmaVal
type
@ -561,73 +560,6 @@ proc toPreserveHook*[A,B](table: Table[A,B]|TableRef[A,B]): Preserve =
result = Preserve(kind: pkDictionary, dict: initTable[Preserve, Preserve](table.len))
for k, v in table.pairs: result.dict[toPreserve k] = toPreserve v
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")
proc fromPreserve*[T](v: var T; prs: Preserve): bool =
## Inplace version of `preserveTo`.
## Partial matches on compond values may leave artifacts in ``v``.

View File

@ -0,0 +1,72 @@
# 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")

View File

@ -1,6 +1,7 @@
# SPDX-FileCopyrightText: 2021 ☭ Emery Hemingway
# SPDX-License-Identifier: ISC
import preserves
import preserves, preserves/jsonhooks
import std/[json,jsonutils,streams, unittest]
let testVectors = [