1use super::ZeroHashMap;
6use crate::{
7 map::{ZeroMapKV, ZeroVecLike},
8 ZeroVec,
9};
10
11use serde::{de, Deserialize, Serialize};
12
13impl<'a, K, V> Serialize for ZeroHashMap<'a, K, V>
14where
15 K: ZeroMapKV<'a> + Serialize + ?Sized,
16 V: ZeroMapKV<'a> + Serialize + ?Sized,
17 K::Container: Serialize,
18 V::Container: Serialize,
19{
20 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
21 where
22 S: serde::Serializer,
23 {
24 (&self.displacements, &self.keys, &self.values).serialize(serializer)
25 }
26}
27
28impl<'de, 'a, K, V> Deserialize<'de> for ZeroHashMap<'a, K, V>
29where
30 K: ZeroMapKV<'a> + ?Sized,
31 V: ZeroMapKV<'a> + ?Sized,
32 K::Container: Deserialize<'de>,
33 V::Container: Deserialize<'de>,
34 'de: 'a,
35{
36 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
37 where
38 D: serde::Deserializer<'de>,
39 {
40 let (displacements, keys, values): (ZeroVec<(u32, u32)>, K::Container, V::Container) =
41 Deserialize::deserialize(deserializer)?;
42 if keys.zvl_len() != values.zvl_len() {
43 return Err(de::Error::custom(
44 "Mismatched key and value sizes in ZeroHashMap",
45 ));
46 }
47 if displacements.zvl_len() != keys.zvl_len() {
48 return Err(de::Error::custom(
49 "Mismatched displacements and key, value sizes in ZeroHashMap",
50 ));
51 }
52 Ok(Self {
53 displacements,
54 keys,
55 values,
56 })
57 }
58}
59
60#[cfg(test)]
61mod test {
62 use crate::{VarZeroVec, ZeroHashMap, ZeroVec};
63 use serde::{Deserialize, Serialize};
64
65 const JSON_STR: &str = "[[[0,0],[0,1],[0,1]],[1,2,0],[\"b\",\"c\",\"a\"]]";
66
67 const BINCODE_BYTES: &[u8] = &[
68 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0,
69 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0,
70 3, 0, 1, 0, 2, 0, 98, 99, 97,
71 ];
72
73 #[derive(Serialize, Deserialize)]
74 #[allow(
75 dead_code,
76 reason = "Tests compatibility of custom impl with Serde derive."
77 )]
78 struct DeriveTestZeroHashMap<'data> {
79 #[serde(borrow)]
80 _data: ZeroHashMap<'data, str, [u8]>,
81 }
82
83 fn make_zerohashmap() -> ZeroHashMap<'static, u32, str> {
84 ZeroHashMap::from_iter([(0, "a"), (1, "b"), (2, "c")])
85 }
86
87 fn build_invalid_hashmap_str(
88 displacements: Vec<(u32, u32)>,
89 keys: Vec<u32>,
90 values: Vec<&str>,
91 ) -> String {
92 let invalid_hm: ZeroHashMap<u32, str> = ZeroHashMap {
93 displacements: ZeroVec::alloc_from_slice(&displacements),
94 keys: ZeroVec::alloc_from_slice(&keys),
95 values: VarZeroVec::<str>::from(&values),
96 };
97 serde_json::to_string(&invalid_hm).expect("serialize")
98 }
99
100 #[test]
101 fn test_invalid_deser_zhm() {
102 let mut invalid_hm_str =
104 build_invalid_hashmap_str(vec![(0, 1), (0, 0)], vec![1, 2], vec!["a", "b", "c"]);
105
106 assert_eq!(
107 serde_json::from_str::<ZeroHashMap<u32, str>>(&invalid_hm_str)
108 .unwrap_err()
109 .to_string(),
110 "Mismatched key and value sizes in ZeroHashMap"
111 );
112
113 invalid_hm_str =
116 build_invalid_hashmap_str(vec![(0, 1), (0, 0)], vec![2, 1, 0], vec!["a", "b", "c"]);
117
118 assert_eq!(
119 serde_json::from_str::<ZeroHashMap<u32, str>>(&invalid_hm_str)
120 .unwrap_err()
121 .to_string(),
122 "Mismatched displacements and key, value sizes in ZeroHashMap"
123 );
124 }
125
126 #[cfg(target_endian = "little")]
128 #[test]
129 fn test_serde_valid_deser_zhm() {
130 let hm = make_zerohashmap();
131 let json_str = serde_json::to_string(&hm).expect("serialize");
132 assert_eq!(json_str, JSON_STR);
133 let deserialized_hm: ZeroHashMap<u32, str> =
134 serde_json::from_str(JSON_STR).expect("deserialize");
135 assert_eq!(
136 hm.iter().collect::<Vec<_>>(),
137 deserialized_hm.iter().collect::<Vec<_>>()
138 );
139 }
140
141 #[cfg(target_endian = "little")]
143 #[test]
144 fn test_bincode_zhm() {
145 let hm = make_zerohashmap();
146 let bincode_bytes = bincode::serialize(&hm).expect("serialize");
147 assert_eq!(bincode_bytes, BINCODE_BYTES);
148 let deserialized_hm: ZeroHashMap<u32, str> =
149 bincode::deserialize(BINCODE_BYTES).expect("deserialize");
150 assert_eq!(
151 hm.iter().collect::<Vec<_>>(),
152 deserialized_hm.iter().collect::<Vec<_>>()
153 );
154 }
155}