Repository: billyrieger/bimap-rs (language: rust)

Issue:
std::iter::Extend for bimap
Hi, I've found your crate useful and have experimented with implementing `std::iter::Extend` for `BiHashMap`.

I have a working implementation (with test), and was wondering if you'd have any interest in a PR? If so I'll open one and we can iterate from there if necessary.

It's straightforward (15 lines) and I'm happy to implement the trait for `BiBTreeMap` as well, if that's helpful.


Discussion / hints:
That would be great! I think it'd be best to implement `Extend` for both `BiHashMap` and `BiBTreeMap`.

Fix patch:
diff --git a/src/btree.rs b/src/btree.rs
index 585646e..9189601 100644
--- a/src/btree.rs
+++ b/src/btree.rs
@@ -7,14 +7,14 @@ cfg_if::cfg_if! {
             cmp::Ordering,
             collections::{btree_map, BTreeMap},
             fmt,
-            iter::{FromIterator, FusedIterator},
+            iter::{Extend, FromIterator, FusedIterator},
             rc::Rc,
         };
     } else {
         use core::{
             cmp::Ordering,
             fmt,
-            iter::{FromIterator, FusedIterator},
+            iter::{Extend, FromIterator, FusedIterator},
         };
         use alloc::{collections::{btree_map, BTreeMap }, rc::Rc};
     }
@@ -497,6 +497,18 @@ where
     }
 }
 
+impl<L, R> Extend<(L, R)> for BiBTreeMap<L, R>
+where
+    L: Ord,
+    R: Ord,
+{
+    fn extend<T: IntoIterator<Item = (L, R)>>(&mut self, iter: T) {
+        iter.into_iter().for_each(move |(l, r)| {
+            self.insert(l, r);
+        });
+    }
+}
+
 impl<L, R> Ord for BiBTreeMap<L, R>
 where
     L: Ord,
@@ -773,6 +785,19 @@ mod tests {
         assert_eq!(pairs, vec![(&'a', &3), (&'b', &2), (&'c', &1)]);
     }
 
+    #[test]
+    fn extend() {
+        let mut bimap = BiBTreeMap::new();
+        bimap.insert('a', 3);
+        bimap.insert('b', 2);
+        bimap.extend(vec![('c', 3), ('b', 1), ('a', 4)]);
+        let mut bimap2 = BiBTreeMap::new();
+        bimap2.insert('a', 4);
+        bimap2.insert('b', 1);
+        bimap2.insert('c', 3);
+        assert_eq!(bimap, bimap2);
+    }
+
     #[test]
     fn cmp() {
         let bimap = BiBTreeMap::from_iter(vec![('a', 2)]);
diff --git a/src/hash.rs b/src/hash.rs
index 9402a03..28b8312 100644
--- a/src/hash.rs
+++ b/src/hash.rs
@@ -5,7 +5,7 @@ use std::{
     collections::{hash_map, HashMap},
     fmt,
     hash::{BuildHasher, Hash},
-    iter::{FromIterator, FusedIterator},
+    iter::{Extend, FromIterator, FusedIterator},
     ops::Deref,
     rc::Rc,
 };
@@ -636,6 +636,20 @@ where
     }
 }
 
+impl<L, R, LS, RS> Extend<(L, R)> for BiHashMap<L, R, LS, RS>
+where
+    L: Eq + Hash,
+    R: Eq + Hash,
+    LS: BuildHasher,
+    RS: BuildHasher,
+{
+    fn extend<T: IntoIterator<Item = (L, R)>>(&mut self, iter: T) {
+        iter.into_iter().for_each(move |(l, r)| {
+            self.insert(l, r);
+        });
+    }
+}
+
 impl<L, R, LS, RS> PartialEq for BiHashMap<L, R, LS, RS>
 where
     L: Eq + Hash,
@@ -874,6 +888,19 @@ mod tests {
         assert_eq!(pairs, vec![(&'a', &3), (&'b', &2), (&'c', &1)]);
     }
 
+    #[test]
+    fn extend() {
+        let mut bimap = BiHashMap::new();
+        bimap.insert('a', 3);
+        bimap.insert('b', 2);
+        bimap.extend(vec![('c', 3), ('b', 1), ('a', 4)]);
+        let mut bimap2 = BiHashMap::new();
+        bimap2.insert('a', 4);
+        bimap2.insert('b', 1);
+        bimap2.insert('c', 3);
+        assert_eq!(bimap, bimap2);
+    }
+
     #[test]
     fn iter() {
         let mut bimap = BiHashMap::new();
diff --git a/src/lib.rs b/src/lib.rs
index 3e6361d..8c582f4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -131,9 +131,9 @@
 //! );
 //! ```
 //!
-//! Note that the `FromIterator` implementations for both `BiHashMap` and `BiBTreeMap` use the
-//! `insert` method internally, meaning that values from the original iterator can be silently
-//! overwritten.
+//! Note that the `FromIterator` and `Extend` implementations for both `BiHashMap` and `BiBTreeMap`
+//! use the `insert` method internally, meaning that values from the original iterator/collection
+//! can be silently overwritten.
 //!
 //! ```
 //! use bimap::BiMap;


Test patch: