Kotlin / kotlinx.serialization

Kotlin multiplatform / multi-format serialization
Apache License 2.0
5.4k stars 620 forks source link

Store and expose current Json path during encoding and decoding #1556

Open sandwwraith opened 3 years ago

sandwwraith commented 3 years ago

JSON path even in the most simple form like [foo, bar, baz] is extremely useful during error reporting. Also, it can be used for features like #1384. Proposed solution is to store current path in JsonEncoder/Decoder, and probably add a method to these interfaces to access it.

Note that providing X-Path (Json-path) like selectors to access/match arbitrary data inside JsonElement is currently a non-goal, but can be added as a separate feature later.

KevinBassaDevelopment commented 3 years ago

@sandwwraith Hi, with with https://github.com/Kotlin/kotlinx.serialization/pull/1440#issuecomment-858720841 you said i might ping you if json path is not available after some time. Is there any progress on this feature? Still really looking forward to it!

sandwwraith commented 3 years ago

We have a prototype (https://github.com/Kotlin/kotlinx.serialization/pull/1638), but we decided to postpone it in favor of other features like io streams. It works now for simple cases, but more delicate efforts are required for making it work with advanced serialization features, like polymorphism, inline classes, maps-as-arrays, etc

sschuberth commented 1 year ago

How about alternatively teaching a JsonElement to know its parent? That would allow users to construct a JSON path to the current element on demand. And also selectDeserializer(element: JsonElement) could access sibling elements which might contain the actual discriminating property.

sandwwraith commented 1 year ago

By the way, there is an internal implementation of path tracking now, which is used for error reporting. Although it is not exposed.

sschuberth commented 1 year ago

And also selectDeserializer(element: JsonElement) could access sibling elements which might contain the actual discriminating property.

Or change the signature to selectDeserializer(element: JsonElement, root: JsonElement) so via root any element in the JSON could be accessed to select the deserializer, which would probably also solve #1384.