serde_json_any_key 1.0.0

Workaround for "key must be a string" error with serde_json. Serialize any HashMap<K,V>, Vec<K,V>, Iter<(&K,&V)>, or Iter<&(K,V)> as a JSON map.
Documentation

serde_json_any_key

Workaround for "key must be a string" error with serde_json. Serialize any HashMap<K,V>, Vec<K,V>, Iter<(&K,&V)>, or Iter<&(K,V)> as a JSON map. The output will be the same as if you manually serialized the struct key to a string.

Also supports deserialization to HashMap<K,V> or Vec<(K,V)>.

use std::collections::HashMap;
use serde::{Serialize, Deserialize};
use serde_json_any_key::*;

#[derive(Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
pub struct Test {
  pub a: i32,
  pub b: i32
}

fn main() {
  let mut map = HashMap::<Test, Test>::new();
  map.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9});

  // Fails with error: key must be a string
  let serialized = serde_json::to_string(&map);
  match serialized {
    Ok(serialized) => { println!("{}", serialized); }
    Err(e) => { println!("Error as expected: {}", e); }
  }

  // Long winded workaround that copies the map
  // Prints {"{\"a\":3,\"b\":5}":{"a":7,"b":9}}
  let string_map: HashMap<String, Test> = map.iter().map(|(k, &v)| (serde_json::to_string(k).unwrap(), v)).collect();
  let serialized = serde_json::to_string(&string_map).unwrap();
  println!("{}", serialized);
  
  // Use this crate's utility function - elements are serialized lazily
  // Same output
  let serialized = serde_json_any_key::map_to_json(&map).unwrap();
  println!("{}", serialized);

  // Utility function also exists for vec of tuples
  // Same output
  let vec = vec![(Test {a: 3, b: 5}, Test {a: 7, b: 9})];
  let serialized = serde_json_any_key::vec_to_json(&vec).unwrap();
  println!("{}", serialized);

  // Also supports any other data type that generates an Iter<&(K,V)> or Iter<(&K, &V)>
  // Same output
  let mut btree = std::collections::BTreeMap::<Test, Test>::new();
  btree.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9});
  let serialized = serde_json_any_key::map_iter_to_json(&mut btree.iter()).unwrap();
  println!("{}", serialized);

  // Also supports deserialization, back to HashMap or Vec
  let deserialized_map: HashMap<Test,Test> = serde_json_any_key::json_to_map(&serialized).unwrap();
  assert_eq!(map, deserialized_map);
  let deserialized_vec: Vec<(Test,Test)> = serde_json_any_key::json_to_vec(&serialized).unwrap();
  assert_eq!(vec, deserialized_vec);
}

Output:

Error as expected: key must be a string
{"{\"a\":3,\"b\":5}":{"a":7,"b":9}}
{"{\"a\":3,\"b\":5}":{"a":7,"b":9}}
{"{\"a\":3,\"b\":5}":{"a":7,"b":9}}
{"{\"a\":3,\"b\":5}":{"a":7,"b":9}}