Expand description

De/Serialize a Map into a list of tuples

Some formats, like JSON, have limitations on the type of keys for maps. In case of JSON, keys are restricted to strings. Rust features more powerful keys, for example tuple, which can not be serialized to JSON.

This helper serializes the Map into a list of tuples, which does not have the same type restrictions. The module can be applied on any type implementing IntoIterator<Item = (&'a K, &'a V)> and FromIterator<(K, V)>, with K and V being the key and value types. From the standard library both HashMap and BTreeMap fullfil the condition and can be used here.

Converting to serde_as

If the map is of type HashMap or BTreeMap the same functionality can be expressed more clearly using the serde_as macro. The _ is a placeholder which works for any type which implements Serialize/Deserialize, such as the tuple and u32 type.

#[serde_as]
#[derive(Deserialize, Serialize)]
struct A {
    #[serde_as(as = "Vec<(_, _)>")]
    hashmap: HashMap<(String, u32), u32>,
    #[serde_as(as = "Vec<(_, _)>")]
    btreemap: BTreeMap<(String, u32), u32>,
}

Examples

#[derive(Deserialize, Serialize)]
struct A {
    #[serde(with = "serde_with::rust::map_as_tuple_list")]
    s: BTreeMap<(String, u32), u32>,
}

let v: A = serde_json::from_value(json!({
    "s": [
        [["Hello", 123], 0],
        [["World", 456], 1]
    ]
})).unwrap();

assert_eq!(2, v.s.len());
assert_eq!(1, v.s[&("World".to_string(), 456)]);

The helper is generic over the hasher type of the HashMap and works with different variants, such as FnvHashMap.

use fnv::FnvHashMap;

#[derive(Deserialize, Serialize)]
struct A {
    #[serde(with = "serde_with::rust::map_as_tuple_list")]
    s: FnvHashMap<u32, bool>,
}

let v: A = serde_json::from_value(json!({
    "s": [
        [0, false],
        [1, true]
    ]
})).unwrap();

assert_eq!(2, v.s.len());
assert_eq!(true, v.s[&1]);

Functions

Deserialize a map from a list of tuples

Serialize the map as a list of tuples