non_empty_collections/index_map/
entry.rs1use super::Index;
2use std::hash::{BuildHasher, Hash};
3use std::mem;
4use std::ops::{Deref, DerefMut};
5use {Error, NonEmptyIndexMap};
6
7pub struct Occupied<'a, K: 'a, V: 'a, S: 'a> {
9 pub(super) key: K,
10 pub(super) index: Index,
11 pub(super) map: &'a mut NonEmptyIndexMap<K, V, S>,
12}
13
14pub struct Vacant<'a, K: 'a, V: 'a, S: 'a> {
16 pub(super) key: K,
17 pub(super) map: &'a mut NonEmptyIndexMap<K, V, S>,
18}
19
20pub enum Entry<'a, K: 'a, V: 'a, S: 'a> {
22 Occupied(Occupied<'a, K, V, S>),
24 Vacant(Vacant<'a, K, V, S>),
26}
27
28impl<'a, K: 'a, V: 'a, S: 'a> Deref for Occupied<'a, K, V, S>
29where
30 K: Eq + Hash,
31 S: BuildHasher,
32{
33 type Target = V;
34
35 fn deref(&self) -> &V {
36 self.map.get_entry(self.index)
37 }
38}
39
40impl<'a, K: 'a, V: 'a, S: 'a> DerefMut for Occupied<'a, K, V, S>
41where
42 K: Eq + Hash,
43 S: BuildHasher,
44{
45 fn deref_mut(&mut self) -> &mut V {
46 self.map.get_entry_mut(self.index)
47 }
48}
49
50impl<'a, K: 'a, V: 'a, S: 'a> Occupied<'a, K, V, S>
51where
52 K: Eq + Hash,
53 S: BuildHasher,
54{
55 pub fn remove_entry(self) -> Result<(K, V), Error> {
59 let key = self.key;
60 let map = self.map;
61 map.remove_entry(&key)
62 .map(|x| x.expect("The entry exists for sure"))
63 }
64
65 pub fn replace(&mut self, new_value: V) -> V {
67 let old = self.map.get_entry_mut(self.index);
68 mem::replace(old, new_value)
69 }
70
71 pub fn into_value(self) -> &'a mut V {
72 let idx = self.index;
73 self.map.get_entry_mut(idx)
74 }
75}
76
77impl<'a, K: 'a, V: 'a, S: 'a> Vacant<'a, K, V, S>
78where
79 K: Eq + Hash,
80 S: BuildHasher,
81{
82 pub fn insert(self, value: V) -> &'a mut V {
83 let map = self.map;
84 let key = self.key;
85 match map.get_rest_mut().entry(key) {
86 ::indexmap::map::Entry::Occupied(_) => panic!("The entry exists for sure"),
87 ::indexmap::map::Entry::Vacant(entry) => entry.insert(value),
88 }
89 }
90}
91
92impl<'a, K: 'a, V: 'a, S: 'a> Entry<'a, K, V, S>
93where
94 K: Eq + Hash,
95 S: BuildHasher,
96{
97 pub fn or_insert(self, value: V) -> &'a mut V {
101 match self {
102 Entry::Occupied(x) => x.into_value(),
103 Entry::Vacant(v) => v.insert(value),
104 }
105 }
106
107 pub fn or_insert_with<F>(self, f: F) -> &'a mut V
111 where
112 F: FnOnce() -> V,
113 {
114 match self {
115 Entry::Occupied(x) => x.into_value(),
116 Entry::Vacant(v) => v.insert(f()),
117 }
118 }
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 #[test]
126 fn test_occupied_one() {
127 let mut map = NonEmptyIndexMap::new(1, 2);
128 let entry = map.entry(1);
129 let occupied = match entry {
130 Entry::Occupied(x) => x,
131 Entry::Vacant(_) => panic!("Expected an occupied entry"),
132 };
133 assert_eq!(Err(Error::EmptyCollection), occupied.remove_entry());
134 }
135
136 #[test]
137 fn test_occupied() {
138 let mut map = NonEmptyIndexMap::from_item_and_iterator(1, 2, vec![(3, 4), (5, 6), (7, 8)]);
139 {
140 let entry = map.entry(1);
141 let occupied = match entry {
142 Entry::Occupied(x) => x,
143 Entry::Vacant(_) => panic!("Expected an occupied entry"),
144 };
145 assert_eq!(Ok((1, 2)), occupied.remove_entry());
146 }
147 assert_eq!(3, map.len());
148 {
149 let entry = map.entry(5);
150 match entry {
151 Entry::Occupied(x) => x,
152 Entry::Vacant(_) => panic!("Expected an occupied entry"),
153 };
154 }
155 assert_eq!(3, map.len());
156 }
157
158 #[test]
159 fn test_vacant() {
160 let mut map = NonEmptyIndexMap::new(1, 2);
161 {
162 let entry = map.entry(2);
163 let vacant = match entry {
164 Entry::Vacant(x) => x,
165 Entry::Occupied(_) => panic!("Expected a vacant entry"),
166 };
167 assert_eq!(&3, vacant.insert(3));
168 }
169 assert_eq!(Some(&3), map.get(&2));
170 }
171
172 #[test]
173 fn test_or_insert() {
174 let mut map = NonEmptyIndexMap::new(1, 2);
175 {
176 let entry = map.entry(1);
177 assert_eq!(&2, entry.or_insert(3));
178 }
179 assert_eq!(Some(&2), map.get(&1));
180 assert_eq!(1, map.len());
181 {
182 let entry = map.entry(2);
183 assert_eq!(&3, entry.or_insert(3));
184 }
185 assert_eq!(Some(&3), map.get(&2));
186 assert_eq!(2, map.len());
187 }
188
189 #[test]
190 fn test_or_insert_with() {
191 let mut map = NonEmptyIndexMap::new(1, 2);
192 {
193 let entry = map.entry(1);
194 assert_eq!(&2, entry.or_insert_with(|| 3));
195 }
196 assert_eq!(Some(&2), map.get(&1));
197 assert_eq!(1, map.len());
198 {
199 let entry = map.entry(2);
200 assert_eq!(&3, entry.or_insert_with(|| 3));
201 }
202 assert_eq!(Some(&3), map.get(&2));
203 assert_eq!(2, map.len());
204 }
205}