serdejsonany_key

View the docs on docs.rs

Workaround for \"key must be a string\" error with serde_json. De/serialize any HashMap, 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 K to a String. If K already is a String, it will behave identically to serde_json.

Serialization is implemented for any type that implements IntoIterator Deserialization is implemented for any type that implements FromIterator<(K,V)>.

De/serialization of structs with nested maps is supported via the following attributes:

[serde(with = "anykeyvec")]

[serde(with = "anykeymap")]

This crate is implemented purely using safe, stable Rust.

Example

```rust use std::collections::HashMap; use serde::{Serialize, Deserialize}; use serdejsonany_key::*;

[derive(Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, Debug)]

pub struct Test { pub a: i32, pub b: i32 }

fn main() { // Create a map with a struct key let mut map = HashMap::::new(); map.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9});

// Regular serdejson cannot serialize this map let fail = serdejson::tostring(&map); asserteq!(fail.err().unwrap().to_string(), "key must be a string");

// Use this crate's utility function // Outputs {"{\"a\":3,\"b\":5}":{"a":7,"b":9}} let ser1 = map.tojsonmap().unwrap(); assert_eq!(ser1, r#"{"{\"a\":3,\"b\":5}":{"a":7,"b":9}}"#);

// You can also serialize a Vec or slice of tuples to a JSON map let mut vec = Vec::<(Test, Test)>::new(); vec.push((Test {a: 3, b: 5}, Test {a: 7, b: 9})); let ser2 = vec.tojsonmap().unwrap();

// Output is identical in either case assert_eq!(ser1, ser2);

// And can be deserialized to either type let desermap: HashMap = jsontomap(&ser2).unwrap(); let deservec: Vec<(Test, Test)> = jsontovec(&ser1).unwrap(); asserteq!(map, desermap); asserteq!(vec, deservec);

// De/serialization of structs with nested maps is supported via the following attributes: // #[serde(with = "anykeyvec")] // #[serde(with = "anykeymap")]

// Both the "map" and "vec" fields will serialize identically - as a JSON map #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] pub struct NestedTest { #[serde(with = "anykeymap")] map: HashMap, #[serde(with = "anykeyvec")] vec: Vec<(Test, Test)> } let nested = NestedTest { map: map, vec: vec, }; // You can use the usual serdejson functions now let sernested = serdejson::tostring(&nested).unwrap(); let desernested: NestedTest = serdejson::fromstr(&sernested).unwrap(); asserteq!(nested, desernested); } ```