This example code:
use std::collections::BTreeMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
struct Foo {
bar: String,
baz: Baz
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
enum Baz {
Quux(u32),
Flob,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
struct Bish {
bash: u16,
bosh: i8
}
fn main() -> std::io::Result<()> {
let mut btree: BTreeMap<Foo, Bish> = BTreeMap::new();
let foo = Foo {
bar: "thud".to_string(),
baz: Baz::Flob
};
let bish = Bish {
bash: 1,
bosh: 2
};
println!("foo: {}", serde_json::to_string(&foo)?);
println!("bish: {}", serde_json::to_string(&bish)?);
btree.insert(foo, bish);
println!("btree: {}", serde_json::to_string(&btree)?);
Ok(())
}
gives the runtime output/error:
foo: {"bar":"thud","baz":"Flob"}
bish: {"bash":1,"bosh":2}
Error: Custom { kind: InvalidData, error: Error("key must be a string", line: 0, column: 0) }
I've googled this, and found that the problem is that the serialiser would be trying to write:
{{"bar":"thud","baz":"Flob"}:{"bash":1,"bosh":2}}}
which is not valid JSON, as keys must be strings.
The internet tells me to write custom serialisers.
This is not a practical option, as I have a large number of different non-string keys.
How can I make serde_json serialise to (and deserialise from):
{"{\"bar\":\"thud\",\"baz\":\"Flob\"}":{"bash":1,"bosh":2}}
for arbitrary non-string keys in BTreeMap and HashMap?