Implement Table/OrderedTable support for json.to macro.
This commit is contained in:
parent
8ca41ce637
commit
8187e83645
2 changed files with 49 additions and 2 deletions
|
|
@ -1677,6 +1677,30 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
|
||||||
(
|
(
|
||||||
if `lenientJsonNode`.isNil: `workaround`[`optionGeneric`]() else: some[`optionGeneric`](`value`)
|
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":
|
of "ref":
|
||||||
# Ref type.
|
# Ref type.
|
||||||
var typeName = $typeSym[1]
|
var typeName = $typeSym[1]
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ discard """
|
||||||
file: "tjsonmacro.nim"
|
file: "tjsonmacro.nim"
|
||||||
output: ""
|
output: ""
|
||||||
"""
|
"""
|
||||||
import json, strutils, options
|
import json, strutils, options, tables
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
# Tests inspired by own use case (with some additional tests).
|
# Tests inspired by own use case (with some additional tests).
|
||||||
|
|
@ -315,5 +315,28 @@ when isMainModule:
|
||||||
doAssert noYearDeser.year.isNone
|
doAssert noYearDeser.year.isNone
|
||||||
doAssert noYearDeser.engine.name == "V8"
|
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
|
# TODO: JsonNode support
|
||||||
Loading…
Add table
Add a link
Reference in a new issue