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