forked from docopt/docopt.rs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsynonym.rs
107 lines (90 loc) · 2.63 KB
/
synonym.rs
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<'a>(&'a self) -> Keys<'a, K, V> {
self.vals.keys()
}
pub fn iter<'a>(&'a self) -> Iter<'a, K, V> {
self.vals.iter()
}
pub fn synonyms<'a>(&'a self) -> Iter<'a, K, K> {
self.syns.iter()
}
pub fn find<'a>(&'a self, k: &K) -> Option<&'a 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 {
try!(self.vals.fmt(f));
write!(f, " (synomyns: {:?})", self.syns)
}
}