use crate::list::KeyNodeList;
use crate::map::Map;
use crate::node::Node;
use crate::{node_next_mut, node_prev_mut};
use std::fmt;
use std::hash::Hash;
macro_rules! impl_cursor {
($name:ident<$a:lifetime, $k:ident, $n:ident, $m:ident>($list:ident, $key:ident)) => {
impl<$a, $k, $n, $m> $name<$a, $k, $n, $m> {
#[inline]
pub fn is_null(&self) -> bool {
self.$key.is_none()
}
#[inline]
pub fn key(&self) -> Option<&$k> {
self.$key.as_ref()
}
#[inline]
pub fn front_key(&self) -> Option<&$k> {
self.$list.head.as_ref()
}
#[inline]
pub fn back_key(&self) -> Option<&$k> {
self.$list.tail.as_ref()
}
}
impl<$a, $k, $n, $m> $name<$a, $k, $n, $m>
where
$k: Hash + Eq,
$m: Map<K, N>,
{
#[inline]
pub fn node(&self) -> Option<&$n> {
self.$key.as_ref().and_then(|k| self.$list.nodes.get(k))
}
#[inline]
pub fn front_node(&self) -> Option<&$n> {
self.front_key().and_then(|k| self.$list.nodes.get(k))
}
#[inline]
pub fn back_node(&self) -> Option<&$n> {
self.back_key().and_then(|k| self.$list.nodes.get(k))
}
}
impl<$a, $k, $n, $m> $name<$a, $k, $n, $m>
where
$k: Hash + Eq,
$n: Node<Key = $k>,
$m: Map<K, N>,
{
#[inline]
pub fn next_key(&self) -> Option<&$k> {
self.$key.as_ref().map_or_else(
|| self.$list.head.as_ref(),
|k| self.$list.node(k).and_then(|n| n.next()),
)
}
#[inline]
pub fn prev_key(&self) -> Option<&$k> {
self.$key.as_ref().map_or_else(
|| self.$list.tail.as_ref(),
|k| self.$list.node(k).and_then(|n| n.prev()),
)
}
#[inline]
pub fn next_node(&self) -> Option<&$n> {
self.next_key().and_then(|k| self.$list.node(k))
}
#[inline]
pub fn prev_node(&self) -> Option<&$n> {
self.prev_key().and_then(|k| self.$list.node(k))
}
}
impl<$a, $k, $n, $m> $name<$a, $k, $n, $m>
where
$k: Hash + Eq + Clone,
$n: Node<Key = $k>,
$m: Map<K, N>,
{
#[inline]
pub fn move_next(&mut self) {
self.$key = self.$key.as_ref().map_or_else(
|| self.$list.head.clone(),
|k| self.$list.node(k).and_then(|n| n.next().cloned()),
);
}
#[inline]
pub fn move_prev(&mut self) {
self.$key = self.$key.as_ref().map_or_else(
|| self.$list.tail.clone(),
|k| self.$list.node(k).and_then(|n| n.prev().cloned()),
);
}
}
impl<$a, $k, $n, $m> fmt::Debug for $name<$a, $k, $n, $m>
where
$k: Hash + Eq + fmt::Debug,
$n: Node<Key = $k> + fmt::Debug,
$m: Map<K, N>,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple(stringify!($name))
.field(self.$list)
.field(&self.$key)
.finish()
}
}
};
}
#[derive(Clone)]
pub struct Cursor<'a, K, N, M> {
pub(crate) list: &'a KeyNodeList<K, N, M>,
pub(crate) key: Option<K>,
}
impl_cursor!(Cursor<'a, K, N, M>(list, key));
pub struct CursorMut<'a, K, N, M> {
pub(crate) list: &'a mut KeyNodeList<K, N, M>,
pub(crate) key: Option<K>,
}
impl_cursor!(CursorMut<'a, K, N, M>(list, key));
impl<'a, K, N, M> CursorMut<'a, K, N, M>
where
K: Clone,
{
#[inline]
pub fn as_cursor(&self) -> Cursor<'_, K, N, M> {
Cursor {
list: self.list,
key: self.key.clone(),
}
}
}
impl<'a, K, N, M> CursorMut<'a, K, N, M>
where
K: Hash + Eq,
M: Map<K, N>,
{
#[inline]
pub fn node_mut(&mut self) -> Option<&mut N> {
self.key.as_ref().and_then(|k| self.list.nodes.get_mut(k))
}
#[inline]
pub fn front_node_mut(&mut self) -> Option<&mut N> {
self
.list
.head
.as_ref()
.and_then(|k| self.list.nodes.get_mut(k))
}
#[inline]
pub fn back_node_mut(&mut self) -> Option<&mut N> {
self
.list
.tail
.as_ref()
.and_then(|k| self.list.nodes.get_mut(k))
}
}
impl<'a, K, N, M> CursorMut<'a, K, N, M>
where
K: Hash + Eq + Clone,
N: Node<Key = K>,
M: Map<K, N>,
{
pub fn insert_after<T: Into<N>>(&mut self, key: K, node: T) -> Result<(), (K, T)> {
self.list.nodes.insert(key.clone(), node).map(|_| {
let next = match &self.key {
Some(k) => node_next_mut!(self.list, k).replace(key.clone()),
None => self.list.head.replace(key.clone()),
};
match &next {
Some(k) => *node_prev_mut!(self.list, k) = Some(key.clone()),
None => self.list.tail = Some(key.clone()),
}
let node = self.list.node_mut(&key).unwrap();
*node_prev_mut!(node) = self.key.clone();
*node_next_mut!(node) = next;
})
}
pub fn insert_before<T: Into<N>>(&mut self, key: K, node: T) -> Result<(), (K, T)> {
self.list.nodes.insert(key.clone(), node).map(|_| {
let prev = match &self.key {
Some(k) => node_prev_mut!(self.list, k).replace(key.clone()),
None => self.list.tail.replace(key.clone()),
};
match &prev {
Some(k) => *node_next_mut!(self.list, k) = Some(key.clone()),
None => self.list.head = Some(key.clone()),
}
let node = self.list.node_mut(&key).unwrap();
*node_prev_mut!(node) = prev;
*node_next_mut!(node) = self.key.clone();
})
}
pub fn insert_key_after(&mut self, key: K) -> Result<(), K>
where
(): Into<N>,
{
self.insert_after(key, ()).map_err(|(k, _)| k)
}
pub fn insert_key_before(&mut self, key: K) -> Result<(), K>
where
(): Into<N>,
{
self.insert_before(key, ()).map_err(|(k, _)| k)
}
#[inline]
pub fn remove_current(&mut self) -> Option<(K, N)> {
self.key.take().map(|k| {
let pair = self.list.remove(&k).unwrap();
self.key = pair.1.next().cloned();
pair
})
}
#[inline]
pub fn push_front<T: Into<N>>(&mut self, key: K, node: T) -> Result<(), (K, T)> {
self.list.push_front(key, node)
}
#[inline]
pub fn push_back<T: Into<N>>(&mut self, key: K, node: T) -> Result<(), (K, T)> {
self.list.push_back(key, node)
}
#[inline]
pub fn pop_front(&mut self) -> Option<(K, N)> {
if self.list.head == self.key {
self.move_next();
}
self.list.pop_front()
}
#[inline]
pub fn pop_back(&mut self) -> Option<(K, N)> {
if self.list.tail == self.key {
self.key = None;
}
self.list.pop_back()
}
}