indexmap-rs / indexmap

A hash table with consistent order and fast iteration; access items by key or sequence index
https://docs.rs/indexmap/
Other
1.71k stars 150 forks source link

serde_json::to_string serializes (key, value) #325

Closed couleurm closed 5 months ago

couleurm commented 6 months ago

serde_seq says:

The default serde implementation serializes IndexMap as a normal map, but there is no guarantee that serialization formats will preserve the order of the key-value pairs. This module serializes IndexMap as a sequence of (key, value) elements instead, in order.

From what I understand, feeding a HashMap and IndexMap to serde_json::to_string end up serializing in a different structure (not talking about order)

For a HashMap<String, HashMap<String, String>:

https://gist.github.com/couleurm/5288b03750968ead5049b2f938c27b77

For an IndexMap<String, IndexMap<String, String>:

https://gist.github.com/couleurm/35c143f464d479290aafce5bf09bc4ba

Is this designed this way, and if yes are there known ways to replicate the original?

cuviper commented 6 months ago

Yes, serde_seq is designed that way as an explicit tradeoff to avoid serialized maps that don't preserve order. If you're only working with a known serialized format, you may have different options, like the serde_json/preserve_order feature.

couleurm commented 6 months ago

Do you have any usage examples? So far I'm using this quite scuffed workaround

old way with HashMaps:

let rc_string = serde_json::to_string(&recipe).expect("Failed serializing recipe to JSON");

I'm parsing and fixing up the debugger view and it suprisingly works

let rc_string = (format!("{:?}", &recipe)).replace("Recipe { data: {", "{ \"data\": {");

ps: recipe variable is of Recipe type

cuviper commented 6 months ago

I don't understand what example you're asking for -- serde_json::to_string should work just fine with IndexMap too, as long as you've enabled the indexmap/serde feature. And if you need to maintain the indexmap order in that json, enable the serde_json/preserve_order feature too.