2021-08-28 09:31:33 +00:00
|
|
|
# SPDX-FileCopyrightText: 2021 ☭ Emery Hemingway
|
2021-08-31 15:00:00 +00:00
|
|
|
# SPDX-License-Identifier: Unlicense
|
2021-08-28 09:31:33 +00:00
|
|
|
|
|
|
|
import std/[json, tables]
|
2021-09-21 07:30:40 +00:00
|
|
|
import ../preserves
|
2021-08-28 09:31:33 +00:00
|
|
|
|
2021-09-23 13:20:06 +00:00
|
|
|
proc toPreserveHook*(js: JsonNode; E: typedesc): Preserve[E] =
|
2021-08-28 09:31:33 +00:00
|
|
|
case js.kind
|
|
|
|
of JString:
|
2021-09-23 13:20:06 +00:00
|
|
|
result = Preserve[E](kind: pkString, string: js.str)
|
2021-08-28 09:31:33 +00:00
|
|
|
of JInt:
|
2021-09-23 13:20:06 +00:00
|
|
|
result = Preserve[E](kind: pkSignedInteger, int: js.num)
|
2021-08-28 09:31:33 +00:00
|
|
|
of JFloat:
|
2021-09-23 13:20:06 +00:00
|
|
|
result = Preserve[E](kind: pkDouble, double: js.fnum)
|
2021-08-28 09:31:33 +00:00
|
|
|
of JBool:
|
|
|
|
result = case js.bval
|
2021-09-23 13:20:06 +00:00
|
|
|
of false: symbol[E]"false"
|
|
|
|
of true: symbol[E]"true"
|
2021-08-28 09:31:33 +00:00
|
|
|
of JNull:
|
2021-09-23 13:20:06 +00:00
|
|
|
result = symbol[E]"null"
|
2021-08-28 09:31:33 +00:00
|
|
|
of JObject:
|
2021-09-23 13:20:06 +00:00
|
|
|
result = Preserve[E](kind: pkDictionary)
|
2021-08-28 09:31:33 +00:00
|
|
|
for key, val in js.fields.pairs:
|
2021-09-23 13:20:06 +00:00
|
|
|
result[Preserve[E](kind: pkString, string: key)] = toPreserveHook(val, E)
|
2021-08-28 09:31:33 +00:00
|
|
|
of JArray:
|
2021-09-23 13:20:06 +00:00
|
|
|
result = Preserve[E](kind: pkSequence,
|
|
|
|
sequence: newSeq[Preserve[E]](js.elems.len))
|
2021-08-28 09:31:33 +00:00
|
|
|
for i, e in js.elems:
|
2021-09-23 13:20:06 +00:00
|
|
|
result.sequence[i] = toPreserveHook(e, E)
|
2021-08-28 09:31:33 +00:00
|
|
|
|
2021-09-23 13:20:06 +00:00
|
|
|
proc fromPreserveHook*[E](js: var JsonNode; prs: Preserve[E]): bool =
|
2021-08-28 09:31:33 +00:00
|
|
|
case prs.kind:
|
|
|
|
of pkBoolean:
|
2021-09-08 09:00:38 +00:00
|
|
|
js = newJBool(prs.bool)
|
2021-08-28 09:31:33 +00:00
|
|
|
of pkFloat:
|
2021-09-08 09:00:38 +00:00
|
|
|
js = newJFloat(prs.float)
|
2021-08-28 09:31:33 +00:00
|
|
|
of pkDouble:
|
2021-09-08 09:00:38 +00:00
|
|
|
js = newJFloat(prs.double)
|
2021-08-28 09:31:33 +00:00
|
|
|
of pkSignedInteger:
|
2021-09-08 09:00:38 +00:00
|
|
|
js = newJInt(prs.int)
|
2021-08-28 09:31:33 +00:00
|
|
|
of pkString:
|
2021-09-08 09:00:38 +00:00
|
|
|
js = newJString(prs.string)
|
2021-08-28 09:31:33 +00:00
|
|
|
of pkSymbol:
|
|
|
|
case prs.symbol
|
|
|
|
of "false":
|
2021-09-08 09:00:38 +00:00
|
|
|
js = newJBool(false)
|
2021-08-28 09:31:33 +00:00
|
|
|
of "true":
|
2021-09-08 09:00:38 +00:00
|
|
|
js = newJBool(true)
|
2021-08-28 09:31:33 +00:00
|
|
|
of "null":
|
2021-09-08 09:00:38 +00:00
|
|
|
js = newJNull()
|
2021-08-28 09:31:33 +00:00
|
|
|
else:
|
2021-09-08 09:00:38 +00:00
|
|
|
return false
|
2021-08-28 09:31:33 +00:00
|
|
|
of pkSequence:
|
2021-09-08 09:00:38 +00:00
|
|
|
js = newJArray()
|
|
|
|
js.elems.setLen(prs.sequence.len)
|
|
|
|
for i, val in prs.sequence:
|
|
|
|
if not fromPreserve(js.elems[i], val):
|
|
|
|
return false
|
2021-08-28 09:31:33 +00:00
|
|
|
of pkDictionary:
|
2021-09-08 09:00:38 +00:00
|
|
|
js = newJObject()
|
2021-08-28 10:48:50 +00:00
|
|
|
for (key, val) in prs.dict.items:
|
2021-08-28 09:31:33 +00:00
|
|
|
if key.kind != pkString:
|
2021-09-08 09:00:38 +00:00
|
|
|
return false
|
|
|
|
var jsVal: JsonNode
|
|
|
|
if not fromPreserve(jsVal, val): return false
|
|
|
|
js[key.string] = jsVal
|
|
|
|
else: return false
|
|
|
|
true
|
|
|
|
|
2021-09-23 13:20:06 +00:00
|
|
|
proc toJsonHook*[E](pr: Preserve[E]): JsonNode =
|
|
|
|
if not fromPreserveHook(result, pr):
|
2021-09-08 09:00:38 +00:00
|
|
|
raise newException(ValueError, "cannot convert Preserves value to JSON")
|
2021-09-23 13:20:06 +00:00
|
|
|
|
|
|
|
proc fromJsonHook*[E](pr: var Preserve[E]; js: JsonNode) =
|
|
|
|
pr = toPreserveHook(js, E)
|
|
|
|
|
|
|
|
when isMainModule:
|
|
|
|
var js = JsonNode()
|
|
|
|
var pr = js.toPreserveHook(void)
|
|
|
|
assert fromPreserveHook(js, pr)
|
|
|
|
fromJsonHook(pr, js)
|
|
|
|
js = toJsonHook(pr)
|