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