From e78b48395f7fbb25a0c644b7685062d103b5c3db Mon Sep 17 00:00:00 2001 From: George Lemon Date: Mon, 1 Apr 2024 15:39:08 +0300 Subject: [PATCH 1/3] extend `skipHook` to skip object fields based on values Signed-off-by: George Lemon --- src/jsony.nim | 9 +++++++++ tests/test_skipHook.nim | 30 +++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/jsony.nim b/src/jsony.nim index 0fcb67b..e737ee7 100644 --- a/src/jsony.nim +++ b/src/jsony.nim @@ -827,6 +827,15 @@ proc dumpHook*(s: var string, v: object) = s.dumpKey(k) s.dumpHook(e) inc i + elif compiles(skipHook(e, k)): + if skipHook(e, k): + discard + else: + if i > 0: + s.add ',' + s.dumpKey(k) + s.dumpHook(e) + inc i else: if i > 0: s.add ',' diff --git a/tests/test_skipHook.nim b/tests/test_skipHook.nim index f1b51a0..a4beb23 100644 --- a/tests/test_skipHook.nim +++ b/tests/test_skipHook.nim @@ -1,5 +1,4 @@ import jsony - type Conn = object id: int @@ -15,3 +14,32 @@ proc skipHook(T: typedesc[Foo], key: static string): bool = let v = Foo(a:1, password: "12345", b:0.6, conn: Conn(id: 1)) doAssert v.toJson() == """{"a":1,"b":0.6}""" + +type + Boo = ref object + hoo: string + x: seq[string] + i: int + b: bool + + Woo = object + boo: Boo + +proc skipHook(v: Boo, key: string): bool = + result = v == nil + +proc skipHook(v: string, key: string): bool = + result = v.len == 0 + +proc skipHook(v: seq[string], key: string): bool = + result = v.len == 0 + +let w = Woo(boo: Boo()) +doAssert w.toJson() == + """{"boo":{"i":0,"b":false}}""" +let w2 = Woo() +doAssert w2.toJson() == + """{}""" +let b = Boo() +doAssert b.toJson() == + """{"i":0,"b":false}""" From 4340dd8647489c6d33d912d62ccf2bafdd374014 Mon Sep 17 00:00:00 2001 From: George Lemon Date: Tue, 2 Apr 2024 07:43:33 +0300 Subject: [PATCH 2/3] add examples in `README.md` | add `skipHook` test with generics Signed-off-by: George Lemon --- README.md | 36 ++++++++++++++++++++++++++++++++++++ tests/test_skipHook.nim | 3 ++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b9f248..363d116 100644 --- a/README.md +++ b/README.md @@ -277,6 +277,42 @@ Gives us: "{"a":1,"b":0.5}" ``` +Also, `skipHook` can be used at runtime to skip fields based on their current value. For example: +```nim +type + Boo = ref object + hoo: string + x: seq[string] + y: seq[int] + i: int + b: bool + + Woo = object + boo: Boo + +proc skipHook(v: Boo, key: string): bool = + ## Skip `nil` fields + result = v == nil + +proc skipHook(v: string, key: string): bool = + ## skip all fields that contains empty strings + result = v.len == 0 + +proc skipHook[T](v: seq[T], key: string): bool = + # skip all fields that contains empty sequences + result = v.len == 0 + +let w = Woo(boo: Boo()) +assert w.toJson() == """{"boo":{"i":0,"b":false}}""" + +let w2 = Woo() +assert w2.toJson() == "{}" + +let b = Boo() +assert b.toJson() == + """{"i":0,"b":false}""" +``` + ## Static writing with `toStaticJson`. Sometimes you have some json, and you want to write it in a static way. There is a special function for that: diff --git a/tests/test_skipHook.nim b/tests/test_skipHook.nim index a4beb23..1facda1 100644 --- a/tests/test_skipHook.nim +++ b/tests/test_skipHook.nim @@ -19,6 +19,7 @@ type Boo = ref object hoo: string x: seq[string] + y: seq[int] i: int b: bool @@ -31,7 +32,7 @@ proc skipHook(v: Boo, key: string): bool = proc skipHook(v: string, key: string): bool = result = v.len == 0 -proc skipHook(v: seq[string], key: string): bool = +proc skipHook[T](v: seq[T], key: string): bool = result = v.len == 0 let w = Woo(boo: Boo()) From 290f1e283aad4a63989b12de7af93e6f7a0cd9da Mon Sep 17 00:00:00 2001 From: George Lemon Date: Tue, 2 Apr 2024 09:30:12 +0300 Subject: [PATCH 3/3] `skipHook` runtime with `typedesc` Signed-off-by: George Lemon --- src/jsony.nim | 9 +++++++++ tests/test_skipHook.nim | 14 +++++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/jsony.nim b/src/jsony.nim index e737ee7..e6db6b9 100644 --- a/src/jsony.nim +++ b/src/jsony.nim @@ -827,6 +827,15 @@ proc dumpHook*(s: var string, v: object) = s.dumpKey(k) s.dumpHook(e) inc i + elif compiles(skipHook(type(v), e, k)): + if skipHook(type(v), e, k): + discard + else: + if i > 0: + s.add ',' + s.dumpKey(k) + s.dumpHook(e) + inc i elif compiles(skipHook(e, k)): if skipHook(e, k): discard diff --git a/tests/test_skipHook.nim b/tests/test_skipHook.nim index 1facda1..e0741b5 100644 --- a/tests/test_skipHook.nim +++ b/tests/test_skipHook.nim @@ -26,7 +26,10 @@ type Woo = object boo: Boo -proc skipHook(v: Boo, key: string): bool = + Moo = object + boo: Boo + +proc skipHook(T: typedesc[Woo], v: Boo, key: string): bool = result = v == nil proc skipHook(v: string, key: string): bool = @@ -44,3 +47,12 @@ doAssert w2.toJson() == let b = Boo() doAssert b.toJson() == """{"i":0,"b":false}""" + +block: + let m = Moo() # not covered by `skipHook` + doAssert m.toJson() == + """{"boo":null}""" +block: + let m = Moo(boo: Boo(hoo: "just moo")) + doAssert m.toJson() == + """{"boo":{"hoo":"just moo","i":0,"b":false}}""" \ No newline at end of file