key_node_list/cursor.rs
1use crate::list::KeyNodeList;
2use crate::map::Map;
3use crate::node::Node;
4use crate::{node_next_mut, node_prev_mut};
5use std::fmt;
6use std::hash::Hash;
7
8macro_rules! impl_cursor {
9 ($name:ident<$a:lifetime, $k:ident, $n:ident, $m:ident>($list:ident, $key:ident)) => {
10 impl<$a, $k, $n, $m> $name<$a, $k, $n, $m> {
11 /// Checks if the cursor is currently pointing to the null pair.
12 #[inline]
13 pub fn is_null(&self) -> bool {
14 self.$key.is_none()
15 }
16
17 /// Returns a reference to the key that the cursor is currently pointing to.
18 ///
19 /// Returns `None` if the cursor is currently pointing to the null pair.
20 #[inline]
21 pub fn key(&self) -> Option<&$k> {
22 self.$key.as_ref()
23 }
24
25 /// Provides a reference to the front key of the cursor’s parent list,
26 /// or `None` if the list is empty.
27 #[inline]
28 pub fn front_key(&self) -> Option<&$k> {
29 self.$list.head.as_ref()
30 }
31
32 /// Provides a reference to the back key of the cursor’s parent list,
33 /// or `None` if the list is empty.
34 #[inline]
35 pub fn back_key(&self) -> Option<&$k> {
36 self.$list.tail.as_ref()
37 }
38 }
39
40 impl<$a, $k, $n, $m> $name<$a, $k, $n, $m>
41 where
42 $k: Hash + Eq,
43 $m: Map<K, N>,
44 {
45 /// Returns a reference to the node that the cursor is currently pointing to.
46 ///
47 /// Returns `None` if the cursor is currently pointing to the null pair.
48 #[inline]
49 pub fn node(&self) -> Option<&$n> {
50 self.$key.as_ref().and_then(|k| self.$list.nodes.get(k))
51 }
52
53 /// Provides a reference to the front node of the cursor’s parent list,
54 /// or `None` if the list is empty.
55 #[inline]
56 pub fn front_node(&self) -> Option<&$n> {
57 self.front_key().and_then(|k| self.$list.nodes.get(k))
58 }
59
60 /// Provides a reference to the back node of the cursor’s parent list,
61 /// or `None` if the list is empty.
62 #[inline]
63 pub fn back_node(&self) -> Option<&$n> {
64 self.back_key().and_then(|k| self.$list.nodes.get(k))
65 }
66 }
67
68 impl<$a, $k, $n, $m> $name<$a, $k, $n, $m>
69 where
70 $k: Hash + Eq,
71 $n: Node<Key = $k>,
72 $m: Map<K, N>,
73 {
74 /// Returns a reference to the next key.
75 ///
76 /// If the cursor is pointing to the null pair then this returns the first
77 /// key of the [`KeyNodeList`]. If it is pointing to the last key of the
78 /// [`KeyNodeList`] then this returns `None`.
79 #[inline]
80 pub fn next_key(&self) -> Option<&$k> {
81 self.$key.as_ref().map_or_else(
82 || self.$list.head.as_ref(),
83 |k| self.$list.node(k).and_then(|n| n.next()),
84 )
85 }
86
87 /// Returns a reference to the previous key.
88 ///
89 /// If the cursor is pointing to the null pair then this returns the last
90 /// key of the [`KeyNodeList`]. If it is pointing to the first key of the
91 /// [`KeyNodeList`] then this returns `None`.
92 #[inline]
93 pub fn prev_key(&self) -> Option<&$k> {
94 self.$key.as_ref().map_or_else(
95 || self.$list.tail.as_ref(),
96 |k| self.$list.node(k).and_then(|n| n.prev()),
97 )
98 }
99
100 /// Returns a reference to the next node.
101 ///
102 /// If the cursor is pointing to the null pair then this returns the first
103 /// node of the [`KeyNodeList`]. If it is pointing to the last node of the
104 /// [`KeyNodeList`] then this returns `None`.
105 #[inline]
106 pub fn next_node(&self) -> Option<&$n> {
107 self.next_key().and_then(|k| self.$list.node(k))
108 }
109
110 /// Returns a reference to the previous node.
111 ///
112 /// If the cursor is pointing to the null pair then this returns the last
113 /// node of the [`KeyNodeList`]. If it is pointing to the first node of the
114 /// [`KeyNodeList`] then this returns `None`.
115 #[inline]
116 pub fn prev_node(&self) -> Option<&$n> {
117 self.prev_key().and_then(|k| self.$list.node(k))
118 }
119 }
120
121 impl<$a, $k, $n, $m> $name<$a, $k, $n, $m>
122 where
123 $k: Hash + Eq + Clone,
124 $n: Node<Key = $k>,
125 $m: Map<K, N>,
126 {
127 /// Moves the cursor to the next key-node pair of the [`KeyNodeList`].
128 ///
129 /// If the cursor is pointing to the null pair then this will move it to
130 /// the first key-node pair of the [`KeyNodeList`]. If it is pointing to
131 /// the last key-node pair of the [`KeyNodeList`] then this will move it
132 /// to the null pair.
133 #[inline]
134 pub fn move_next(&mut self) {
135 self.$key = self.$key.as_ref().map_or_else(
136 || self.$list.head.clone(),
137 |k| self.$list.node(k).and_then(|n| n.next().cloned()),
138 );
139 }
140
141 /// Moves the cursor to the previous key-node pair of the [`KeyNodeList`].
142 ///
143 /// If the cursor is pointing to the null pair then this will move it to
144 /// the last key-node pair of the [`KeyNodeList`]. If it is pointing to
145 /// the first key-node pair of the [`KeyNodeList`] then this will move it
146 /// to the null pair.
147 #[inline]
148 pub fn move_prev(&mut self) {
149 self.$key = self.$key.as_ref().map_or_else(
150 || self.$list.tail.clone(),
151 |k| self.$list.node(k).and_then(|n| n.prev().cloned()),
152 );
153 }
154 }
155
156 impl<$a, $k, $n, $m> fmt::Debug for $name<$a, $k, $n, $m>
157 where
158 $k: Hash + Eq + fmt::Debug,
159 $n: Node<Key = $k> + fmt::Debug,
160 $m: Map<K, N>,
161 {
162 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
163 f.debug_tuple(stringify!($name))
164 .field(self.$list)
165 .field(&self.$key)
166 .finish()
167 }
168 }
169 };
170}
171
172/// A cursor over a [`KeyNodeList`].
173#[derive(Clone)]
174pub struct Cursor<'a, K, N, M> {
175 pub(crate) list: &'a KeyNodeList<K, N, M>,
176 pub(crate) key: Option<K>,
177}
178
179impl_cursor!(Cursor<'a, K, N, M>(list, key));
180
181/// A cursor over a [`KeyNodeList`] with editing operations.
182pub struct CursorMut<'a, K, N, M> {
183 pub(crate) list: &'a mut KeyNodeList<K, N, M>,
184 pub(crate) key: Option<K>,
185}
186
187impl_cursor!(CursorMut<'a, K, N, M>(list, key));
188
189impl<'a, K, N, M> CursorMut<'a, K, N, M>
190where
191 K: Clone,
192{
193 /// Returns a read-only cursor pointing to the current pair.
194 ///
195 /// The lifetime of the returned [`Cursor`] is bound to that of the
196 /// [`CursorMut`], which means it cannot outlive the [`CursorMut`] and that
197 /// the [`CursorMut`] is frozen for the lifetime of the [`Cursor`].
198 #[inline]
199 pub fn as_cursor(&self) -> Cursor<'_, K, N, M> {
200 Cursor {
201 list: self.list,
202 key: self.key.clone(),
203 }
204 }
205}
206
207impl<'a, K, N, M> CursorMut<'a, K, N, M>
208where
209 K: Hash + Eq,
210 M: Map<K, N>,
211{
212 /// Returns a mutable reference to the node that the cursor is currently
213 /// pointing to.
214 ///
215 /// Returns `None` if the cursor is currently pointing to the null pair.
216 #[inline]
217 pub fn node_mut(&mut self) -> Option<&mut N> {
218 self.key.as_ref().and_then(|k| self.list.nodes.get_mut(k))
219 }
220
221 /// Provides a mutable reference to the front node of the cursor’s parent
222 /// list, or `None` if the list is empty.
223 #[inline]
224 pub fn front_node_mut(&mut self) -> Option<&mut N> {
225 self
226 .list
227 .head
228 .as_ref()
229 .and_then(|k| self.list.nodes.get_mut(k))
230 }
231
232 /// Provides a mutable reference to the back node of the cursor’s parent
233 /// list, or `None` if the list is empty.
234 #[inline]
235 pub fn back_node_mut(&mut self) -> Option<&mut N> {
236 self
237 .list
238 .tail
239 .as_ref()
240 .and_then(|k| self.list.nodes.get_mut(k))
241 }
242}
243
244impl<'a, K, N, M> CursorMut<'a, K, N, M>
245where
246 K: Hash + Eq + Clone,
247 N: Node<Key = K>,
248 M: Map<K, N>,
249{
250 /// Inserts a new key-node pair into the [`KeyNodeList`] after the current one.
251 ///
252 /// If the cursor is pointing at the null pair then the new pair is inserted
253 /// at the front of the [`KeyNodeList`].
254 ///
255 /// If `key` already exists, returns an error containing `key` and `node`.
256 pub fn insert_after<T: Into<N>>(&mut self, key: K, node: T) -> Result<(), (K, T)> {
257 self.list.nodes.insert(key.clone(), node).map(|_| {
258 // get the `next` pointer of the node pointed by the cursor
259 let next = match &self.key {
260 // cursor points to the key `k`
261 // update the `next` pointer of the `k` node
262 Some(k) => node_next_mut!(self.list, k).replace(key.clone()),
263 // cursor points to the null pair
264 // insert at front of the list, update the head pointer
265 None => self.list.head.replace(key.clone()),
266 };
267 // update the next node at the insertion position
268 match &next {
269 // next node has key `k`, update its `prev` pointer
270 Some(k) => *node_prev_mut!(self.list, k) = Some(key.clone()),
271 // next node is the null pair, update the tail pointer
272 None => self.list.tail = Some(key.clone()),
273 }
274 // update node's previous pointer and next pointer
275 let node = self.list.node_mut(&key).unwrap();
276 *node_prev_mut!(node) = self.key.clone();
277 *node_next_mut!(node) = next;
278 })
279 }
280
281 /// Inserts a new key-node pair into the [`KeyNodeList`] before the current one.
282 ///
283 /// If the cursor is pointing at the null pair then the new pair is inserted
284 /// at the end of the [`KeyNodeList`].
285 ///
286 /// If `key` already exists, returns an error containing `key` and `node`.
287 pub fn insert_before<T: Into<N>>(&mut self, key: K, node: T) -> Result<(), (K, T)> {
288 self.list.nodes.insert(key.clone(), node).map(|_| {
289 // get the `prev` pointer of the node pointed by the cursor
290 let prev = match &self.key {
291 // cursor points to the key `k`
292 // update the `prev` pointer of the `k` node
293 Some(k) => node_prev_mut!(self.list, k).replace(key.clone()),
294 // cursor points to the null pair
295 // insert at end of the list, update the tail pointer
296 None => self.list.tail.replace(key.clone()),
297 };
298 // update the previous node at the insertion position
299 match &prev {
300 // previous node has key `k`, update its `next` pointer
301 Some(k) => *node_next_mut!(self.list, k) = Some(key.clone()),
302 // previous node is the null pair, update the head pointer
303 None => self.list.head = Some(key.clone()),
304 }
305 // update node's previous pointer and next pointer
306 let node = self.list.node_mut(&key).unwrap();
307 *node_prev_mut!(node) = prev;
308 *node_next_mut!(node) = self.key.clone();
309 })
310 }
311
312 /// Inserts a key into the [`KeyNodeList`] after the current one.
313 ///
314 /// If the cursor is pointing at the null pair then the key is inserted
315 /// at the front of the [`KeyNodeList`].
316 ///
317 /// If `key` already exists, returns an error containing `key`.
318 pub fn insert_key_after(&mut self, key: K) -> Result<(), K>
319 where
320 (): Into<N>,
321 {
322 self.insert_after(key, ()).map_err(|(k, _)| k)
323 }
324
325 /// Inserts a key into the [`KeyNodeList`] before the current one.
326 ///
327 /// If the cursor is pointing at the null pair then the key is inserted
328 /// at the front of the [`KeyNodeList`].
329 ///
330 /// If `key` already exists, returns an error containing `key`.
331 pub fn insert_key_before(&mut self, key: K) -> Result<(), K>
332 where
333 (): Into<N>,
334 {
335 self.insert_before(key, ()).map_err(|(k, _)| k)
336 }
337
338 /// Removes the current pair from the [`KeyNodeList`].
339 ///
340 /// The pair that was removed is returned, and the cursor is moved to point
341 /// to the next pair in the [`KeyNodeList`].
342 ///
343 /// If the cursor is currently pointing to the null pair then no pair is
344 /// removed and `None` is returned.
345 #[inline]
346 pub fn remove_current(&mut self) -> Option<(K, N)> {
347 self.key.take().map(|k| {
348 let pair = self.list.remove(&k).unwrap();
349 self.key = pair.1.next().cloned();
350 pair
351 })
352 }
353
354 /// Appends an pair to the front of the cursor’s parent list. The pair that
355 /// the cursor points to is unchanged, even if it is the null pair.
356 ///
357 /// If `key` already exists, returns an error containing `key` and `node`.
358 ///
359 /// This operation should compute in *O*(1) time on average.
360 #[inline]
361 pub fn push_front<T: Into<N>>(&mut self, key: K, node: T) -> Result<(), (K, T)> {
362 self.list.push_front(key, node)
363 }
364
365 /// Appends an pair to the back of the cursor’s parent list. The pair that
366 /// the cursor points to is unchanged, even if it is the null pair.
367 ///
368 /// If `key` already exists, returns an error containing `key` and `node`.
369 ///
370 /// This operation should compute in *O*(1) time on average.
371 #[inline]
372 pub fn push_back<T: Into<N>>(&mut self, key: K, node: T) -> Result<(), (K, T)> {
373 self.list.push_back(key, node)
374 }
375
376 /// Removes the first pair from the cursor’s parent list and returns it, or
377 /// `None` if the list is empty. The pair the cursor points to remains
378 /// unchanged, unless it was pointing to the front pair. In that case, it
379 /// points to the new front pair.
380 ///
381 /// This operation should compute in *O*(1) time on average.
382 #[inline]
383 pub fn pop_front(&mut self) -> Option<(K, N)> {
384 if self.list.head == self.key {
385 self.move_next();
386 }
387 self.list.pop_front()
388 }
389
390 /// Removes the last pair from the cursor’s parent list and returns it, or
391 /// `None` if the list is empty. The pair the cursor points to remains
392 /// unchanged, unless it was pointing to the back pair. In that case, it
393 /// points to the null pair.
394 ///
395 /// This operation should compute in *O*(1) time on average.
396 #[inline]
397 pub fn pop_back(&mut self) -> Option<(K, N)> {
398 if self.list.tail == self.key {
399 self.key = None;
400 }
401 self.list.pop_back()
402 }
403}