├── .gitignore ├── .vscode ├── settings.json └── launch.json ├── Cargo.toml ├── UNLICENSE ├── src ├── json_to_vec.rs ├── json_to_map.rs ├── serde_with_utils.rs ├── json_to_iter.rs ├── lib.rs ├── vec_iter_to_json.rs ├── map_iter_to_json.rs ├── consuming_iter_to_json.rs ├── main.rs ├── any_key_map.rs └── any_key_vec.rs ├── README.md └── tests └── mod.rs /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | Cargo.lock 3 | **/*.rs.bk 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2, 3 | "editor.detectIndentation": false 4 | } -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "serde_json_any_key" 3 | version = "2.0.0" 4 | edition = "2021" 5 | license = "Unlicense" 6 | repository = "https://github.com/tzcnt/serde_json_any_key/" 7 | description = "Workaround for \"key must be a string\" error with serde_json. De/serialize any HashMap, Vec, Iter<(&K,&V)>, or Iter<&(K,V)> as a JSON map." 8 | keywords = ["serde_json", "hashmap", "iterator", "struct", "key"] 9 | categories = ["encoding"] 10 | exclude = ["main.rs", ".vscode/"] 11 | 12 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 13 | 14 | [dependencies] 15 | serde = {version="1",features=["derive"]} 16 | serde_json = "1" 17 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /src/json_to_vec.rs: -------------------------------------------------------------------------------- 1 | 2 | use std::any::{Any, TypeId}; 3 | use serde::ser::Error; 4 | use serde::de::Deserialize; 5 | 6 | /// Reverses to_json_map(), returning a `Vec<(K,V)>`. 7 | /// 8 | /// # Examples 9 | /// ``` 10 | /// use serde::{Serialize, Deserialize}; 11 | /// use serde_json::Error; 12 | /// use serde_json_any_key::*; 13 | /// 14 | /// #[derive(Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, Debug)] 15 | /// pub struct Test { 16 | /// pub a: i32, 17 | /// pub b: i32 18 | /// } 19 | /// 20 | /// fn try_main() -> Result<(), Error> { 21 | /// let vec: Vec<(Test,Test)> = vec![(Test {a: 3, b: 5}, Test {a: 7, b: 9})]; 22 | /// 23 | /// let ser = vec.to_json_map().unwrap(); 24 | /// let deser: Vec<(Test,Test)> = json_to_vec(&ser).unwrap(); 25 | /// 26 | /// assert_eq!(vec, deser); 27 | /// Ok(()) } 28 | /// try_main().unwrap(); 29 | /// ``` 30 | pub fn json_to_vec<'a,K,V>(str: &'a str) -> Result, serde_json::Error> where 31 | for<'de> K: Deserialize<'de> + Any, 32 | for<'de> V: Deserialize<'de> 33 | { 34 | let mut vec: Vec<(K,V)> = vec![]; 35 | let v: serde_json::Value = serde_json::from_str(&str)?; 36 | let o = v.as_object().ok_or(serde_json::Error::custom("Value is not a JSON map"))?; 37 | // handle strings specially as they are not objects 38 | // compiler seems to be able to optimize this branch away statically 39 | if TypeId::of::() == TypeId::of::() { 40 | for (key, val) in o.iter() { 41 | let key_obj: K = ::deserialize(serde_json::Value::from(key.as_str()))?; 42 | let val_obj: V = ::deserialize(val)?; 43 | vec.push((key_obj, val_obj)); 44 | } 45 | } else { 46 | for (key, val) in o.iter() { 47 | let key_obj: K = serde_json::from_str(key)?; 48 | let val_obj: V = ::deserialize(val)?; 49 | vec.push((key_obj, val_obj)); 50 | } 51 | } 52 | Ok(vec) 53 | } 54 | -------------------------------------------------------------------------------- /src/json_to_map.rs: -------------------------------------------------------------------------------- 1 | 2 | use std::any::{Any, TypeId}; 3 | use std::hash::Hash; 4 | use serde::ser::Error; 5 | use serde::de::Deserialize; 6 | 7 | /// Reverses to_json_map(), returning a `HashMap`. 8 | /// 9 | /// # Examples 10 | /// ``` 11 | /// use std::collections::HashMap; 12 | /// use serde::{Serialize, Deserialize}; 13 | /// use serde_json::Error; 14 | /// use serde_json_any_key::*; 15 | /// 16 | /// #[derive(Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, Debug)] 17 | /// pub struct Test { 18 | /// pub a: i32, 19 | /// pub b: i32 20 | /// } 21 | /// 22 | /// fn try_main() -> Result<(), Error> { 23 | /// let mut map = HashMap::::new(); 24 | /// map.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 25 | /// 26 | /// let ser = map.to_json_map().unwrap(); 27 | /// let deser: HashMap = json_to_map(&ser).unwrap(); 28 | /// 29 | /// assert_eq!(map, deser); 30 | /// Ok(()) } 31 | /// try_main().unwrap(); 32 | /// ``` 33 | pub fn json_to_map<'a,K,V>(str: &'a str) -> Result, serde_json::Error> where 34 | for<'de> K: Deserialize<'de> + std::cmp::Eq + Hash + Any, 35 | for<'de> V: Deserialize<'de> 36 | { 37 | let mut map: std::collections::HashMap = std::collections::HashMap::new(); 38 | let v: serde_json::Value = serde_json::from_str(&str)?; 39 | let o = v.as_object().ok_or(serde_json::Error::custom("Value is not a JSON map"))?; 40 | // handle strings specially as they are not objects 41 | // compiler seems to be able to optimize this branch away statically 42 | if TypeId::of::() == TypeId::of::() { 43 | for (key, val) in o.iter() { 44 | let key_obj: K = ::deserialize(serde_json::Value::from(key.as_str()))?; 45 | let val_obj: V = ::deserialize(val)?; 46 | map.insert(key_obj, val_obj); 47 | } 48 | } else { 49 | for (key, val) in o.iter() { 50 | let key_obj: K = serde_json::from_str(key)?; 51 | let val_obj: V = ::deserialize(val)?; 52 | map.insert(key_obj, val_obj); 53 | } 54 | } 55 | Ok(map) 56 | } 57 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "lldb", 9 | "request": "launch", 10 | "name": "Debug executable 'serde_json_any_key' (Debug)", 11 | "cargo": { 12 | "args": [ 13 | "build", 14 | "--bin=serde_json_any_key", 15 | "--package=serde_json_any_key" 16 | ], 17 | "filter": { 18 | "name": "serde_json_any_key", 19 | "kind": "bin" 20 | } 21 | }, 22 | "args": [], 23 | "cwd": "${workspaceFolder}" 24 | }, 25 | { 26 | "type": "lldb", 27 | "request": "launch", 28 | "name": "Debug executable 'serde_json_any_key' (Release)", 29 | "cargo": { 30 | "args": [ 31 | "build", 32 | "--bin=serde_json_any_key", 33 | "--package=serde_json_any_key", 34 | "--profile=release" 35 | ], 36 | "filter": { 37 | "name": "serde_json_any_key", 38 | "kind": "bin" 39 | } 40 | }, 41 | "args": [], 42 | "cwd": "${workspaceFolder}" 43 | }, 44 | { 45 | "type": "lldb", 46 | "request": "launch", 47 | "name": "Debug unit tests in 'serde_json_any_key' (Debug)", 48 | "cargo": { 49 | "args": [ 50 | "test", 51 | "--package=serde_json_any_key" 52 | ], 53 | "filter": { 54 | "name": "serde_json_any_key", 55 | "kind": "lib" 56 | } 57 | }, 58 | "args": [], 59 | "cwd": "${workspaceFolder}" 60 | }, 61 | { 62 | "type": "lldb", 63 | "request": "launch", 64 | "name": "Debug unit tests in 'serde_json_any_key' (Release)", 65 | "cargo": { 66 | "args": [ 67 | "test", 68 | "--package=serde_json_any_key", 69 | "--profile=release" 70 | ], 71 | "filter": { 72 | "name": "serde_json_any_key", 73 | "kind": "lib" 74 | } 75 | }, 76 | "args": [], 77 | "cwd": "${workspaceFolder}" 78 | } 79 | ] 80 | } 81 | -------------------------------------------------------------------------------- /src/serde_with_utils.rs: -------------------------------------------------------------------------------- 1 | 2 | use std::any::{Any, TypeId}; 3 | use std::marker::PhantomData; 4 | use serde::de::{Deserialize, Deserializer, Visitor}; 5 | use serde::de::{MapAccess}; 6 | use std::fmt; 7 | 8 | // Some utilities required to implement any_key_map / any_key_vec 9 | 10 | pub struct MapIter<'de,A,K,V> { 11 | pub access: A, 12 | marker: PhantomData<(&'de (),K,V)>, 13 | } 14 | 15 | impl<'de,A,K,V> MapIter<'de,A,K,V> { 16 | pub fn new(access: A) -> Self 17 | where 18 | A: serde::de::MapAccess<'de>, 19 | { 20 | Self { 21 | access, 22 | marker: PhantomData, 23 | } 24 | } 25 | } 26 | 27 | impl<'de,A,K,V> Iterator for MapIter<'de,A,K,V> 28 | where 29 | A: serde::de::MapAccess<'de>, 30 | K: Deserialize<'de>, 31 | V: Deserialize<'de>, 32 | { 33 | type Item = Result<(K,V), A::Error>; 34 | 35 | fn next(&mut self) -> Option { 36 | self.access.next_entry().transpose() 37 | } 38 | 39 | fn size_hint(&self) -> (usize, Option) { 40 | match self.access.size_hint() { 41 | Some(size) => (size, Some(size)), 42 | None => (0, None), 43 | } 44 | } 45 | } 46 | 47 | // any_key_map and any_key_vec use the same deserialize function 48 | #[inline] 49 | pub fn deserialize<'d,D,C,K,V>(deserializer: D) -> Result where 50 | D: Deserializer<'d>, 51 | C: FromIterator<(K,V)> + Sized, 52 | for<'de> K: Deserialize<'de> + Any + 'd, 53 | for<'de> V: Deserialize<'de> + 'd, 54 | { 55 | struct Helper(PhantomData<(C,K,V)>); 56 | impl<'d,C,K,V> Visitor<'d> for Helper 57 | where 58 | C: FromIterator<(K,V)> + Sized, 59 | for<'de> K: Deserialize<'de> + Any + 'd, 60 | for<'de> V: Deserialize<'de> + 'd 61 | { 62 | type Value = C; 63 | 64 | fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { 65 | write!(formatter, "a JSON map") 66 | } 67 | 68 | fn visit_map(self, seq: A) -> Result 69 | where 70 | A: MapAccess<'d>, 71 | { 72 | // https://stackoverflow.com/a/26370894/19260728 73 | let coll: Result = MapIter::<'d, A, String, V>::new(seq) 74 | .map(|res| { 75 | res.and_then(|value: (String,V)| { 76 | // handle strings specially as they are not objects 77 | // compiler seems to be able to optimize this branch away statically 78 | let key_obj: K = match TypeId::of::() == TypeId::of::() { 79 | true => match ::deserialize(serde_json::Value::from(value.0)) { 80 | Ok(k) => k, 81 | Err(e) => { return Err(e).map_err(serde::de::Error::custom); } 82 | }, 83 | false => match serde_json::from_str(&value.0) { 84 | Ok(k) => k, 85 | Err(e) => { return Err(e).map_err(serde::de::Error::custom); } 86 | } 87 | }; 88 | Ok((key_obj, value.1)) 89 | }) 90 | }).collect(); 91 | coll 92 | } 93 | } 94 | 95 | deserializer.deserialize_map(Helper(PhantomData)) 96 | } 97 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## serde_json_any_key 2 | #### [View the docs on docs.rs](https://docs.rs/serde_json_any_key/latest/serde_json_any_key/) 3 | 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. 4 | 5 | The output will be the same as if you manually serialized K to a String. 6 | If K already is a String, it will behave identically to serde_json. 7 | 8 | Serialization is implemented for any type that implements IntoIterator, IntoIterator, or IntoIterator. 9 | Deserialization is implemented for any type that implements FromIterator<(K,V)>. 10 | 11 | De/serialization of structs with nested maps is supported via the following attributes: 12 | #[serde(with = "any_key_vec")] 13 | #[serde(with = "any_key_map")] 14 | 15 | All de/serialization is done in a single pass, with no intermediate collection. 16 | 17 | This crate is implemented purely using safe, stable Rust. 18 | 19 | ## Example 20 | 21 | ```rust 22 | use std::collections::HashMap; 23 | use serde::{Serialize, Deserialize}; 24 | use serde_json_any_key::*; 25 | 26 | #[derive(Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, Debug)] 27 | pub struct Test { 28 | pub a: i32, 29 | pub b: i32 30 | } 31 | 32 | fn main() { 33 | // Create a map with a struct key 34 | let mut map = HashMap::::new(); 35 | map.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 36 | 37 | // Regular serde_json cannot serialize this map 38 | let fail = serde_json::to_string(&map); 39 | assert_eq!(fail.err().unwrap().to_string(), "key must be a string"); 40 | 41 | // Use this crate's utility function 42 | // Outputs {"{\"a\":3,\"b\":5}":{"a":7,"b":9}} 43 | let ser1 = map.to_json_map().unwrap(); 44 | assert_eq!(ser1, r#"{"{\"a\":3,\"b\":5}":{"a":7,"b":9}}"#); 45 | 46 | // You can also serialize a Vec or slice of tuples to a JSON map 47 | let mut vec = Vec::<(Test, Test)>::new(); 48 | vec.push((Test {a: 3, b: 5}, Test {a: 7, b: 9})); 49 | let ser2 = vec.to_json_map().unwrap(); 50 | 51 | // Output is identical in either case 52 | assert_eq!(ser1, ser2); 53 | 54 | // And can be deserialized to either type 55 | let deser_map: HashMap = json_to_map(&ser2).unwrap(); 56 | let deser_vec: Vec<(Test, Test)> = json_to_vec(&ser1).unwrap(); 57 | assert_eq!(map, deser_map); 58 | assert_eq!(vec, deser_vec); 59 | 60 | // De/serialization of structs with nested maps is supported via the following attributes: 61 | // #[serde(with = "any_key_vec")] 62 | // #[serde(with = "any_key_map")] 63 | 64 | // Both the "map" and "vec" fields will serialize identically - as a JSON map 65 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 66 | pub struct NestedTest { 67 | #[serde(with = "any_key_map")] 68 | map: HashMap, 69 | #[serde(with = "any_key_vec")] 70 | vec: Vec<(Test, Test)> 71 | } 72 | let nested = NestedTest { 73 | map: map, 74 | vec: vec, 75 | }; 76 | // You can use the usual serde_json functions now 77 | let ser_nested = serde_json::to_string(&nested).unwrap(); 78 | let deser_nested: NestedTest = serde_json::from_str(&ser_nested).unwrap(); 79 | assert_eq!(nested, deser_nested); 80 | } 81 | ``` 82 | 83 | This crate is not abandoned; there just hasn't been any reason to make changes since the initial release. I'm available to fix any issues that arise. 84 | -------------------------------------------------------------------------------- /src/json_to_iter.rs: -------------------------------------------------------------------------------- 1 | 2 | use std::any::{Any, TypeId}; 3 | use serde::ser::Error; 4 | use serde::de::Deserialize; 5 | 6 | /// Reverses to_json_map(), returning an `Iterator>`. 7 | /// 8 | /// Note that because JSON deserialization may fail for any individual element of the map, 9 | /// you will need to check for errors with each element returned from the iterator. 10 | /// 11 | /// # Examples 12 | /// ``` 13 | /// use std::collections::{BTreeMap, HashMap}; 14 | /// use serde::{Serialize, Deserialize}; 15 | /// use serde_json::Error; 16 | /// use serde_json_any_key::*; 17 | /// 18 | /// #[derive(Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, Debug, Ord, PartialOrd)] 19 | /// pub struct Test { 20 | /// pub a: i32, 21 | /// pub b: i32 22 | /// } 23 | /// 24 | /// fn try_main() -> Result<(), Error> { 25 | /// let mut map = HashMap::::new(); 26 | /// map.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 27 | /// let ser = map.to_json_map().unwrap(); 28 | /// 29 | /// // Contruct any type of collection using from_iter(), collect(), or extend() 30 | /// let deser1: HashMap = HashMap::from_iter(json_to_iter::(&ser).unwrap().map(|x| x.unwrap())); 31 | /// assert_eq!(map, deser1); 32 | /// 33 | /// let deser2: BTreeMap = json_to_iter::(&ser).unwrap().map(|x| x.unwrap()).collect(); 34 | /// 35 | /// let mut deser3: Vec<(Test, Test)> = Vec::new(); 36 | /// deser3.extend(json_to_iter::(&ser).unwrap().map(|x| x.unwrap())); 37 | /// Ok(()) } 38 | /// try_main().unwrap(); 39 | /// ``` 40 | pub fn json_to_iter(str: &str) -> Result>, serde_json::Error> where 41 | for<'de> K: Deserialize<'de> + Any, 42 | for<'de> V: Deserialize<'de> 43 | { 44 | let json_value = serde_json::from_str(&str)?; 45 | let json_map = match json_value { 46 | serde_json::Value::Object(map) => map, 47 | _ => { return Err(serde_json::Error::custom("Value is not a JSON map")); }, 48 | }; 49 | Ok(JsonToTupleIter { 50 | iter: json_map.into_iter(), 51 | kv: std::marker::PhantomData 52 | }) 53 | } 54 | 55 | /// Return type of [json_to_iter()](fn.json_to_iter.html). It implements `Iterator>`. 56 | struct JsonToTupleIter { 57 | iter: serde_json::map::IntoIter, 58 | kv: std::marker::PhantomData<(K,V)>, 59 | } 60 | 61 | 62 | impl Iterator for JsonToTupleIter where 63 | for<'de> K: Deserialize<'de> + Any, 64 | for<'de> V: Deserialize<'de> 65 | { 66 | type Item = Result<(K,V), serde_json::Error>; 67 | fn next(&mut self) -> Option { 68 | match self.iter.next() { 69 | Some(a) => { 70 | // handle strings specially as they are not objects 71 | // compiler seems to be able to optimize this branch away statically 72 | let key_obj: K = match TypeId::of::() == TypeId::of::() { 73 | true => match ::deserialize(serde_json::Value::from(a.0)) { 74 | Ok(k) => k, 75 | Err(e) => { return Some(Err(e)); } 76 | }, 77 | false => match serde_json::from_str(&a.0) { 78 | Ok(k) => k, 79 | Err(e) => { return Some(Err(e)); } 80 | } 81 | }; 82 | let val_obj: V = match ::deserialize(a.1) { 83 | Ok(v) => v, 84 | Err(e) => { return Some(Err(e)); } 85 | }; 86 | Some(Ok((key_obj, val_obj))) 87 | }, 88 | None => None 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! ##### Why? : serde_json will not serialize JSON maps where the key is not a string, such as `i32` or `struct` types. 2 | //! ##### What?: This crate simplifies the process of converting the key to/from a string that serde_json is happy with. 3 | //! 4 | //! To serialize a collection, simply call `.to_json_map()`. It's implemented for both [Map-like](trait.MapIterToJson.html#method.to_json_map) and [Vec-like](trait.VecIterToJson.html#method.to_json_map) structures. 5 | //! There is also a version that consumes/moves out of the collection: [.into_json_map()](trait.ConsumingIterToJson.html#method.into_json_map). 6 | //! 7 | //! You can deserialize into a [HashMap](fn.json_to_map.html), [Vec of tuples](fn.json_to_vec.html), or [any other collection via Iterator](fn.json_to_iter.html) and the string key will be automatically converted back into the native type. 8 | //! 9 | //! De/serialization of structs with nested maps is supported via the following attributes: 10 | //! [#[serde(with = "any_key_map")]](any_key_map/index.html) 11 | //! [#[serde(with = "any_key_vec")]](any_key_vec/index.html) 12 | //! ``` 13 | //! use std::collections::HashMap; 14 | //! use serde::{Serialize, Deserialize}; 15 | //! use serde_json::Error; 16 | //! use serde_json_any_key::*; 17 | //! 18 | //! #[derive(Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, Debug)] 19 | //! pub struct Test { 20 | //! pub a: i32, 21 | //! pub b: i32 22 | //! } 23 | //! 24 | //! fn try_main() -> Result<(), Error> { 25 | //! 26 | //! // Create a map with a struct key 27 | //! let mut map = HashMap::::new(); 28 | //! map.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 29 | //! 30 | //! // Regular serde_json cannot serialize this map 31 | //! let fail = serde_json::to_string(&map); 32 | //! assert_eq!(fail.err().unwrap().to_string(), "key must be a string"); 33 | //! 34 | //! // Use this crate's utility function 35 | //! // Outputs {"{\"a\":3,\"b\":5}":{"a":7,"b":9}} 36 | //! let ser1 = map.to_json_map().unwrap(); 37 | //! 38 | //! // You can also serialize a Vec or slice of tuples to a JSON map 39 | //! let mut vec = Vec::<(Test, Test)>::new(); 40 | //! vec.push((Test {a: 3, b: 5}, Test {a: 7, b: 9})); 41 | //! let ser2 = vec.to_json_map().unwrap(); 42 | //! 43 | //! // Output is identical in either case 44 | //! assert_eq!(ser1, ser2); 45 | //! 46 | //! // And can be deserialized to either type 47 | //! let deser_map: HashMap = json_to_map(&ser2).unwrap(); 48 | //! let deser_vec: Vec<(Test, Test)> = json_to_vec(&ser1).unwrap(); 49 | //! assert_eq!(map, deser_map); 50 | //! assert_eq!(vec, deser_vec); 51 | //! 52 | //! // De/serialization of structs with nested maps is supported via the following attributes: 53 | //! // #[serde(with = "any_key_vec")] 54 | //! // #[serde(with = "any_key_map")] 55 | //! 56 | //! // Both the "map" and "vec" fields will serialize identically - as a JSON map 57 | //! #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 58 | //! pub struct NestedTest { 59 | //! #[serde(with = "any_key_map")] 60 | //! map: HashMap, 61 | //! #[serde(with = "any_key_vec")] 62 | //! vec: Vec<(Test, Test)> 63 | //! } 64 | //! let nested = NestedTest { 65 | //! map: map, 66 | //! vec: vec, 67 | //! }; 68 | //! // You can use the usual serde_json functions now 69 | //! let ser_nested = serde_json::to_string(&nested).unwrap(); 70 | //! let deser_nested: NestedTest = serde_json::from_str(&ser_nested).unwrap(); 71 | //! assert_eq!(nested, deser_nested); 72 | //! Ok(()) } 73 | //! try_main().unwrap(); 74 | //! ``` 75 | 76 | // modules 77 | mod json_to_map; 78 | mod json_to_vec; 79 | mod json_to_iter; 80 | mod map_iter_to_json; 81 | mod vec_iter_to_json; 82 | mod consuming_iter_to_json; 83 | mod serde_with_utils; 84 | 85 | // exports 86 | pub use json_to_map::json_to_map; 87 | pub use json_to_vec::json_to_vec; 88 | pub use json_to_iter::json_to_iter; 89 | pub use map_iter_to_json::MapIterToJson; 90 | pub use vec_iter_to_json::VecIterToJson; 91 | pub use consuming_iter_to_json::ConsumingIterToJson; 92 | pub mod any_key_map; 93 | pub mod any_key_vec; 94 | -------------------------------------------------------------------------------- /src/vec_iter_to_json.rs: -------------------------------------------------------------------------------- 1 | 2 | use std::any::{Any, TypeId}; 3 | use std::cell::RefCell; 4 | use serde::ser::{Serialize, Serializer, SerializeMap, Error}; 5 | 6 | /// Blanket impl [to_json_map()](trait.VecIterToJson.html#method.to_json_map) for all `IntoIterator` types. 7 | pub trait VecIterToJson<'a,K,V>: IntoIterator where 8 | Self: Sized, 9 | K: 'a + Serialize + Any, 10 | V: 'a + Serialize, 11 | ::IntoIter: 'a 12 | { 13 | /// Serialize any `IntoIterator<&(K,V)>` to a JSON map. This includes, but is not limited to, the following example types: 14 | /// `Vec<(K,V)>` 15 | /// return type of `Vec<(K,V)>::iter()` 16 | /// 17 | /// To create the JSON map keys, `serde_json::to_string()` will be called on each K element. 18 | /// 19 | /// **This does not consume self**, and is not compatible with consuming iterators, such as those returned by the common 20 | /// `std::collections::Type::into_iter()` function. For those consuming iterators, call [into_json_map()](trait.ConsumingIterToJson.html#method.into_json_map) instead. 21 | /// 22 | /// # Examples 23 | /// ``` 24 | /// use std::collections::HashMap; 25 | /// use serde::Serialize; 26 | /// use serde_json::Error; 27 | /// use serde_json_any_key::*; 28 | /// 29 | /// #[derive(Clone, Copy, Serialize, PartialEq, Eq, Hash)] 30 | /// pub struct Test { 31 | /// pub a: i32, 32 | /// pub b: i32 33 | /// } 34 | /// 35 | /// fn try_main() -> Result<(), Error> { 36 | /// let mut vec = Vec::<(Test, Test)>::new(); 37 | /// vec.push((Test {a: 3, b: 5}, Test {a: 7, b: 9})); 38 | /// 39 | /// // Regular serde_json will serialize this as an array, not a map. 40 | /// // Outputs [[{"a":3,"b":5},{"a":7,"b":9}]] 41 | /// let ser1 = serde_json::to_string(&vec).unwrap(); 42 | /// assert_eq!(ser1, "[[{\"a\":3,\"b\":5},{\"a\":7,\"b\":9}]]"); 43 | /// 44 | /// // Use this crate's utility function - elements are serialized lazily. 45 | /// // Outputs {"{\"a\":3,\"b\":5}":{"a":7,"b":9}} 46 | /// let ser2 = vec.to_json_map().unwrap(); // vec.iter().to_json_map() is also valid 47 | /// 48 | /// assert_eq!(ser2, "{\"{\\\"a\\\":3,\\\"b\\\":5}\":{\"a\":7,\"b\":9}}"); 49 | /// Ok(()) } 50 | /// try_main().unwrap(); 51 | /// ``` 52 | fn to_json_map(self) -> Result { 53 | serde_json::to_string(&SerializeVecIterWrapper { 54 | iter: RefCell::new(self.into_iter()) 55 | }) 56 | } 57 | } 58 | 59 | impl<'a,K,V,T: IntoIterator> VecIterToJson<'a,K,V> for T where 60 | T: IntoIterator, 61 | K: 'a + Serialize + Any, 62 | V: 'a + Serialize, 63 | ::IntoIter: 'a 64 | { } 65 | 66 | pub(crate) struct SerializeVecIterWrapper<'a,K,V,I> where 67 | I: Iterator, 68 | K: 'a, 69 | V: 'a, 70 | { 71 | pub iter: RefCell 72 | } 73 | 74 | impl<'a,K,V,I> Serialize for SerializeVecIterWrapper<'a,K,V,I> where 75 | I: Iterator, 76 | K: Serialize + Any, 77 | V: Serialize, 78 | { 79 | fn serialize(&self, serializer: S) -> Result where 80 | S: Serializer 81 | { 82 | let mut ser_map = serializer.serialize_map(None)?; 83 | let mut iter = self.iter.borrow_mut(); 84 | // handle strings specially so they don't get escaped and wrapped inside another string 85 | // compiler seems to be able to optimize this branch away statically 86 | if TypeId::of::() == TypeId::of::() { 87 | while let Some((k, v)) = iter.next() { 88 | let s = (k as &dyn Any).downcast_ref::().ok_or(S::Error::custom("Failed to serialize String as string"))?; 89 | ser_map.serialize_entry(s, &v)?; 90 | } 91 | } else { 92 | while let Some((k, v)) = iter.next() { 93 | ser_map.serialize_entry(match &serde_json::to_string(&k) 94 | { 95 | Ok(key_string) => key_string, 96 | Err(e) => { return Err(e).map_err(S::Error::custom); } 97 | }, &v)?; 98 | } 99 | } 100 | ser_map.end() 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/map_iter_to_json.rs: -------------------------------------------------------------------------------- 1 | 2 | use std::any::{Any, TypeId}; 3 | use std::cell::RefCell; 4 | use serde::ser::{Serialize, Serializer, SerializeMap, Error}; 5 | 6 | /// Blanket impl [to_json_map()](trait.MapIterToJson.html#method.to_json_map) for all `IntoIterator` types. 7 | pub trait MapIterToJson<'a,K,V>: IntoIterator where 8 | Self: Sized, 9 | K: 'a + Serialize + Any, 10 | V: 'a + Serialize, 11 | ::IntoIter: 'a 12 | { 13 | /// Serialize any `IntoIterator<(&K,&V)>` to a JSON map. This includes, but is not limited to, the following example types: 14 | /// `HashMap` 15 | /// return type of `HashMap::iter()` 16 | /// `BTreeMap` 17 | /// return type of `BTreeMap::iter()` 18 | /// 19 | /// To create the JSON map keys, `serde_json::to_string()` will be called on each K element. 20 | /// 21 | /// **This does not consume self**, and is not compatible with consuming iterators, such as those returned by the common 22 | /// `std::collections::Type::into_iter()` function. For those consuming iterators, call [into_json_map()](trait.ConsumingIterToJson.html#method.into_json_map) instead. 23 | /// 24 | /// # Examples 25 | /// ``` 26 | /// use std::collections::HashMap; 27 | /// use serde::Serialize; 28 | /// use serde_json::Error; 29 | /// use serde_json_any_key::*; 30 | /// 31 | /// #[derive(Clone, Copy, Serialize, PartialEq, Eq, Hash)] 32 | /// pub struct Test { 33 | /// pub a: i32, 34 | /// pub b: i32 35 | /// } 36 | /// 37 | /// fn try_main() -> Result<(), Error> { 38 | /// let mut map = HashMap::::new(); 39 | /// map.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 40 | /// 41 | /// // Regular serde_json cannot serialize this map. 42 | /// let fail = serde_json::to_string(&map); 43 | /// assert_eq!(fail.err().unwrap().to_string(), "key must be a string"); 44 | /// 45 | /// // Use this crate's utility function - elements are serialized lazily. 46 | /// // Outputs {"{\"a\":3,\"b\":5}":{"a":7,"b":9}} 47 | /// let ser1 = map.to_json_map().unwrap(); // map.iter().to_json_map() is also valid 48 | /// 49 | /// // Compare to a long-winded workaround that constructs a new intermediate map. 50 | /// // Same output 51 | /// let string_map: HashMap = map.iter().map(|(k, &v)| (serde_json::to_string(k).unwrap(), v)).collect(); 52 | /// let ser2 = serde_json::to_string(&string_map).unwrap(); 53 | /// 54 | /// assert_eq!(ser1, ser2); 55 | /// Ok(()) } 56 | /// try_main().unwrap(); 57 | /// ``` 58 | fn to_json_map(self) -> Result { 59 | serde_json::to_string(&SerializeMapIterWrapper { 60 | iter: RefCell::new(self.into_iter()) 61 | }) 62 | } 63 | } 64 | 65 | impl<'a,K,V,T> MapIterToJson<'a,K,V> for T where 66 | T: IntoIterator, 67 | K: 'a + Serialize + Any, 68 | V: 'a + Serialize, 69 | ::IntoIter: 'a 70 | { } 71 | 72 | pub(crate) struct SerializeMapIterWrapper<'a,K,V,I> where 73 | I: Iterator, 74 | K: 'a, 75 | V: 'a 76 | { 77 | pub iter: RefCell 78 | } 79 | 80 | impl<'a,K,V,I> Serialize for SerializeMapIterWrapper<'a,K,V,I> where 81 | I: Iterator, 82 | K: Serialize + Any, 83 | V: Serialize, 84 | { 85 | fn serialize(&self, serializer: S) -> Result where 86 | S: Serializer 87 | { 88 | let mut ser_map = serializer.serialize_map(None)?; 89 | let mut iter = self.iter.borrow_mut(); 90 | // handle strings specially so they don't get escaped and wrapped inside another string 91 | // compiler seems to be able to optimize this branch away statically 92 | if TypeId::of::() == TypeId::of::() { 93 | while let Some((k, v)) = iter.next() { 94 | let s = (k as &dyn Any).downcast_ref::().ok_or(S::Error::custom("Failed to serialize String as string"))?; 95 | ser_map.serialize_entry(s, &v)?; 96 | } 97 | } else { 98 | while let Some((k, v)) = iter.next() { 99 | ser_map.serialize_entry(match &serde_json::to_string(&k) 100 | { 101 | Ok(key_string) => key_string, 102 | Err(e) => { return Err(e).map_err(S::Error::custom); } 103 | }, &v)?; 104 | } 105 | } 106 | ser_map.end() 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/consuming_iter_to_json.rs: -------------------------------------------------------------------------------- 1 | 2 | use std::any::{Any, TypeId}; 3 | use std::cell::RefCell; 4 | use serde::ser::{Serialize, Serializer, SerializeMap, Error}; 5 | 6 | /// Blanket impl [into_json_map()](trait.ConsumingIterToJson.html#method.into_json_map) for all `IntoIterator` types. 7 | pub trait ConsumingIterToJson<'a,K,V>: IntoIterator where 8 | Self: Sized, 9 | K: Serialize + Any, 10 | V: Serialize, 11 | ::IntoIter: 'a 12 | { 13 | /// Serialize any `IntoIterator<(K,V)>` to a JSON map. This includes, but is not limited to, the following example types: 14 | /// `HashMap` 15 | /// return type of `HashMap::into_iter()` 16 | /// `Vec<(K,V)>` 17 | /// return type of `Vec<(K,V)>::into_iter()` 18 | /// 19 | /// To create the JSON map keys, `serde_json::to_string()` will be called on each K element. 20 | /// 21 | /// **This consumes self**, and is not compatible with non-consuming iterators, such as those returned by the common 22 | /// `std::collections::Type::iter()` function. For those non-consuming iterators, call `to_json_map()` instead: 23 | /// [For Map-like types](trait.MapIterToJson.html#method.to_json_map) 24 | /// [For Vec-like types](trait.VecIterToJson.html#method.to_json_map) 25 | /// 26 | /// # Examples 27 | /// ``` 28 | /// use std::collections::{HashMap, BTreeMap}; 29 | /// use serde::Serialize; 30 | /// use serde_json::Error; 31 | /// use serde_json_any_key::*; 32 | /// 33 | /// #[derive(Clone, Copy, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord)] 34 | /// pub struct Test { 35 | /// pub a: i32, 36 | /// pub b: i32 37 | /// } 38 | /// 39 | /// fn try_main() -> Result<(), Error> { 40 | /// let mut map = HashMap::::new(); 41 | /// map.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 42 | /// 43 | /// let mut btr = BTreeMap::::new(); 44 | /// btr.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 45 | /// 46 | /// let mut vec = Vec::<(Test, Test)>::new(); 47 | /// vec.push((Test {a: 3, b: 5}, Test {a: 7, b: 9})); 48 | /// 49 | /// // Outputs {"{\"a\":3,\"b\":5}":{"a":7,"b":9}} 50 | /// let ser1 = map.into_json_map().unwrap(); // map.into_iter().into_json_map() is also valid 51 | /// let ser2 = btr.into_json_map().unwrap(); // btr.into_iter().into_json_map() is also valid 52 | /// let ser3 = vec.into_json_map().unwrap(); // vec.into_iter().into_json_map() is also valid 53 | /// 54 | /// // map, btr, and vec have all been consumed. 55 | /// 56 | /// assert_eq!(ser1, "{\"{\\\"a\\\":3,\\\"b\\\":5}\":{\"a\":7,\"b\":9}}"); 57 | /// assert_eq!(ser1, ser2); 58 | /// assert_eq!(ser1, ser3); 59 | /// Ok(()) } 60 | /// try_main().unwrap(); 61 | /// ``` 62 | fn into_json_map(self) -> Result { 63 | serde_json::to_string(&SerializeConsumingIterWrapper { 64 | iter: RefCell::new(self.into_iter()) 65 | }) 66 | } 67 | } 68 | 69 | impl<'a,K,V,T: IntoIterator> ConsumingIterToJson<'a,K,V> for T where 70 | T: IntoIterator, 71 | K: Serialize + Any, 72 | V: Serialize, 73 | ::IntoIter: 'a 74 | { } 75 | 76 | struct SerializeConsumingIterWrapper where 77 | I: Iterator, 78 | { 79 | pub iter: RefCell 80 | } 81 | 82 | impl Serialize for SerializeConsumingIterWrapper where 83 | I: Iterator, 84 | K: Serialize + Any, 85 | V: Serialize 86 | { 87 | fn serialize(&self, serializer: S) -> Result where 88 | S: Serializer 89 | { 90 | let mut ser_map = serializer.serialize_map(None)?; 91 | let mut iter = self.iter.borrow_mut(); 92 | // handle strings specially so they don't get escaped and wrapped inside another string 93 | // compiler seems to be able to optimize this branch away statically 94 | if TypeId::of::() == TypeId::of::() { 95 | while let Some((k, v)) = iter.next() { 96 | let s = (&k as &dyn Any).downcast_ref::().ok_or(S::Error::custom("Failed to serialize String as string"))?; 97 | ser_map.serialize_entry(s, &v)?; 98 | } 99 | } else { 100 | while let Some((k, v)) = iter.next() { 101 | ser_map.serialize_entry(match &serde_json::to_string(&k) 102 | { 103 | Ok(key_string) => key_string, 104 | Err(e) => { return Err(e).map_err(S::Error::custom); } 105 | }, &v)?; 106 | } 107 | } 108 | ser_map.end() 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | // Examples of how to use the library 2 | use std::collections::{BTreeMap, HashMap}; 3 | use serde::{Serialize, Deserialize}; 4 | use serde_json_any_key::*; 5 | 6 | #[derive(Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] 7 | pub struct Test { 8 | pub a: i32, 9 | pub b: i32 10 | } 11 | 12 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 13 | pub struct NestedTest { 14 | #[serde(with = "any_key_map")] 15 | map: HashMap, 16 | #[serde(with = "any_key_map")] 17 | btr: BTreeMap, 18 | #[serde(with = "any_key_vec")] 19 | vec: Vec<(Test, Test)> 20 | } 21 | 22 | fn main() { 23 | let mut map = HashMap::::new(); 24 | map.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 25 | 26 | // Fails with error: key must be a string 27 | let serialized = serde_json::to_string(&map); 28 | match serialized { 29 | Ok(s) => { println!("0 - {}", s); } 30 | Err(e) => { println!("0 - Error as expected: {}", e); } 31 | } 32 | 33 | // Long winded workaround that duplicates the map entirely 34 | // Prints {"{\"a\":3,\"b\":5}":{"a":7,"b":9}} 35 | let string_map: HashMap = map.iter().map(|(k, &v)| (serde_json::to_string(k).unwrap(), v)).collect(); 36 | let canonical_serialization = serde_json::to_string(&string_map).unwrap(); 37 | println!("1 - {}", canonical_serialization); 38 | 39 | // Use this crate's utility function - elements are serialized lazily 40 | // Same output 41 | let serialized = map.to_json_map().unwrap(); 42 | println!("2 - {}", serialized); // Same output 43 | assert_eq!(serialized, canonical_serialization); 44 | 45 | // Utility function also exists for vec of tuples 46 | // Same output 47 | let vec = vec![(Test {a: 3, b: 5}, Test {a: 7, b: 9})]; 48 | let serialized = vec.to_json_map().unwrap(); 49 | println!("3 - {}", serialized); // Same output 50 | assert_eq!(serialized, canonical_serialization); 51 | 52 | // You can also use any other data type that provides an Iter<&(K,V)> or Iter<(&K, &V)> 53 | // Same output 54 | let mut btree = BTreeMap::::new(); 55 | btree.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 56 | let serialized = btree.to_json_map().unwrap(); 57 | println!("4 - {}", serialized); 58 | assert_eq!(serialized, canonical_serialization); 59 | 60 | // Also supports deserialization, back to HashMap or Vec 61 | let deserialized_map: HashMap = serde_json_any_key::json_to_map(&serialized).unwrap(); 62 | assert_eq!(map, deserialized_map); 63 | let deserialized_vec: Vec<(Test,Test)> = serde_json_any_key::json_to_vec(&serialized).unwrap(); 64 | assert_eq!(vec, deserialized_vec); 65 | 66 | // Explicitly deserializing a Struct key to a String key will work 67 | let ds: HashMap = serde_json_any_key::json_to_map(&serialized).unwrap(); 68 | println!("5 - {:?}",ds); 69 | { 70 | // Collections can be extended using json_to_iter 71 | let g = serde_json_any_key::json_to_iter::(&serialized).unwrap(); 72 | let mut bt: BTreeMap = BTreeMap::new(); 73 | bt.extend(g.map(|x|x.unwrap())); 74 | println!("6 - {:?}", bt); 75 | } 76 | { 77 | // Collections can be extended using json_to_iter 78 | let g = serde_json_any_key::json_to_iter::(&serialized).unwrap(); 79 | let mut bt: BTreeMap = BTreeMap::new(); 80 | bt.extend(g.map(|x|x.unwrap())); 81 | println!("7 - {:?}", bt); 82 | } 83 | 84 | // If K actually is a String, it will behave identically to serde_json. 85 | let mut string_map: HashMap = HashMap::new(); 86 | string_map.insert("foo".to_owned(), 1234i32); 87 | let ser1 = serde_json::to_string(&string_map).unwrap(); 88 | let ser2 = string_map.to_json_map().unwrap(); 89 | println!("8 - {}", ser2); 90 | assert_eq!(ser1, ser2); 91 | let deser1: HashMap = serde_json::from_str(&ser1).unwrap(); 92 | let deser2: HashMap = serde_json_any_key::json_to_map(&ser1).unwrap(); 93 | assert_eq!(deser1, deser2); 94 | 95 | // De/serialization of structs with nested maps is supported via the following annotations: 96 | // #[serde(with = "any_key_vec")] 97 | // #[serde(with = "any_key_map")] 98 | let mut nested = NestedTest { 99 | map: Default::default(), 100 | btr: Default::default(), 101 | vec: Default::default(), 102 | }; 103 | nested.map = map; 104 | nested.vec = vec; 105 | nested.btr = btree; 106 | // You can use the usual serde_json functions now 107 | let serialized = serde_json::to_string(&nested).unwrap(); 108 | println!("9 - {}", serialized); 109 | let deser: NestedTest = serde_json::from_str(&serialized).unwrap(); 110 | assert_eq!(nested, deser); 111 | } 112 | -------------------------------------------------------------------------------- /src/any_key_map.rs: -------------------------------------------------------------------------------- 1 | /// Apply the attribute `#[serde(with = "any_key_map")]` to de/serialize structs with nested maps that contain non-string keys. 2 | /// 3 | /// This attribute supports any type that impls `IntoIterator` and `FromIterator<(K,V)>`. 4 | /// ``` 5 | /// use std::collections::HashMap; 6 | /// use serde::{Serialize, Deserialize}; 7 | /// use serde_json::Error; 8 | /// use serde_json_any_key::*; 9 | /// 10 | /// #[derive(Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, Debug)] 11 | /// pub struct Test { 12 | /// pub a: i32, 13 | /// pub b: i32 14 | /// } 15 | /// 16 | /// #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Debug)] 17 | /// pub struct WithNestedMap { 18 | /// #[serde(with = "any_key_map")] 19 | /// pub struct_map: HashMap, 20 | /// #[serde(with = "any_key_map")] 21 | /// pub int_map: HashMap 22 | /// } 23 | /// 24 | /// fn try_main() -> Result<(), Error> { 25 | /// let mut data: WithNestedMap = Default::default(); 26 | /// data.struct_map.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 27 | /// data.int_map.insert(5, "foo".to_string()); 28 | /// 29 | /// // you can use the usual serde_json functions now 30 | /// let ser = serde_json::to_string(&data).unwrap(); 31 | /// let deser: WithNestedMap = serde_json::from_str(&ser).unwrap(); 32 | /// 33 | /// assert_eq!(data, deser); 34 | /// Ok(()) } 35 | /// try_main().unwrap(); 36 | /// ``` 37 | 38 | use crate::serde_with_utils; 39 | use std::any::Any; 40 | use std::cell::RefCell; 41 | use serde::ser::{Serialize, Serializer}; 42 | use serde::de::{Deserialize, Deserializer}; 43 | 44 | /// See docs for [any_key_map](index.html). 45 | pub fn serialize<'s,S,C,K,V>(coll: C, serializer: S) -> Result 46 | where S: Serializer, 47 | C: IntoIterator, 48 | K: Serialize + Any + 's, 49 | V: Serialize + 's 50 | { 51 | let mut iter = coll.into_iter(); 52 | let wrap = crate::map_iter_to_json::SerializeMapIterWrapper { 53 | iter: RefCell::new(&mut iter), 54 | }; 55 | wrap.serialize(serializer) 56 | } 57 | 58 | /// See docs for [any_key_map](index.html). 59 | pub fn deserialize<'d,D,C,K,V>(deserializer: D) -> Result where 60 | D: Deserializer<'d>, 61 | C: FromIterator<(K,V)> + Sized, 62 | for<'de> K: Deserialize<'de> + Any + 'd, 63 | for<'de> V: Deserialize<'de> + 'd, 64 | { 65 | // any_key_map and any_key_vec use the same deserialize function 66 | serde_with_utils::deserialize::<'d,D,C,K,V>(deserializer) 67 | } 68 | 69 | #[cfg(test)] 70 | mod tests { 71 | use crate::any_key_map; 72 | use std::collections::HashMap; 73 | use serde::{Serialize, Deserialize}; 74 | 75 | #[derive(Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] 76 | struct Test { 77 | pub a: i32, 78 | pub b: i32 79 | } 80 | 81 | #[test] 82 | fn test_struct_serde_with_map() { 83 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 84 | struct SerdeWithMap { 85 | #[serde(with = "any_key_map")] 86 | pub inner: HashMap 87 | } 88 | let mut data = SerdeWithMap { 89 | inner: HashMap::new() 90 | }; 91 | data.inner.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 92 | let serialized = serde_json::to_string(&data).unwrap(); 93 | assert_eq!(serialized, "{\"inner\":{\"{\\\"a\\\":3,\\\"b\\\":5}\":{\"a\":7,\"b\":9}}}"); 94 | let deser: SerdeWithMap = serde_json::from_str(&serialized).unwrap(); 95 | assert_eq!(data, deser); 96 | } 97 | 98 | 99 | #[test] 100 | fn test_string_serde_with_map() { 101 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 102 | struct SerdeWithMap { 103 | #[serde(with = "any_key_map")] 104 | pub inner: HashMap 105 | } 106 | let mut data = SerdeWithMap { 107 | inner: HashMap::new() 108 | }; 109 | data.inner.insert("foo".to_string(), 5); 110 | 111 | let serialized = serde_json::to_string(&data).unwrap(); 112 | assert_eq!(serialized, "{\"inner\":{\"foo\":5}}"); 113 | let deser: SerdeWithMap = serde_json::from_str(&serialized).unwrap(); 114 | assert_eq!(data, deser); 115 | } 116 | 117 | #[test] 118 | fn test_int_serde_with_map() { 119 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 120 | struct SerdeWithMap { 121 | #[serde(with = "any_key_map")] 122 | pub inner: HashMap 123 | } 124 | let mut data = SerdeWithMap { 125 | inner: HashMap::new() 126 | }; 127 | data.inner.insert(5, Test {a: 6, b: 7}); 128 | 129 | let serialized = serde_json::to_string(&data).unwrap(); 130 | assert_eq!(serialized, "{\"inner\":{\"5\":{\"a\":6,\"b\":7}}}"); 131 | let deser: SerdeWithMap = serde_json::from_str(&serialized).unwrap(); 132 | assert_eq!(data, deser); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/any_key_vec.rs: -------------------------------------------------------------------------------- 1 | /// Apply the attribute `#[serde(with = "any_key_vec")]` to de/serialize structs 2 | /// with nested `Vec<(K,V)>` that contain non-string keys. 3 | /// These Vecs will be serialized as JSON maps (as if they were a `HashMap`). 4 | /// 5 | /// This attribute supports any type that impls `IntoIterator` and `FromIterator<(K,V)>`. 6 | /// ``` 7 | /// use std::collections::HashMap; 8 | /// use serde::{Serialize, Deserialize}; 9 | /// use serde_json::Error; 10 | /// use serde_json_any_key::*; 11 | /// 12 | /// #[derive(Clone, Copy, Serialize, Deserialize, PartialEq, Eq, Hash, Debug)] 13 | /// pub struct Test { 14 | /// pub a: i32, 15 | /// pub b: i32 16 | /// } 17 | /// 18 | /// #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Debug)] 19 | /// pub struct WithNestedVec { 20 | /// #[serde(with = "any_key_vec")] 21 | /// pub structs: Vec<(Test, Test)>, 22 | /// #[serde(with = "any_key_vec")] 23 | /// pub ints: Vec<(i32, String)> 24 | /// } 25 | /// 26 | /// #[derive(Clone, Default, Serialize, Deserialize, PartialEq, Eq, Debug)] 27 | /// pub struct WithNestedMap { 28 | /// #[serde(with = "any_key_map")] 29 | /// pub structs: HashMap, 30 | /// #[serde(with = "any_key_map")] 31 | /// pub ints: HashMap 32 | /// } 33 | /// 34 | /// fn try_main() -> Result<(), Error> { 35 | /// let mut vec_data: WithNestedVec = Default::default(); 36 | /// vec_data.structs.push((Test {a: 3, b: 5}, Test {a: 7, b: 9})); 37 | /// vec_data.ints.push((5, "foo".to_string())); 38 | /// 39 | /// let mut map_data: WithNestedMap = Default::default(); 40 | /// map_data.structs.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 41 | /// map_data.ints.insert(5, "foo".to_string()); 42 | /// 43 | /// // you can use the usual serde_json functions now 44 | /// // both structs produce the same JSON representation 45 | /// let ser_vec = serde_json::to_string(&vec_data).unwrap(); 46 | /// let ser_map = serde_json::to_string(&map_data).unwrap(); 47 | /// assert_eq!(ser_vec, ser_map); 48 | /// 49 | /// // and can deserialize into each other 50 | /// let deser_vec: WithNestedVec = serde_json::from_str(&ser_map).unwrap(); 51 | /// let deser_map: WithNestedMap = serde_json::from_str(&ser_vec).unwrap(); 52 | /// assert_eq!(vec_data, deser_vec); 53 | /// assert_eq!(map_data, deser_map); 54 | /// Ok(()) } 55 | /// try_main().unwrap(); 56 | /// ``` 57 | 58 | use crate::serde_with_utils; 59 | use std::any::Any; 60 | use std::cell::RefCell; 61 | use serde::ser::{Serialize, Serializer}; 62 | use serde::de::{Deserialize, Deserializer}; 63 | 64 | /// See docs for [any_key_vec](index.html). 65 | pub fn serialize<'s,S,C,K,V>(coll: C, serializer: S) -> Result 66 | where S: Serializer, 67 | C: IntoIterator, 68 | K: Serialize + Any + 's, 69 | V: Serialize + 's 70 | { 71 | let mut iter = coll.into_iter(); 72 | let wrap = crate::vec_iter_to_json::SerializeVecIterWrapper { 73 | iter: RefCell::new(&mut iter), 74 | }; 75 | wrap.serialize(serializer) 76 | } 77 | 78 | /// See docs for [any_key_vec](index.html). 79 | pub fn deserialize<'d,D,C,K,V>(deserializer: D) -> Result where 80 | D: Deserializer<'d>, 81 | C: FromIterator<(K,V)> + Sized, 82 | for<'de> K: Deserialize<'de> + Any + 'd, 83 | for<'de> V: Deserialize<'de> + 'd, 84 | { 85 | // any_key_map and any_key_vec use the same deserialize function 86 | serde_with_utils::deserialize::<'d,D,C,K,V>(deserializer) 87 | } 88 | 89 | #[cfg(test)] 90 | mod tests { 91 | use crate::any_key_vec; 92 | use serde::{Serialize, Deserialize}; 93 | 94 | #[derive(Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] 95 | struct Test { 96 | pub a: i32, 97 | pub b: i32 98 | } 99 | 100 | #[test] 101 | fn test_struct_serde_with_vec() { 102 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 103 | struct SerdeWithVec { 104 | #[serde(with = "any_key_vec")] 105 | pub inner: Vec<(Test,Test)> 106 | } 107 | let mut data = SerdeWithVec { 108 | inner: vec![] 109 | }; 110 | data.inner.push((Test {a: 3, b: 5}, Test {a: 7, b: 9})); 111 | let serialized = serde_json::to_string(&data).unwrap(); 112 | assert_eq!(serialized, "{\"inner\":{\"{\\\"a\\\":3,\\\"b\\\":5}\":{\"a\":7,\"b\":9}}}"); 113 | let deser: SerdeWithVec = serde_json::from_str(&serialized).unwrap(); 114 | assert_eq!(data, deser); 115 | } 116 | 117 | #[test] 118 | fn test_string_serde_with_vec() { 119 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 120 | struct SerdeWithVec { 121 | #[serde(with = "any_key_vec")] 122 | pub inner: Vec<(String, i32)> 123 | } 124 | let mut data = SerdeWithVec { 125 | inner: vec![] 126 | }; 127 | data.inner.push(("foo".to_string(), 5)); 128 | 129 | let serialized = serde_json::to_string(&data).unwrap(); 130 | assert_eq!(serialized, "{\"inner\":{\"foo\":5}}"); 131 | let deser: SerdeWithVec = serde_json::from_str(&serialized).unwrap(); 132 | assert_eq!(data, deser); 133 | } 134 | 135 | #[test] 136 | fn test_int_serde_with_vec() { 137 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 138 | struct SerdeWithVec { 139 | #[serde(with = "any_key_vec")] 140 | pub inner: Vec<(i32, Test)> 141 | } 142 | let mut data = SerdeWithVec { 143 | inner: vec![] 144 | }; 145 | data.inner.push((5, Test {a: 6, b: 7})); 146 | 147 | let serialized = serde_json::to_string(&data).unwrap(); 148 | assert_eq!(serialized, "{\"inner\":{\"5\":{\"a\":6,\"b\":7}}}"); 149 | let deser: SerdeWithVec = serde_json::from_str(&serialized).unwrap(); 150 | assert_eq!(data, deser); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /tests/mod.rs: -------------------------------------------------------------------------------- 1 | 2 | #[cfg(test)] 3 | mod tests { 4 | use serde_json_any_key::*; 5 | use std::collections::HashMap; 6 | use serde::{Serialize, Deserialize}; 7 | 8 | #[derive(Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] 9 | struct Test { 10 | pub a: i32, 11 | pub b: i32 12 | } 13 | 14 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] 15 | struct TestWithString { 16 | pub a: i32, 17 | pub b: i32, 18 | pub c: String 19 | } 20 | 21 | #[test] 22 | fn test_struct_attr_top_level_map() { 23 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 24 | struct SerdeWithMap { 25 | #[serde(with = "any_key_map")] 26 | pub inner: HashMap 27 | } 28 | 29 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 30 | struct SerdeWithVec { 31 | #[serde(with = "any_key_vec")] 32 | pub inner: Vec<(TestWithString,TestWithString)> 33 | } 34 | 35 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 36 | struct Outer { 37 | pub map: SerdeWithMap, 38 | pub vec: SerdeWithVec 39 | } 40 | 41 | let mut map = SerdeWithMap { inner: HashMap::new() }; 42 | map.inner.insert(TestWithString {a: 3, b: 5, c: "foo".to_string()}, 43 | TestWithString {a: 7, b: 9, c: "bar".to_string()}); 44 | 45 | let mut vec = SerdeWithVec { inner: vec![] }; 46 | vec.inner.push((TestWithString {a: 3, b: 5, c: "foo".to_string()}, 47 | TestWithString {a: 7, b: 9, c: "bar".to_string()})); 48 | 49 | let outer = Outer { 50 | map: map, 51 | vec: vec 52 | }; 53 | { 54 | let mut top_level_string_map = HashMap::::new(); 55 | top_level_string_map.insert("top".to_string(), outer.clone()); 56 | 57 | let ser1 = serde_json::to_string(&top_level_string_map).unwrap(); 58 | let ser2 = top_level_string_map.to_json_map().unwrap(); 59 | assert_eq!(ser1, ser2); 60 | let deser1: HashMap = serde_json::from_str(&ser1).unwrap(); 61 | let deser2: HashMap = json_to_map(&ser1).unwrap(); 62 | assert_eq!(top_level_string_map, deser1); 63 | assert_eq!(top_level_string_map, deser2); 64 | } 65 | { 66 | let mut top_level_struct_map = HashMap::::new(); 67 | top_level_struct_map.insert(TestWithString { a: 10, b: 11, c: "bbq".to_string() }, outer.clone()); 68 | 69 | let ser = top_level_struct_map.to_json_map().unwrap(); 70 | let deser: HashMap = json_to_map(&ser).unwrap(); 71 | assert_eq!(top_level_struct_map, deser); 72 | } 73 | } 74 | 75 | #[test] 76 | fn test_struct_attr_1_level() { 77 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 78 | struct SerdeWithMap { 79 | #[serde(with = "any_key_map")] 80 | pub inner: HashMap 81 | } 82 | 83 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 84 | struct SerdeWithVec { 85 | #[serde(with = "any_key_vec")] 86 | pub inner: Vec<(TestWithString,TestWithString)> 87 | } 88 | 89 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 90 | struct Outer { 91 | pub map: SerdeWithMap, 92 | pub vec: SerdeWithVec 93 | } 94 | 95 | let mut map = SerdeWithMap { inner: HashMap::new() }; 96 | map.inner.insert(TestWithString {a: 3, b: 5, c: "foo".to_string()}, 97 | TestWithString {a: 7, b: 9, c: "bar".to_string()}); 98 | 99 | let mut vec = SerdeWithVec { inner: vec![] }; 100 | vec.inner.push((TestWithString {a: 3, b: 5, c: "foo".to_string()}, 101 | TestWithString {a: 7, b: 9, c: "bar".to_string()})); 102 | 103 | let outer = Outer { 104 | map: map, 105 | vec: vec 106 | }; 107 | 108 | let serialized = serde_json::to_string(&outer).unwrap(); 109 | let deser: Outer = serde_json::from_str(&serialized).unwrap(); 110 | assert_eq!(outer, deser); 111 | } 112 | 113 | #[test] 114 | fn test_struct_attr_2_level() { 115 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 116 | struct SerdeWithMap { 117 | #[serde(with = "any_key_map")] 118 | pub inner: HashMap 119 | } 120 | 121 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug, Hash)] 122 | struct SerdeWithVec { 123 | #[serde(with = "any_key_vec")] 124 | pub inner: Vec<(TestWithString,TestWithString)> 125 | } 126 | 127 | #[derive(Clone, Deserialize, Serialize, PartialEq, Eq, Debug)] 128 | struct Outer { 129 | #[serde(with = "any_key_map")] 130 | pub map: HashMap, 131 | #[serde(with = "any_key_vec")] 132 | pub vec: Vec<(SerdeWithMap, SerdeWithVec)> 133 | } 134 | 135 | let mut map = SerdeWithMap { inner: HashMap::new() }; 136 | map.inner.insert(TestWithString {a: 3, b: 5, c: "foo".to_string()}, 137 | TestWithString {a: 7, b: 9, c: "bar".to_string()}); 138 | 139 | let mut vec = SerdeWithVec { inner: vec![] }; 140 | vec.inner.push((TestWithString {a: 3, b: 5, c: "foo".to_string()}, 141 | TestWithString {a: 7, b: 9, c: "bar".to_string()})); 142 | 143 | let mut outer_map = HashMap::::new(); 144 | outer_map.insert(vec.clone(), map.clone()); 145 | let mut outer_vec = Vec::<(SerdeWithMap, SerdeWithVec)>::new(); 146 | outer_vec.push((map, vec)); 147 | let outer = Outer { 148 | map: outer_map, 149 | vec: outer_vec 150 | }; 151 | 152 | let serialized = serde_json::to_string(&outer).unwrap(); 153 | let deser: Outer = serde_json::from_str(&serialized).unwrap(); 154 | assert_eq!(outer, deser); 155 | } 156 | 157 | #[test] 158 | fn test_struct_roundtrip_map() { 159 | let mut data = HashMap::::new(); 160 | data.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 161 | data.insert(Test {a: 11, b: 12}, Test {a: 13, b: 14}); 162 | let serialized = data.to_json_map().unwrap(); 163 | let deser: HashMap = json_to_map(&serialized).unwrap(); 164 | 165 | assert_eq!(data, deser); 166 | } 167 | 168 | #[test] 169 | fn test_struct_roundtrip_map_iter() { 170 | let mut data = HashMap::::new(); 171 | data.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 172 | data.insert(Test {a: 11, b: 12}, Test {a: 13, b: 14}); 173 | let serialized = data.iter().to_json_map().unwrap(); 174 | let deser: HashMap = json_to_map(&serialized).unwrap(); 175 | 176 | assert_eq!(data, deser); 177 | } 178 | 179 | #[test] 180 | fn test_struct_roundtrip_vec() { 181 | let mut data = Vec::<(Test, Test)>::new(); 182 | data.push((Test {a: 3, b: 5}, Test {a: 7, b: 9})); 183 | data.push((Test {a: 11, b: 12}, Test {a: 13, b: 14})); 184 | let serialized = data.to_json_map().unwrap(); 185 | let mut deser: Vec<(Test, Test)> = json_to_vec(&serialized).unwrap(); 186 | deser.sort(); 187 | 188 | assert_eq!(data, deser); 189 | } 190 | 191 | #[test] 192 | fn test_struct_roundtrip_vec_iter() { 193 | let mut data = Vec::<(Test, Test)>::new(); 194 | data.push((Test {a: 3, b: 5}, Test {a: 7, b: 9})); 195 | data.push((Test {a: 11, b: 12}, Test {a: 13, b: 14})); 196 | let serialized = data.iter().to_json_map().unwrap(); 197 | let mut deser: Vec<(Test, Test)> = json_to_vec(&serialized).unwrap(); 198 | deser.sort(); 199 | 200 | assert_eq!(data, deser); 201 | } 202 | 203 | #[test] 204 | fn test_struct_canonical_serialization() { 205 | let mut map = HashMap::::new(); 206 | map.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 207 | let string_map: HashMap = map.iter().map(|(k, &v)| (serde_json::to_string(k).unwrap(), v)).collect(); 208 | let canonical_serialization = serde_json::to_string(&string_map).unwrap(); 209 | 210 | let serialized = map.to_json_map().unwrap(); 211 | assert_eq!(serialized, canonical_serialization); 212 | 213 | let vec = vec![(Test {a: 3, b: 5}, Test {a: 7, b: 9})]; 214 | let serialized = vec.to_json_map().unwrap(); 215 | assert_eq!(serialized, canonical_serialization); 216 | 217 | let mut btree = std::collections::BTreeMap::::new(); 218 | btree.insert(Test {a: 3, b: 5}, Test {a: 7, b: 9}); 219 | let serialized = btree.to_json_map().unwrap(); 220 | assert_eq!(serialized, canonical_serialization); 221 | } 222 | 223 | #[test] 224 | fn test_string_roundtrip_map() { 225 | let mut data = HashMap::::new(); 226 | data.insert("bar".to_string(), 7); 227 | data.insert("foo".to_string(), 5); 228 | let serialized = data.to_json_map().unwrap(); 229 | let deser: HashMap = json_to_map(&serialized).unwrap(); 230 | 231 | assert_eq!(data, deser); 232 | } 233 | 234 | #[test] 235 | fn test_string_roundtrip_map_iter() { 236 | let mut data = HashMap::::new(); 237 | data.insert("bar".to_string(), 7); 238 | data.insert("foo".to_string(), 5); 239 | let serialized = data.iter().to_json_map().unwrap(); 240 | let deser: HashMap = json_to_map(&serialized).unwrap(); 241 | 242 | assert_eq!(data, deser); 243 | } 244 | 245 | #[test] 246 | fn test_string_roundtrip_vec() { 247 | let mut data = Vec::<(String, i32)>::new(); 248 | data.push(("bar".to_string(), 7)); 249 | data.push(("foo".to_string(), 5)); 250 | let serialized = data.to_json_map().unwrap(); 251 | let mut deser: Vec<(String, i32)> = json_to_vec(&serialized).unwrap(); 252 | deser.sort(); 253 | 254 | assert_eq!(data, deser); 255 | } 256 | 257 | #[test] 258 | fn test_string_roundtrip_vec_iter() { 259 | let mut data = Vec::<(String, i32)>::new(); 260 | data.push(("bar".to_string(), 7)); 261 | data.push(("foo".to_string(), 5)); 262 | let serialized = data.iter().to_json_map().unwrap(); 263 | let mut deser: Vec<(String, i32)> = json_to_vec(&serialized).unwrap(); 264 | deser.sort(); 265 | 266 | assert_eq!(data, deser); 267 | } 268 | 269 | #[test] 270 | fn test_string_canonical_serialization() { 271 | let mut map = HashMap::::new(); 272 | map.insert("foo".to_string(), 5); 273 | let canonical_serialization = serde_json::to_string(&map).unwrap(); 274 | 275 | let serialized = map.to_json_map().unwrap(); 276 | assert_eq!(serialized, canonical_serialization); 277 | 278 | let vec = vec![("foo".to_string(), 5)]; 279 | let serialized = vec.to_json_map().unwrap(); 280 | assert_eq!(serialized, canonical_serialization); 281 | 282 | let mut btree = std::collections::BTreeMap::::new(); 283 | btree.insert("foo".to_string(), 5); 284 | let serialized = btree.to_json_map().unwrap(); 285 | assert_eq!(serialized, canonical_serialization); 286 | } 287 | 288 | 289 | #[test] 290 | fn test_int_roundtrip_map() { 291 | let mut data = HashMap::::new(); 292 | data.insert(5, Test {a: 6, b: 7}); 293 | data.insert(6, Test {a: 9, b: 11}); 294 | let serialized = data.to_json_map().unwrap(); 295 | let deser: HashMap = json_to_map(&serialized).unwrap(); 296 | 297 | assert_eq!(data, deser); 298 | } 299 | 300 | #[test] 301 | fn test_int_roundtrip_map_iter() { 302 | let mut data = HashMap::::new(); 303 | data.insert(5, Test {a: 6, b: 7}); 304 | data.insert(6, Test {a: 9, b: 11}); 305 | let serialized = data.iter().to_json_map().unwrap(); 306 | let deser: HashMap = json_to_map(&serialized).unwrap(); 307 | 308 | assert_eq!(data, deser); 309 | } 310 | 311 | #[test] 312 | fn test_int_roundtrip_vec() { 313 | let mut data = Vec::<(i32, Test)>::new(); 314 | data.push((5, Test {a: 6, b: 7})); 315 | data.push((6, Test {a: 9, b: 11})); 316 | let serialized = data.to_json_map().unwrap(); 317 | let mut deser: Vec<(i32, Test)> = json_to_vec(&serialized).unwrap(); 318 | deser.sort(); 319 | 320 | assert_eq!(data, deser); 321 | } 322 | 323 | #[test] 324 | fn test_int_roundtrip_vec_iter() { 325 | let mut data = Vec::<(i32, Test)>::new(); 326 | data.push((5, Test {a: 6, b: 7})); 327 | data.push((6, Test {a: 9, b: 11})); 328 | let serialized = data.iter().to_json_map().unwrap(); 329 | let mut deser: Vec<(i32, Test)> = json_to_vec(&serialized).unwrap(); 330 | deser.sort(); 331 | 332 | assert_eq!(data, deser); 333 | } 334 | 335 | #[test] 336 | fn test_int_canonical_serialization() { 337 | let mut map = HashMap::::new(); 338 | map.insert(5, 7.0f32); 339 | let canonical_serialization = serde_json::to_string(&map).unwrap(); 340 | 341 | let serialized = map.to_json_map().unwrap(); 342 | assert_eq!(serialized, canonical_serialization); 343 | 344 | let vec = vec![(5, 7.0f32)]; 345 | let serialized = vec.to_json_map().unwrap(); 346 | assert_eq!(serialized, canonical_serialization); 347 | 348 | let mut btree = std::collections::BTreeMap::::new(); 349 | btree.insert(5, 7.0f32); 350 | let serialized = btree.to_json_map().unwrap(); 351 | assert_eq!(serialized, canonical_serialization); 352 | } 353 | } 354 | --------------------------------------------------------------------------------