-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
toJson
, jsonTo
, json (de)serialization for custom types; remove dependency on strtabs thanks to a hooking mechanism
#14563
Conversation
cb06c77
to
1ec8322
Compare
This wouldn't really work as it is now. Take the strtabs example, with this simple serialisation routine you won't be able to have a key called "mode" as that name is taken up by the strtabs mode field. It is of course possible to build an ever more complex serialisation routine structure, but at some point it would've been easier to just have it import the JSON module and do it manually (apart from that this also would allow serialisation to other formats). |
technically, duplicate keys are valid in json however, so the format i used would still allow for a mode key (https://stackoverflow.com/questions/21832701/does-json-syntax-allow-duplicate-keys-in-an-object) but as I mentioned in https://github.com/nim-lang/Nim/pull/14563/files#diff-62bc00948f1e69981aabd6de006e25fbR426
|
there, it now serializes as
and it technically is json agnostic, eg would work just as well with bson/protobuf/msgpack |
This is what I was talking about when I said "It is of course possible to build an ever more complex serialisation routine structure, but at some point it would've been easier to just have it import the JSON module and do it manually". This still doesn't handle arrays for example, adding that would make it even more complex. I do like the fact that this is JSON agnostic, but I feel that building a sufficiently complex serialisation structure might tie it to hard to JSON and JSON-esque formats to really be viable for any other usages. That is just a hunch though.. |
that dependency would be bad, especially since json imports a lot itself.
That argument is invalid, array support is not needed for strtabs, it's only needed for toJson to be feature complete so it handles arbitrary types (yes, including |
I know the import would be bad, that's the whole point. But building all the same functionality into a serialisation procedure structure is very messy. The argument isn't invalid, I wasn't saying it was required for strtabs. I was saying that as a general approach this would have to be expanded into something that could easily become too complex and unwieldy for common use. I'd love to be proven wrong however, so please show an implementation of this, preferably with usage examples for various types around the stdlib to gauge how simple/complex this really is. Don't get me wrong, I like the idea of this, but I feel that as a feature it still needs a bit of work in order to prove itself. |
the only complex part is the custom hook if you wanted to support custom types other than strtabs (until we have symbol alias, then it'll be simple too), the rest is straightforward recursion. proc testToJson() =
var t = {"z": "Z", "y": "Y"}.newStringTable
type A = ref object
a1: string
let a = (1.1, "fo", 'x', @[10,11], [true, false], [t,newStringTable()], (foo: 0.5'f32, bar: A(a1: "abc"), bar2: A.default))
let j = a.toJson
doAssert $j == """[1.1,"fo",120,[10,11],[true,false],[{"mode":"modeCaseSensitive","table":{"y":"Y","z":"Z"}},{"mode":"modeCaseSensitive","table":{}}],{"foo":0.5,"bar":{"a1":"abc"},"bar2":null}]""" it's already handling most cases (and the reverse direction (parsing T from JsonNode) is equally doable, I've implemented it in my own code. A full featured solution would work like that by default but would also allow user to customize behavior for things like ptr-like types (eg whether to serialize the dereference or the address), and handle cycles correctly (to avoid infinite recursion). Likewise, it's not hard and I've implemented this. |
4fa73b4
to
ed41da8
Compare
This is looking better and better. Not loving the declaration of Not quite sure what you mean by "the only complex part is the custom hook if you wanted to support custom types other than strtabs", wouldn't this simply be the same Also the different |
ed41da8
to
5ad78f5
Compare
PTAL.
fixed
found a better way using mixin
not relevant anymore EDIT: now allows roundtrip, see updated top post |
toJson
, jsonTo
, json (de)serialization for custom types; remove dependency on strtabs thanks to a hooking mechanism
23d82ca
to
5885916
Compare
a38ac86
to
1867fa9
Compare
This reverts commit 7cb4ef2.
bd570f5
to
5a6f594
Compare
PTAL, you can just look at last few commits; added testing for js + vm |
Superb work! |
Hmm, I went back to NimBot to try and implement it with these changes and noticed that it only works when you call |
see long answer here: #14563 (comment); using |
Still not quite sure why though? Just backwards compatibility? |
several reasons as mentioned:
maybe |
toJson
,jsonTo
, for json (de)serialization from custom types; all reasonable types are supported recursively.object,ref,ptr,pointer,tuple,numbers,string,seq,array,ordinals,distinct,tables
=> all self contained in 1 single proc for
toJson
andfromJson
; no need for forward declaration or any boilerplateexample
it now works with roundtrip serialization/deserialization: see tests/stdlib/tjsonmacro.nim
future work
json=>options
dependency using same hooking approach, and perhaps other