1use std::borrow::Borrow;
14use std::collections::hash_map;
15use std::fmt::{self, Debug, Formatter};
16use std::hash::Hash;
17use std::ops::Index;
18
19use ahash::{HashMap, HashMapExt};
20
21pub use std::collections::TryReserveError;
22
23mod errors;
24pub use errors::KeyConflictError;
25
26mod entry;
27pub use entry::{Entry, OccupiedEntry, VacantEntry};
28
29mod iter;
30pub use iter::{Drain, IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, Values, ValuesMut};
31
32pub struct DoubleMap<K1, K2, V> {
34 primary: HashMap<K1, (K2, V)>,
37 secondary: HashMap<K2, K1>,
39}
40
41impl<K1, K2, V> DoubleMap<K1, K2, V> {
42 pub fn new() -> Self {
44 Self {
45 primary: HashMap::default(),
46 secondary: HashMap::default(),
47 }
48 }
49
50 pub fn with_capacity(capacity: usize) -> Self {
53 Self {
54 primary: HashMap::with_capacity(capacity),
55 secondary: HashMap::with_capacity(capacity),
56 }
57 }
58
59 pub fn capacity(&self) -> usize {
61 self.primary.capacity().min(self.secondary.capacity())
62 }
63
64 pub fn keys(&self) -> Keys<'_, K1, K2, V> {
66 Keys::new(self.primary.iter())
67 }
68
69 pub fn into_keys(self) -> IntoKeys<K1, K2, V> {
72 let Self {
73 primary,
74 secondary: _,
75 } = self;
76 IntoKeys::new(primary.into_iter())
77 }
78
79 pub fn values(&self) -> Values<'_, K1, K2, V> {
81 Values::new(self.primary.values())
82 }
83
84 pub fn values_mut(&mut self) -> ValuesMut<'_, K1, K2, V> {
86 ValuesMut::new(self.primary.values_mut())
87 }
88
89 pub fn into_values(self) -> IntoValues<K1, K2, V> {
92 let Self {
93 primary,
94 secondary: _,
95 } = self;
96 IntoValues::new(primary.into_values())
97 }
98
99 pub fn iter(&self) -> Iter<'_, K1, K2, V> {
101 Iter::new(self.primary.iter())
102 }
103
104 pub fn iter_mut(&mut self) -> IterMut<'_, K1, K2, V> {
109 IterMut::new(self.primary.iter_mut())
110 }
111
112 pub fn len(&self) -> usize {
114 self.primary.len()
115 }
116
117 pub fn is_empty(&self) -> bool {
119 self.primary.is_empty()
120 }
121
122 pub fn drain(&mut self) -> Drain<'_, K1, K2, V> {
124 self.secondary.clear();
125 Drain::new(self.primary.drain())
126 }
127
128 pub fn clear(&mut self) {
130 self.primary.clear();
131 self.secondary.clear();
132 }
133}
134
135impl<K1, K2, V> DoubleMap<K1, K2, V>
136where
137 K1: Eq + Hash,
138 K2: Eq + Hash,
139{
140 pub fn retain<F>(&mut self, mut f: F)
142 where
143 F: FnMut(&K1, &K2, &mut V) -> bool,
144 {
145 self.primary.retain(|k1, (k2, v)| {
146 let keep = f(k1, k2, v);
147 if !keep {
148 self.secondary.remove(k2);
149 }
150 keep
151 });
152 }
153
154 pub fn reserve(&mut self, additional: usize) {
156 self.primary.reserve(additional);
157 self.secondary.reserve(additional);
158 }
159
160 pub fn try_reserve(&mut self, additional: usize) -> Result<(), TryReserveError> {
163 self.primary.try_reserve(additional)?;
164 self.secondary.try_reserve(additional)?;
165 Ok(())
166 }
167
168 pub fn shrink_to_fit(&mut self) {
170 self.primary.shrink_to_fit();
171 self.secondary.shrink_to_fit();
172 }
173
174 pub fn shrink_to(&mut self, min_capacity: usize) {
176 self.primary.shrink_to(min_capacity);
177 self.secondary.shrink_to(min_capacity);
178 }
179
180 pub fn get_by_key1<Q>(&self, key: &Q) -> Option<&V>
182 where
183 K1: Borrow<Q>,
184 Q: Eq + Hash + ?Sized,
185 {
186 self.primary.get(key).map(|(_, v)| v)
187 }
188
189 pub fn get_by_key2<Q>(&self, key: &Q) -> Option<&V>
191 where
192 K2: Borrow<Q>,
193 Q: Eq + Hash + ?Sized,
194 {
195 let k1 = self.secondary.get(key)?;
196 self.primary.get(k1).map(|(_, v)| v)
197 }
198
199 pub fn get_by_keys<Q1, Q2>(&self, key1: &Q1, key2: &Q2) -> Option<&V>
203 where
204 K1: Borrow<Q1>,
205 K2: Borrow<Q2>,
206 Q1: Eq + Hash + ?Sized,
207 Q2: Eq + Hash + ?Sized,
208 {
209 let (k2_stored, v) = self.primary.get(key1)?;
210 if k2_stored.borrow() == key2 {
211 Some(v)
212 } else {
213 None
214 }
215 }
216
217 pub fn get_key1_value<Q>(&self, key: &Q) -> Option<(&K1, &V)>
220 where
221 K1: Borrow<Q>,
222 Q: Eq + Hash + ?Sized,
223 {
224 self.primary.get_key_value(key).map(|(k1, (_, v))| (k1, v))
225 }
226
227 pub fn get_key2_value<Q>(&self, key: &Q) -> Option<(&K2, &V)>
230 where
231 K2: Borrow<Q>,
232 Q: Eq + Hash + ?Sized,
233 {
234 let (k2_stored, k1) = self.secondary.get_key_value(key)?;
235 let (_, v) = self.primary.get(k1)?;
236 Some((k2_stored, v))
237 }
238
239 pub fn get_keys_value<Q1, Q2>(&self, key1: &Q1, key2: &Q2) -> Option<(&K1, &K2, &V)>
243 where
244 K1: Borrow<Q1>,
245 K2: Borrow<Q2>,
246 Q1: Eq + Hash + ?Sized,
247 Q2: Eq + Hash + ?Sized,
248 {
249 let (k1_stored, (k2_stored, v)) = self.primary.get_key_value(key1)?;
250 if k2_stored.borrow() == key2 {
251 Some((k1_stored, k2_stored, v))
252 } else {
253 None
254 }
255 }
256
257 pub fn contains_key1<Q>(&self, key: &Q) -> bool
259 where
260 K1: Borrow<Q>,
261 Q: Eq + Hash + ?Sized,
262 {
263 self.primary.contains_key(key)
264 }
265
266 pub fn contains_key2<Q>(&self, key: &Q) -> bool
268 where
269 K2: Borrow<Q>,
270 Q: Eq + Hash + ?Sized,
271 {
272 self.secondary.contains_key(key)
273 }
274
275 pub fn contains_keys<Q1, Q2>(&self, key1: &Q1, key2: &Q2) -> bool
278 where
279 K1: Borrow<Q1>,
280 K2: Borrow<Q2>,
281 Q1: Eq + Hash + ?Sized,
282 Q2: Eq + Hash + ?Sized,
283 {
284 self.get_by_keys(key1, key2).is_some()
285 }
286
287 pub fn get_mut_by_key1<Q>(&mut self, key: &Q) -> Option<&mut V>
289 where
290 K1: Borrow<Q>,
291 Q: Eq + Hash + ?Sized,
292 {
293 self.primary.get_mut(key).map(|(_, v)| v)
294 }
295
296 pub fn get_mut_by_key2<Q>(&mut self, key: &Q) -> Option<&mut V>
298 where
299 K2: Borrow<Q>,
300 Q: Eq + Hash + ?Sized,
301 {
302 let k1 = self.secondary.get(key)?;
303 self.primary.get_mut(k1).map(|(_, v)| v)
304 }
305
306 pub fn get_mut_by_keys<Q1, Q2>(&mut self, key1: &Q1, key2: &Q2) -> Option<&mut V>
310 where
311 K1: Borrow<Q1>,
312 K2: Borrow<Q2>,
313 Q1: Eq + Hash + ?Sized,
314 Q2: Eq + Hash + ?Sized,
315 {
316 let (k2_stored, v) = self.primary.get_mut(key1)?;
317 if <K2 as Borrow<Q2>>::borrow(k2_stored) == key2 {
318 Some(v)
319 } else {
320 None
321 }
322 }
323
324 pub fn remove_by_key1<Q>(&mut self, key: &Q) -> Option<V>
326 where
327 K1: Borrow<Q>,
328 Q: Eq + Hash + ?Sized,
329 {
330 let (k2, value) = self.primary.remove(key)?;
331 self.secondary.remove(&k2);
332 Some(value)
333 }
334
335 pub fn remove_by_key2<Q>(&mut self, key: &Q) -> Option<V>
337 where
338 K2: Borrow<Q>,
339 Q: Eq + Hash + ?Sized,
340 {
341 let k1 = self.secondary.remove(key)?;
342 let (_, value) = self
343 .primary
344 .remove(&k1)
345 .expect("primary map must contain key 1 whenever secondary map points to it");
346 Some(value)
347 }
348
349 pub fn remove_by_keys<Q1, Q2>(&mut self, key1: &Q1, key2: &Q2) -> Option<V>
353 where
354 K1: Borrow<Q1>,
355 K2: Borrow<Q2>,
356 Q1: Eq + Hash + ?Sized,
357 Q2: Eq + Hash + ?Sized,
358 {
359 let (k1, (k2, value)) = self.primary.remove_entry(key1)?;
360 if <K2 as Borrow<Q2>>::borrow(&k2) != key2 {
361 self.primary.insert(k1, (k2, value));
362 return None;
363 }
364 self.secondary.remove::<K2>(&k2);
365 Some(value)
366 }
367
368 pub fn remove_entry_by_key1<Q>(&mut self, key: &Q) -> Option<(K1, K2, V)>
371 where
372 K1: Borrow<Q>,
373 Q: Eq + Hash + ?Sized,
374 {
375 let (k1, (k2, value)) = self.primary.remove_entry(key)?;
376 self.secondary.remove(&k2);
377 Some((k1, k2, value))
378 }
379
380 pub fn remove_entry_by_key2<Q>(&mut self, key: &Q) -> Option<(K1, K2, V)>
383 where
384 K2: Borrow<Q>,
385 Q: Eq + Hash + ?Sized,
386 {
387 let k1 = self.secondary.remove(key)?;
388 let (k1, (k2, value)) = self
389 .primary
390 .remove_entry(&k1)
391 .expect("primary map must contain key 1 whenever secondary map points to it");
392 Some((k1, k2, value))
393 }
394
395 pub fn remove_entry_by_keys<Q1, Q2>(&mut self, key1: &Q1, key2: &Q2) -> Option<(K1, K2, V)>
400 where
401 K1: Borrow<Q1>,
402 K2: Borrow<Q2>,
403 Q1: Eq + Hash + ?Sized,
404 Q2: Eq + Hash + ?Sized,
405 {
406 let (k1, (k2, value)) = self.primary.remove_entry(key1)?;
407 if <K2 as Borrow<Q2>>::borrow(&k2) != key2 {
408 self.primary.insert(k1, (k2, value));
409 return None;
410 }
411 self.secondary.remove::<K2>(&k2);
412 Some((k1, k2, value))
413 }
414}
415
416impl<K1, K2, V> DoubleMap<K1, K2, V>
417where
418 K1: Eq + Hash + Clone,
419 K2: Eq + Hash + Clone,
420{
421 pub fn entry(
430 &mut self,
431 key1: K1,
432 key2: K2,
433 ) -> Result<Entry<'_, K1, K2, V>, KeyConflictError<K1, K2>> {
434 let key1_matches_key2 = self
435 .primary
436 .get(&key1)
437 .map(|(k2_stored, _)| k2_stored == &key2);
438 let key2_present = self.secondary.contains_key(&key2);
439
440 match (key1_matches_key2, key2_present) {
441 (Some(true), _) => {
443 let hash_map::Entry::Occupied(e1) = self.primary.entry(key1) else {
444 unreachable!("primary.get just observed key 1 as present");
445 };
446 let hash_map::Entry::Occupied(e2) = self.secondary.entry(key2) else {
447 unreachable!(
448 "key 1's stored key 2 matches the argument, so secondary must contain it",
449 );
450 };
451 Ok(Entry::Occupied(OccupiedEntry::new(e1, e2)))
452 }
453 (None, false) => {
455 let hash_map::Entry::Vacant(e1) = self.primary.entry(key1) else {
456 unreachable!("primary.get just observed key 1 as absent");
457 };
458 let hash_map::Entry::Vacant(e2) = self.secondary.entry(key2) else {
459 unreachable!("secondary.contains_key just observed key 2 as absent");
460 };
461 Ok(Entry::Vacant(VacantEntry::new(e1, e2)))
462 }
463 (Some(false), true) => Err(KeyConflictError::BothKeysExist(key1, key2, ())),
465 (Some(false), false) => Err(KeyConflictError::Key1Exists(key1, key2, ())),
466 (None, true) => Err(KeyConflictError::Key2Exists(key1, key2, ())),
468 }
469 }
470
471 pub fn insert(
481 &mut self,
482 key1: K1,
483 key2: K2,
484 value: V,
485 ) -> Result<Option<V>, KeyConflictError<K1, K2, V>> {
486 if let Some((existing_k2, _)) = self.primary.get(&key1) {
487 if existing_k2 == &key2 {
488 let old = self.primary.insert(key1, (key2, value));
490 return Ok(old.map(|(_, v_old)| v_old));
491 }
492 if self.secondary.contains_key(&key2) {
495 return Err(KeyConflictError::BothKeysExist(key1, key2, value));
496 }
497 return Err(KeyConflictError::Key1Exists(key1, key2, value));
498 }
499
500 if self.secondary.contains_key(&key2) {
502 return Err(KeyConflictError::Key2Exists(key1, key2, value));
503 }
504
505 self.secondary.insert(key2.clone(), key1.clone());
506 self.primary.insert(key1, (key2, value));
507
508 Ok(None)
509 }
510}
511
512impl<K1, K2, V> Clone for DoubleMap<K1, K2, V>
513where
514 K1: Clone,
515 K2: Clone,
516 V: Clone,
517{
518 fn clone(&self) -> Self {
519 Self {
520 primary: self.primary.clone(),
521 secondary: self.secondary.clone(),
522 }
523 }
524
525 fn clone_from(&mut self, source: &Self) {
526 self.primary.clone_from(&source.primary);
527 self.secondary.clone_from(&source.secondary);
528 }
529}
530
531impl<K1, K2, V> PartialEq for DoubleMap<K1, K2, V>
532where
533 K1: Eq + Hash,
534 K2: Eq + Hash,
535 V: PartialEq,
536{
537 fn eq(&self, other: &Self) -> bool {
538 self.primary == other.primary
539 }
540}
541
542impl<K1, K2, V> Eq for DoubleMap<K1, K2, V>
543where
544 K1: Eq + Hash,
545 K2: Eq + Hash,
546 V: Eq,
547{
548}
549
550impl<K1, K2, V> Debug for DoubleMap<K1, K2, V>
551where
552 K1: Debug,
553 K2: Debug,
554 V: Debug,
555{
556 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
557 f.debug_map()
558 .entries(self.iter().map(|(k1, k2, v)| ((k1, k2), v)))
559 .finish()
560 }
561}
562
563impl<K1, K2, V> Default for DoubleMap<K1, K2, V> {
564 fn default() -> Self {
565 Self::new()
566 }
567}
568
569impl<K1, K2, V, Q> Index<&Q> for DoubleMap<K1, K2, V>
570where
571 K1: Eq + Hash + Borrow<Q>,
572 K2: Eq + Hash,
573 Q: Eq + Hash + ?Sized,
574{
575 type Output = V;
576
577 fn index(&self, key: &Q) -> &V {
583 self.get_by_key1(key).expect("no entry found for key")
584 }
585}
586
587impl<K1, K2, V> IntoIterator for DoubleMap<K1, K2, V> {
588 type Item = (K1, K2, V);
589 type IntoIter = IntoIter<K1, K2, V>;
590
591 fn into_iter(self) -> Self::IntoIter {
593 let Self {
594 primary,
595 secondary: _,
596 } = self;
597 IntoIter::new(primary.into_iter())
598 }
599}
600
601impl<'a, K1, K2, V> IntoIterator for &'a DoubleMap<K1, K2, V> {
602 type Item = (&'a K1, &'a K2, &'a V);
603 type IntoIter = Iter<'a, K1, K2, V>;
604
605 fn into_iter(self) -> Self::IntoIter {
607 self.iter()
608 }
609}
610
611impl<'a, K1, K2, V> IntoIterator for &'a mut DoubleMap<K1, K2, V> {
612 type Item = (&'a K1, &'a K2, &'a mut V);
613 type IntoIter = IterMut<'a, K1, K2, V>;
614
615 fn into_iter(self) -> Self::IntoIter {
618 self.iter_mut()
619 }
620}
621
622impl<K1, K2, V> Extend<(K1, K2, V)> for DoubleMap<K1, K2, V>
623where
624 K1: Eq + Hash + Clone,
625 K2: Eq + Hash + Clone,
626{
627 fn extend<I>(&mut self, iter: I)
634 where
635 I: IntoIterator<Item = (K1, K2, V)>,
636 {
637 let iter = iter.into_iter();
638 let (lower, _) = iter.size_hint();
639 self.reserve(lower);
640 for (k1, k2, v) in iter {
641 let _ = self.insert(k1, k2, v);
642 }
643 }
644}
645
646impl<'a, K1, K2, V> Extend<(&'a K1, &'a K2, &'a V)> for DoubleMap<K1, K2, V>
647where
648 K1: Eq + Hash + Copy,
649 K2: Eq + Hash + Copy,
650 V: Copy,
651{
652 fn extend<I>(&mut self, iter: I)
657 where
658 I: IntoIterator<Item = (&'a K1, &'a K2, &'a V)>,
659 {
660 self.extend(iter.into_iter().map(|(k1, k2, v)| (*k1, *k2, *v)));
661 }
662}
663
664impl<K1, K2, V> FromIterator<(K1, K2, V)> for DoubleMap<K1, K2, V>
665where
666 K1: Eq + Hash + Clone,
667 K2: Eq + Hash + Clone,
668{
669 fn from_iter<I>(iter: I) -> Self
673 where
674 I: IntoIterator<Item = (K1, K2, V)>,
675 {
676 let mut map = Self::new();
677 map.extend(iter);
678 map
679 }
680}
681
682impl<K1, K2, V, const N: usize> From<[(K1, K2, V); N]> for DoubleMap<K1, K2, V>
683where
684 K1: Eq + Hash + Clone,
685 K2: Eq + Hash + Clone,
686{
687 fn from(arr: [(K1, K2, V); N]) -> Self {
691 Self::from_iter(arr)
692 }
693}
694
695#[cfg(test)]
696mod tests {
697 use super::*;
698
699 fn fresh() -> DoubleMap<u64, String, i32> {
700 DoubleMap::new()
701 }
702
703 fn populated() -> DoubleMap<u64, String, i32> {
704 let mut map = fresh();
705 map.insert(1, "foo".to_string(), 10).unwrap();
706 map.insert(2, "bar".to_string(), 20).unwrap();
707 map
708 }
709
710 mod construction {
711 use pretty_assertions::assert_eq;
712
713 use super::*;
714
715 #[test]
716 fn new() {
717 let map = fresh();
718 assert!(map.is_empty());
719 assert_eq!(map.len(), 0);
720 }
721
722 #[test]
723 fn with_capacity() {
724 let map: DoubleMap<u64, String, i32> = DoubleMap::with_capacity(64);
725 assert!(map.capacity() >= 64);
726 assert!(map.is_empty());
727 }
728 }
729
730 mod capacity {
731 use pretty_assertions::assert_eq;
732
733 use super::*;
734
735 #[test]
736 fn reserve() -> anyhow::Result<()> {
737 let mut map = fresh();
738 map.reserve(128);
739 assert!(map.capacity() >= 128);
740 map.insert(1, "foo".to_string(), 10)?;
741 assert_eq!(map.get_by_key1(&1), Some(&10));
742
743 Ok(())
744 }
745
746 #[test]
747 fn try_reserve() -> anyhow::Result<()> {
748 let mut map: DoubleMap<u64, String, i32> = fresh();
749 map.try_reserve(64)?;
750 assert!(map.capacity() >= 64);
751
752 Ok(())
753 }
754
755 #[test]
756 fn shrink_to_fit() {
757 let mut map = populated();
758 map.reserve(128);
759 map.shrink_to_fit();
760 assert_eq!(map.get_by_key1(&1), Some(&10));
761 assert_eq!(map.get_by_key2("bar"), Some(&20));
762 }
763
764 #[test]
765 fn shrink_to() {
766 let mut map = populated();
767 map.reserve(256);
768 map.shrink_to(32);
769 assert!(map.capacity() >= 32);
770 assert_eq!(map.get_by_key1(&1), Some(&10));
771 assert_eq!(map.get_by_key2("bar"), Some(&20));
772 }
773 }
774
775 mod insert {
776 use pretty_assertions::assert_eq;
777
778 use super::*;
779
780 #[test]
781 fn insert() -> anyhow::Result<()> {
782 let mut map = fresh();
783
784 assert_eq!(map.insert(1, "foo".to_string(), 10)?, None);
786 assert_eq!(map.get_by_key1(&1), Some(&10));
787 assert_eq!(map.get_by_key2("foo"), Some(&10));
788
789 assert_eq!(map.insert(1, "foo".to_string(), 99)?, Some(10));
791 assert_eq!(map.get_by_key1(&1), Some(&99));
792
793 let err = map.insert(1, "bar".to_string(), 20).unwrap_err();
795 assert!(matches!(err, KeyConflictError::Key1Exists(1, _, 20)));
796
797 let err = map.insert(2, "foo".to_string(), 30).unwrap_err();
799 assert!(matches!(err, KeyConflictError::Key2Exists(2, _, 30)));
800
801 map.insert(2, "bar".to_string(), 20)?;
803 let err = map.insert(1, "bar".to_string(), 42).unwrap_err();
804 assert!(matches!(err, KeyConflictError::BothKeysExist(1, _, 42)));
805
806 Ok(())
807 }
808 }
809
810 mod get {
811 use pretty_assertions::assert_eq;
812
813 use super::*;
814
815 #[test]
816 fn by_key1() {
817 let map = populated();
818 assert_eq!(map.get_by_key1(&1), Some(&10));
819 assert_eq!(map.get_by_key1(&99), None);
820 }
821
822 #[test]
823 fn by_key2() {
824 let map = populated();
825 assert_eq!(map.get_by_key2("foo"), Some(&10));
827 assert_eq!(map.get_by_key2("missing"), None);
828 }
829
830 #[test]
831 fn by_keys() {
832 let map = populated();
833 assert_eq!(map.get_by_keys(&1, "foo"), Some(&10));
834 assert_eq!(map.get_by_keys(&1, "bar"), None);
836 assert_eq!(map.get_by_keys(&99, "foo"), None);
838 }
839
840 #[test]
841 fn key1_value() {
842 let map = populated();
843 let (k1, v) = map.get_key1_value(&1).unwrap();
844 assert_eq!((*k1, *v), (1, 10));
845 assert!(map.get_key1_value(&99).is_none());
846 }
847
848 #[test]
849 fn key2_value() {
850 let map = populated();
851 let (k2, v) = map.get_key2_value("foo").unwrap();
852 assert_eq!((k2.as_str(), *v), ("foo", 10));
853 assert!(map.get_key2_value("missing").is_none());
854 }
855
856 #[test]
857 fn keys_value() {
858 let map = populated();
859 let (k1, k2, v) = map.get_keys_value(&1, "foo").unwrap();
860 assert_eq!((*k1, k2.as_str(), *v), (1, "foo", 10));
861 assert!(map.get_keys_value(&1, "bar").is_none());
862 }
863
864 #[test]
865 fn contains_key1() {
866 let map = populated();
867 assert!(map.contains_key1(&1));
868 assert!(!map.contains_key1(&99));
869 }
870
871 #[test]
872 fn contains_key2() {
873 let map = populated();
874 assert!(map.contains_key2("foo"));
875 assert!(!map.contains_key2("missing"));
876 }
877
878 #[test]
879 fn contains_keys() {
880 let map = populated();
881 assert!(map.contains_keys(&1, "foo"));
882 assert!(!map.contains_keys(&1, "bar"));
883 assert!(!map.contains_keys(&99, "foo"));
884 }
885 }
886
887 mod modify {
888 use pretty_assertions::assert_eq;
889
890 use super::*;
891
892 #[test]
893 fn get_mut_by_key1() {
894 let mut map = populated();
895 *map.get_mut_by_key1(&1).unwrap() = 42;
896 assert_eq!(map.get_by_key1(&1), Some(&42));
897 assert_eq!(map.get_by_key2("foo"), Some(&42));
898 }
899
900 #[test]
901 fn get_mut_by_key2() {
902 let mut map = populated();
903 *map.get_mut_by_key2("foo").unwrap() = 42;
904 assert_eq!(map.get_by_key1(&1), Some(&42));
905 }
906
907 #[test]
908 fn get_mut_by_keys() {
909 let mut map = populated();
910 *map.get_mut_by_keys(&1, "foo").unwrap() = 42;
911 assert_eq!(map.get_by_key1(&1), Some(&42));
912 assert!(map.get_mut_by_keys(&1, "bar").is_none());
914 }
915
916 #[test]
917 fn clear() {
918 let mut map = populated();
919 map.clear();
920 assert!(map.is_empty());
921 assert!(map.get_by_key1(&1).is_none());
922 }
923
924 #[test]
925 fn drain() {
926 let mut map = populated();
927 let mut drained: Vec<_> = map.drain().collect();
928 drained.sort_by_key(|(k1, _, _)| *k1);
929 assert_eq!(
930 drained,
931 vec![(1, "foo".to_string(), 10), (2, "bar".to_string(), 20)]
932 );
933 assert!(map.is_empty());
934 }
935
936 #[test]
937 fn retain() {
938 let mut map = populated();
939 map.retain(|_, _, v| *v >= 20);
940 assert_eq!(map.len(), 1);
941 assert!(!map.contains_key1(&1));
942 assert!(!map.contains_key2("foo"));
943 assert!(map.contains_key1(&2));
944 }
945 }
946
947 mod remove {
948 use pretty_assertions::assert_eq;
949
950 use super::*;
951
952 #[test]
953 fn by_key1() {
954 let mut map = populated();
955 assert_eq!(map.remove_by_key1(&1), Some(10));
956 assert!(!map.contains_key1(&1));
957 assert!(!map.contains_key2("foo"));
958 assert_eq!(map.remove_by_key1(&99), None);
959 }
960
961 #[test]
962 fn by_key2() {
963 let mut map = populated();
964 assert_eq!(map.remove_by_key2("foo"), Some(10));
965 assert!(!map.contains_key1(&1));
966 assert!(!map.contains_key2("foo"));
967 assert_eq!(map.remove_by_key2("missing"), None);
968 }
969
970 #[test]
971 fn by_keys() {
972 let mut map = populated();
973
974 assert_eq!(map.remove_by_keys(&1, "bar"), None);
976 assert_eq!(map.len(), 2);
977 assert!(map.contains_key1(&1));
978
979 assert_eq!(map.remove_by_keys(&1, "foo"), Some(10));
981 assert!(!map.contains_key1(&1));
982 assert!(!map.contains_key2("foo"));
983 }
984
985 #[test]
986 fn entry_by_key1() {
987 let mut map = populated();
988 assert_eq!(
989 map.remove_entry_by_key1(&1),
990 Some((1, "foo".to_string(), 10))
991 );
992 assert!(map.remove_entry_by_key1(&99).is_none());
993 }
994
995 #[test]
996 fn entry_by_key2() {
997 let mut map = populated();
998 assert_eq!(
999 map.remove_entry_by_key2("foo"),
1000 Some((1, "foo".to_string(), 10))
1001 );
1002 assert!(map.remove_entry_by_key2("missing").is_none());
1003 }
1004
1005 #[test]
1006 fn entry_by_keys() {
1007 let mut map = populated();
1008 assert_eq!(
1009 map.remove_entry_by_keys(&1, "foo"),
1010 Some((1, "foo".to_string(), 10))
1011 );
1012 assert!(map.remove_entry_by_keys(&2, "foo").is_none());
1014 }
1015 }
1016
1017 mod iter {
1018 use pretty_assertions::assert_eq;
1019
1020 use super::*;
1021
1022 #[test]
1023 fn iter() {
1024 let map = populated();
1025 let mut entries: Vec<_> = map
1026 .iter()
1027 .map(|(k1, k2, v)| (*k1, k2.clone(), *v))
1028 .collect();
1029 entries.sort_by_key(|(k1, _, _)| *k1);
1030 assert_eq!(
1031 entries,
1032 vec![(1, "foo".to_string(), 10), (2, "bar".to_string(), 20)]
1033 );
1034 }
1035
1036 #[test]
1037 fn iter_mut() {
1038 let mut map = populated();
1039 for (_, _, v) in &mut map {
1041 *v *= 10;
1042 }
1043 assert_eq!(map.get_by_key1(&1), Some(&100));
1044 assert_eq!(map.get_by_key1(&2), Some(&200));
1045 }
1046
1047 #[test]
1048 fn for_shared_ref() {
1049 let map = populated();
1050 let mut count = 0;
1051 for (_, _, _) in &map {
1052 count += 1;
1053 }
1054 assert_eq!(count, 2);
1055 }
1056
1057 #[test]
1058 fn keys() {
1059 let map = populated();
1060 let mut keys: Vec<_> = map.keys().map(|(k1, k2)| (*k1, k2.clone())).collect();
1061 keys.sort_by_key(|(k1, _)| *k1);
1062 assert_eq!(keys, vec![(1, "foo".to_string()), (2, "bar".to_string())]);
1063 }
1064
1065 #[test]
1066 fn values() {
1067 let map = populated();
1068 let mut values: Vec<_> = map.values().copied().collect();
1069 values.sort();
1070 assert_eq!(values, vec![10, 20]);
1071 }
1072
1073 #[test]
1074 fn values_mut() {
1075 let mut map = populated();
1076 for v in map.values_mut() {
1077 *v += 1;
1078 }
1079 assert_eq!(map.get_by_key1(&1), Some(&11));
1080 }
1081
1082 #[test]
1083 fn into_iter() {
1084 let mut collected: Vec<_> = populated().into_iter().collect();
1085 collected.sort_by_key(|(k1, _, _)| *k1);
1086 assert_eq!(
1087 collected,
1088 vec![(1, "foo".to_string(), 10), (2, "bar".to_string(), 20)]
1089 );
1090 }
1091
1092 #[test]
1093 fn into_keys() {
1094 let mut keys: Vec<_> = populated().into_keys().collect();
1095 keys.sort_by_key(|(k1, _)| *k1);
1096 assert_eq!(keys, vec![(1, "foo".to_string()), (2, "bar".to_string())]);
1097 }
1098
1099 #[test]
1100 fn into_values() {
1101 let mut values: Vec<_> = populated().into_values().collect();
1102 values.sort();
1103 assert_eq!(values, vec![10, 20]);
1104 }
1105
1106 #[test]
1107 fn iter_clone_and_size_hint() {
1108 let map = populated();
1109 let it = map.iter();
1110 assert_eq!(it.len(), 2);
1111 assert_eq!(it.size_hint(), (2, Some(2)));
1112
1113 let it2 = it.clone();
1114 let mut a: Vec<_> = it.map(|(k1, _, _)| *k1).collect();
1115 let mut b: Vec<_> = it2.map(|(k1, _, _)| *k1).collect();
1116 a.sort();
1117 b.sort();
1118 assert_eq!(a, b);
1119 assert_eq!(a, vec![1, 2]);
1120 }
1121
1122 #[test]
1123 fn keys_values_clone() {
1124 let map = populated();
1125
1126 let keys = map.keys();
1127 let keys2 = keys.clone();
1128 assert_eq!(keys.len(), 2);
1129 let mut a: Vec<_> = keys.map(|(k1, _)| *k1).collect();
1130 let mut b: Vec<_> = keys2.map(|(k1, _)| *k1).collect();
1131 a.sort();
1132 b.sort();
1133 assert_eq!(a, b);
1134
1135 let values = map.values();
1136 let values2 = values.clone();
1137 assert_eq!(values.len(), 2);
1138 let mut a: Vec<_> = values.copied().collect();
1139 let mut b: Vec<_> = values2.copied().collect();
1140 a.sort();
1141 b.sort();
1142 assert_eq!(a, b);
1143 }
1144
1145 #[test]
1146 fn size_hints() {
1147 let mut map = populated();
1148 assert_eq!(map.iter_mut().len(), 2);
1149 assert_eq!(map.iter_mut().size_hint(), (2, Some(2)));
1150 assert_eq!(map.values_mut().len(), 2);
1151 assert_eq!(map.values_mut().size_hint(), (2, Some(2)));
1152
1153 let mut drain_src = map.clone();
1155 let drain = drain_src.drain();
1156 assert_eq!(drain.len(), 2);
1157 assert_eq!(drain.size_hint(), (2, Some(2)));
1158
1159 assert_eq!(map.clone().into_iter().len(), 2);
1160 assert_eq!(map.clone().into_keys().len(), 2);
1161 assert_eq!(map.into_values().len(), 2);
1162 }
1163 }
1164
1165 mod entry {
1166 use pretty_assertions::assert_eq;
1167
1168 use super::*;
1169
1170 #[test]
1171 fn entry() -> anyhow::Result<()> {
1172 let mut map = populated();
1173
1174 match map.entry(1, "foo".to_string())? {
1176 Entry::Occupied(mut occ) => {
1177 assert_eq!(*occ.get(), 10);
1178 *occ.get_mut() = 42;
1179 let old = occ.insert(7);
1180 assert_eq!(old, 42);
1181 assert_eq!(occ.remove_entry(), (1, "foo".to_string(), 7));
1182 }
1183 Entry::Vacant(_) => panic!("expected Occupied"),
1184 }
1185 assert!(!map.contains_key1(&1));
1186
1187 match map.entry(3, "baz".to_string())? {
1189 Entry::Vacant(vac) => {
1190 assert_eq!(*vac.key1(), 3);
1191 assert_eq!(vac.key2(), "baz");
1192 vac.insert(30);
1193 }
1194 Entry::Occupied(_) => panic!("expected Vacant"),
1195 }
1196 assert_eq!(map.get_by_key1(&3), Some(&30));
1197
1198 assert!(matches!(
1200 map.entry(2, "quux".to_string()),
1201 Err(KeyConflictError::Key1Exists(2, _, _))
1202 ));
1203
1204 assert!(matches!(
1206 map.entry(99, "bar".to_string()),
1207 Err(KeyConflictError::Key2Exists(99, _, _))
1208 ));
1209
1210 assert!(matches!(
1212 map.entry(2, "baz".to_string()),
1213 Err(KeyConflictError::BothKeysExist(2, _, _))
1214 ));
1215
1216 Ok(())
1217 }
1218
1219 #[test]
1220 fn key_accessors() -> anyhow::Result<()> {
1221 let mut map = populated();
1222
1223 let e = map.entry(1, "foo".to_string())?;
1225 assert_eq!(*e.key1(), 1);
1226 assert_eq!(e.key2(), "foo");
1227 let (k1, k2) = e.keys();
1228 assert_eq!((*k1, k2.as_str()), (1, "foo"));
1229
1230 let e = map.entry(3, "baz".to_string())?;
1232 assert_eq!(*e.key1(), 3);
1233 assert_eq!(e.key2(), "baz");
1234 let (k1, k2) = e.keys();
1235 assert_eq!((*k1, k2.as_str()), (3, "baz"));
1236
1237 Ok(())
1238 }
1239
1240 #[test]
1241 fn or_insert() -> anyhow::Result<()> {
1242 let mut map = fresh();
1243
1244 let v = map.entry(1, "foo".to_string())?.or_insert(10);
1246 *v = 42;
1247 assert_eq!(map.get_by_key1(&1), Some(&42));
1248
1249 let v = map.entry(1, "foo".to_string())?.or_insert(99);
1251 assert_eq!(*v, 42);
1252
1253 Ok(())
1254 }
1255
1256 #[test]
1257 fn or_insert_with() -> anyhow::Result<()> {
1258 let mut map = populated();
1259
1260 let v = map
1262 .entry(1, "foo".to_string())?
1263 .or_insert_with(|| panic!("closure should not run on Occupied"));
1264 assert_eq!(*v, 10);
1265
1266 let v = map.entry(3, "baz".to_string())?.or_insert_with(|| 30);
1268 assert_eq!(*v, 30);
1269 assert_eq!(map.get_by_key1(&3), Some(&30));
1270
1271 Ok(())
1272 }
1273
1274 #[test]
1275 fn or_insert_with_keys() -> anyhow::Result<()> {
1276 let mut map = populated();
1277
1278 let v = map
1280 .entry(1, "foo".to_string())?
1281 .or_insert_with_keys(|_, _| panic!("closure should not run on Occupied"));
1282 assert_eq!(*v, 10);
1283
1284 let v = map
1286 .entry(3, "baz".to_string())?
1287 .or_insert_with_keys(|k1, k2| *k1 as i32 + k2.len() as i32);
1288 assert_eq!(*v, 3 + 3);
1289
1290 Ok(())
1291 }
1292
1293 #[test]
1294 fn or_default() -> anyhow::Result<()> {
1295 let mut map: DoubleMap<u64, String, i32> = fresh();
1296 let v = map.entry(1, "foo".to_string())?.or_default();
1297 assert_eq!(*v, 0);
1298
1299 Ok(())
1300 }
1301
1302 #[test]
1303 fn and_modify() -> anyhow::Result<()> {
1304 let mut map = populated();
1305
1306 map.entry(1, "foo".to_string())?
1308 .and_modify(|v| *v *= 2)
1309 .or_insert(0);
1310 assert_eq!(map.get_by_key1(&1), Some(&20));
1311
1312 map.entry(3, "baz".to_string())?
1314 .and_modify(|v| *v *= 2)
1315 .or_insert(5);
1316 assert_eq!(map.get_by_key1(&3), Some(&5));
1317
1318 Ok(())
1319 }
1320
1321 #[test]
1322 fn insert_entry() -> anyhow::Result<()> {
1323 let mut map = populated();
1324
1325 let occ = map.entry(1, "foo".to_string())?.insert_entry(42);
1327 assert_eq!(*occ.get(), 42);
1328 assert_eq!(map.get_by_key1(&1), Some(&42));
1329
1330 let occ = map.entry(3, "baz".to_string())?.insert_entry(30);
1332 assert_eq!(*occ.get(), 30);
1333 assert_eq!(map.get_by_key1(&3), Some(&30));
1334 assert_eq!(map.get_by_key2("baz"), Some(&30));
1335
1336 Ok(())
1337 }
1338
1339 #[test]
1340 fn vacant_into_keys() -> anyhow::Result<()> {
1341 let mut map = fresh();
1342 let (k1, k2) = match map.entry(1u64, "foo".to_string())? {
1343 Entry::Vacant(v) => v.into_keys(),
1344 Entry::Occupied(_) => panic!("expected Vacant"),
1345 };
1346 assert_eq!((k1, k2.as_str()), (1, "foo"));
1347 assert!(map.is_empty());
1349
1350 Ok(())
1351 }
1352
1353 #[test]
1354 fn vacant_insert_entry() -> anyhow::Result<()> {
1355 let mut map = fresh();
1356 match map.entry(1u64, "foo".to_string())? {
1357 Entry::Vacant(v) => {
1358 let occ = v.insert_entry(10);
1359 assert_eq!(*occ.get(), 10);
1360 }
1361 Entry::Occupied(_) => panic!("expected Vacant"),
1362 }
1363 assert_eq!(map.get_by_key1(&1), Some(&10));
1364 assert_eq!(map.get_by_key2("foo"), Some(&10));
1365
1366 Ok(())
1367 }
1368
1369 #[test]
1370 fn occupied_accessors() -> anyhow::Result<()> {
1371 let mut map = populated();
1372 match map.entry(1u64, "foo".to_string())? {
1373 Entry::Occupied(occ) => {
1374 assert_eq!(*occ.key1(), 1);
1375 assert_eq!(occ.key2(), "foo");
1376 let (k1, k2) = occ.keys();
1377 assert_eq!((*k1, k2.as_str()), (1, "foo"));
1378 }
1379 Entry::Vacant(_) => panic!("expected Occupied"),
1380 }
1381
1382 Ok(())
1383 }
1384
1385 #[test]
1386 fn occupied_remove() -> anyhow::Result<()> {
1387 let mut map = populated();
1388 match map.entry(1u64, "foo".to_string())? {
1389 Entry::Occupied(occ) => assert_eq!(occ.remove(), 10),
1390 Entry::Vacant(_) => panic!("expected Occupied"),
1391 }
1392 assert!(!map.contains_key1(&1));
1393 assert!(!map.contains_key2("foo"));
1394 assert_eq!(map.len(), 1);
1395
1396 Ok(())
1397 }
1398 }
1399
1400 mod traits {
1401 use pretty_assertions::{assert_eq, assert_ne};
1402
1403 use super::*;
1404
1405 #[test]
1406 fn from() {
1407 let map: DoubleMap<u64, String, i32> = DoubleMap::from([
1409 (1, "foo".to_string(), 10),
1410 (2, "bar".to_string(), 20),
1411 (1, "zzz".to_string(), 99),
1412 ]);
1413 assert_eq!(map.len(), 2);
1414 assert_eq!(map.get_by_key1(&1), Some(&10));
1415 assert!(!map.contains_key2("zzz"));
1416 }
1417
1418 #[test]
1419 fn from_iter() {
1420 let map: DoubleMap<u64, String, i32> =
1421 vec![(1u64, "foo".to_string(), 10), (2u64, "bar".to_string(), 20)]
1422 .into_iter()
1423 .collect();
1424 assert_eq!(map.len(), 2);
1425 assert_eq!(map.get_by_key1(&1), Some(&10));
1426 }
1427
1428 #[test]
1429 fn extend() -> anyhow::Result<()> {
1430 let mut map = fresh();
1431 map.insert(1, "foo".to_string(), 10)?;
1432
1433 map.extend(vec![
1435 (2, "bar".to_string(), 20),
1436 (1, "zzz".to_string(), 99),
1437 (1, "foo".to_string(), 42),
1438 ]);
1439 assert_eq!(map.len(), 2);
1440 assert_eq!(map.get_by_key1(&1), Some(&42));
1441 assert_eq!(map.get_by_key1(&2), Some(&20));
1442 assert!(!map.contains_key2("zzz"));
1443
1444 Ok(())
1445 }
1446
1447 #[test]
1448 fn extend_borrowed() {
1449 let mut map: DoubleMap<u64, u64, i32> = DoubleMap::new();
1450 let items = [(1u64, 10u64, 100i32), (2, 20, 200)];
1451 map.extend(items.iter().map(|(k1, k2, v)| (k1, k2, v)));
1452 assert_eq!(map.len(), 2);
1453 assert_eq!(map.get_by_key1(&1), Some(&100));
1454 assert_eq!(map.get_by_key2(&20), Some(&200));
1455 }
1456
1457 #[test]
1458 fn index() {
1459 let map = populated();
1460 assert_eq!(map[&1], 10);
1461 assert_eq!(map[&2], 20);
1462 }
1463
1464 #[test]
1465 #[should_panic(expected = "no entry found for key")]
1466 fn index_panics() {
1467 let _ = fresh()[&1];
1468 }
1469
1470 #[test]
1471 fn clone() {
1472 let cloned = populated().clone();
1473 assert_eq!(cloned.len(), 2);
1474 assert_eq!(cloned.get_by_key1(&1), Some(&10));
1475 assert_eq!(cloned.get_by_key2("bar"), Some(&20));
1476 }
1477
1478 #[test]
1479 fn clone_from() -> anyhow::Result<()> {
1480 let mut target = fresh();
1481 target.insert(99, "old".to_string(), 999)?;
1482 target.clone_from(&populated());
1483 assert_eq!(target.len(), 2);
1484 assert_eq!(target.get_by_key1(&1), Some(&10));
1485 assert!(!target.contains_key1(&99));
1486 assert!(!target.contains_key2("old"));
1487
1488 Ok(())
1489 }
1490
1491 #[test]
1492 fn eq() -> anyhow::Result<()> {
1493 let a = populated();
1494
1495 let mut b = fresh();
1497 b.insert(2, "bar".to_string(), 20)?;
1498 b.insert(1, "foo".to_string(), 10)?;
1499 assert_eq!(a, b);
1500
1501 let mut c = fresh();
1503 c.insert(1, "foo".to_string(), 10)?;
1504 c.insert(2, "bar".to_string(), 99)?;
1505 assert_ne!(a, c);
1506
1507 Ok(())
1508 }
1509
1510 #[test]
1511 fn debug_fmt() -> anyhow::Result<()> {
1512 let mut map = fresh();
1513 map.insert(1, "foo".to_string(), 10)?;
1514 let s = format!("{:?}", map);
1515 assert!(s.contains('1'));
1516 assert!(s.contains("foo"));
1517 assert!(s.contains("10"));
1518
1519 Ok(())
1520 }
1521 }
1522
1523 mod errors {
1524 use super::*;
1525
1526 #[test]
1527 fn key_conflict_display() {
1528 let e1: KeyConflictError<u64, String> = KeyConflictError::Key1Exists(1, "a".into(), ());
1529 let e2: KeyConflictError<u64, String> = KeyConflictError::Key2Exists(1, "a".into(), ());
1530 let e3: KeyConflictError<u64, String> =
1531 KeyConflictError::BothKeysExist(1, "a".into(), ());
1532 assert!(e1.to_string().contains("key 1"));
1533 assert!(e2.to_string().contains("key 2"));
1534 assert!(e3.to_string().contains("both"));
1535 }
1536 }
1537}