Fixes #6095.
This commit is contained in:
parent
11fcae5705
commit
e0681715dc
2 changed files with 52 additions and 21 deletions
|
|
@ -1524,26 +1524,34 @@ proc processObjField(field, jsonNode: NimNode): seq[NimNode] =
|
||||||
|
|
||||||
doAssert result.len > 0
|
doAssert result.len > 0
|
||||||
|
|
||||||
proc processObjFields(obj: NimNode,
|
proc processFields(obj: NimNode,
|
||||||
jsonNode: NimNode): seq[NimNode] {.compileTime.} =
|
jsonNode: NimNode): seq[NimNode] {.compileTime.} =
|
||||||
## Process all the fields of an ``ObjectTy`` and any of its
|
## Process all the fields of an ``ObjectTy`` and any of its
|
||||||
## parent type's fields (via inheritance).
|
## parent type's fields (via inheritance).
|
||||||
result = @[]
|
result = @[]
|
||||||
|
case obj.kind
|
||||||
|
of nnkObjectTy:
|
||||||
|
expectKind(obj[2], nnkRecList)
|
||||||
|
for field in obj[2]:
|
||||||
|
let nodes = processObjField(field, jsonNode)
|
||||||
|
result.add(nodes)
|
||||||
|
|
||||||
expectKind(obj[2], nnkRecList)
|
# process parent type fields
|
||||||
for field in obj[2]:
|
case obj[1].kind
|
||||||
let nodes = processObjField(field, jsonNode)
|
of nnkBracketExpr:
|
||||||
result.add(nodes)
|
assert $obj[1][0] == "ref"
|
||||||
|
result.add(processFields(getType(obj[1][1]), jsonNode))
|
||||||
# process parent type fields
|
of nnkSym:
|
||||||
case obj[1].kind
|
result.add(processFields(getType(obj[1]), jsonNode))
|
||||||
of nnkBracketExpr:
|
else:
|
||||||
assert $obj[1][0] == "ref"
|
discard
|
||||||
result.add(processObjFields(getType(obj[1][1]), jsonNode))
|
of nnkTupleTy:
|
||||||
of nnkSym:
|
for identDefs in obj:
|
||||||
result.add(processObjFields(getType(obj[1]), jsonNode))
|
expectKind(identDefs, nnkIdentDefs)
|
||||||
|
let nodes = processObjField(identDefs[0], jsonNode)
|
||||||
|
result.add(nodes)
|
||||||
else:
|
else:
|
||||||
discard
|
doAssert false, "Unable to process field type: " & $obj.kind
|
||||||
|
|
||||||
proc processType(typeName: NimNode, obj: NimNode,
|
proc processType(typeName: NimNode, obj: NimNode,
|
||||||
jsonNode: NimNode, isRef: bool): NimNode {.compileTime.} =
|
jsonNode: NimNode, isRef: bool): NimNode {.compileTime.} =
|
||||||
|
|
@ -1558,13 +1566,17 @@ proc processType(typeName: NimNode, obj: NimNode,
|
||||||
## RecList
|
## RecList
|
||||||
## Sym "events"
|
## Sym "events"
|
||||||
case obj.kind
|
case obj.kind
|
||||||
of nnkObjectTy:
|
of nnkObjectTy, nnkTupleTy:
|
||||||
# Create object constructor.
|
# Create object constructor.
|
||||||
result = newNimNode(nnkObjConstr)
|
result =
|
||||||
result.add(typeName) # Name of the type to construct.
|
if obj.kind == nnkObjectTy: newNimNode(nnkObjConstr)
|
||||||
|
else: newNimNode(nnkPar)
|
||||||
|
|
||||||
# Process each object field and add it as an exprColonExpr
|
if obj.kind == nnkObjectTy:
|
||||||
result.add(processObjFields(obj, jsonNode))
|
result.add(typeName) # Name of the type to construct.
|
||||||
|
|
||||||
|
# Process each object/tuple field and add it as an exprColonExpr
|
||||||
|
result.add(processFields(obj, jsonNode))
|
||||||
|
|
||||||
# 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:
|
||||||
|
|
@ -1687,6 +1699,8 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
|
||||||
result = createConstructor(obj, jsonNode)
|
result = createConstructor(obj, jsonNode)
|
||||||
else:
|
else:
|
||||||
result = processType(typeSym, obj, jsonNode, false)
|
result = processType(typeSym, obj, jsonNode, false)
|
||||||
|
of nnkTupleTy:
|
||||||
|
result = processType(typeSym, typeSym, jsonNode, false)
|
||||||
else:
|
else:
|
||||||
doAssert false, "Unable to create constructor for: " & $typeSym.kind
|
doAssert false, "Unable to create constructor for: " & $typeSym.kind
|
||||||
|
|
||||||
|
|
@ -1818,6 +1832,7 @@ macro to*(node: JsonNode, T: typedesc): untyped =
|
||||||
# TODO: Rename postProcessValue and move it (?)
|
# TODO: Rename postProcessValue and move it (?)
|
||||||
result = postProcessValue(result)
|
result = postProcessValue(result)
|
||||||
|
|
||||||
|
# echo(treeRepr(result))
|
||||||
# echo(toStrLit(result))
|
# echo(toStrLit(result))
|
||||||
|
|
||||||
when false:
|
when false:
|
||||||
|
|
|
||||||
|
|
@ -260,3 +260,19 @@ when isMainModule:
|
||||||
let msg = data.to(MsgChallenge)
|
let msg = data.to(MsgChallenge)
|
||||||
doAssert msg.name == "foo"
|
doAssert msg.name == "foo"
|
||||||
doAssert msg.challenge == "bar"
|
doAssert msg.challenge == "bar"
|
||||||
|
|
||||||
|
block:
|
||||||
|
type
|
||||||
|
Color = enum Red, Brown
|
||||||
|
Thing = object
|
||||||
|
animal: tuple[fur: bool, legs: int]
|
||||||
|
color: Color
|
||||||
|
|
||||||
|
var j = parseJson("""
|
||||||
|
{"animal":{"fur":true,"legs":6},"color":"Red"}
|
||||||
|
""")
|
||||||
|
|
||||||
|
let parsed = to(j, Thing)
|
||||||
|
doAssert parsed.animal.fur
|
||||||
|
doAssert parsed.animal.legs == 6
|
||||||
|
doAssert parsed.color == Red
|
||||||
Loading…
Add table
Add a link
Reference in a new issue