Implement Table/OrderedTable support for json.to macro.

This commit is contained in:
Dominik Picheta
2017-11-29 20:30:40 +00:00
committed by Dominik Picheta
parent 8ca41ce637
commit 8187e83645
2 changed files with 49 additions and 2 deletions

View File

@@ -1677,6 +1677,30 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
(
if `lenientJsonNode`.isNil: `workaround`[`optionGeneric`]() else: some[`optionGeneric`](`value`)
)
of "table", "orderedtable":
let tableKeyType = typeSym[1]
if ($tableKeyType).cmpIgnoreStyle("string") != 0:
error("JSON doesn't support keys of type " & $tableKeyType)
let tableValueType = typeSym[2]
let forLoopKey = genSym(nskForVar, "key")
let indexerNode = createJsonIndexer(jsonNode, forLoopKey)
let constructorNode = createConstructor(tableValueType, indexerNode)
let tableInit =
if bracketName == "table":
bindSym("initTable")
else:
bindSym("initOrderedTable")
# Create a statement expression containing a for loop.
result = quote do:
(
var map = `tableInit`[`tableKeyType`, `tableValueType`]();
verifyJsonKind(`jsonNode`, {JObject}, astToStr(`jsonNode`));
for `forLoopKey` in keys(`jsonNode`.fields): map[`forLoopKey`] = `constructorNode`;
map
)
of "ref":
# Ref type.
var typeName = $typeSym[1]

View File

@@ -2,7 +2,7 @@ discard """
file: "tjsonmacro.nim"
output: ""
"""
import json, strutils, options
import json, strutils, options, tables
when isMainModule:
# Tests inspired by own use case (with some additional tests).
@@ -315,5 +315,28 @@ when isMainModule:
doAssert noYearDeser.year.isNone
doAssert noYearDeser.engine.name == "V8"
# TODO: Table[T, Y] support.
# Table[T, Y] support.
block:
type
Friend = object
name: string
age: int
Dynamic = object
name: string
friends: Table[string, Friend]
let data = """
{"friends": {
"John": {"name": "John", "age": 35},
"Elizabeth": {"name": "Elizabeth", "age": 23}
}, "name": "Dominik"}
"""
let dataParsed = parseJson(data)
let dataDeser = to(dataParsed, Dynamic)
doAssert dataDeser.name == "Dominik"
doAssert dataDeser.friends["John"].age == 35
doAssert dataDeser.friends["Elizabeth"].age == 23
# TODO: JsonNode support