fix jsonutils with generic sandwiches, don't use strformat (#24560)

fixes #24559

The strformat macros have the problem that they don't capture symbols,
so don't use them in the generic `fromJson` proc here. Also `fromJson`
refers to `jsonTo` before it is declared which doesn't capture it, so
it's now forward declared.
This commit is contained in:
metagn
2024-12-23 08:08:46 +03:00
committed by GitHub
parent 6bc52737b3
commit 5c71fbab30
3 changed files with 28 additions and 5 deletions

View File

@@ -16,7 +16,7 @@ runnableExamples:
assert 0.0.toJson.kind == JFloat
assert Inf.toJson.kind == JString
import std/[json, strutils, tables, sets, strtabs, options, strformat]
import std/[json, strutils, tables, sets, strtabs, options]
#[
Future directions:
@@ -205,6 +205,8 @@ proc discKeysMatch[T](obj: T, json: JsonNode, keys: static seq[string]): bool =
result = true
discKeysMatchBodyGen(obj, json, keys)
proc jsonTo*(b: JsonNode, T: typedesc, opt = Joptions()): T
proc fromJson*[T](a: var T, b: JsonNode, opt = Joptions()) =
## inplace version of `jsonTo`
#[
@@ -218,7 +220,7 @@ proc fromJson*[T](a: var T, b: JsonNode, opt = Joptions()) =
case b.kind
of JInt: a = T(b.getBiggestInt())
of JString: a = parseEnum[T](b.getStr())
else: checkJson false, fmt"Expecting int/string for {$T} got {b.pretty()}"
else: checkJson false, "Expecting int/string for " & $T & " got " & b.pretty()
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))
@@ -228,7 +230,7 @@ proc fromJson*[T](a: var T, b: JsonNode, opt = Joptions()) =
case b.kind
of JNull: a = nil
of JString: a = b.str
else: checkJson false, fmt"Expecting null/string for {$T} got {b.pretty()}"
else: checkJson false, "Expecting null/string for " & $T & " got " & b.pretty()
elif T is JsonNode: a = b
elif T is ref | ptr:
if b.kind == JNull: a = nil
@@ -236,7 +238,7 @@ proc fromJson*[T](a: var T, b: JsonNode, opt = Joptions()) =
a = T()
fromJson(a[], b, opt)
elif T is array:
checkJson a.len == b.len, fmt"Json array size doesn't match for {$T}"
checkJson a.len == b.len, "Json array size doesn't match for " & $T
var i = 0
for ai in mitems(a):
fromJson(ai, b[i], opt)
@@ -282,7 +284,7 @@ proc fromJson*[T](a: var T, b: JsonNode, opt = Joptions()) =
for val in fields(a):
tupleSize.inc
checkJson b.len == tupleSize, fmt"Json doesn't match expected length of {tupleSize}, got {b.pretty()}"
checkJson b.len == tupleSize, "Json doesn't match expected length of " & $tupleSize & ", got " & b.pretty()
var i = 0
for val in fields(a):
fromJson(val, b[i], opt)

View File

@@ -0,0 +1,11 @@
import std/[json, jsonutils]
type
Kind* = enum kind1
Foo* = ref object
bleh: string
case kind*: Kind # Remove these lines and everything works 🤡
of kind1: discard # Remove these lines and everything works 🤡
proc unserialize*[T](s: string) =
discard jsonTo(parseJson(s), T)

View File

@@ -0,0 +1,10 @@
discard """
action: compile
"""
# issue #24559
import mjsonutilssandwich
# import std/[json, jsonutils] # Add this line and everything works 🤡
unserialize[Foo]("{}")