Skip to content

Commit 11df699

Browse files
committed
Parse optinally parse named tupples as arrays.
1 parent eb63a32 commit 11df699

File tree

2 files changed

+61
-20
lines changed

2 files changed

+61
-20
lines changed

src/jsony.nim

+40-11
Original file line numberDiff line numberDiff line change
@@ -260,17 +260,6 @@ proc parseHook*[T](s: string, i: var int, v: var seq[T]) =
260260
break
261261
eatChar(s, i, ']')
262262

263-
proc parseHook*[T: tuple](s: string, i: var int, v: var T) =
264-
eatSpace(s, i)
265-
eatChar(s, i, '[')
266-
for name, value in v.fieldPairs:
267-
eatSpace(s, i)
268-
parseHook(s, i, value)
269-
eatSpace(s, i)
270-
if i < s.len and s[i] == ',':
271-
inc i
272-
eatChar(s, i, ']')
273-
274263
proc parseHook*[T: array](s: string, i: var int, v: var T) =
275264
eatSpace(s, i)
276265
eatChar(s, i, '[')
@@ -341,6 +330,46 @@ template snakeCase(s: string): string =
341330
const k = snakeCaseDynamic(s)
342331
k
343332

333+
proc parseObject[T](s: string, i: var int, v: var T) =
334+
eatChar(s, i, '{')
335+
while i < s.len:
336+
eatSpace(s, i)
337+
if i < s.len and s[i] == '}':
338+
break
339+
var key: string
340+
parseHook(s, i, key)
341+
eatChar(s, i, ':')
342+
when compiles(renameHook(v, key)):
343+
renameHook(v, key)
344+
block all:
345+
for k, v in v.fieldPairs:
346+
if k == key or snakeCase(k) == key:
347+
var v2: type(v)
348+
parseHook(s, i, v2)
349+
v = v2
350+
break all
351+
skipValue(s, i)
352+
eatSpace(s, i)
353+
if i < s.len and s[i] == ',':
354+
inc i
355+
else:
356+
break
357+
358+
proc parseHook*[T: tuple](s: string, i: var int, v: var T) =
359+
eatSpace(s, i)
360+
when T.isNamedTuple():
361+
if i < s.len and s[i] == '{':
362+
parseObject(s, i, v)
363+
return
364+
eatChar(s, i, '[')
365+
for name, value in v.fieldPairs:
366+
eatSpace(s, i)
367+
parseHook(s, i, value)
368+
eatSpace(s, i)
369+
if i < s.len and s[i] == ',':
370+
inc i
371+
eatChar(s, i, ']')
372+
344373
proc parseHook*[T: enum](s: string, i: var int, v: var T) =
345374
eatSpace(s, i)
346375
var strV: string

tests/test_tuples.nim

+21-9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,18 @@ block:
1414
doAssert v[1] == "hi"
1515
doAssert v[2] == 3.5
1616

17+
block:
18+
type Vector3i = tuple[x: int, y: int, z: int]
19+
var s = """[0, 1, 2]"""
20+
var v = s.fromJson(Vector3i)
21+
doAssert v[0] == 0
22+
doAssert v[1] == 1
23+
doAssert v[2] == 2
24+
doAssert v.x == 0
25+
doAssert v.y == 1
26+
doAssert v.z == 2
27+
28+
1729
block:
1830
type Entry = tuple[id: int, name: string, dist: float32]
1931
var s = """[134, "red", 13.5]"""
@@ -26,12 +38,12 @@ block:
2638
doAssert v.dist == 13.5
2739

2840
block:
29-
type Vector3i = tuple[x: int, y: int, z: int]
30-
var s = """[0, 1, 2]"""
31-
var v = s.fromJson(Vector3i)
32-
doAssert v[0] == 0
33-
doAssert v[1] == 1
34-
doAssert v[2] == 2
35-
doAssert v.x == 0
36-
doAssert v.y == 1
37-
doAssert v.z == 2
41+
type Entry = tuple[id: int, name: string, dist: float32]
42+
var s = """{"id": 134, "name": "red", "dist": 13.5}"""
43+
var v = s.fromJson(Entry)
44+
doAssert v[0] == 134
45+
doAssert v[1] == "red"
46+
doAssert v[2] == 13.5
47+
doAssert v.id == 134
48+
doAssert v.name == "red"
49+
doAssert v.dist == 13.5

0 commit comments

Comments
 (0)