1use crate::{
7 codec::{EncodeSize, Read, Write},
8 error::Error,
9 types::read_ordered_map,
10 RangeCfg,
11};
12use bytes::{Buf, BufMut};
13use std::{collections::HashMap, hash::Hash};
14
15const HASHMAP_TYPE: &str = "HashMap";
16
17impl<K: Ord + Hash + Eq + Write, V: Write> Write for HashMap<K, V> {
20 fn write(&self, buf: &mut impl BufMut) {
21 self.len().write(buf);
22
23 let mut entries: Vec<_> = self.iter().collect();
25 entries.sort_by(|a, b| a.0.cmp(b.0));
26 for (k, v) in entries {
27 k.write(buf);
28 v.write(buf);
29 }
30 }
31}
32
33impl<K: Ord + Hash + Eq + EncodeSize, V: EncodeSize> EncodeSize for HashMap<K, V> {
34 fn encode_size(&self) -> usize {
35 let mut size = self.len().encode_size();
37
38 for (k, v) in self {
41 size += k.encode_size();
42 size += v.encode_size();
43 }
44 size
45 }
46}
47
48impl<K: Read + Clone + Ord + Hash + Eq, V: Read + Clone> Read for HashMap<K, V> {
50 type Cfg = (RangeCfg<usize>, (K::Cfg, V::Cfg));
51
52 fn read_cfg(buf: &mut impl Buf, (range, (k_cfg, v_cfg)): &Self::Cfg) -> Result<Self, Error> {
53 let len = usize::read_cfg(buf, range)?;
55 let mut map = Self::with_capacity(len);
56
57 read_ordered_map(
59 buf,
60 len,
61 k_cfg,
62 v_cfg,
63 |k, v| map.insert(k, v),
64 HASHMAP_TYPE,
65 )?;
66
67 Ok(map)
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74 use crate::{Decode, Encode, FixedSize};
75 use bytes::{Bytes, BytesMut};
76 use std::fmt::Debug;
77
78 fn round_trip_hash<K, V, KCfg, VCfg>(
80 map: &HashMap<K, V>,
81 range_cfg: RangeCfg<usize>,
82 k_cfg: KCfg,
83 v_cfg: VCfg,
84 ) where
85 K: Write + EncodeSize + Read<Cfg = KCfg> + Clone + Ord + Hash + Eq + PartialEq + Debug,
86 V: Write + EncodeSize + Read<Cfg = VCfg> + Clone + PartialEq + Debug,
87 HashMap<K, V>: Read<Cfg = (RangeCfg<usize>, (K::Cfg, V::Cfg))>
88 + Decode<Cfg = (RangeCfg<usize>, (K::Cfg, V::Cfg))>
89 + PartialEq
90 + Write
91 + EncodeSize,
92 {
93 let encoded = map.encode();
94 assert_eq!(encoded.len(), map.encode_size());
95 let config_tuple = (range_cfg, (k_cfg, v_cfg));
96 let decoded = HashMap::<K, V>::decode_cfg(encoded, &config_tuple)
97 .expect("decode_cfg failed for HashMap");
98 assert_eq!(map, &decoded);
99 }
100
101 #[test]
104 fn test_empty_hashmap() {
105 let map = HashMap::<u32, u64>::new();
106 round_trip_hash(&map, (..).into(), (), ());
107 assert_eq!(map.encode_size(), 1);
108 let encoded = map.encode();
109 assert_eq!(encoded, 0usize.encode());
110 }
111
112 #[test]
113 fn test_simple_hashmap_u32_u64() {
114 let mut map = HashMap::new();
115 map.insert(1u32, 100u64);
116 map.insert(5u32, 500u64);
117 map.insert(2u32, 200u64);
118 round_trip_hash(&map, (..).into(), (), ());
119 assert_eq!(map.encode_size(), 1 + 3 * (u32::SIZE + u64::SIZE));
120 }
121
122 #[test]
123 fn test_large_hashmap() {
124 let mut map = HashMap::new();
126 for i in 0..1000 {
127 map.insert(i as u16, i as u64 * 2);
128 }
129 round_trip_hash(&map, (0..=1000).into(), (), ());
130
131 let mut map = HashMap::new();
133 for i in 0..1000usize {
134 map.insert(i, 1000usize + i);
135 }
136 round_trip_hash(
137 &map,
138 (0..=1000).into(),
139 (..=1000).into(),
140 (1000..=2000).into(),
141 );
142 }
143
144 #[test]
145 fn test_hashmap_with_variable_values() {
146 let mut map = HashMap::new();
147 map.insert(Bytes::from_static(b"apple"), vec![1, 2]);
148 map.insert(Bytes::from_static(b"banana"), vec![3, 4, 5]);
149 map.insert(Bytes::from_static(b"cherry"), vec![]);
150
151 let map_range = RangeCfg::from(0..=10);
152 let key_range = RangeCfg::from(..=10);
153 let val_range = RangeCfg::from(0..=100);
154
155 round_trip_hash(&map, map_range, key_range, (val_range, ()));
156 }
157
158 #[test]
159 fn test_hashmap_decode_length_limit_exceeded() {
160 let mut map = HashMap::new();
161 map.insert(1u32, 100u64);
162 map.insert(5u32, 500u64);
163
164 let encoded = map.encode();
165 let config_tuple = ((0..=1).into(), ((), ()));
166
167 let result = HashMap::<u32, u64>::decode_cfg(encoded, &config_tuple);
168 assert!(matches!(result, Err(Error::InvalidLength(2))));
169 }
170
171 #[test]
172 fn test_hashmap_decode_value_length_limit_exceeded() {
173 let mut map = HashMap::new();
174 map.insert(Bytes::from_static(b"key1"), vec![1u8, 2u8, 3u8, 4u8, 5u8]);
175
176 let key_range = RangeCfg::from(..=10);
177 let map_range = RangeCfg::from(0..=10);
178 let restrictive_val_range = RangeCfg::from(0..=3);
179
180 let encoded = map.encode();
181 let config_tuple = (map_range, (key_range, (restrictive_val_range, ())));
182 let result = HashMap::<Bytes, Vec<u8>>::decode_cfg(encoded, &config_tuple);
183
184 assert!(matches!(result, Err(Error::InvalidLength(5))));
185 }
186
187 #[test]
188 fn test_hashmap_decode_invalid_key_order() {
189 let mut encoded = BytesMut::new();
190 2usize.write(&mut encoded); 5u32.write(&mut encoded); 500u64.write(&mut encoded); 2u32.write(&mut encoded); 200u64.write(&mut encoded); let range = (..).into();
197 let config_tuple = (range, ((), ()));
198
199 let result = HashMap::<u32, u64>::decode_cfg(encoded, &config_tuple);
200 assert!(matches!(
201 result,
202 Err(Error::Invalid("HashMap", "Keys must ascend"))
203 ));
204 }
205
206 #[test]
207 fn test_hashmap_decode_duplicate_key() {
208 let mut encoded = BytesMut::new();
209 2usize.write(&mut encoded); 1u32.write(&mut encoded); 100u64.write(&mut encoded); 1u32.write(&mut encoded); 200u64.write(&mut encoded); let range = (..).into();
216 let config_tuple = (range, ((), ()));
217
218 let result = HashMap::<u32, u64>::decode_cfg(encoded, &config_tuple);
219 assert!(matches!(
220 result,
221 Err(Error::Invalid("HashMap", "Duplicate key"))
222 ));
223 }
224
225 #[test]
226 fn test_hashmap_decode_end_of_buffer_key() {
227 let mut map = HashMap::new();
228 map.insert(1u32, 100u64);
229 map.insert(5u32, 500u64);
230
231 let mut encoded = map.encode();
232 encoded.truncate(map.encode_size() - 10); let range = (..).into();
235 let config_tuple = (range, ((), ()));
236 let result = HashMap::<u32, u64>::decode_cfg(encoded, &config_tuple);
237 assert!(matches!(result, Err(Error::EndOfBuffer)));
238 }
239
240 #[test]
241 fn test_hashmap_decode_end_of_buffer_value() {
242 let mut map = HashMap::new();
243 map.insert(1u32, 100u64);
244 map.insert(5u32, 500u64);
245
246 let mut encoded = map.encode();
247 encoded.truncate(map.encode_size() - 4); let range = RangeCfg::from(..);
250 let config_tuple = (range, ((), ()));
251 let result = HashMap::<u32, u64>::decode_cfg(encoded, &config_tuple);
252 assert!(matches!(result, Err(Error::EndOfBuffer)));
253 }
254
255 #[test]
256 fn test_hashmap_decode_extra_data() {
257 let mut map = HashMap::new();
258 map.insert(1u32, 100u64);
259
260 let mut encoded = map.encode_mut();
261 encoded.put_u8(0xFF); let config_tuple = ((..).into(), ((), ()));
265 let result = HashMap::<u32, u64>::decode_cfg(encoded.clone(), &config_tuple);
266 assert!(matches!(result, Err(Error::ExtraData(1))));
267
268 let read_result = HashMap::<u32, u64>::read_cfg(&mut encoded, &config_tuple);
270 assert!(read_result.is_ok());
271 let decoded_map = read_result.unwrap();
272 assert_eq!(decoded_map.len(), 1);
273 assert_eq!(decoded_map.get(&1u32), Some(&100u64));
274 }
275
276 #[test]
277 fn test_hashmap_deterministic_encoding() {
278 let mut map2 = HashMap::new();
280 (0..=1000u32).for_each(|i| {
281 map2.insert(i, i * 2);
282 });
283
284 let mut map1 = HashMap::new();
286 (0..=1000u32).rev().for_each(|i| {
287 map1.insert(i, i * 2);
288 });
289
290 assert_eq!(map1.encode(), map2.encode());
291 }
292
293 #[test]
294 fn test_hashmap_conformity() {
295 let map1 = HashMap::<u8, u16>::new();
297 let mut expected1 = BytesMut::new();
298 0usize.write(&mut expected1); assert_eq!(map1.encode(), expected1.freeze());
300
301 let mut map2 = HashMap::<u8, u16>::new();
304 map2.insert(2u8, 0xBBBBu16); map2.insert(1u8, 0xAAAAu16);
306
307 let mut expected2 = BytesMut::new();
308 2usize.write(&mut expected2); 1u8.write(&mut expected2); 0xAAAAu16.write(&mut expected2); 2u8.write(&mut expected2); 0xBBBBu16.write(&mut expected2); assert_eq!(map2.encode(), expected2.freeze());
314
315 let mut map3 = HashMap::<u16, bool>::new();
318 map3.insert(0x0303u16, true);
319 map3.insert(0x0101u16, false);
320 map3.insert(0x0202u16, true);
321
322 let mut expected3 = BytesMut::new();
323 3usize.write(&mut expected3); 0x0101u16.write(&mut expected3); false.write(&mut expected3); 0x0202u16.write(&mut expected3); true.write(&mut expected3); 0x0303u16.write(&mut expected3); true.write(&mut expected3); assert_eq!(map3.encode(), expected3.freeze());
331
332 let mut map4 = HashMap::<Bytes, Vec<u8>>::new();
335 map4.insert(Bytes::from_static(b"b"), vec![20u8, 21u8]);
336 map4.insert(Bytes::from_static(b"a"), vec![10u8]);
337
338 let mut expected4 = BytesMut::new();
339 2usize.write(&mut expected4); Bytes::from_static(b"a").write(&mut expected4);
343 vec![10u8].write(&mut expected4);
345
346 Bytes::from_static(b"b").write(&mut expected4);
348 vec![20u8, 21u8].write(&mut expected4);
350
351 assert_eq!(map4.encode(), expected4.freeze());
352 }
353
354 #[cfg(feature = "arbitrary")]
355 mod conformance {
356 use super::*;
357 use crate::conformance::CodecConformance;
358
359 commonware_conformance::conformance_tests! {
360 CodecConformance<HashMap<u32, u32>>,
361 }
362 }
363}