1use std::borrow::Borrow;
2use std::clone::Clone;
3use std::fmt;
4use std::fmt::Write;
5use std::hash::Hash;
6
7use indexmap::IndexMap;
8
9#[derive(PartialEq)]
10pub struct Dictionary<K, V>
11where
12 K: Hash + Eq,
13{
14 table: IndexMap<K, V>,
15}
16
17#[allow(dead_code)]
18impl<K, V> Dictionary<K, V>
19where
20 K: Clone + Hash + PartialEq + Copy + Eq,
21 V: Clone + Copy,
22{
23 pub fn new() -> Dictionary<K, V> {
24 Dictionary {
25 table: IndexMap::new(),
26 }
27 }
28
29 pub fn with_capacity(size: usize) -> Dictionary<K, V> {
30 if size == 0 {
31 panic!("Cannot create a zero-sized dict");
32 }
33
34 Dictionary {
35 table: IndexMap::with_capacity(size),
36 }
37 }
38
39 pub fn clear(&mut self) {
41 self.table.clear()
42 }
43
44 pub fn contains_key(&self, key: &K) -> bool {
45 self.table.contains_key(key)
46 }
47
48 pub fn from_vecs(mut key_vec: Vec<K>, mut value_vec: Vec<V>) -> Dictionary<K, V> {
50 if key_vec.len() != value_vec.len() {
51 panic!("Differently sized vecs");
52 } else if key_vec.is_empty() {
53 panic!("Cannot create a zero-sized dict");
54 } else {
55 let mut dict: Dictionary<K, V> = Dictionary::with_capacity(key_vec.len());
56 for _ in 0..key_vec.len() {
57 let key = key_vec.pop().unwrap();
58 let value = value_vec.pop().unwrap();
59 dict.insert(key, value);
60 }
61
62 dict
63 }
64 }
65
66 pub fn from_tuples(tuples: Vec<(K, V)>) -> Dictionary<K, V> {
67 if tuples.is_empty() {
68 panic!("Cannot create a zero-sized vec");
69 }
70 let mut dict: Dictionary<K, V> = Dictionary::with_capacity(tuples.len());
71
72 for (key, value) in tuples {
73 dict.insert(key, value);
74 }
75
76 dict
77 }
78
79 pub fn get<Q>(&self, key: &Q) -> Option<&V>
80 where
81 K: Borrow<Q>,
82 Q: Hash + Eq + ?Sized,
83 {
84 let val = self.table.get(key);
85 return val;
86 }
87
88 pub fn get_full<Q>(&self, key: &Q) -> Option<(usize, &K, &V)>
89 where
90 K: Borrow<Q>,
91 Q: Hash + Eq + ?Sized,
92 {
93 let val = self.table.get_full(key);
94 return val;
95 }
96
97 pub fn get_index_of<Q>(&self, key: &Q) -> Option<usize>
98 where
99 K: Borrow<Q>,
100 Q: Hash + Eq + ?Sized,
101 {
102 let val = self.table.get_index_of(key);
103 return val;
104 }
105
106 pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
107 where
108 K: Borrow<Q>,
109 Q: Hash + Eq + ?Sized,
110 {
111 let val = self.table.get_key_value(key);
112 return val;
113 }
114
115 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
116 self.table.insert(key, value)
117 }
118
119 pub fn iter(&self) -> indexmap::map::Iter<K, V> {
120 self.table.iter()
121 }
122
123 pub fn is_empty(&self) -> bool {
124 self.table.is_empty()
125 }
126
127 pub fn len(&self) -> usize {
128 self.table.len()
129 }
130
131 pub fn remove(&mut self, key: &K) -> Option<V> {
132 let val = self.table.remove(key);
133 return val;
134 }
135
136 pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(K, V)>
137 where
138 K: Borrow<Q>,
139 Q: Hash + Eq + ?Sized,
140 {
141 self.table.remove_entry(key)
142 }
143}
144
145impl<K, V> fmt::Display for Dictionary<K, V>
146where
147 K: fmt::Display + Clone + Copy + Hash + Eq,
148 V: fmt::Display + Clone + Copy,
149{
150 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
151 let mut output_str = String::new();
152 output_str.push_str("{");
153
154 for k in self.table.iter()
155 {
157 write!(output_str, "{}: {}, ", k.0, k.1)?;
158 }
159
160 let len = output_str.len();
161 if len > 1 {
162 output_str = String::from(&output_str[..len - 2]);
163 }
164 output_str.push_str("}");
165
166 write!(f, "{}", output_str)
167 }
168}
169
170impl<K, V> fmt::Debug for Dictionary<K, V>
171where
172 K: fmt::Display + Clone + Copy + Hash + fmt::Debug + Eq,
173 V: fmt::Display + Clone + Copy + fmt::Debug,
174{
175 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 let mut output_str = String::new();
177 output_str.push_str("{");
178
179 for k in self.table.iter()
180 {
182 write!(output_str, "{}: {}, ", k.0, k.1)?;
183 }
184
185 let len = output_str.len();
186 if len > 1 {
187 output_str = String::from(&output_str[..len - 2]);
188 }
189 output_str.push_str("}");
190
191 write!(f, "{}", output_str)
192 }
193}
194
195impl<'a, K, V> FromIterator<&'a (K, V)> for Dictionary<K, V>
196where
197 K: Clone + Copy + Hash + std::cmp::PartialEq + Eq + 'a,
198 V: Clone + Copy + std::cmp::PartialEq + 'a,
199{
200 fn from_iter<T: IntoIterator<Item = &'a (K, V)>>(iter: T) -> Self {
201 let mut dict: Dictionary<K, V> = Dictionary::new();
202 for (k, v) in iter {
203 let _ = dict.insert(*k, *v);
204 }
205 dict
206 }
207}
208
209impl<K, V> FromIterator<(K, V)> for Dictionary<K, V>
210where
211 K: Hash + Eq + Copy,
212 V: Copy,
213{
214 fn from_iter<T: IntoIterator<Item = (K, V)>>(iter: T) -> Self {
215 let mut dict: Dictionary<K, V> = Dictionary::new();
216 for (k, v) in iter {
217 let _ = dict.insert(k, v);
218 }
219 dict
220 }
221}
222
223impl<K, V, X> indexmap::Equivalent<X> for Dictionary<K, V>
224where
225 Dictionary<K, V>: PartialEq<X>,
226 K: Eq + Hash,
227{
228 fn equivalent(&self, other: &X) -> bool {
229 *self == *other
230 }
231}