I need to serialize and deserialize a HashMap, h
, with enum Foo
as a key to and from JSON. Foo
's variants contain data (here simplified to u32
, but actually are enums themselves):
use serde::{Serialize, Deserialize};
use serde_json;
use std::collections::HashMap;
#[derive(Serialize, Deserialize)]
enum Foo {
A(u32),
B(u32),
}
// Tried several different things here! Just deriving the relevant traits doesn't work.
struct Bar {
h: HashMap<Foo, i32>, // The i32 value type is arbitrary
}
fn main() {
let mut bar = Bar { h: HashMap::new() };
bar.h.insert(Foo::A(0), 1);
// I want to be able to do this
let bar_string = serde_json::to_string(&bar).unwrap();
let bar_deser: Bar = serde_json::from_str(&bar_string).unwrap();
}
Since the JSON specification requires keys to be strings I know I need to customise the way serialization and deserialization are done for Foo
when it is a key in h
. I've tried the following:
- Custom implementations of Serialize and Deserialize (e.g. in the accepted answer here)
- Serde attributes e.g.:
#[serde(into = "String", try_from = "String")]
+ implementingInto<String> for Foo
andTryFrom<String> for Foo
(described in the answers here) - Using the 'serde_with' crate (also described in the answers here).
Unfortunately none of these have worked - all eventually failed with different panics after compiling successfully.
What is a good way to achieve what I want in serde, if there is one? If not, I'd be very grateful for any workaround suggestions.
Bonus question: why doesn't serde/serde_json provide a default serialization to a String
+ deserialization of an enum like Foo
when it is used as a key in a HashMap
?