1use crate::io;
2use alloc::collections::BTreeMap;
3
4use super::{Deserialize, Error, Serialize, VarUint32};
5
6use core::iter::{FromIterator, IntoIterator};
7
8#[derive(Debug, Default)]
12pub struct IndexMap<T> {
13 entries: BTreeMap<u32, T>,
15}
16
17impl<T> IndexMap<T> {
18 pub fn new() -> IndexMap<T> {
20 IndexMap { entries: BTreeMap::new() }
21 }
22
23 #[deprecated]
29 pub fn with_capacity(_capacity: usize) -> IndexMap<T> {
30 Self::new()
31 }
32
33 #[inline]
35 pub fn clear(&mut self) {
36 self.entries.clear();
37 }
38
39 #[inline]
41 pub fn get(&self, idx: u32) -> Option<&T> {
42 self.entries.get(&idx)
43 }
44
45 #[inline]
47 pub fn contains_key(&self, idx: u32) -> bool {
48 self.entries.contains_key(&idx)
49 }
50
51 #[inline]
53 pub fn insert(&mut self, idx: u32, value: T) -> Option<T> {
54 self.entries.insert(idx, value)
55 }
56
57 #[inline]
59 pub fn remove(&mut self, idx: u32) -> Option<T> {
60 self.entries.remove(&idx)
61 }
62
63 #[inline]
65 pub fn len(&self) -> usize {
66 self.entries.len()
67 }
68
69 #[inline]
71 pub fn is_empty(&self) -> bool {
72 self.entries.is_empty()
73 }
74
75 pub fn iter(&self) -> impl Iterator<Item = (u32, &T)> {
77 self.entries.iter().map(|(k, v)| (*k, v))
79 }
80
81 pub fn deserialize_with<R, F>(
96 max_entry_space: usize,
97 deserialize_value: &F,
98 rdr: &mut R,
99 ) -> Result<IndexMap<T>, Error>
100 where
101 R: io::Read,
102 F: Fn(u32, &mut R) -> Result<T, Error>,
103 {
104 let len: u32 = VarUint32::deserialize(rdr)?.into();
105 let mut map = IndexMap::new();
106 let mut prev_idx = None;
107 for _ in 0..len {
108 let idx: u32 = VarUint32::deserialize(rdr)?.into();
109 if idx as usize >= max_entry_space {
110 return Err(Error::Other("index is larger than expected"));
111 }
112 match prev_idx {
113 Some(prev) if prev >= idx => {
114 return Err(Error::Other("indices are out of order"));
117 },
118 _ => {
119 prev_idx = Some(idx);
120 },
121 }
122 let val = deserialize_value(idx, rdr)?;
123 map.insert(idx, val);
124 }
125 Ok(map)
126 }
127}
128
129impl<T: Clone> Clone for IndexMap<T> {
130 fn clone(&self) -> IndexMap<T> {
131 IndexMap { entries: self.entries.clone() }
132 }
133}
134
135impl<T: PartialEq> PartialEq<IndexMap<T>> for IndexMap<T> {
136 fn eq(&self, other: &IndexMap<T>) -> bool {
137 self.entries.eq(&other.entries)
138 }
139}
140
141impl<T: Eq> Eq for IndexMap<T> {}
142
143impl<T> FromIterator<(u32, T)> for IndexMap<T> {
144 fn from_iter<I>(iter: I) -> Self
150 where
151 I: IntoIterator<Item = (u32, T)>,
152 {
153 let iter = iter.into_iter();
154 let mut map = IndexMap::new();
155 for (idx, value) in iter {
156 map.insert(idx, value);
157 }
158 map
159 }
160}
161
162impl<T> IntoIterator for IndexMap<T> {
163 type Item = (u32, T);
164
165 type IntoIter = <BTreeMap<u32, T> as IntoIterator>::IntoIter;
166
167 #[inline]
168 fn into_iter(self) -> Self::IntoIter {
169 self.entries.into_iter()
170 }
171}
172
173impl<T> Serialize for IndexMap<T>
174where
175 T: Serialize,
176 Error: From<<T as Serialize>::Error>,
177{
178 type Error = Error;
179
180 fn serialize<W: io::Write>(self, wtr: &mut W) -> Result<(), Self::Error> {
181 VarUint32::try_from(self.len())
182 .map_err(|_| Self::Error::InvalidVarInt32)?
183 .serialize(wtr)?;
184 for (idx, value) in self.entries.into_iter() {
185 VarUint32::from(idx).serialize(wtr)?;
186 value.serialize(wtr)?;
187 }
188 Ok(())
189 }
190}
191
192impl<T: Deserialize> IndexMap<T>
193where
194 T: Deserialize,
195 Error: From<<T as Deserialize>::Error>,
196{
197 pub fn deserialize<R: io::Read>(max_entry_space: usize, rdr: &mut R) -> Result<Self, Error> {
201 let deserialize_value: fn(u32, &mut R) -> Result<T, Error> =
202 |_idx, rdr| T::deserialize(rdr).map_err(Error::from);
203 Self::deserialize_with(max_entry_space, &deserialize_value, rdr)
204 }
205}
206
207#[cfg(test)]
208mod tests {
209 use super::*;
210 use crate::{
211 alloc::string::{String, ToString},
212 io,
213 };
214
215 #[test]
216 fn default_is_empty_no_matter_how_we_look_at_it() {
217 let map = IndexMap::<String>::default();
218 assert_eq!(map.len(), 0);
219 assert!(map.is_empty());
220 assert_eq!(map.iter().count(), 0);
221 assert_eq!(map.into_iter().count(), 0);
222 }
223
224 #[test]
225 fn new_creates_empty_map() {
226 let map = IndexMap::<String>::new();
227 assert!(map.is_empty());
228 }
229
230 #[test]
231 fn clear_removes_all_values() {
232 let mut map = IndexMap::<String>::default();
233 map.insert(0, "sample value".to_string());
234 assert_eq!(map.len(), 1);
235 map.clear();
236 assert_eq!(map.len(), 0);
237 }
238
239 #[test]
240 fn get_returns_elements_that_are_there_but_nothing_else() {
241 let mut map = IndexMap::<String>::default();
242 map.insert(1, "sample value".to_string());
243 assert_eq!(map.len(), 1);
244 assert_eq!(map.get(0), None);
245 assert_eq!(map.get(1), Some(&"sample value".to_string()));
246 assert_eq!(map.get(2), None);
247 }
248
249 #[test]
250 fn contains_key_returns_true_when_a_key_is_present() {
251 let mut map = IndexMap::<String>::default();
252 map.insert(1, "sample value".to_string());
253 assert!(!map.contains_key(0));
254 assert!(map.contains_key(1));
255 assert!(!map.contains_key(2));
256 }
257
258 #[test]
259 fn insert_behaves_like_other_maps() {
260 let mut map = IndexMap::<String>::default();
261
262 assert_eq!(map.insert(1, "val 1".to_string()), None);
264 assert_eq!(map.len(), 1);
265 assert!(map.contains_key(1));
266
267 assert_eq!(map.insert(0, "val 0".to_string()), None);
269 assert_eq!(map.len(), 2);
270 assert!(map.contains_key(0));
271
272 assert_eq!(map.insert(1, "val 1.1".to_string()), Some("val 1".to_string()));
274 assert_eq!(map.len(), 2);
275 assert!(map.contains_key(1));
276 assert_eq!(map.get(1), Some(&"val 1.1".to_string()));
277 }
278
279 #[test]
280 fn remove_behaves_like_other_maps() {
281 let mut map = IndexMap::<String>::default();
282 assert_eq!(map.insert(1, "val 1".to_string()), None);
283
284 assert_eq!(map.remove(2), None);
286 assert_eq!(map.len(), 1);
287
288 assert_eq!(map.remove(0), None);
290 assert_eq!(map.len(), 1);
291
292 assert_eq!(map.remove(1), Some("val 1".to_string()));
294 assert_eq!(map.len(), 0);
295 }
296
297 #[test]
298 fn partial_eq_works_as_expected_in_simple_cases() {
299 let mut map1 = IndexMap::<String>::default();
300 let mut map2 = IndexMap::<String>::default();
301 assert_eq!(map1, map2);
302
303 map1.insert(1, "a".to_string());
304 map2.insert(1, "a".to_string());
305 assert_eq!(map1, map2);
306
307 map1.insert(0, "b".to_string());
308 assert_ne!(map1, map2);
309 map1.remove(0);
310 assert_eq!(map1, map2);
311
312 map1.insert(1, "not a".to_string());
313 assert_ne!(map1, map2);
314 }
315
316 #[test]
317 fn partial_eq_is_smart_about_none_values_at_the_end() {
318 let mut map1 = IndexMap::<String>::default();
319 let mut map2 = IndexMap::<String>::default();
320
321 map1.insert(1, "a".to_string());
322 map2.insert(1, "a".to_string());
323
324 map2.insert(10, "b".to_string());
326 map2.remove(10);
327 assert_eq!(map1, map2);
328
329 map1.insert(100, "b".to_string());
331 map1.remove(100);
332 assert_eq!(map1, map2);
333
334 map2.insert(1, "b".to_string());
336 assert_ne!(map1, map2);
337 }
338
339 #[test]
340 fn from_iterator_builds_a_map() {
341 let data = &[
342 (3, "val 3"),
344 (2, "val 2"),
345 (5, "val 5"),
346 ];
347 let iter = data.iter().map(|&(idx, val)| (idx, val.to_string()));
348 let map = iter.collect::<IndexMap<_>>();
349 assert_eq!(map.len(), 3);
350 assert_eq!(map.get(2), Some(&"val 2".to_string()));
351 assert_eq!(map.get(3), Some(&"val 3".to_string()));
352 assert_eq!(map.get(5), Some(&"val 5".to_string()));
353 }
354
355 #[test]
356 fn iterators_are_well_behaved() {
357 let data = &[(3, "val 3"), (2, "val 2"), (5, "val 5")];
361 let src_iter = data.iter().map(|&(idx, val)| (idx, val.to_string()));
362 let mut map = src_iter.collect::<IndexMap<_>>();
363 map.remove(5);
364
365 {
367 let mut iter1 = map.iter();
368 assert_eq!(iter1.size_hint(), (2, Some(2)));
369 assert_eq!(iter1.next(), Some((2, &"val 2".to_string())));
370 assert_eq!(iter1.size_hint(), (1, Some(1)));
371 assert_eq!(iter1.next(), Some((3, &"val 3".to_string())));
372 assert_eq!(iter1.size_hint(), (0, Some(0)));
373 assert_eq!(iter1.next(), None);
374 assert_eq!(iter1.size_hint(), (0, Some(0)));
375 assert_eq!(iter1.next(), None);
376 assert_eq!(iter1.size_hint(), (0, Some(0)));
377 }
378
379 let mut iter2 = map.into_iter();
381 assert_eq!(iter2.size_hint(), (2, Some(2)));
382 assert_eq!(iter2.next(), Some((2, "val 2".to_string())));
383 assert_eq!(iter2.size_hint(), (1, Some(1)));
384 assert_eq!(iter2.next(), Some((3, "val 3".to_string())));
385 assert_eq!(iter2.size_hint(), (0, Some(0)));
386 assert_eq!(iter2.next(), None);
387 assert_eq!(iter2.size_hint(), (0, Some(0)));
388 assert_eq!(iter2.next(), None);
389 assert_eq!(iter2.size_hint(), (0, Some(0)));
390 }
391
392 #[test]
393 fn serialize_and_deserialize() {
394 let mut map = IndexMap::<String>::default();
395 map.insert(1, "val 1".to_string());
396
397 let mut output = vec![];
398 map.clone().serialize(&mut output).expect("serialize failed");
399
400 let mut input = io::Cursor::new(&output);
401 let deserialized = IndexMap::deserialize(2, &mut input).expect("deserialize failed");
402
403 assert_eq!(deserialized, map);
404 }
405
406 #[test]
407 fn deserialize_requires_elements_to_be_in_order() {
408 let mut valid = vec![];
410 VarUint32::from(2u32).serialize(&mut valid).unwrap();
411 VarUint32::from(0u32).serialize(&mut valid).unwrap();
412 "val 0".to_string().serialize(&mut valid).unwrap();
413 VarUint32::from(1u32).serialize(&mut valid).unwrap();
414 "val 1".to_string().serialize(&mut valid).unwrap();
415 let map = IndexMap::<String>::deserialize(2, &mut io::Cursor::new(valid))
416 .expect("unexpected error deserializing");
417 assert_eq!(map.len(), 2);
418
419 let mut invalid = vec![];
421 VarUint32::from(2u32).serialize(&mut invalid).unwrap();
422 VarUint32::from(1u32).serialize(&mut invalid).unwrap();
423 "val 1".to_string().serialize(&mut invalid).unwrap();
424 VarUint32::from(0u32).serialize(&mut invalid).unwrap();
425 "val 0".to_string().serialize(&mut invalid).unwrap();
426 let res = IndexMap::<String>::deserialize(2, &mut io::Cursor::new(invalid));
427 assert!(res.is_err());
428 }
429
430 #[test]
431 fn deserialize_enforces_max_idx() {
432 let mut invalid = vec![];
434 VarUint32::from(1u32).serialize(&mut invalid).unwrap();
435 VarUint32::from(5u32).serialize(&mut invalid).unwrap();
436 "val 5".to_string().serialize(&mut invalid).unwrap();
437 let res = IndexMap::<String>::deserialize(1, &mut io::Cursor::new(invalid));
438 assert!(res.is_err());
439 }
440
441 #[test]
442 fn deserialize_with_capacity() {
443 let mut invalid = vec![];
444 VarUint32::from(u32::MAX).serialize(&mut invalid).unwrap();
445 VarUint32::from(5u32).serialize(&mut invalid).unwrap();
446 "fooba".to_string().serialize(&mut invalid).unwrap();
447 let _error = IndexMap::<String>::deserialize(6, &mut io::Cursor::new(invalid)).unwrap_err();
448 }
449
450 #[test]
451 fn very_large_idx() {
452 let mut invalid = vec![];
453 VarUint32::from(1u32).serialize(&mut invalid).unwrap();
454 VarUint32::from(u32::MAX - 1).serialize(&mut invalid).unwrap();
455 "fooba".to_string().serialize(&mut invalid).unwrap();
456 let indexmap =
457 IndexMap::<String>::deserialize(u32::MAX as usize, &mut io::Cursor::new(invalid))
458 .unwrap();
459 assert_eq!(indexmap.get(u32::MAX - 1), Some(&"fooba".to_string()));
460 assert_eq!(indexmap.len(), 1);
461 }
462}