Fixes #5856. Code based on @loloiccl's PR (#5879).

This commit is contained in:
Dominik Picheta 2017-11-28 21:49:34 +00:00 • committed by Dominik Picheta
commit 11fcae5705
2 changed files with 37 additions and 6 deletions

View file

@ -1524,6 +1524,27 @@ proc processObjField(field, jsonNode: NimNode): seq[NimNode] =
doAssert result.len > 0 doAssert result.len > 0
proc processObjFields(obj: NimNode,
jsonNode: NimNode): seq[NimNode] {.compileTime.} =
## Process all the fields of an ``ObjectTy`` and any of its
## parent type's fields (via inheritance).
result = @[]
expectKind(obj[2], nnkRecList)
for field in obj[2]:
let nodes = processObjField(field, jsonNode)
result.add(nodes)
# process parent type fields
case obj[1].kind
of nnkBracketExpr:
assert $obj[1][0] == "ref"
result.add(processObjFields(getType(obj[1][1]), jsonNode))
of nnkSym:
result.add(processObjFields(getType(obj[1]), jsonNode))
else:
discard
proc processType(typeName: NimNode, obj: NimNode, proc processType(typeName: NimNode, obj: NimNode,
jsonNode: NimNode, isRef: bool): NimNode {.compileTime.} = jsonNode: NimNode, isRef: bool): NimNode {.compileTime.} =
## Process a type such as ``Sym "float"`` or ``ObjectTy ...``. ## Process a type such as ``Sym "float"`` or ``ObjectTy ...``.
@ -1533,7 +1554,7 @@ proc processType(typeName: NimNode, obj: NimNode,
## .. code-block::plain ## .. code-block::plain
## ObjectTy ## ObjectTy
## Empty ## Empty
## Empty ## InheritanceInformation
## RecList ## RecList
## Sym "events" ## Sym "events"
case obj.kind case obj.kind
@ -1543,10 +1564,7 @@ proc processType(typeName: NimNode, obj: NimNode,
result.add(typeName) # Name of the type to construct. result.add(typeName) # Name of the type to construct.
# Process each object field and add it as an exprColonExpr # Process each object field and add it as an exprColonExpr
expectKind(obj[2], nnkRecList) result.add(processObjFields(obj, jsonNode))
for field in obj[2]:
let nodes = processObjField(field, jsonNode)
result.add(nodes)
# Object might be null. So we need to check for that. # Object might be null. So we need to check for that.
if isRef: if isRef:

View file

@ -246,4 +246,17 @@ when isMainModule:
var b = Bird(age: 3, height: 1.734, name: "bardo", colors: [red, blue]) var b = Bird(age: 3, height: 1.734, name: "bardo", colors: [red, blue])
let jnode = %b let jnode = %b
let data = jnode.to(Bird) let data = jnode.to(Bird)
doAssert data == b doAssert data == b
block:
type
MsgBase = ref object of RootObj
name*: string
MsgChallenge = ref object of MsgBase
challenge*: string
let data = %*{"name": "foo", "challenge": "bar"}
let msg = data.to(MsgChallenge)
doAssert msg.name == "foo"
doAssert msg.challenge == "bar"