diff options
-rw-r--r-- | lib/pure/json.nim | 28 | ||||
-rw-r--r-- | tests/stdlib/tjsonmacro.nim | 15 |
2 files changed, 37 insertions, 6 deletions
diff --git a/lib/pure/json.nim b/lib/pure/json.nim index cea485c43..1b887a0c5 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -1524,6 +1524,27 @@ proc processObjField(field, jsonNode: NimNode): seq[NimNode] = 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, jsonNode: NimNode, isRef: bool): NimNode {.compileTime.} = ## Process a type such as ``Sym "float"`` or ``ObjectTy ...``. @@ -1533,7 +1554,7 @@ proc processType(typeName: NimNode, obj: NimNode, ## .. code-block::plain ## ObjectTy ## Empty - ## Empty + ## InheritanceInformation ## RecList ## Sym "events" case obj.kind @@ -1543,10 +1564,7 @@ proc processType(typeName: NimNode, obj: NimNode, result.add(typeName) # Name of the type to construct. # Process each object field and add it as an exprColonExpr - expectKind(obj[2], nnkRecList) - for field in obj[2]: - let nodes = processObjField(field, jsonNode) - result.add(nodes) + result.add(processObjFields(obj, jsonNode)) # Object might be null. So we need to check for that. if isRef: diff --git a/tests/stdlib/tjsonmacro.nim b/tests/stdlib/tjsonmacro.nim index 153cf8556..2d20063ab 100644 --- a/tests/stdlib/tjsonmacro.nim +++ b/tests/stdlib/tjsonmacro.nim @@ -246,4 +246,17 @@ when isMainModule: var b = Bird(age: 3, height: 1.734, name: "bardo", colors: [red, blue]) let jnode = %b let data = jnode.to(Bird) - doAssert data == b \ No newline at end of file + 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" \ No newline at end of file |