1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
use std::collections::HashMap; use std::collections::hash_map::{Iter, Keys}; use std::fmt::Debug; use std::hash::Hash; use std::iter::{FromIterator, IntoIterator}; use std::mem; #[derive(Clone)] pub struct SynonymMap<K, V> { vals: HashMap<K, V>, syns: HashMap<K, K>, } impl<K: Eq + Hash, V> SynonymMap<K, V> { pub fn new() -> SynonymMap<K, V> { SynonymMap { vals: HashMap::new(), syns: HashMap::new(), } } pub fn insert_synonym(&mut self, from: K, to: K) -> bool { assert!(self.vals.contains_key(&to)); self.syns.insert(from, to).is_none() } pub fn keys(&self) -> Keys<'_, K, V> { self.vals.keys() } pub fn iter(&self) -> Iter<'_, K, V> { self.vals.iter() } pub fn synonyms(&self) -> Iter<'_, K, K> { self.syns.iter() } pub fn find(&self, k: &K) -> Option<&V> { self.with_key(k, |k| self.vals.get(k)) } pub fn contains_key(&self, k: &K) -> bool { self.with_key(k, |k| self.vals.contains_key(k)) } pub fn len(&self) -> usize { self.vals.len() } fn with_key<T, F>(&self, k: &K, with: F) -> T where F: FnOnce(&K) -> T { if self.syns.contains_key(k) { with(&self.syns[k]) } else { with(k) } } } impl<K: Eq + Hash + Clone, V> SynonymMap<K, V> { pub fn resolve(&self, k: &K) -> K { self.with_key(k, |k| k.clone()) } pub fn get<'a>(&'a self, k: &K) -> &'a V { self.find(k).unwrap() } pub fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> { if self.syns.contains_key(k) { self.vals.get_mut(&self.syns[k]) } else { self.vals.get_mut(k) } } pub fn swap(&mut self, k: K, mut new: V) -> Option<V> { if self.syns.contains_key(&k) { let old = self.vals.get_mut(&k).unwrap(); mem::swap(old, &mut new); Some(new) } else { self.vals.insert(k, new) } } pub fn insert(&mut self, k: K, v: V) -> bool { self.swap(k, v).is_none() } } impl<K: Eq + Hash + Clone, V> FromIterator<(K, V)> for SynonymMap<K, V> { fn from_iter<T: IntoIterator<Item=(K, V)>>(iter: T) -> SynonymMap<K, V> { let mut map = SynonymMap::new(); for (k, v) in iter { map.insert(k, v); } map } } impl<K: Eq + Hash + Debug, V: Debug> Debug for SynonymMap<K, V> { fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { self.vals.fmt(f)?; write!(f, " (synomyns: {:?})", self.syns) } }