How do I use Serde to serialize a HashMap with structs as keys to JSON?

牧云@^-^@ 提交于 2019-12-22 05:29:27

问题


I want to serialize a HashMap with structs as keys:

extern crate serde_json; // 1.0.22
#[macro_use]
extern crate serde_derive; // 1.0.68

use std::collections::HashMap;

fn main() {
    #[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash)]
    struct Foo {
        x: u64,
    }

    #[derive(Serialize, Deserialize, Debug)]
    struct Bar {
        x: HashMap<Foo, f64>,
    }

    let mut p = Bar { x: HashMap::new() };
    p.x.insert(Foo { x: 0 }, 0.0);
    let serialized = serde_json::to_string(&p).unwrap();
}

This code compiles, but when I run it I get an error:

Error("key must be a string", line: 0, column: 0)'

I changed the code:

#[derive(Serialize, Deserialize, Debug)]
struct Bar {
    x: HashMap<u64, f64>,
}

let mut p = Bar { x: HashMap::new() };
p.x.insert(0, 0.0);
let serialized = serde_json::to_string(&p).unwrap();

The key in the HashMap is now a u64 instead of a string. Why does the first code give an error?


回答1:


In order to serialize your custom data type into JSON (or any other format), you need to implement the Serialize trait. Otherwise Serde doesn't know how to serialize your type.

It should go something along these lines:

impl Display for Foo {
    fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
        write!(f, "{}", self.x)
    }
}

impl Serialize for Bar {
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        let mut map = serializer.serialize_map(Some(self.x.len()))?;
        for (k, v) in &self.x {
            map.serialize_entry(&k.to_string(), &v)?;
        }
        map.end()
    }
}

(playground)

If your data structure is an enum, then you will need to change Foo's Display implementation.



来源:https://stackoverflow.com/questions/51276896/how-do-i-use-serde-to-serialize-a-hashmap-with-structs-as-keys-to-json

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!