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 super::*;
712
713 #[test]
714 fn new() {
715 let map = fresh();
716 assert!(map.is_empty());
717 assert_eq!(map.len(), 0);
718 }
719
720 #[test]
721 fn with_capacity() {
722 let map: DoubleMap<u64, String, i32> = DoubleMap::with_capacity(64);
723 assert!(map.capacity() >= 64);
724 assert!(map.is_empty());
725 }
726 }
727
728 mod capacity {
729 use super::*;
730
731 #[test]
732 fn reserve() {
733 let mut map = fresh();
734 map.reserve(128);
735 assert!(map.capacity() >= 128);
736 map.insert(1, "foo".to_string(), 10).unwrap();
737 assert_eq!(map.get_by_key1(&1), Some(&10));
738 }
739
740 #[test]
741 fn try_reserve() {
742 let mut map: DoubleMap<u64, String, i32> = fresh();
743 map.try_reserve(64).unwrap();
744 assert!(map.capacity() >= 64);
745 }
746
747 #[test]
748 fn shrink_to_fit() {
749 let mut map = populated();
750 map.reserve(128);
751 map.shrink_to_fit();
752 assert_eq!(map.get_by_key1(&1), Some(&10));
753 assert_eq!(map.get_by_key2("bar"), Some(&20));
754 }
755
756 #[test]
757 fn shrink_to() {
758 let mut map = populated();
759 map.reserve(256);
760 map.shrink_to(32);
761 assert!(map.capacity() >= 32);
762 assert_eq!(map.get_by_key1(&1), Some(&10));
763 assert_eq!(map.get_by_key2("bar"), Some(&20));
764 }
765 }
766
767 mod insert {
768 use super::*;
769
770 #[test]
771 fn insert() {
772 let mut map = fresh();
773
774 assert_eq!(map.insert(1, "foo".to_string(), 10).unwrap(), None);
776 assert_eq!(map.get_by_key1(&1), Some(&10));
777 assert_eq!(map.get_by_key2("foo"), Some(&10));
778
779 assert_eq!(map.insert(1, "foo".to_string(), 99).unwrap(), Some(10));
781 assert_eq!(map.get_by_key1(&1), Some(&99));
782
783 let err = map.insert(1, "bar".to_string(), 20).unwrap_err();
785 assert!(matches!(err, KeyConflictError::Key1Exists(1, _, 20)));
786
787 let err = map.insert(2, "foo".to_string(), 30).unwrap_err();
789 assert!(matches!(err, KeyConflictError::Key2Exists(2, _, 30)));
790
791 map.insert(2, "bar".to_string(), 20).unwrap();
793 let err = map.insert(1, "bar".to_string(), 42).unwrap_err();
794 assert!(matches!(err, KeyConflictError::BothKeysExist(1, _, 42)));
795 }
796 }
797
798 mod get {
799 use super::*;
800
801 #[test]
802 fn by_key1() {
803 let map = populated();
804 assert_eq!(map.get_by_key1(&1), Some(&10));
805 assert_eq!(map.get_by_key1(&99), None);
806 }
807
808 #[test]
809 fn by_key2() {
810 let map = populated();
811 assert_eq!(map.get_by_key2("foo"), Some(&10));
813 assert_eq!(map.get_by_key2("missing"), None);
814 }
815
816 #[test]
817 fn by_keys() {
818 let map = populated();
819 assert_eq!(map.get_by_keys(&1, "foo"), Some(&10));
820 assert_eq!(map.get_by_keys(&1, "bar"), None);
822 assert_eq!(map.get_by_keys(&99, "foo"), None);
824 }
825
826 #[test]
827 fn key1_value() {
828 let map = populated();
829 let (k1, v) = map.get_key1_value(&1).unwrap();
830 assert_eq!((*k1, *v), (1, 10));
831 assert!(map.get_key1_value(&99).is_none());
832 }
833
834 #[test]
835 fn key2_value() {
836 let map = populated();
837 let (k2, v) = map.get_key2_value("foo").unwrap();
838 assert_eq!((k2.as_str(), *v), ("foo", 10));
839 assert!(map.get_key2_value("missing").is_none());
840 }
841
842 #[test]
843 fn keys_value() {
844 let map = populated();
845 let (k1, k2, v) = map.get_keys_value(&1, "foo").unwrap();
846 assert_eq!((*k1, k2.as_str(), *v), (1, "foo", 10));
847 assert!(map.get_keys_value(&1, "bar").is_none());
848 }
849
850 #[test]
851 fn contains_key1() {
852 let map = populated();
853 assert!(map.contains_key1(&1));
854 assert!(!map.contains_key1(&99));
855 }
856
857 #[test]
858 fn contains_key2() {
859 let map = populated();
860 assert!(map.contains_key2("foo"));
861 assert!(!map.contains_key2("missing"));
862 }
863
864 #[test]
865 fn contains_keys() {
866 let map = populated();
867 assert!(map.contains_keys(&1, "foo"));
868 assert!(!map.contains_keys(&1, "bar"));
869 assert!(!map.contains_keys(&99, "foo"));
870 }
871 }
872
873 mod modify {
874 use super::*;
875
876 #[test]
877 fn get_mut_by_key1() {
878 let mut map = populated();
879 *map.get_mut_by_key1(&1).unwrap() = 42;
880 assert_eq!(map.get_by_key1(&1), Some(&42));
881 assert_eq!(map.get_by_key2("foo"), Some(&42));
882 }
883
884 #[test]
885 fn get_mut_by_key2() {
886 let mut map = populated();
887 *map.get_mut_by_key2("foo").unwrap() = 42;
888 assert_eq!(map.get_by_key1(&1), Some(&42));
889 }
890
891 #[test]
892 fn get_mut_by_keys() {
893 let mut map = populated();
894 *map.get_mut_by_keys(&1, "foo").unwrap() = 42;
895 assert_eq!(map.get_by_key1(&1), Some(&42));
896 assert!(map.get_mut_by_keys(&1, "bar").is_none());
898 }
899
900 #[test]
901 fn clear() {
902 let mut map = populated();
903 map.clear();
904 assert!(map.is_empty());
905 assert!(map.get_by_key1(&1).is_none());
906 }
907
908 #[test]
909 fn drain() {
910 let mut map = populated();
911 let mut drained: Vec<_> = map.drain().collect();
912 drained.sort_by_key(|(k1, _, _)| *k1);
913 assert_eq!(
914 drained,
915 vec![(1, "foo".to_string(), 10), (2, "bar".to_string(), 20)]
916 );
917 assert!(map.is_empty());
918 }
919
920 #[test]
921 fn retain() {
922 let mut map = populated();
923 map.retain(|_, _, v| *v >= 20);
924 assert_eq!(map.len(), 1);
925 assert!(!map.contains_key1(&1));
926 assert!(!map.contains_key2("foo"));
927 assert!(map.contains_key1(&2));
928 }
929 }
930
931 mod remove {
932 use super::*;
933
934 #[test]
935 fn by_key1() {
936 let mut map = populated();
937 assert_eq!(map.remove_by_key1(&1), Some(10));
938 assert!(!map.contains_key1(&1));
939 assert!(!map.contains_key2("foo"));
940 assert_eq!(map.remove_by_key1(&99), None);
941 }
942
943 #[test]
944 fn by_key2() {
945 let mut map = populated();
946 assert_eq!(map.remove_by_key2("foo"), Some(10));
947 assert!(!map.contains_key1(&1));
948 assert!(!map.contains_key2("foo"));
949 assert_eq!(map.remove_by_key2("missing"), None);
950 }
951
952 #[test]
953 fn by_keys() {
954 let mut map = populated();
955
956 assert_eq!(map.remove_by_keys(&1, "bar"), None);
958 assert_eq!(map.len(), 2);
959 assert!(map.contains_key1(&1));
960
961 assert_eq!(map.remove_by_keys(&1, "foo"), Some(10));
963 assert!(!map.contains_key1(&1));
964 assert!(!map.contains_key2("foo"));
965 }
966
967 #[test]
968 fn entry_by_key1() {
969 let mut map = populated();
970 assert_eq!(
971 map.remove_entry_by_key1(&1),
972 Some((1, "foo".to_string(), 10))
973 );
974 assert!(map.remove_entry_by_key1(&99).is_none());
975 }
976
977 #[test]
978 fn entry_by_key2() {
979 let mut map = populated();
980 assert_eq!(
981 map.remove_entry_by_key2("foo"),
982 Some((1, "foo".to_string(), 10))
983 );
984 assert!(map.remove_entry_by_key2("missing").is_none());
985 }
986
987 #[test]
988 fn entry_by_keys() {
989 let mut map = populated();
990 assert_eq!(
991 map.remove_entry_by_keys(&1, "foo"),
992 Some((1, "foo".to_string(), 10))
993 );
994 assert!(map.remove_entry_by_keys(&2, "foo").is_none());
996 }
997 }
998
999 mod iter {
1000 use super::*;
1001
1002 #[test]
1003 fn iter() {
1004 let map = populated();
1005 let mut entries: Vec<_> = map
1006 .iter()
1007 .map(|(k1, k2, v)| (*k1, k2.clone(), *v))
1008 .collect();
1009 entries.sort_by_key(|(k1, _, _)| *k1);
1010 assert_eq!(
1011 entries,
1012 vec![(1, "foo".to_string(), 10), (2, "bar".to_string(), 20)]
1013 );
1014 }
1015
1016 #[test]
1017 fn iter_mut() {
1018 let mut map = populated();
1019 for (_, _, v) in &mut map {
1021 *v *= 10;
1022 }
1023 assert_eq!(map.get_by_key1(&1), Some(&100));
1024 assert_eq!(map.get_by_key1(&2), Some(&200));
1025 }
1026
1027 #[test]
1028 fn for_shared_ref() {
1029 let map = populated();
1030 let mut count = 0;
1031 for (_, _, _) in &map {
1032 count += 1;
1033 }
1034 assert_eq!(count, 2);
1035 }
1036
1037 #[test]
1038 fn keys() {
1039 let map = populated();
1040 let mut keys: Vec<_> = map.keys().map(|(k1, k2)| (*k1, k2.clone())).collect();
1041 keys.sort_by_key(|(k1, _)| *k1);
1042 assert_eq!(keys, vec![(1, "foo".to_string()), (2, "bar".to_string())]);
1043 }
1044
1045 #[test]
1046 fn values() {
1047 let map = populated();
1048 let mut values: Vec<_> = map.values().copied().collect();
1049 values.sort();
1050 assert_eq!(values, vec![10, 20]);
1051 }
1052
1053 #[test]
1054 fn values_mut() {
1055 let mut map = populated();
1056 for v in map.values_mut() {
1057 *v += 1;
1058 }
1059 assert_eq!(map.get_by_key1(&1), Some(&11));
1060 }
1061
1062 #[test]
1063 fn into_iter() {
1064 let mut collected: Vec<_> = populated().into_iter().collect();
1065 collected.sort_by_key(|(k1, _, _)| *k1);
1066 assert_eq!(
1067 collected,
1068 vec![(1, "foo".to_string(), 10), (2, "bar".to_string(), 20)]
1069 );
1070 }
1071
1072 #[test]
1073 fn into_keys() {
1074 let mut keys: Vec<_> = populated().into_keys().collect();
1075 keys.sort_by_key(|(k1, _)| *k1);
1076 assert_eq!(keys, vec![(1, "foo".to_string()), (2, "bar".to_string())]);
1077 }
1078
1079 #[test]
1080 fn into_values() {
1081 let mut values: Vec<_> = populated().into_values().collect();
1082 values.sort();
1083 assert_eq!(values, vec![10, 20]);
1084 }
1085
1086 #[test]
1087 fn iter_clone_and_size_hint() {
1088 let map = populated();
1089 let it = map.iter();
1090 assert_eq!(it.len(), 2);
1091 assert_eq!(it.size_hint(), (2, Some(2)));
1092
1093 let it2 = it.clone();
1094 let mut a: Vec<_> = it.map(|(k1, _, _)| *k1).collect();
1095 let mut b: Vec<_> = it2.map(|(k1, _, _)| *k1).collect();
1096 a.sort();
1097 b.sort();
1098 assert_eq!(a, b);
1099 assert_eq!(a, vec![1, 2]);
1100 }
1101
1102 #[test]
1103 fn keys_values_clone() {
1104 let map = populated();
1105
1106 let keys = map.keys();
1107 let keys2 = keys.clone();
1108 assert_eq!(keys.len(), 2);
1109 let mut a: Vec<_> = keys.map(|(k1, _)| *k1).collect();
1110 let mut b: Vec<_> = keys2.map(|(k1, _)| *k1).collect();
1111 a.sort();
1112 b.sort();
1113 assert_eq!(a, b);
1114
1115 let values = map.values();
1116 let values2 = values.clone();
1117 assert_eq!(values.len(), 2);
1118 let mut a: Vec<_> = values.copied().collect();
1119 let mut b: Vec<_> = values2.copied().collect();
1120 a.sort();
1121 b.sort();
1122 assert_eq!(a, b);
1123 }
1124
1125 #[test]
1126 fn size_hints() {
1127 let mut map = populated();
1128 assert_eq!(map.iter_mut().len(), 2);
1129 assert_eq!(map.iter_mut().size_hint(), (2, Some(2)));
1130 assert_eq!(map.values_mut().len(), 2);
1131 assert_eq!(map.values_mut().size_hint(), (2, Some(2)));
1132
1133 let mut drain_src = map.clone();
1135 let drain = drain_src.drain();
1136 assert_eq!(drain.len(), 2);
1137 assert_eq!(drain.size_hint(), (2, Some(2)));
1138
1139 assert_eq!(map.clone().into_iter().len(), 2);
1140 assert_eq!(map.clone().into_keys().len(), 2);
1141 assert_eq!(map.into_values().len(), 2);
1142 }
1143 }
1144
1145 mod entry {
1146 use super::*;
1147
1148 #[test]
1149 fn entry() {
1150 let mut map = populated();
1151
1152 match map.entry(1, "foo".to_string()).unwrap() {
1154 Entry::Occupied(mut occ) => {
1155 assert_eq!(*occ.get(), 10);
1156 *occ.get_mut() = 42;
1157 let old = occ.insert(7);
1158 assert_eq!(old, 42);
1159 assert_eq!(occ.remove_entry(), (1, "foo".to_string(), 7));
1160 }
1161 Entry::Vacant(_) => panic!("expected Occupied"),
1162 }
1163 assert!(!map.contains_key1(&1));
1164
1165 match map.entry(3, "baz".to_string()).unwrap() {
1167 Entry::Vacant(vac) => {
1168 assert_eq!(*vac.key1(), 3);
1169 assert_eq!(vac.key2(), "baz");
1170 vac.insert(30);
1171 }
1172 Entry::Occupied(_) => panic!("expected Vacant"),
1173 }
1174 assert_eq!(map.get_by_key1(&3), Some(&30));
1175
1176 assert!(matches!(
1178 map.entry(2, "quux".to_string()),
1179 Err(KeyConflictError::Key1Exists(2, _, _))
1180 ));
1181
1182 assert!(matches!(
1184 map.entry(99, "bar".to_string()),
1185 Err(KeyConflictError::Key2Exists(99, _, _))
1186 ));
1187
1188 assert!(matches!(
1190 map.entry(2, "baz".to_string()),
1191 Err(KeyConflictError::BothKeysExist(2, _, _))
1192 ));
1193 }
1194
1195 #[test]
1196 fn key_accessors() {
1197 let mut map = populated();
1198
1199 let e = map.entry(1, "foo".to_string()).unwrap();
1201 assert_eq!(*e.key1(), 1);
1202 assert_eq!(e.key2(), "foo");
1203 let (k1, k2) = e.keys();
1204 assert_eq!((*k1, k2.as_str()), (1, "foo"));
1205
1206 let e = map.entry(3, "baz".to_string()).unwrap();
1208 assert_eq!(*e.key1(), 3);
1209 assert_eq!(e.key2(), "baz");
1210 let (k1, k2) = e.keys();
1211 assert_eq!((*k1, k2.as_str()), (3, "baz"));
1212 }
1213
1214 #[test]
1215 fn or_insert() {
1216 let mut map = fresh();
1217
1218 let v = map.entry(1, "foo".to_string()).unwrap().or_insert(10);
1220 *v = 42;
1221 assert_eq!(map.get_by_key1(&1), Some(&42));
1222
1223 let v = map.entry(1, "foo".to_string()).unwrap().or_insert(99);
1225 assert_eq!(*v, 42);
1226 }
1227
1228 #[test]
1229 fn or_insert_with() {
1230 let mut map = populated();
1231
1232 let v = map
1234 .entry(1, "foo".to_string())
1235 .unwrap()
1236 .or_insert_with(|| panic!("closure should not run on Occupied"));
1237 assert_eq!(*v, 10);
1238
1239 let v = map
1241 .entry(3, "baz".to_string())
1242 .unwrap()
1243 .or_insert_with(|| 30);
1244 assert_eq!(*v, 30);
1245 assert_eq!(map.get_by_key1(&3), Some(&30));
1246 }
1247
1248 #[test]
1249 fn or_insert_with_keys() {
1250 let mut map = populated();
1251
1252 let v = map
1254 .entry(1, "foo".to_string())
1255 .unwrap()
1256 .or_insert_with_keys(|_, _| panic!("closure should not run on Occupied"));
1257 assert_eq!(*v, 10);
1258
1259 let v = map
1261 .entry(3, "baz".to_string())
1262 .unwrap()
1263 .or_insert_with_keys(|k1, k2| *k1 as i32 + k2.len() as i32);
1264 assert_eq!(*v, 3 + 3);
1265 }
1266
1267 #[test]
1268 fn or_default() {
1269 let mut map: DoubleMap<u64, String, i32> = fresh();
1270 let v = map.entry(1, "foo".to_string()).unwrap().or_default();
1271 assert_eq!(*v, 0);
1272 }
1273
1274 #[test]
1275 fn and_modify() {
1276 let mut map = populated();
1277
1278 map.entry(1, "foo".to_string())
1280 .unwrap()
1281 .and_modify(|v| *v *= 2)
1282 .or_insert(0);
1283 assert_eq!(map.get_by_key1(&1), Some(&20));
1284
1285 map.entry(3, "baz".to_string())
1287 .unwrap()
1288 .and_modify(|v| *v *= 2)
1289 .or_insert(5);
1290 assert_eq!(map.get_by_key1(&3), Some(&5));
1291 }
1292
1293 #[test]
1294 fn insert_entry() {
1295 let mut map = populated();
1296
1297 let occ = map.entry(1, "foo".to_string()).unwrap().insert_entry(42);
1299 assert_eq!(*occ.get(), 42);
1300 assert_eq!(map.get_by_key1(&1), Some(&42));
1301
1302 let occ = map.entry(3, "baz".to_string()).unwrap().insert_entry(30);
1304 assert_eq!(*occ.get(), 30);
1305 assert_eq!(map.get_by_key1(&3), Some(&30));
1306 assert_eq!(map.get_by_key2("baz"), Some(&30));
1307 }
1308
1309 #[test]
1310 fn vacant_into_keys() {
1311 let mut map = fresh();
1312 let (k1, k2) = match map.entry(1u64, "foo".to_string()).unwrap() {
1313 Entry::Vacant(v) => v.into_keys(),
1314 Entry::Occupied(_) => panic!("expected Vacant"),
1315 };
1316 assert_eq!((k1, k2.as_str()), (1, "foo"));
1317 assert!(map.is_empty());
1319 }
1320
1321 #[test]
1322 fn vacant_insert_entry() {
1323 let mut map = fresh();
1324 match map.entry(1u64, "foo".to_string()).unwrap() {
1325 Entry::Vacant(v) => {
1326 let occ = v.insert_entry(10);
1327 assert_eq!(*occ.get(), 10);
1328 }
1329 Entry::Occupied(_) => panic!("expected Vacant"),
1330 }
1331 assert_eq!(map.get_by_key1(&1), Some(&10));
1332 assert_eq!(map.get_by_key2("foo"), Some(&10));
1333 }
1334
1335 #[test]
1336 fn occupied_accessors() {
1337 let mut map = populated();
1338 match map.entry(1u64, "foo".to_string()).unwrap() {
1339 Entry::Occupied(occ) => {
1340 assert_eq!(*occ.key1(), 1);
1341 assert_eq!(occ.key2(), "foo");
1342 let (k1, k2) = occ.keys();
1343 assert_eq!((*k1, k2.as_str()), (1, "foo"));
1344 }
1345 Entry::Vacant(_) => panic!("expected Occupied"),
1346 }
1347 }
1348
1349 #[test]
1350 fn occupied_remove() {
1351 let mut map = populated();
1352 match map.entry(1u64, "foo".to_string()).unwrap() {
1353 Entry::Occupied(occ) => assert_eq!(occ.remove(), 10),
1354 Entry::Vacant(_) => panic!("expected Occupied"),
1355 }
1356 assert!(!map.contains_key1(&1));
1357 assert!(!map.contains_key2("foo"));
1358 assert_eq!(map.len(), 1);
1359 }
1360 }
1361
1362 mod traits {
1363 use super::*;
1364
1365 #[test]
1366 fn from() {
1367 let map: DoubleMap<u64, String, i32> = DoubleMap::from([
1369 (1, "foo".to_string(), 10),
1370 (2, "bar".to_string(), 20),
1371 (1, "zzz".to_string(), 99),
1372 ]);
1373 assert_eq!(map.len(), 2);
1374 assert_eq!(map.get_by_key1(&1), Some(&10));
1375 assert!(!map.contains_key2("zzz"));
1376 }
1377
1378 #[test]
1379 fn from_iter() {
1380 let map: DoubleMap<u64, String, i32> =
1381 vec![(1u64, "foo".to_string(), 10), (2u64, "bar".to_string(), 20)]
1382 .into_iter()
1383 .collect();
1384 assert_eq!(map.len(), 2);
1385 assert_eq!(map.get_by_key1(&1), Some(&10));
1386 }
1387
1388 #[test]
1389 fn extend() {
1390 let mut map = fresh();
1391 map.insert(1, "foo".to_string(), 10).unwrap();
1392
1393 map.extend(vec![
1395 (2, "bar".to_string(), 20),
1396 (1, "zzz".to_string(), 99),
1397 (1, "foo".to_string(), 42),
1398 ]);
1399 assert_eq!(map.len(), 2);
1400 assert_eq!(map.get_by_key1(&1), Some(&42));
1401 assert_eq!(map.get_by_key1(&2), Some(&20));
1402 assert!(!map.contains_key2("zzz"));
1403 }
1404
1405 #[test]
1406 fn extend_borrowed() {
1407 let mut map: DoubleMap<u64, u64, i32> = DoubleMap::new();
1408 let items = [(1u64, 10u64, 100i32), (2, 20, 200)];
1409 map.extend(items.iter().map(|(k1, k2, v)| (k1, k2, v)));
1410 assert_eq!(map.len(), 2);
1411 assert_eq!(map.get_by_key1(&1), Some(&100));
1412 assert_eq!(map.get_by_key2(&20), Some(&200));
1413 }
1414
1415 #[test]
1416 fn index() {
1417 let map = populated();
1418 assert_eq!(map[&1], 10);
1419 assert_eq!(map[&2], 20);
1420 }
1421
1422 #[test]
1423 #[should_panic(expected = "no entry found for key")]
1424 fn index_panics() {
1425 let _ = fresh()[&1];
1426 }
1427
1428 #[test]
1429 fn clone() {
1430 let cloned = populated().clone();
1431 assert_eq!(cloned.len(), 2);
1432 assert_eq!(cloned.get_by_key1(&1), Some(&10));
1433 assert_eq!(cloned.get_by_key2("bar"), Some(&20));
1434 }
1435
1436 #[test]
1437 fn clone_from() {
1438 let mut target = fresh();
1439 target.insert(99, "old".to_string(), 999).unwrap();
1440 target.clone_from(&populated());
1441 assert_eq!(target.len(), 2);
1442 assert_eq!(target.get_by_key1(&1), Some(&10));
1443 assert!(!target.contains_key1(&99));
1444 assert!(!target.contains_key2("old"));
1445 }
1446
1447 #[test]
1448 fn eq() {
1449 let a = populated();
1450
1451 let mut b = fresh();
1453 b.insert(2, "bar".to_string(), 20).unwrap();
1454 b.insert(1, "foo".to_string(), 10).unwrap();
1455 assert_eq!(a, b);
1456
1457 let mut c = fresh();
1459 c.insert(1, "foo".to_string(), 10).unwrap();
1460 c.insert(2, "bar".to_string(), 99).unwrap();
1461 assert_ne!(a, c);
1462 }
1463
1464 #[test]
1465 fn debug_fmt() {
1466 let mut map = fresh();
1467 map.insert(1, "foo".to_string(), 10).unwrap();
1468 let s = format!("{:?}", map);
1469 assert!(s.contains('1'));
1470 assert!(s.contains("foo"));
1471 assert!(s.contains("10"));
1472 }
1473 }
1474
1475 mod errors {
1476 use super::*;
1477
1478 #[test]
1479 fn key_conflict_display() {
1480 let e1: KeyConflictError<u64, String> = KeyConflictError::Key1Exists(1, "a".into(), ());
1481 let e2: KeyConflictError<u64, String> = KeyConflictError::Key2Exists(1, "a".into(), ());
1482 let e3: KeyConflictError<u64, String> =
1483 KeyConflictError::BothKeysExist(1, "a".into(), ());
1484 assert!(e1.to_string().contains("key 1"));
1485 assert!(e2.to_string().contains("key 2"));
1486 assert!(e3.to_string().contains("both"));
1487 }
1488 }
1489}