I am struggling to instruct serde
to deserialize a JSON array of objects into a HashMap whose key is found from one of the fields of the object and value is a struct built out of the remaining keys of the object. Here's a simplified example:
[
{"name" : "John", "age" : 11, "registry" : true},
{"name" : "Clyde", "age" : 14, "registry" : false},
{"name" : "Bob", "age" : 12, "registry" : true}
]
Now I need to deserialize the whole JSON into AllPeople
with each object getting deserialized into Person
:
use std::collections::HashMap;
struct AllPeople(HashMap<String, Person>);
struct Person {
age: u32,
registry: bool,
}
I'd like for the value associated with the "name"
field of the JSON object to serve as the key for the AllPeople
map.
- Is there a way to achieve this using any macros provided by
serde
? - If not, how do I modify the behavior of deserialize to handle this?
You can do this by specifying a custom deserialization function in your wrapper via
#[serde(deserialize_with = "mappify")]
:Playground
Note that as mentioned in the issue linked by @ChayimFriedman, the performance benefits are questionable and probably not worth the wordiness. Possibly, the Vec is even faster, because it doesn't need to do the complicated resizing of a hashmap during adding.
Personally, I'd probably go with
Playground
Side note: I feel like
serde_with::serde_as
should be able to do that with something likebut I've only been able to get it to produce a
Vec<(String, Person)>
. If somebody can demonstrateserde_as
, that'd be neat.