Module bimap::serde

source ·
Expand description

Implementations of serde::Serialize and serde::Deserialize for BiHashMap and BiBTreeMap.

You do not need to import anything from this module to use this functionality, simply enable the serde feature in your dependency manifest. Note that currently, this requires the std feature to also be enabled, and thus cannot be used in no_std enviroments.

Examples

You can easily serialize and deserialize bimaps with any serde-compatbile serializer or deserializer.

Serializing and deserializing a BiHashMap:

// create a new bimap
let mut map = BiHashMap::new();

// insert some pairs
map.insert('A', 1);
map.insert('B', 2);
map.insert('C', 3);

// convert the bimap to json
let json = serde_json::to_string(&map).unwrap();

// convert the json back into a bimap
let map2 = serde_json::from_str(&json).unwrap();

// check that the two bimaps are equal
assert_eq!(map, map2);

Serializing and deserializing a BiBTreeMap:

// create a new bimap
let mut map = BiBTreeMap::new();

// insert some pairs
map.insert('A', 3);
map.insert('B', 2);
map.insert('C', 1);

// convert the bimap to json
let json = serde_json::to_string(&map).unwrap();

// convert the json back into a bimap
let map2 = serde_json::from_str(&json).unwrap();

// check that the two bimaps are equal
assert_eq!(map, map2);

Of course, this is only possible for bimaps where the values also implement Serialize and Deserialize respectively:

// this type doesn't implement Serialize or Deserialize!
#[derive(PartialEq, Eq, Hash)]
enum MyEnum { A, B, C }

// create a bimap and add some pairs
let mut map = BiHashMap::new();
map.insert(MyEnum::A, 1);
map.insert(MyEnum::B, 2);
map.insert(MyEnum::C, 3);

// this line will cause the code to fail to compile
let json = serde_json::to_string(&map).unwrap();

Implementation details

Bimaps are serialized and deserialized as a map data type in serde. Consequentially, it is possible to serialize and deserialize bimaps to/from other types that are represented the same way. This is considered an implementation detail and should not be relied upon.

For example, a bimap can be deserialized from the serialized form of a standard HashMap. However, deserializing a bimap silently overwrites any conflicting pairs, leading to non-deterministic results.

// construct a regular map
let mut map = HashMap::new();

// insert some entries
// note that both 'B' and 'C' are associated with the value 2 here
map.insert('A', 1);
map.insert('B', 2);
map.insert('C', 2);

// serialize the map
let json = serde_json::to_string(&map).unwrap();

// deserialize it into a bimap
let bimap: BiHashMap<char, i32> = serde_json::from_str(&json).unwrap();

// deserialization succeeds, but the bimap is now in a non-deterministic
// state - either ('B', 2) or ('C', 2) will have been overwritten while
// deserializing, but this depends on the iteration order of the original
// HashMap that was serialized.

// we can still demonstrate that certain properties of the bimap are still
// in a known state, but this shouldn't be relied upon
assert_eq!(bimap.len(), 2);
assert_eq!(bimap.get_by_left(&'A'), Some(&1));
assert!(bimap.get_by_left(&'B') == Some(&2) || bimap.get_by_left(&'C') == Some(&2))

The reverse is also possible: bimaps may be serialized and then deserialized as other compatible types, such as a HashMap.

// construct a bimap
let mut bimap = BiHashMap::new();

// insert some pairs
bimap.insert('A', 1);
bimap.insert('B', 2);
bimap.insert('C', 3);

// serialize the bimap
let json = serde_json::to_string(&bimap).unwrap();

// deserialize it as a regular map
let map: HashMap<char, i32> = serde_json::from_str(&json).unwrap();

// this succeeds and the result is sensible, but this is still an
// implementation detail and shouldn't be relied upon.
assert_eq!(map.len(), 3);
assert_eq!(map[&'A'], 1);
assert_eq!(map[&'B'], 2);
assert_eq!(map[&'C'], 3);