1#![crate_name = "indexedlinkedhashmap"]
2
3use std::collections::HashMap;
6use std::fmt::{Debug, Formatter, Result};
7use std::hash::Hash;
8use traits::Ordered;
9
10#[derive(PartialEq, Clone, Copy)]
12pub struct IndexedLinkedHashMapValue<V> {
13 pub index: Option<usize>,
14 pub value: V,
15}
16
17pub struct IndexedLinkedHashMap<I, K, V> {
19 _keys: I,
20 _values: HashMap<K, IndexedLinkedHashMapValue<V>>,
21}
22
23impl<I, K, V> IndexedLinkedHashMap<I, K, V>
24where
25 I: Ordered<K> + Default,
26 K: Eq + Hash + Clone,
27 V: Clone,
28{
29 pub fn new() -> Self {
31 return IndexedLinkedHashMap {
32 _keys: I::default(),
33 _values: HashMap::new(),
34 };
35 }
36
37 pub fn get(&self, k: K) -> Option<&V> {
39 return match self._values.get(&k) {
40 Some(v) => Some(&v.value),
41 None => None,
42 };
43 }
44
45 pub fn set(&mut self, k: K, v: V) {
47 if self._values.contains_key(&k) {
48 let value: &IndexedLinkedHashMapValue<V> = self._values.get(&k).unwrap();
49 self._values.insert(
50 k,
51 IndexedLinkedHashMapValue {
52 index: value.index,
53 value: v,
54 },
55 );
56 } else {
57 self._keys.push(k.to_owned());
58 self._values.insert(
59 k,
60 IndexedLinkedHashMapValue {
61 index: Some(self._keys.len() - 1),
62 value: v,
63 },
64 );
65 }
66 }
67
68 pub fn at(&self, i: Option<usize>) -> Option<&V> {
70 return match i {
71 Some(i) => match i >= self._keys.len() {
72 true => None,
73 false => match self._keys.get(Some(i)) {
74 Some(k) => match self._values.get(k) {
75 Some(v) => Some(&v.value),
76 None => None,
77 },
78 None => None,
79 },
80 },
81 None => match self._keys.get(i) {
82 Some(k) => match self._values.get(k) {
83 Some(v) => Some(&v.value),
84 None => None,
85 },
86 None => None,
87 },
88 };
89 }
90
91 pub fn key_at(&self, i: Option<usize>) -> Option<&K> {
93 return match i {
94 Some(i) => match i >= self._keys.len() {
95 true => None,
96 false => self._keys.get(Some(i)),
97 },
98 None => self._keys.get(i),
99 };
100 }
101
102 pub fn set_at(&mut self, i: Option<usize>, k: K, v: V) {
104 return match i {
105 Some(i) => match i >= self._keys.len() {
106 true => (),
107 false => {
108 self._keys.set(Some(i), k.to_owned());
109 self._values.insert(
110 k,
111 IndexedLinkedHashMapValue {
112 index: Some(i),
113 value: v,
114 },
115 );
116 }
117 },
118 None => {
119 self._keys.set(i, k.to_owned());
120 self._values
121 .insert(k, IndexedLinkedHashMapValue { index: i, value: v });
122 }
123 };
124 }
125
126 pub fn remove(&mut self, k: K) -> Option<IndexedLinkedHashMapValue<V>> {
128 if self._values.contains_key(&k) {
129 let removed = self._values.remove(&k).unwrap();
130 self._keys.remove(removed.index);
131
132 return Some(removed);
133 }
134
135 return None;
136 }
137
138 pub fn clear(&mut self) {
140 self._keys.clear();
141 self._values.clear();
142 }
143
144 pub fn len(&self) -> usize {
146 return self._keys.len();
147 }
148
149 pub fn contains_key(&self, k: K) -> bool {
151 return self._values.contains_key(&k);
152 }
153
154 pub fn keys(&self) -> &I {
156 return &self._keys;
157 }
158
159 pub fn values(&self) -> Vec<&IndexedLinkedHashMapValue<V>> {
161 return self
162 ._values
163 .values()
164 .collect::<Vec<&IndexedLinkedHashMapValue<V>>>();
165 }
166}
167
168impl<I, K, V> Debug for IndexedLinkedHashMap<I, K, V>
169where
170 I: Ordered<K> + Default,
171 K: Eq + Hash + Clone + Debug,
172 V: Clone + Debug,
173{
174 fn fmt(&self, f: &mut Formatter) -> Result {
175 let mut out: String = String::new();
176 for i in 0..self._keys.len() {
177 match self._keys.get(Some(i)) {
178 Some(k) => match self._values.get(k) {
179 Some(v) => out += format!("{:?}: {:?}", k, v.value).as_str(),
180 None => (),
181 },
182 None => (),
183 };
184 }
185
186 return write!(f, "{}", out);
187 }
188}
189
190pub mod traits {
191 pub trait Ordered<K> {
192 fn get(&self, i: Option<usize>) -> Option<&K>;
193 fn set(&mut self, i: Option<usize>, k: K);
194 fn push(&mut self, k: K);
195 fn remove(&mut self, i: Option<usize>);
196 fn clear(&mut self);
197 fn len(&self) -> usize;
198 }
199}
200
201#[cfg(any(
202 feature = "collections_ordering_vec",
203 feature = "collections_ordering_binary_heap"
204))]
205pub mod collections {
206 pub mod ordering {
207 use super::super::traits::Ordered;
208 use std::collections::BinaryHeap;
209
210 #[cfg(feature = "collections_ordering_vec")]
211 impl<K> Ordered<K> for Vec<K> {
212 fn get(&self, i: Option<usize>) -> Option<&K> {
213 return match i {
214 Some(i) => match i >= self.len() {
215 true => None,
216 false => Some(&self[i]),
217 },
218 None => None,
219 };
220 }
221
222 fn set(&mut self, i: Option<usize>, k: K) {
223 match i {
224 Some(i) => match i >= self.len() {
225 true => (),
226 false => {
227 self[i] = k;
228 }
229 },
230 None => (),
231 };
232 }
233
234 fn push(&mut self, k: K) {
235 self.push(k);
236 }
237
238 fn remove(&mut self, i: Option<usize>) {
239 match i {
240 Some(i) => match i >= self.len() {
241 true => (),
242 false => {
243 self.remove(i);
244 }
245 },
246 None => (),
247 };
248 }
249
250 fn clear(&mut self) {
251 self.clear();
252 }
253
254 fn len(&self) -> usize {
255 return self.len();
256 }
257 }
258
259 #[cfg(feature = "collections_ordering_binary_heap")]
260 impl<K> Ordered<K> for BinaryHeap<K>
261 where
262 K: Ord + Eq,
263 BinaryHeap<K>: From<Vec<K>> + Clone,
264 {
265 fn get(&self, i: Option<usize>) -> Option<&K> {
266 return match i {
267 Some(i) => match i >= self.len() {
268 true => None,
269 false => {
270 for (idx, k) in self.iter().enumerate() {
271 if i == idx {
272 return Some(k);
273 }
274 }
275
276 return None;
277 }
278 },
279 None => None,
280 };
281 }
282
283 fn set(&mut self, _i: Option<usize>, k: K) {
284 let mut p = Vec::from(self.clone());
285 p.push(k);
286
287 self.append(&mut BinaryHeap::<K>::from(p));
288 }
289
290 fn push(&mut self, k: K) {
291 self.push(k);
292 }
293
294 fn remove(&mut self, i: Option<usize>) {
295 return match i {
296 Some(i) => match i >= self.len() {
297 true => (),
298 false => {
299 let p: Vec<K> = Vec::from(self.clone());
300 let mut n: Vec<&K> = Vec::new();
301 for (idx, k) in p.iter().enumerate() {
302 if idx != i {
303 n.push(k);
304 }
305 }
306
307 self.append(&mut BinaryHeap::<K>::from(p));
308 }
309 },
310 None => (),
311 };
312 }
313
314 fn clear(&mut self) {
315 self.clear();
316 }
317
318 fn len(&self) -> usize {
319 return self.len();
320 }
321 }
322 }
323}
324
325#[cfg(test)]
326mod tests {
327 mod indexedlinkedhashmap {
328 use crate::*;
329
330 #[test]
331 fn new() {
332 let ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
333 assert!(ins.len() == 0);
334 assert!(ins.keys().len() == 0);
335 assert!(ins.values().len() == 0);
336 }
337
338 #[test]
339 fn get() {
340 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
341 assert!(ins.get(&"k") == None);
342 ins.set("k", 1);
343 assert!(ins.get(&"k") == Some(&1));
344 }
345
346 #[test]
347 fn set() {
348 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
349 ins.set("k", 1);
350 assert!(ins.len() == 1);
351 assert!(ins.keys().len() == 1);
352 assert!(ins.values().len() == 1);
353 assert!(ins.get("k") == Some(&1));
354 }
355
356 #[test]
357 fn at() {
358 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
359 assert!(ins.at(Some(0)) == None);
360 ins.set("k", 1);
361 assert!(ins.at(Some(0)) == Some(&1));
362 assert!(ins.at(Some(1)) == None);
363 }
364
365 #[test]
366 fn key_at() {
367 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
368 assert!(ins.at(Some(0)) == None);
369 ins.set("k", 1);
370 assert!(ins.key_at(Some(0)) == Some(&"k"));
371 assert!(ins.key_at(Some(1)) == None);
372 }
373
374 #[test]
375 fn set_at() {
376 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
377 ins.set_at(Some(1), "a", 2);
378 assert!(ins.get(&"a") == None);
379 ins.set("k", 1);
380 ins.set_at(Some(0), "b", 3);
381 assert!(ins.at(Some(0)) == Some(&3));
382 assert!(ins.get(&"b") == Some(&3));
383 }
384
385 #[test]
386 fn remove() {
387 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
388 assert!(ins.remove("k") == None);
389 assert!(ins.len() == 0);
390 assert!(ins.keys().len() == 0);
391 assert!(ins.values().len() == 0);
392 ins.set("k", 1);
393 assert!(
394 ins.remove("k")
395 == Some(IndexedLinkedHashMapValue {
396 index: Some(0),
397 value: 1
398 })
399 );
400 assert!(ins.len() == 0);
401 assert!(ins.keys().len() == 0);
402 assert!(ins.values().len() == 0);
403 }
404
405 #[test]
406 fn clear() {
407 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
408 ins.clear();
409 assert!(ins.len() == 0);
410 assert!(ins.keys().len() == 0);
411 assert!(ins.values().len() == 0);
412 ins.set("k", 1);
413 ins.clear();
414 assert!(ins.len() == 0);
415 assert!(ins.keys().len() == 0);
416 assert!(ins.values().len() == 0);
417 }
418
419 #[test]
420 fn len() {
421 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
422 assert!(ins.len() == 0);
423 ins.clear();
424 assert!(ins.len() == 0);
425 ins.set("k", 1);
426 assert!(ins.len() == 1);
427 ins.clear();
428 assert!(ins.len() == 0);
429 }
430
431 #[test]
432 fn contains_key() {
433 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
434 assert!(ins.contains_key(&"k") == false);
435 ins.set("k", 1);
436 assert!(ins.contains_key(&"k") == true);
437 }
438
439 #[test]
440 fn keys() {
441 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
442 let mut keys: Vec<&str> = Vec::new();
443 assert!(ins.keys().eq(&keys));
444 ins.set("k", 1);
445 keys.push("k");
446 assert!(ins.keys().eq(&keys));
447 }
448
449 #[test]
450 fn values() {
451 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
452 let mut values: Vec<&IndexedLinkedHashMapValue<usize>> = Vec::new();
453 assert!(ins.values().eq(&values));
454 ins.set("k", 1);
455 values.push(&IndexedLinkedHashMapValue {
456 index: Some(0),
457 value: 1,
458 });
459 assert!(ins.values().eq(&values));
460 }
461
462 mod debug {
463 use crate::*;
464
465 #[test]
466 fn fmt() {
467 let mut ins = IndexedLinkedHashMap::<Vec<&str>, &str, usize>::new();
468 assert!("" == format!("{:?}", ins));
469 ins.set("k", 1);
470 println!("{:?}", ins);
471 assert!("\"k\": 1" == format!("{:?}", ins));
472 }
473 }
474 }
475}