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}