From 60d953fae99c7b30b9b16fb556465d159aeba3e8 Mon Sep 17 00:00:00 2001 From: metagn Date: Mon, 23 Dec 2024 04:57:26 +0300 Subject: [PATCH] fix jsonutils with generic sandwiches, don't use strformat fixes #24559 --- lib/std/jsonutils.nim | 12 +++++++----- tests/stdlib/mjsonutilssandwich.nim | 11 +++++++++++ tests/stdlib/tjsonutilssandwich.nim | 10 ++++++++++ 3 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 tests/stdlib/mjsonutilssandwich.nim create mode 100644 tests/stdlib/tjsonutilssandwich.nim diff --git a/lib/std/jsonutils.nim b/lib/std/jsonutils.nim index 89b81a2f7dc8d..d378812b691b7 100644 --- a/lib/std/jsonutils.nim +++ b/lib/std/jsonutils.nim @@ -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) diff --git a/tests/stdlib/mjsonutilssandwich.nim b/tests/stdlib/mjsonutilssandwich.nim new file mode 100644 index 0000000000000..12c2826382661 --- /dev/null +++ b/tests/stdlib/mjsonutilssandwich.nim @@ -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) diff --git a/tests/stdlib/tjsonutilssandwich.nim b/tests/stdlib/tjsonutilssandwich.nim new file mode 100644 index 0000000000000..98d45d56b154a --- /dev/null +++ b/tests/stdlib/tjsonutilssandwich.nim @@ -0,0 +1,10 @@ +discard """ + action: compile +""" + +# issue #24559 + +import mjsonutilssandwich +# import std/[json, jsonutils] # Add this line and everything works 🤡 + +unserialize[Foo]("{}")