use std::{ borrow::Borrow, collections::HashMap, fmt::{self, Debug}, hash::Hash, }; /// A map whose value contains a set of multiple values. #[derive(Clone)] pub struct MultiMap { inner: HashMap>, } #[allow(dead_code)] // This is a core library-ish struct, unused stuff is ok impl MultiMap { pub fn new() -> Self { MultiMap { inner: HashMap::new(), } } pub fn get(&self, k: &Q) -> &[V] where K: Borrow, Q: Hash + Eq, { self.inner.get(k).map(Vec::as_slice).unwrap_or(&[]) } pub fn insert(&mut self, k: K, v: V) { let bucket = self.inner.entry(k).or_default(); for value in &*bucket { if *value == v { return; } } bucket.push(v); } pub fn remove, U: Borrow>(&mut self, k: Q, v: U) -> Option { let b = v.borrow(); if let Some(bucket) = self.inner.get_mut(k.borrow()) { let mut removed_value = None; if let Some(index) = bucket.iter().position(|value| value == b) { removed_value = Some(bucket.swap_remove(index)); } if bucket.is_empty() { self.inner.remove(k.borrow()); } removed_value } else { None } } } impl Debug for MultiMap { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { self.inner.fmt(formatter) } } impl PartialEq for MultiMap { fn eq(&self, other: &Self) -> bool { self.inner == other.inner } }