Skip to content

Commit a9a1896

Browse files
committed
Fixes #6095.
1 parent bf61ef6 commit a9a1896

File tree

2 files changed

+53
-22
lines changed

2 files changed

+53
-22
lines changed

lib/pure/json.nim

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,26 +1524,34 @@ proc processObjField(field, jsonNode: NimNode): seq[NimNode] =
15241524

15251525
doAssert result.len > 0
15261526

1527-
proc processObjFields(obj: NimNode,
1528-
jsonNode: NimNode): seq[NimNode] {.compileTime.} =
1527+
proc processFields(obj: NimNode,
1528+
jsonNode: NimNode): seq[NimNode] {.compileTime.} =
15291529
## Process all the fields of an ``ObjectTy`` and any of its
15301530
## parent type's fields (via inheritance).
15311531
result = @[]
1532-
1533-
expectKind(obj[2], nnkRecList)
1534-
for field in obj[2]:
1535-
let nodes = processObjField(field, jsonNode)
1536-
result.add(nodes)
1537-
1538-
# process parent type fields
1539-
case obj[1].kind
1540-
of nnkBracketExpr:
1541-
assert $obj[1][0] == "ref"
1542-
result.add(processObjFields(getType(obj[1][1]), jsonNode))
1543-
of nnkSym:
1544-
result.add(processObjFields(getType(obj[1]), jsonNode))
1532+
case obj.kind
1533+
of nnkObjectTy:
1534+
expectKind(obj[2], nnkRecList)
1535+
for field in obj[2]:
1536+
let nodes = processObjField(field, jsonNode)
1537+
result.add(nodes)
1538+
1539+
# process parent type fields
1540+
case obj[1].kind
1541+
of nnkBracketExpr:
1542+
assert $obj[1][0] == "ref"
1543+
result.add(processFields(getType(obj[1][1]), jsonNode))
1544+
of nnkSym:
1545+
result.add(processFields(getType(obj[1]), jsonNode))
1546+
else:
1547+
discard
1548+
of nnkTupleTy:
1549+
for identDefs in obj:
1550+
expectKind(identDefs, nnkIdentDefs)
1551+
let nodes = processObjField(identDefs[0], jsonNode)
1552+
result.add(nodes)
15451553
else:
1546-
discard
1554+
doAssert false, "Unable to process field type: " & $obj.kind
15471555

15481556
proc processType(typeName: NimNode, obj: NimNode,
15491557
jsonNode: NimNode, isRef: bool): NimNode {.compileTime.} =
@@ -1558,13 +1566,17 @@ proc processType(typeName: NimNode, obj: NimNode,
15581566
## RecList
15591567
## Sym "events"
15601568
case obj.kind
1561-
of nnkObjectTy:
1569+
of nnkObjectTy, nnkTupleTy:
15621570
# Create object constructor.
1563-
result = newNimNode(nnkObjConstr)
1564-
result.add(typeName) # Name of the type to construct.
1571+
result =
1572+
if obj.kind == nnkObjectTy: newNimNode(nnkObjConstr)
1573+
else: newNimNode(nnkPar)
1574+
1575+
if obj.kind == nnkObjectTy:
1576+
result.add(typeName) # Name of the type to construct.
15651577

1566-
# Process each object field and add it as an exprColonExpr
1567-
result.add(processObjFields(obj, jsonNode))
1578+
# Process each object/tuple field and add it as an exprColonExpr
1579+
result.add(processFields(obj, jsonNode))
15681580

15691581
# Object might be null. So we need to check for that.
15701582
if isRef:
@@ -1687,6 +1699,8 @@ proc createConstructor(typeSym, jsonNode: NimNode): NimNode =
16871699
result = createConstructor(obj, jsonNode)
16881700
else:
16891701
result = processType(typeSym, obj, jsonNode, false)
1702+
of nnkTupleTy:
1703+
result = processType(typeSym, typeSym, jsonNode, false)
16901704
else:
16911705
doAssert false, "Unable to create constructor for: " & $typeSym.kind
16921706

@@ -1818,6 +1832,7 @@ macro to*(node: JsonNode, T: typedesc): untyped =
18181832
# TODO: Rename postProcessValue and move it (?)
18191833
result = postProcessValue(result)
18201834

1835+
# echo(treeRepr(result))
18211836
# echo(toStrLit(result))
18221837

18231838
when false:

tests/stdlib/tjsonmacro.nim

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,4 +259,20 @@ when isMainModule:
259259
let data = %*{"name": "foo", "challenge": "bar"}
260260
let msg = data.to(MsgChallenge)
261261
doAssert msg.name == "foo"
262-
doAssert msg.challenge == "bar"
262+
doAssert msg.challenge == "bar"
263+
264+
block:
265+
type
266+
Color = enum Red, Brown
267+
Thing = object
268+
animal: tuple[fur: bool, legs: int]
269+
color: Color
270+
271+
var j = parseJson("""
272+
{"animal":{"fur":true,"legs":6},"color":"Red"}
273+
""")
274+
275+
let parsed = to(j, Thing)
276+
doAssert parsed.animal.fur
277+
doAssert parsed.animal.legs == 6
278+
doAssert parsed.color == Red

0 commit comments

Comments
 (0)