Skip to content

Commit

Permalink
fix #17383: json.%,to and jsonutils.formJson,toJson now works with ui…
Browse files Browse the repository at this point in the history
…nt|uint64
  • Loading branch information
timotheecour committed Mar 15, 2021
1 parent da83b99 commit 9e8773e
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 4 deletions.
22 changes: 18 additions & 4 deletions lib/pure/json.nim
Original file line number Diff line number Diff line change
Expand Up @@ -304,15 +304,21 @@ proc `%`*(s: string): JsonNode =

proc `%`*(n: uint): JsonNode =
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
result = JsonNode(kind: JInt, num: BiggestInt(n))
if n > static(BiggestUInt(BiggestInt.high)):
result = newJRawNumber($n)
else:
result = JsonNode(kind: JInt, num: BiggestInt(n))

proc `%`*(n: int): JsonNode =
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
result = JsonNode(kind: JInt, num: n)

proc `%`*(n: BiggestUInt): JsonNode =
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
result = JsonNode(kind: JInt, num: BiggestInt(n))
if n > static(BiggestUInt(BiggestInt.high)):
result = newJRawNumber($n)
else:
result = JsonNode(kind: JInt, num: BiggestInt(n))

proc `%`*(n: BiggestInt): JsonNode =
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
Expand Down Expand Up @@ -1055,8 +1061,16 @@ when defined(nimFixedForwardGeneric):
dst = jsonNode.copy

proc initFromJson[T: SomeInteger](dst: var T; jsonNode: JsonNode, jsonPath: var string) =
verifyJsonKind(jsonNode, {JInt}, jsonPath)
dst = T(jsonNode.num)
when T is uint|uint64:
case jsonNode.kind
of JString:
dst = T(parseBiggestUint(jsonNode.str))
else:
verifyJsonKind(jsonNode, {JInt}, jsonPath)
dst = T(jsonNode.num)
else:
verifyJsonKind(jsonNode, {JInt}, jsonPath)
dst = T(jsonNode.num)

proc initFromJson[T: SomeFloat](dst: var T; jsonNode: JsonNode; jsonPath: var string) =
verifyJsonKind(jsonNode, {JInt, JFloat}, jsonPath)
Expand Down
2 changes: 2 additions & 0 deletions lib/std/jsonutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ proc fromJson*[T](a: var T, b: JsonNode, opt = Joptions()) =
of JInt: a = T(b.getBiggestInt())
of JString: a = parseEnum[T](b.getStr())
else: checkJson false, $($T, " ", b)
elif T is uint|uint64: a = T(to(b, uint64))
elif T is Ordinal: a = T(to(b, int))
elif T is pointer: a = cast[pointer](to(b, int))
elif T is distinct:
Expand Down Expand Up @@ -270,6 +271,7 @@ proc toJson*[T](a: T): JsonNode =
# in simpler code for `toJson` and `fromJson`.
elif T is distinct: result = toJson(a.distinctBase)
elif T is bool: result = %(a)
elif T is SomeInteger: result = %a
elif T is Ordinal: result = %(a.ord)
else: result = %a

Expand Down
16 changes: 16 additions & 0 deletions tests/stdlib/tjson.nim
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ Note: Macro tests are in tests/stdlib/tjsonmacro.nim

import std/[json,parsejson,strutils,streams]

proc testRoundtrip[T](t: T, expected: string) =
let j = %t
doAssert $j == expected, $j
doAssert %(j.to(T)) == j

let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd", "c": "\ud83c\udf83", "d": "\u00E6"}"""
# nil passthrough
doAssert(testJson{"doesnt_exist"}{"anything"}.isNil)
Expand Down Expand Up @@ -281,3 +286,14 @@ let jsonNode = %*mynode
doAssert $jsonNode == """{"kind":"P","pChildren":[{"kind":"Text","textStr":"mychild"},{"kind":"Br"}]}"""
doAssert $jsonNode.to(ContentNode) == """(kind: P, pChildren: @[(kind: Text, textStr: "mychild"), (kind: Br)])"""

block: # bug #17383
testRoundtrip(int32.high): "2147483647"
testRoundtrip(uint32.high): "4294967295"
when int.sizeof == 4:
testRoundtrip(int.high): "2147483647"
testRoundtrip(uint.high): "4294967295"
else:
testRoundtrip(int.high): "9223372036854775807"
testRoundtrip(uint.high): "18446744073709551615"
testRoundtrip(int64.high): "9223372036854775807"
testRoundtrip(uint64.high): "18446744073709551615"
10 changes: 10 additions & 0 deletions tests/stdlib/tjsonutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,16 @@ template fn() =
doAssert b2.ord == 1 # explains the `1`
testRoundtrip(a): """[1,2,3]"""

block: # bug #17383
let a = (int32.high, uint32.high, int64.high, uint64.high)
testRoundtrip(a): "[2147483647,4294967295,9223372036854775807,18446744073709551615]"
testRoundtrip(a): "[2147483647,4294967295,9223372036854775807,18446744073709551615]"
let b = (int.high, uint.high)
when int.sizeof == 4:
testRoundtrip(b): "[2147483647,4294967295]"
else:
testRoundtrip(b): "[9223372036854775807,18446744073709551615]"

block: # case object
type Foo = object
x0: float
Expand Down

0 comments on commit 9e8773e

Please sign in to comment.