Skip to content

Commit

Permalink
fix jsonutils with generic sandwiches, don't use strformat
Browse files Browse the repository at this point in the history
  • Loading branch information
metagn committed Dec 23, 2024
1 parent 6bc5273 commit 60d953f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 5 deletions.
12 changes: 7 additions & 5 deletions lib/std/jsonutils.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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`
#[
Expand All @@ -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))
Expand All @@ -228,15 +230,15 @@ 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
else:
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)
Expand Down Expand Up @@ -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)
Expand Down
11 changes: 11 additions & 0 deletions tests/stdlib/mjsonutilssandwich.nim
Original file line number Diff line number Diff line change
@@ -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)
10 changes: 10 additions & 0 deletions tests/stdlib/tjsonutilssandwich.nim
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
discard """
action: compile
"""

# issue #24559

import mjsonutilssandwich
# import std/[json, jsonutils] # Add this line and everything works 🤡

unserialize[Foo]("{}")

0 comments on commit 60d953f

Please sign in to comment.