fix #17383: json.%,to and jsonutils.formJson,toJson now works with uint|uint64 (#17389) [backport:1.2]
* fix #17383: json.%,to and jsonutils.formJson,toJson now works with uint|uint64 * fixup * fix for js
This commit is contained in:
parent
cfe2f126e5
commit
895a40d1ac
4 changed files with 56 additions and 6 deletions
|
|
@ -304,7 +304,10 @@ proc `%`*(s: string): JsonNode =
|
||||||
|
|
||||||
proc `%`*(n: uint): JsonNode =
|
proc `%`*(n: uint): JsonNode =
|
||||||
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
||||||
result = JsonNode(kind: JInt, num: BiggestInt(n))
|
if n > cast[uint](int.high):
|
||||||
|
result = newJRawNumber($n)
|
||||||
|
else:
|
||||||
|
result = JsonNode(kind: JInt, num: BiggestInt(n))
|
||||||
|
|
||||||
proc `%`*(n: int): JsonNode =
|
proc `%`*(n: int): JsonNode =
|
||||||
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
||||||
|
|
@ -312,7 +315,10 @@ proc `%`*(n: int): JsonNode =
|
||||||
|
|
||||||
proc `%`*(n: BiggestUInt): JsonNode =
|
proc `%`*(n: BiggestUInt): JsonNode =
|
||||||
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
||||||
result = JsonNode(kind: JInt, num: BiggestInt(n))
|
if n > cast[BiggestUInt](BiggestInt.high):
|
||||||
|
result = newJRawNumber($n)
|
||||||
|
else:
|
||||||
|
result = JsonNode(kind: JInt, num: BiggestInt(n))
|
||||||
|
|
||||||
proc `%`*(n: BiggestInt): JsonNode =
|
proc `%`*(n: BiggestInt): JsonNode =
|
||||||
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
## Generic constructor for JSON data. Creates a new `JInt JsonNode`.
|
||||||
|
|
@ -1055,8 +1061,16 @@ when defined(nimFixedForwardGeneric):
|
||||||
dst = jsonNode.copy
|
dst = jsonNode.copy
|
||||||
|
|
||||||
proc initFromJson[T: SomeInteger](dst: var T; jsonNode: JsonNode, jsonPath: var string) =
|
proc initFromJson[T: SomeInteger](dst: var T; jsonNode: JsonNode, jsonPath: var string) =
|
||||||
verifyJsonKind(jsonNode, {JInt}, jsonPath)
|
when T is uint|uint64:
|
||||||
dst = T(jsonNode.num)
|
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 = cast[T](jsonNode.num)
|
||||||
|
|
||||||
proc initFromJson[T: SomeFloat](dst: var T; jsonNode: JsonNode; jsonPath: var string) =
|
proc initFromJson[T: SomeFloat](dst: var T; jsonNode: JsonNode; jsonPath: var string) =
|
||||||
verifyJsonKind(jsonNode, {JInt, JFloat}, jsonPath)
|
verifyJsonKind(jsonNode, {JInt, JFloat}, jsonPath)
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,8 @@ proc fromJson*[T](a: var T, b: JsonNode, opt = Joptions()) =
|
||||||
of JInt: a = T(b.getBiggestInt())
|
of JInt: a = T(b.getBiggestInt())
|
||||||
of JString: a = parseEnum[T](b.getStr())
|
of JString: a = parseEnum[T](b.getStr())
|
||||||
else: checkJson false, $($T, " ", b)
|
else: checkJson false, $($T, " ", b)
|
||||||
elif T is Ordinal: a = T(to(b, int))
|
elif T is uint|uint64: a = T(to(b, uint64))
|
||||||
|
elif T is Ordinal: a = cast[T](to(b, int))
|
||||||
elif T is pointer: a = cast[pointer](to(b, int))
|
elif T is pointer: a = cast[pointer](to(b, int))
|
||||||
elif T is distinct:
|
elif T is distinct:
|
||||||
when nimvm:
|
when nimvm:
|
||||||
|
|
@ -270,6 +271,7 @@ proc toJson*[T](a: T): JsonNode =
|
||||||
# in simpler code for `toJson` and `fromJson`.
|
# in simpler code for `toJson` and `fromJson`.
|
||||||
elif T is distinct: result = toJson(a.distinctBase)
|
elif T is distinct: result = toJson(a.distinctBase)
|
||||||
elif T is bool: result = %(a)
|
elif T is bool: result = %(a)
|
||||||
|
elif T is SomeInteger: result = %a
|
||||||
elif T is Ordinal: result = %(a.ord)
|
elif T is Ordinal: result = %(a.ord)
|
||||||
else: result = %a
|
else: result = %a
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,14 @@ discard """
|
||||||
Note: Macro tests are in tests/stdlib/tjsonmacro.nim
|
Note: Macro tests are in tests/stdlib/tjsonmacro.nim
|
||||||
]#
|
]#
|
||||||
|
|
||||||
import std/[json,parsejson,strutils,streams]
|
import std/[json,parsejson,strutils]
|
||||||
|
when not defined(js):
|
||||||
|
import std/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"}"""
|
let testJson = parseJson"""{ "a": [1, 2, 3, 4], "b": "asd", "c": "\ud83c\udf83", "d": "\u00E6"}"""
|
||||||
# nil passthrough
|
# nil passthrough
|
||||||
|
|
@ -281,3 +288,15 @@ let jsonNode = %*mynode
|
||||||
doAssert $jsonNode == """{"kind":"P","pChildren":[{"kind":"Text","textStr":"mychild"},{"kind":"Br"}]}"""
|
doAssert $jsonNode == """{"kind":"P","pChildren":[{"kind":"Text","textStr":"mychild"},{"kind":"Br"}]}"""
|
||||||
doAssert $jsonNode.to(ContentNode) == """(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"
|
||||||
|
when not defined(js):
|
||||||
|
testRoundtrip(int64.high): "9223372036854775807"
|
||||||
|
testRoundtrip(uint64.high): "18446744073709551615"
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,21 @@ template fn() =
|
||||||
doAssert b2.ord == 1 # explains the `1`
|
doAssert b2.ord == 1 # explains the `1`
|
||||||
testRoundtrip(a): """[1,2,3]"""
|
testRoundtrip(a): """[1,2,3]"""
|
||||||
|
|
||||||
|
block: # bug #17383
|
||||||
|
block:
|
||||||
|
let a = (int32.high, uint32.high)
|
||||||
|
testRoundtrip(a): "[2147483647,4294967295]"
|
||||||
|
when not defined(js):
|
||||||
|
block:
|
||||||
|
let a = (int64.high, uint64.high)
|
||||||
|
testRoundtrip(a): "[9223372036854775807,18446744073709551615]"
|
||||||
|
block:
|
||||||
|
let a = (int.high, uint.high)
|
||||||
|
when int.sizeof == 4:
|
||||||
|
testRoundtrip(a): "[2147483647,4294967295]"
|
||||||
|
else:
|
||||||
|
testRoundtrip(a): "[9223372036854775807,18446744073709551615]"
|
||||||
|
|
||||||
block: # case object
|
block: # case object
|
||||||
type Foo = object
|
type Foo = object
|
||||||
x0: float
|
x0: float
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue