From 4eca659b564bb68a3c61942e4d82b7e639d7da88 Mon Sep 17 00:00:00 2001 From: HeWhoWalksBehind <84110044+siriuslee69@users.noreply.github.com> Date: Mon, 9 Sep 2024 21:55:46 +0200 Subject: [PATCH 1/6] allow tuples as input for `%` Allow tuples as input for `%`, but disallow them in the generic type of the `%` proc that accepts openArrays. Additionally addedthe isNamedTuple(T) proc. Can instead also be imported from std/typetraits, but ig dependencies should be kept to a minimum. --- lib/pure/json.nim | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 53fa7553a422..a372be23869b 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -213,6 +213,8 @@ type const DepthLimit = 1000 +proc isNamedTuple(T: typedesc): bool {.magic: "TypeTrait".} + proc newJString*(s: string): JsonNode = ## Creates a new `JString JsonNode`. result = JsonNode(kind: JString, str: s) @@ -363,7 +365,8 @@ proc `%`*(keyVals: openArray[tuple[key: string, val: JsonNode]]): JsonNode = template `%`*(j: JsonNode): JsonNode = j -proc `%`*[T](elements: openArray[T]): JsonNode = +#tuples must not be allowed - issue #24082 +proc `%`*[T: not tuple](elements: openArray[T]): JsonNode = ## Generic constructor for JSON data. Creates a new `JArray JsonNode` result = newJArray() for elem in elements: result.add(%elem) @@ -396,10 +399,14 @@ proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) {.inline.} = assert(obj.kind == JObject) obj.fields[key] = val -proc `%`*[T: object](o: T): JsonNode = +proc `%`*[T: object | tuple](o: T): JsonNode = ## Construct JsonNode from tuples and objects. - result = newJObject() - for k, v in o.fieldPairs: result[k] = %v + when T is object or isNamedTuple(T): + result = newJObject() + for k, v in a.fieldPairs: result[k] = toJson(v, opt) + else: + result = newJArray() + for v in a.fields: result.add toJson(v, opt) proc `%`*(o: ref object): JsonNode = ## Generic constructor for JSON data. Creates a new `JObject JsonNode` From d625d0195d3119dec527a84cbae0f1e21204dad3 Mon Sep 17 00:00:00 2001 From: HeWhoWalksBehind <84110044+siriuslee69@users.noreply.github.com> Date: Mon, 9 Sep 2024 21:59:10 +0200 Subject: [PATCH 2/6] added tests for tuple to JsObject / JsArray conversion --- tests/stdlib/tjson.nim | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/stdlib/tjson.nim b/tests/stdlib/tjson.nim index e425501f699e..473849b8a56a 100644 --- a/tests/stdlib/tjson.nim +++ b/tests/stdlib/tjson.nim @@ -175,6 +175,14 @@ doAssert($ %*{} == "{}") doAssert(not compiles(%{"error": "No messages"})) +# issue #24082 +block test_tuple: + doAssert $(%(a1: 10, a2: "foo")) == """{"a1":10,"a2":"foo"}""" + doAssert $(%(10, "foo")) == """[10,"foo"]""" + + doAssert $(%* (a1: 10, a2: "foo")) == """{"a1":10,"a2":"foo"}""" + doAssert $(%* (10, "foo")) == """[10,"foo"]""" + # bug #9111 block: type From 8a380308777cbf69383dff29c5964395f5fe7e9c Mon Sep 17 00:00:00 2001 From: HeWhoWalksBehind <84110044+siriuslee69@users.noreply.github.com> Date: Mon, 9 Sep 2024 22:27:39 +0200 Subject: [PATCH 3/6] added some info the proc `%` added additional conversion info to the proc, copied it straight from an earlier issue --- lib/pure/json.nim | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index a372be23869b..e4f7aadb2c97 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -401,6 +401,8 @@ proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) {.inline.} = proc `%`*[T: object | tuple](o: T): JsonNode = ## Construct JsonNode from tuples and objects. + ## If passed an anonymous tuple, creates `JArray JsonNode`, + ## otherwise (named tuples and objects) `JObject JsonNode`. when T is object or isNamedTuple(T): result = newJObject() for k, v in a.fieldPairs: result[k] = toJson(v, opt) From cedc6831dd8bf510a1de72e54db2ab6931cea97c Mon Sep 17 00:00:00 2001 From: HeWhoWalksBehind <84110044+siriuslee69@users.noreply.github.com> Date: Mon, 9 Sep 2024 22:35:59 +0200 Subject: [PATCH 4/6] replaced toJson(v, opt) with %v Forgot to change parts of the copied code from jsonutils. --- lib/pure/json.nim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index e4f7aadb2c97..6b251afa1605 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -405,10 +405,10 @@ proc `%`*[T: object | tuple](o: T): JsonNode = ## otherwise (named tuples and objects) `JObject JsonNode`. when T is object or isNamedTuple(T): result = newJObject() - for k, v in a.fieldPairs: result[k] = toJson(v, opt) + for k, v in o.fieldPairs: result[k] = %(v) else: result = newJArray() - for v in a.fields: result.add toJson(v, opt) + for v in o.fields: result.add(%v) proc `%`*(o: ref object): JsonNode = ## Generic constructor for JSON data. Creates a new `JObject JsonNode` From 7b5b3c546ac895d9cc2d225ba8dbeb396ba7602c Mon Sep 17 00:00:00 2001 From: HeWhoWalksBehind <84110044+siriuslee69@users.noreply.github.com> Date: Mon, 9 Sep 2024 22:37:05 +0200 Subject: [PATCH 5/6] deleted unnecessary brackets in json.nim --- lib/pure/json.nim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 6b251afa1605..086f29467557 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -405,7 +405,7 @@ proc `%`*[T: object | tuple](o: T): JsonNode = ## otherwise (named tuples and objects) `JObject JsonNode`. when T is object or isNamedTuple(T): result = newJObject() - for k, v in o.fieldPairs: result[k] = %(v) + for k, v in o.fieldPairs: result[k] = %v else: result = newJArray() for v in o.fields: result.add(%v) From 8803394a359b99d28b50a9cde739f68ee7b73475 Mon Sep 17 00:00:00 2001 From: HeWhoWalksBehind <84110044+siriuslee69@users.noreply.github.com> Date: Tue, 10 Sep 2024 17:32:46 +0200 Subject: [PATCH 6/6] split overloaded proc `%` for tuple and object in json.nim Something like proc myproc[T: object|tuple](o:T): void = ... might not accept the tuple properly even though it's supposed to, such that: myproc(mytup) doesn't work. Idk if that was the actual problem here, but just to be sure, I changed the respective functions. --- lib/pure/json.nim | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/pure/json.nim b/lib/pure/json.nim index 086f29467557..c0c6813dec17 100644 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -399,17 +399,24 @@ proc `[]=`*(obj: JsonNode, key: string, val: JsonNode) {.inline.} = assert(obj.kind == JObject) obj.fields[key] = val -proc `%`*[T: object | tuple](o: T): JsonNode = - ## Construct JsonNode from tuples and objects. +#Bug #16321 - create seperate proc for tuple and object +proc `%`*[T: tuple](o: T): JsonNode = + ## Construct JsonNode from tuples. + ## ## If passed an anonymous tuple, creates `JArray JsonNode`, - ## otherwise (named tuples and objects) `JObject JsonNode`. - when T is object or isNamedTuple(T): + ## otherwise (named tuples) `JObject JsonNode`. + when T is isNamedTuple(T): result = newJObject() for k, v in o.fieldPairs: result[k] = %v else: result = newJArray() for v in o.fields: result.add(%v) +proc `%`*[T: object](o: T): JsonNode = + ## Construct JsonNode from objects. + result = newJObject() + for k, v in o.fieldPairs: result[k] = %v + proc `%`*(o: ref object): JsonNode = ## Generic constructor for JSON data. Creates a new `JObject JsonNode` if o.isNil: