use std::borrow::Borrow;
use std::collections::hash_map::*;
use std::default::Default;
use std::hash::{BuildHasher, Hash};
#[derive(Clone)]
pub struct Bimap<K, V, S = RandomState> {
fwd: HashMap<K, V, S>,
rev: HashMap<V, K, S>,
}
impl<K: Eq + Hash + Clone, V: Eq + Hash + Clone> Bimap<K, V, RandomState> {
pub fn new() -> Self {
Self {
fwd: HashMap::new(),
rev: HashMap::new(),
}
}
}
impl<K: Eq + Hash + Clone, V: Eq + Hash + Clone, S: BuildHasher + Clone + Default> Bimap<K, V, S> {
pub fn with_hasher(hash_builder: S) -> Self {
Self {
fwd: HashMap::with_hasher(hash_builder.clone()),
rev: HashMap::with_hasher(hash_builder),
}
}
pub fn from_hash_map(fwd: HashMap<K, V, S>) -> Self {
let rev = fwd.iter().map(|(k, v)| (v.clone(), k.clone())).collect();
Self { fwd, rev }
}
pub fn len(&self) -> usize {
self.fwd.len()
}
pub fn is_empty(&self) -> bool {
self.fwd.is_empty()
}
pub fn clear(&mut self) {
self.fwd.clear();
self.rev.clear();
}
pub fn insert(&mut self, k: K, v: V) {
match self.fwd.entry(k.clone()) {
Entry::Vacant(entry) => {
entry.insert(v.clone());
}
Entry::Occupied(_) => panic!("Element aready in bimap"),
}
match self.rev.entry(v) {
Entry::Vacant(entry) => {
entry.insert(k);
}
Entry::Occupied(_) => panic!("Element aready in bimap"),
}
}
pub fn get_fwd<KeyBorrow: ?Sized>(&self, k: &KeyBorrow) -> Option<&V>
where
K: Borrow<KeyBorrow>,
KeyBorrow: Hash + Eq,
{
self.fwd.get(k)
}
pub fn get_rev<ValBorrow: ?Sized>(&self, v: &ValBorrow) -> Option<&K>
where
V: Borrow<ValBorrow>,
ValBorrow: Hash + Eq,
{
self.rev.get(v)
}
pub fn remove_fwd<KeyBorrow: ?Sized>(&mut self, k: &KeyBorrow) -> V
where
K: Borrow<KeyBorrow>,
KeyBorrow: Hash + Eq,
{
let v = self.fwd.remove(k).unwrap();
self.rev.remove(&v);
v
}
pub fn remove_rev<ValBorrow: ?Sized>(&mut self, v: &ValBorrow) -> K
where
V: Borrow<ValBorrow>,
ValBorrow: Hash + Eq,
{
let k = self.rev.remove(v).unwrap();
self.fwd.remove(&k);
k
}
pub fn contains_fwd<KeyBorrow: ?Sized>(&self, k: &KeyBorrow) -> bool
where
K: Borrow<KeyBorrow>,
KeyBorrow: Hash + Eq,
{
self.fwd.contains_key(k)
}
pub fn contains_rev<ValBorrow: ?Sized>(&self, v: &ValBorrow) -> bool
where
V: Borrow<ValBorrow>,
ValBorrow: Hash + Eq,
{
self.rev.contains_key(v)
}
}
impl<K: Eq + Hash + Clone, V: Eq + Hash + Clone, S: BuildHasher + Clone + Default> Default
for Bimap<K, V, S>
{
fn default() -> Self {
Bimap::with_hasher(Default::default())
}
}