crystal
crystal copied to clipboard
`root` property of `JSON::Field` should support nested keys
The JSON::Field
annotation for JSON::Serializable
has a root
property to specify a nested key which the parser unwraps.
require "json"
class Foo
include JSON::Serializable
@[JSON::Field(root: "value")]
property foo : String
end
Foo.from_json %({"foo": {"value": "bar"}}) # => #<Foo:0x7fe0894f1e60 @foo="bar">
This is limited to a single nesting layer though. If you want to unwrap more layers, you need to write a custom converter.
Sometimes the relevant information is nested in a deeper structure. It would be nice if root
could handle that as well.
It would be similar to JSON::Any#dig
.
An example use case is mentioned in https://forum.crystal-lang.org/t/complex-json-deserialization/6095
It should be a simple enhancement to allow root
to be a list of keys describing a path to unwrap.
Example usage:
require "json"
class Foo
include JSON::Serializable
@[JSON::Field(root: ["deeply", "nested", "value"])]
property foo : String
end
Foo.from_json %({"foo": {"deeply": {"nested": {"value": "bar"}}}}) # => #<Foo:0x7fe0894f1e60 @foo="bar">
The same should apply to the root
parameter of Object.from_json
.
The heavy lifting should probably happen in JSON::PullParser#on_key!
(which would also expose this functionality in this lower level API).