Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 1 commit into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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]("{}")