syntax_parser_generator/handles/collections/
handled_hash_map.rs1use std::collections::HashMap;
2use std::hash::Hash;
3use std::ops::Index;
4
5use crate::handles::{Handle, Handled};
6
7pub struct HandledHashMap<T>
31where
32 T: Handled + Eq + PartialEq + Hash,
33{
34 contents: HashMap<T, Handle<T>>,
35}
36
37impl<T> HandledHashMap<T>
38where
39 T: Handled + Eq + PartialEq + Hash,
40{
41 pub fn new() -> Self {
43 Self {
44 contents: HashMap::new(),
45 }
46 }
47
48 pub fn contains(&self, item: &T) -> bool {
50 self.contents.contains_key(item)
51 }
52
53 pub fn insert(&mut self, item: T) {
55 if !self.contains(&item) {
56 let new_handle = self.contents.len().into();
57 self.contents.insert(item, new_handle);
58 }
59 }
60
61 pub fn get_handle(&self, item: &T) -> Option<&Handle<T>> {
63 self.contents.get(item)
64 }
65}
66
67impl<T> FromIterator<T> for HandledHashMap<T>
68where
69 T: Handled + Eq + PartialEq + Hash,
70{
71 fn from_iter<U: IntoIterator<Item=T>>(iter: U) -> Self {
72 let mut set = Self::new();
73 for item in iter {
74 set.insert(item);
75 }
76 set
77 }
78}
79
80impl<T> Index<T> for HandledHashMap<T>
81where
82 T: Handled + Eq + PartialEq + Hash,
83{
84 type Output = Handle<T>;
85
86 fn index(&self, index: T) -> &Self::Output {
88 self.get_handle(&index)
89 .expect("No handles is associated with index item")
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 impl Handled for i32 {
98 type HandleCoreType = u8;
99 }
100
101 #[test]
102 fn test() {
103 let mut set = HandledHashMap::from_iter(1..10);
104 assert_eq!(set.contains(&1), true);
105 assert_eq!(set.contains(&0), false);
106 assert_eq!(set.contains(&5), true);
107
108 set.insert(1);
109 assert_eq!(set.contains(&1), true);
110
111 assert_eq!(set.contains(&12), false);
112 set.insert(12);
113 assert_eq!(set.contains(&12), true);
114
115 assert_eq!(set.contains(&15), false);
116 set.insert(15);
117 assert_eq!(set.contains(&15), true);
118
119 assert_ne!(set.get_handle(&12), None);
120 assert_eq!(set.get_handle(&5412), None);
121
122 assert_eq!(set.get_handle(&25), None);
123 set.insert(25);
124 let handle_of_25 = set.get_handle(&25).copied();
125 assert_ne!(set.get_handle(&25), None);
126 set.insert(25);
127 let handle_of_25_again = set.get_handle(&25).copied();
128 assert_eq!(handle_of_25, handle_of_25_again);
129 }
130}