#![forbid(unsafe_code)]
use std::borrow::Borrow;
use std::collections::hash_map::{IntoIter, Keys, RandomState};
use std::collections::HashMap;
use std::fmt::{self, Debug};
use std::hash::{BuildHasher, Hash};
use std::iter::{FromIterator, IntoIterator, Iterator};
use std::ops::Index;
pub use std::collections::hash_map::Iter as IterAll;
pub use std::collections::hash_map::IterMut as IterAllMut;
pub use entry::{Entry, OccupiedEntry, VacantEntry};
mod entry;
#[cfg(feature = "serde_impl")]
pub mod serde;
#[derive(Clone)]
pub struct MultiMap<K, V, S = RandomState> {
inner: HashMap<K, Vec<V>, S>,
}
impl<K, V> MultiMap<K, V>
where
K: Eq + Hash,
{
pub fn new() -> MultiMap<K, V> {
MultiMap {
inner: HashMap::new(),
}
}
pub fn with_capacity(capacity: usize) -> MultiMap<K, V> {
MultiMap {
inner: HashMap::with_capacity(capacity),
}
}
}
impl<K, V, S> MultiMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
pub fn with_hasher(hash_builder: S) -> MultiMap<K, V, S> {
MultiMap {
inner: HashMap::with_hasher(hash_builder),
}
}
pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> MultiMap<K, V, S> {
MultiMap {
inner: HashMap::with_capacity_and_hasher(capacity, hash_builder),
}
}
pub fn insert(&mut self, k: K, v: V) {
match self.entry(k) {
Entry::Occupied(mut entry) => {
entry.get_vec_mut().push(v);
}
Entry::Vacant(entry) => {
entry.insert_vec(vec![v]);
}
}
}
pub fn insert_many<I: IntoIterator<Item = V>>(&mut self, k: K, v: I) {
match self.entry(k) {
Entry::Occupied(mut entry) => {
entry.get_vec_mut().extend(v);
}
Entry::Vacant(entry) => {
entry.insert_vec(v.into_iter().collect::<Vec<_>>());
}
}
}
pub fn insert_many_from_slice(&mut self, k: K, v: &[V])
where
V: Clone,
{
match self.entry(k) {
Entry::Occupied(mut entry) => {
entry.get_vec_mut().extend_from_slice(v);
}
Entry::Vacant(entry) => {
entry.insert_vec(v.to_vec());
}
}
}
pub fn contains_key<Q>(&self, k: &Q) -> bool
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
self.inner.contains_key(k)
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn remove<Q>(&mut self, k: &Q) -> Option<Vec<V>>
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
self.inner.remove(k)
}
pub fn get<Q>(&self, k: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
self.inner.get(k)?.first()
}
pub fn get_mut<Q>(&mut self, k: &Q) -> Option<&mut V>
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
self.inner.get_mut(k)?.get_mut(0)
}
pub fn get_vec<Q>(&self, k: &Q) -> Option<&Vec<V>>
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
self.inner.get(k)
}
pub fn get_vec_mut<Q>(&mut self, k: &Q) -> Option<&mut Vec<V>>
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
self.inner.get_mut(k)
}
pub fn is_vec<Q>(&self, k: &Q) -> bool
where
K: Borrow<Q>,
Q: Eq + Hash + ?Sized,
{
match self.get_vec(k) {
Some(val) => val.len() > 1,
None => false,
}
}
pub fn capacity(&self) -> usize {
self.inner.capacity()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn clear(&mut self) {
self.inner.clear();
}
pub fn keys(&'_ self) -> Keys<'_, K, Vec<V>> {
self.inner.keys()
}
pub fn iter(&self) -> Iter<K, V> {
Iter {
inner: self.inner.iter(),
}
}
pub fn iter_mut(&mut self) -> IterMut<K, V> {
IterMut {
inner: self.inner.iter_mut(),
}
}
pub fn iter_all(&self) -> IterAll<K, Vec<V>> {
self.inner.iter()
}
pub fn iter_all_mut(&mut self) -> IterAllMut<K, Vec<V>> {
self.inner.iter_mut()
}
pub fn flat_iter(&self) -> impl Iterator<Item = (&K, &V)> {
self.iter_all()
.flat_map(|(k, v)| v.iter().map(move |i| (k, i)))
}
pub fn flat_iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
self.iter_all_mut()
.flat_map(|(k, v)| v.iter_mut().map(move |i| (k, i)))
}
pub fn entry(&mut self, k: K) -> Entry<K, V> {
use std::collections::hash_map::Entry as HashMapEntry;
match self.inner.entry(k) {
HashMapEntry::Occupied(entry) => Entry::Occupied(OccupiedEntry { inner: entry }),
HashMapEntry::Vacant(entry) => Entry::Vacant(VacantEntry { inner: entry }),
}
}
pub fn retain<F>(&mut self, mut f: F)
where
F: FnMut(&K, &V) -> bool,
{
for (key, vector) in &mut self.inner {
vector.retain(|value| f(key, value));
}
self.inner.retain(|_, v| !v.is_empty());
}
}
impl<K, V, S, Q> Index<&Q> for MultiMap<K, V, S>
where
K: Eq + Hash + Borrow<Q>,
Q: Eq + Hash + ?Sized,
S: BuildHasher,
{
type Output = V;
fn index(&self, index: &Q) -> &V {
self.inner
.get(index)
.expect("no entry found for key")
.first()
.expect("no value found for key")
}
}
impl<K, V, S> Debug for MultiMap<K, V, S>
where
K: Eq + Hash + Debug,
V: Debug,
S: BuildHasher,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_map().entries(self.iter_all()).finish()
}
}
impl<K, V, S> PartialEq for MultiMap<K, V, S>
where
K: Eq + Hash,
V: PartialEq,
S: BuildHasher,
{
fn eq(&self, other: &MultiMap<K, V, S>) -> bool {
if self.len() != other.len() {
return false;
}
self.iter_all()
.all(|(key, value)| other.get_vec(key).is_some_and(|v| *value == *v))
}
}
impl<K, V, S> Eq for MultiMap<K, V, S>
where
K: Eq + Hash,
V: Eq,
S: BuildHasher,
{
}
impl<K, V, S> Default for MultiMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher + Default,
{
fn default() -> MultiMap<K, V, S> {
MultiMap {
inner: Default::default(),
}
}
}
impl<K, V, S> FromIterator<(K, V)> for MultiMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher + Default,
{
fn from_iter<T: IntoIterator<Item = (K, V)>>(iterable: T) -> MultiMap<K, V, S> {
let iter = iterable.into_iter();
let hint = iter.size_hint().0;
let mut multimap = MultiMap::with_capacity_and_hasher(hint, S::default());
for (k, v) in iter {
multimap.insert(k, v);
}
multimap
}
}
impl<K, V, S> FromIterator<(K, Vec<V>)> for MultiMap<K, V, S>
where
K: Eq + Hash,
V: Clone,
S: BuildHasher + Default,
{
fn from_iter<T: IntoIterator<Item = (K, Vec<V>)>>(iterable: T) -> MultiMap<K, V, S> {
let iter = iterable.into_iter();
let hint = iter.size_hint().0;
let mut multimap = MultiMap::with_capacity_and_hasher(hint, S::default());
for (k, v) in iter {
multimap.insert_many_from_slice(k, &v[..])
}
multimap
}
}
impl<'a, K, V, S> IntoIterator for &'a MultiMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
type Item = (&'a K, &'a Vec<V>);
type IntoIter = IterAll<'a, K, Vec<V>>;
fn into_iter(self) -> IterAll<'a, K, Vec<V>> {
self.iter_all()
}
}
impl<'a, K, V, S> IntoIterator for &'a mut MultiMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
type Item = (&'a K, &'a mut Vec<V>);
type IntoIter = IterAllMut<'a, K, Vec<V>>;
fn into_iter(self) -> IterAllMut<'a, K, Vec<V>> {
self.inner.iter_mut()
}
}
impl<K, V, S> IntoIterator for MultiMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
type Item = (K, Vec<V>);
type IntoIter = IntoIter<K, Vec<V>>;
fn into_iter(self) -> IntoIter<K, Vec<V>> {
self.inner.into_iter()
}
}
impl<K, V, S> Extend<(K, V)> for MultiMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
for (k, v) in iter {
self.insert(k, v);
}
}
}
impl<'a, K, V, S> Extend<(&'a K, &'a V)> for MultiMap<K, V, S>
where
K: Eq + Hash + Copy,
V: Copy,
S: BuildHasher,
{
fn extend<T: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: T) {
self.extend(iter.into_iter().map(|(&key, &value)| (key, value)));
}
}
impl<K, V, S> Extend<(K, Vec<V>)> for MultiMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
fn extend<T: IntoIterator<Item = (K, Vec<V>)>>(&mut self, iter: T) {
for (k, values) in iter {
match self.entry(k) {
Entry::Occupied(mut entry) => {
entry.get_vec_mut().extend(values);
}
Entry::Vacant(entry) => {
entry.insert_vec(values);
}
}
}
}
}
impl<'a, K, V, S> Extend<(&'a K, &'a Vec<V>)> for MultiMap<K, V, S>
where
K: Eq + Hash + Copy,
V: Copy,
S: BuildHasher,
{
fn extend<T: IntoIterator<Item = (&'a K, &'a Vec<V>)>>(&mut self, iter: T) {
self.extend(
iter.into_iter()
.map(|(&key, values)| (key, values.to_owned())),
);
}
}
#[derive(Clone)]
pub struct Iter<'a, K: 'a, V: 'a> {
inner: IterAll<'a, K, Vec<V>>,
}
impl<'a, K, V> Iterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
fn next(&mut self) -> Option<(&'a K, &'a V)> {
let (k, v) = self.inner.next()?;
let v = v.first()?;
Some((k, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<K, V> ExactSizeIterator for Iter<'_, K, V> {
fn len(&self) -> usize {
self.inner.len()
}
}
pub struct IterMut<'a, K: 'a, V: 'a> {
inner: IterAllMut<'a, K, Vec<V>>,
}
impl<'a, K, V> Iterator for IterMut<'a, K, V> {
type Item = (&'a K, &'a mut V);
fn next(&mut self) -> Option<(&'a K, &'a mut V)> {
let (k, v) = self.inner.next()?;
let v = v.first_mut()?;
Some((k, v))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {
fn len(&self) -> usize {
self.inner.len()
}
}
#[macro_export]
macro_rules! multimap{
(@replace_with_unit $_t:tt) => { () };
(@count $($key:expr),*) => { <[()]>::len(&[$($crate::multimap! { @replace_with_unit $key }),*]) };
($($key:expr => $value:expr),* $(,)?)=>{
{
let mut map = $crate::MultiMap::with_capacity($crate::multimap! { @count $($key),* });
$(
map.insert($key,$value);
)*
map
}
}
}
#[cfg(test)]
mod tests {
use std::collections::HashMap;
use std::iter::FromIterator;
use super::*;
#[test]
fn create() {
let _: MultiMap<usize, usize> = MultiMap {
inner: HashMap::new(),
};
}
#[test]
fn new() {
let _: MultiMap<usize, usize> = MultiMap::new();
}
#[test]
fn with_capacity() {
let _: MultiMap<usize, usize> = MultiMap::with_capacity(20);
}
#[test]
fn insert() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 3);
}
#[test]
fn insert_identical() {
let mut m = MultiMap::new();
m.insert(1, 42);
m.insert(1, 42);
assert_eq!(m.get_vec(&1), Some(&vec![42, 42]));
}
#[test]
fn insert_many() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert_many(1, vec![3, 4]);
assert_eq!(Some(&vec![3, 4]), m.get_vec(&1));
}
#[test]
fn insert_many_again() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 2);
m.insert_many(1, vec![3, 4]);
assert_eq!(Some(&vec![2, 3, 4]), m.get_vec(&1));
}
#[test]
fn insert_many_overlap() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert_many(1, vec![2, 3]);
m.insert_many(1, vec![3, 4]);
assert_eq!(Some(&vec![2, 3, 3, 4]), m.get_vec(&1));
}
#[test]
fn insert_many_from_slice() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert_many_from_slice(1, &[3, 4]);
assert_eq!(Some(&vec![3, 4]), m.get_vec(&1));
}
#[test]
fn insert_many_from_slice_again() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 2);
m.insert_many_from_slice(1, &[3, 4]);
assert_eq!(Some(&vec![2, 3, 4]), m.get_vec(&1));
}
#[test]
fn insert_existing() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 3);
m.insert(1, 4);
assert_eq!(Some(&vec![3, 4]), m.get_vec(&1));
}
#[test]
#[should_panic(expected = "no entry found for key")]
fn index_no_entry() {
let m: MultiMap<usize, usize> = MultiMap::new();
let _ = &m[&1];
}
#[test]
fn index() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 41);
m.insert(2, 42);
m.insert(3, 43);
let values = m[&2];
assert_eq!(values, 42);
}
#[test]
#[should_panic(expected = "no value found for key")]
fn index_empty_vec() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.get_vec_mut(&1).unwrap().clear();
let values = m[&1];
assert_eq!(values, 42);
}
#[test]
fn contains_key_true() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
assert!(m.contains_key(&1));
}
#[test]
fn contains_key_false() {
let m: MultiMap<usize, usize> = MultiMap::new();
assert!(!m.contains_key(&1));
}
#[test]
fn len() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.insert(2, 1337);
m.insert(3, 99);
assert_eq!(m.len(), 3);
}
#[test]
fn remove_not_present() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
let v = m.remove(&1);
assert_eq!(v, None);
}
#[test]
fn remove_present() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
let v = m.remove(&1);
assert_eq!(v, Some(vec![42]));
}
#[test]
fn get_not_present() {
let m: MultiMap<usize, usize> = MultiMap::new();
assert_eq!(m.get(&1), None);
}
#[test]
fn get_present() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
assert_eq!(m.get(&1), Some(&42));
}
#[test]
fn get_empty() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.get_vec_mut(&1).and_then(Vec::pop);
assert_eq!(m.get(&1), None);
}
#[test]
fn get_vec_not_present() {
let m: MultiMap<usize, usize> = MultiMap::new();
assert_eq!(m.get_vec(&1), None);
}
#[test]
fn get_vec_present() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.insert(1, 1337);
assert_eq!(m.get_vec(&1), Some(&vec![42, 1337]));
}
#[test]
fn capacity() {
let m: MultiMap<usize, usize> = MultiMap::with_capacity(20);
assert!(m.capacity() >= 20);
}
#[test]
fn is_empty_true() {
let m: MultiMap<usize, usize> = MultiMap::new();
assert!(m.is_empty());
}
#[test]
fn is_empty_false() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
assert!(!m.is_empty());
}
#[test]
fn clear() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.clear();
assert!(m.is_empty());
}
#[test]
fn get_mut() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
if let Some(v) = m.get_mut(&1) {
*v = 1337;
}
assert_eq!(m[&1], 1337)
}
#[test]
fn get_vec_mut() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.insert(1, 1337);
if let Some(v) = m.get_vec_mut(&1) {
(*v)[0] = 5;
(*v)[1] = 10;
}
assert_eq!(m.get_vec(&1), Some(&vec![5, 10]))
}
#[test]
fn get_mut_empty() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.get_vec_mut(&1).and_then(Vec::pop);
assert_eq!(m.get_mut(&1), None);
}
#[test]
fn keys() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.insert(2, 42);
m.insert(4, 42);
m.insert(8, 42);
let keys: Vec<_> = m.keys().cloned().collect();
assert_eq!(keys.len(), 4);
assert!(keys.contains(&1));
assert!(keys.contains(&2));
assert!(keys.contains(&4));
assert!(keys.contains(&8));
}
#[test]
fn iter() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.insert(1, 42);
m.insert(4, 42);
m.insert(8, 42);
assert!(m.iter().all(|(_, &v)| v == 42));
let mut iter = m.iter();
for _ in iter.by_ref().take(2) {}
assert_eq!(iter.len(), 1);
}
#[test]
fn iter_empty_vec() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(42, 42);
m.get_vec_mut(&42).unwrap().clear();
assert!(m.iter().next().is_none());
}
#[test]
fn flat_iter() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.insert(1, 43);
m.insert(4, 42);
m.insert(8, 42);
let keys = [1, 4, 8];
for (key, value) in m.flat_iter() {
assert!(keys.contains(key));
if key == &1 {
assert!(value == &42 || value == &43);
} else {
assert_eq!(value, &42);
}
}
}
#[test]
fn flat_iter_mut() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.insert(1, 43);
m.insert(4, 42);
m.insert(8, 42);
let keys = [1, 4, 8];
for (key, value) in m.flat_iter_mut() {
assert!(keys.contains(key));
if key == &1 {
assert!(value == &42 || value == &43);
*value = 55;
assert_eq!(value, &55);
} else {
assert_eq!(value, &42);
*value = 76;
assert_eq!(value, &76);
}
}
}
#[test]
fn intoiterator_for_reference_type() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.insert(1, 43);
m.insert(4, 42);
m.insert(8, 42);
let keys = [1, 4, 8];
for (key, value) in &m {
assert!(keys.contains(key));
if key == &1 {
assert_eq!(value, &vec![42, 43]);
} else {
assert_eq!(value, &vec![42]);
}
}
}
#[test]
fn intoiterator_for_mutable_reference_type() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.insert(1, 43);
m.insert(4, 42);
m.insert(8, 42);
let keys = [1, 4, 8];
for (key, value) in &mut m {
assert!(keys.contains(key));
if key == &1 {
assert_eq!(value, &vec![42, 43]);
value.push(666);
} else {
assert_eq!(value, &vec![42]);
}
}
assert_eq!(m.get_vec(&1), Some(&vec![42, 43, 666]));
}
#[test]
fn intoiterator_consuming() {
let mut m: MultiMap<usize, usize> = MultiMap::new();
m.insert(1, 42);
m.insert(1, 43);
m.insert(4, 42);
m.insert(8, 42);
let keys = [1, 4, 8];
for (key, value) in m {
assert!(keys.contains(&key));
if key == 1 {
assert_eq!(value, vec![42, 43]);
} else {
assert_eq!(value, vec![42]);
}
}
}
#[test]
fn test_fmt_debug() {
let mut map = MultiMap::new();
let empty: MultiMap<i32, i32> = MultiMap::new();
map.insert(1, 2);
map.insert(1, 5);
map.insert(1, -1);
map.insert(3, 4);
let map_str = format!("{:?}", map);
assert!(map_str == "{1: [2, 5, -1], 3: [4]}" || map_str == "{3: [4], 1: [2, 5, -1]}");
assert_eq!(format!("{:?}", empty), "{}");
}
#[test]
fn test_eq() {
let mut m1 = MultiMap::new();
m1.insert(1, 2);
m1.insert(2, 3);
m1.insert(3, 4);
let mut m2 = MultiMap::new();
m2.insert(1, 2);
m2.insert(2, 3);
assert_ne!(m1, m2);
m2.insert(3, 4);
assert_eq!(m1, m2);
m2.insert(3, 4);
assert_ne!(m1, m2);
m1.insert(3, 4);
assert_eq!(m1, m2);
}
#[test]
fn test_eq_empty_key() {
let mut m1 = MultiMap::new();
m1.insert(1, 2);
m1.insert(2, 3);
let mut m2 = MultiMap::new();
m2.insert(1, 2);
m2.insert_many(2, []);
assert_ne!(m1, m2);
m2.insert_many(2, [3]);
assert_eq!(m1, m2);
}
#[test]
fn test_default() {
let _: MultiMap<u8, u8> = Default::default();
}
#[test]
fn test_from_iterator() {
let vals: Vec<(&str, i64)> = vec![("foo", 123), ("bar", 456), ("foo", 789)];
let multimap: MultiMap<&str, i64> = MultiMap::from_iter(vals);
let foo_vals: &Vec<i64> = multimap.get_vec("foo").unwrap();
assert!(foo_vals.contains(&123));
assert!(foo_vals.contains(&789));
let bar_vals: &Vec<i64> = multimap.get_vec("bar").unwrap();
assert!(bar_vals.contains(&456));
}
#[test]
fn test_from_vec_iterator() {
let vals: Vec<(&str, Vec<i64>)> = vec![
("foo", vec![123, 456]),
("bar", vec![234]),
("foobar", vec![567, 678, 789]),
("bar", vec![12, 23, 34]),
];
let multimap: MultiMap<&str, i64> = MultiMap::from_iter(vals);
let foo_vals: &Vec<i64> = multimap.get_vec("foo").unwrap();
assert!(foo_vals.contains(&123));
assert!(foo_vals.contains(&456));
let bar_vals: &Vec<i64> = multimap.get_vec("bar").unwrap();
assert!(bar_vals.contains(&234));
assert!(bar_vals.contains(&12));
assert!(bar_vals.contains(&23));
assert!(bar_vals.contains(&34));
let foobar_vals: &Vec<i64> = multimap.get_vec("foobar").unwrap();
assert!(foobar_vals.contains(&567));
assert!(foobar_vals.contains(&678));
assert!(foobar_vals.contains(&789));
}
#[test]
fn test_extend_consuming_hashmap() {
let mut a = MultiMap::new();
a.insert(1, 42);
let mut b = HashMap::new();
b.insert(1, 43);
b.insert(2, 666);
a.extend(b);
assert_eq!(a.len(), 2);
assert_eq!(a.get_vec(&1), Some(&vec![42, 43]));
}
#[test]
fn test_extend_ref_hashmap() {
let mut a = MultiMap::new();
a.insert(1, 42);
let mut b = HashMap::new();
b.insert(1, 43);
b.insert(2, 666);
a.extend(&b);
assert_eq!(a.len(), 2);
assert_eq!(a.get_vec(&1), Some(&vec![42, 43]));
assert_eq!(b.len(), 2);
assert_eq!(b[&1], 43);
}
#[test]
fn test_extend_consuming_multimap() {
let mut a = MultiMap::new();
a.insert(1, 42);
let mut b = MultiMap::new();
b.insert(1, 43);
b.insert(1, 44);
b.insert(2, 666);
a.extend(b);
assert_eq!(a.len(), 2);
assert_eq!(a.get_vec(&1), Some(&vec![42, 43, 44]));
}
#[test]
fn test_extend_ref_multimap() {
let mut a = MultiMap::new();
a.insert(1, 42);
let mut b = MultiMap::new();
b.insert(1, 43);
b.insert(1, 44);
b.insert(2, 666);
a.extend(&b);
assert_eq!(a.len(), 2);
assert_eq!(a.get_vec(&1), Some(&vec![42, 43, 44]));
assert_eq!(b.len(), 2);
assert_eq!(b.get_vec(&1), Some(&vec![43, 44]));
}
#[test]
fn test_entry() {
let mut m = MultiMap::new();
m.insert(1, 42);
{
let v = m.entry(1).or_insert(43);
assert_eq!(v, &42);
*v = 44;
}
assert_eq!(m.entry(2).or_insert(666), &666);
assert_eq!(m[&1], 44);
assert_eq!(m[&2], 666);
}
#[test]
fn test_entry_vec() {
let mut m = MultiMap::new();
m.insert(1, 42);
{
let v = m.entry(1).or_insert_vec(vec![43]);
assert_eq!(v, &vec![42]);
*v.first_mut().unwrap() = 44;
}
assert_eq!(m.entry(2).or_insert_vec(vec![666]), &vec![666]);
assert_eq!(m[&1], 44);
assert_eq!(m[&2], 666);
}
#[test]
fn test_is_vec() {
let mut m = MultiMap::new();
m.insert(1, 42);
m.insert(1, 1337);
m.insert(2, 2332);
assert!(m.is_vec(&1));
assert!(!m.is_vec(&2));
assert!(!m.is_vec(&3));
}
#[test]
fn test_macro() {
let mut manual_map = MultiMap::new();
manual_map.insert("key1", 42);
assert_eq!(manual_map, multimap!("key1" => 42));
manual_map.insert("key1", 1337);
manual_map.insert("key2", 2332);
let macro_map = multimap! {
"key1" => 42,
"key1" => 1337,
"key2" => 2332
};
assert_eq!(manual_map, macro_map);
}
#[test]
fn retain_removes_element() {
let mut m = MultiMap::new();
m.insert(1, 42);
m.insert(1, 99);
m.retain(|&k, &v| k == 1 && v == 42);
assert_eq!(1, m.len());
assert_eq!(Some(&42), m.get(&1));
}
#[test]
fn retain_also_removes_empty_vector() {
let mut m = MultiMap::new();
m.insert(1, 42);
m.insert(1, 99);
m.insert(2, 42);
m.retain(|&k, &v| k == 1 && v == 42);
assert_eq!(1, m.len());
assert_eq!(Some(&42), m.get(&1));
}
}