use crate::cursor::{Cursor, CursorMut};
use crate::iter::{IntoIter, IntoKeys, IntoNodes, Iter, Keys, Nodes};
use crate::map::Map;
use crate::node::Node;
use crate::{node_next_mut, node_prev_mut};
use std::borrow::Borrow;
use std::collections::HashMap;
use std::fmt;
use std::hash::Hash;
use std::iter::FromIterator;
use std::marker::PhantomData;
use std::ops::Index;
#[derive(Clone)]
pub struct KeyNodeList<K, N, M = HashMap<K, N>> {
pub(crate) nodes: M,
pub(crate) head: Option<K>,
pub(crate) tail: Option<K>,
phantom: PhantomData<N>,
}
impl<K, N, M> KeyNodeList<K, N, M>
where
M: Default,
{
#[inline]
pub fn new() -> Self {
Self::default()
}
}
impl<K, N, M> KeyNodeList<K, N, M>
where
M: Map<K, N>,
{
#[inline]
pub fn with_map(map: M) -> Self {
Self {
nodes: map,
head: None,
tail: None,
phantom: PhantomData,
}
}
#[inline]
pub fn front_key(&self) -> Option<&K> {
self.head.as_ref()
}
#[inline]
pub fn back_key(&self) -> Option<&K> {
self.tail.as_ref()
}
#[inline]
pub fn len(&self) -> usize {
self.nodes.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.nodes.is_empty()
}
#[inline]
pub fn clear(&mut self) {
self.nodes.clear();
self.head = None;
self.tail = None;
}
#[inline]
pub fn iter(&self) -> Iter<K, N, M> {
Iter {
list: self,
key: self.head.as_ref(),
}
}
#[inline]
pub fn keys(&self) -> Keys<K, N, M> {
Keys { iter: self.iter() }
}
#[inline]
pub fn nodes(&self) -> Nodes<K, N, M> {
Nodes { iter: self.iter() }
}
}
impl<K, N, M> KeyNodeList<K, N, M>
where
K: Hash + Eq,
M: Map<K, N>,
{
#[inline]
pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.nodes.contains_key(key)
}
#[inline]
pub fn node<Q: ?Sized>(&self, key: &Q) -> Option<&N>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.nodes.get(key)
}
#[inline]
pub fn node_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut N>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.nodes.get_mut(key)
}
#[inline]
pub fn front_node(&self) -> Option<&N> {
self.head.as_ref().and_then(|k| self.nodes.get(k))
}
#[inline]
pub fn front_node_mut(&mut self) -> Option<&mut N> {
self.head.as_ref().and_then(|k| self.nodes.get_mut(k))
}
#[inline]
pub fn back_node(&self) -> Option<&N> {
self.tail.as_ref().and_then(|k| self.nodes.get(k))
}
#[inline]
pub fn back_node_mut(&mut self) -> Option<&mut N> {
self.tail.as_ref().and_then(|k| self.nodes.get_mut(k))
}
#[inline]
pub fn cursor(&self, key: K) -> Cursor<K, N, M> {
Cursor {
list: self,
key: self.contains_key(&key).then_some(key),
}
}
#[inline]
pub fn cursor_mut(&mut self, key: K) -> CursorMut<K, N, M> {
CursorMut {
key: self.contains_key(&key).then_some(key),
list: self,
}
}
}
impl<K, N, M> KeyNodeList<K, N, M>
where
K: Hash + Eq + Clone,
M: Map<K, N>,
{
#[inline]
pub fn cursor_front(&self) -> Cursor<K, N, M> {
Cursor {
list: self,
key: self.head.clone(),
}
}
#[inline]
pub fn cursor_front_mut(&mut self) -> CursorMut<K, N, M> {
CursorMut {
key: self.head.clone(),
list: self,
}
}
#[inline]
pub fn cursor_back(&self) -> Cursor<K, N, M> {
Cursor {
list: self,
key: self.tail.clone(),
}
}
#[inline]
pub fn cursor_back_mut(&mut self) -> CursorMut<K, N, M> {
CursorMut {
key: self.tail.clone(),
list: self,
}
}
}
impl<K, N, M> KeyNodeList<K, N, M>
where
K: Hash + Eq + Clone,
N: Node<Key = K>,
M: Map<K, N>,
{
#[inline]
pub fn into_keys(self) -> IntoKeys<K, N, M> {
IntoKeys {
iter: self.into_iter(),
}
}
#[inline]
pub fn into_nodes(self) -> IntoNodes<K, N, M> {
IntoNodes {
iter: self.into_iter(),
}
}
pub fn push_front<T: Into<N>>(&mut self, key: K, node: T) -> Result<(), (K, T)> {
self.nodes.insert(key.clone(), node).map(|_| {
let next = self.head.replace(key.clone());
match &next {
Some(k) => *node_prev_mut!(self, k) = Some(key.clone()),
None => self.tail = Some(key.clone()),
}
let node = self.node_mut(&key).unwrap();
*node_prev_mut!(node) = None;
*node_next_mut!(node) = next;
})
}
pub fn push_back<T: Into<N>>(&mut self, key: K, node: T) -> Result<(), (K, T)> {
self.nodes.insert(key.clone(), node).map(|_| {
let prev = self.tail.replace(key.clone());
match &prev {
Some(k) => *node_next_mut!(self, k) = Some(key.clone()),
None => self.head = Some(key.clone()),
}
let node = self.node_mut(&key).unwrap();
*node_prev_mut!(node) = prev;
*node_next_mut!(node) = None;
})
}
#[inline]
pub fn push_key_front(&mut self, key: K) -> Result<(), K>
where
(): Into<N>,
{
self.push_front(key, ()).map_err(|(k, _)| k)
}
#[inline]
pub fn push_key_back(&mut self, key: K) -> Result<(), K>
where
(): Into<N>,
{
self.push_back(key, ()).map_err(|(k, _)| k)
}
pub fn pop_front(&mut self) -> Option<(K, N)> {
self.head.take().map(|k| {
let node = self.nodes.remove(&k).unwrap();
self.head = node.next().cloned();
(k, node)
})
}
pub fn pop_back(&mut self) -> Option<(K, N)> {
self.tail.take().map(|k| {
let node = self.nodes.remove(&k).unwrap();
self.tail = node.prev().cloned();
(k, node)
})
}
pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<(K, N)>
where
K: Borrow<Q>,
Q: Hash + Eq,
{
self.nodes.remove_entry(key).map(|(k, n)| {
match n.prev() {
Some(k) => *node_next_mut!(self, k) = n.next().cloned(),
None => self.head = n.next().cloned(),
}
match n.next() {
Some(k) => *node_prev_mut!(self, k) = n.prev().cloned(),
None => self.tail = n.prev().cloned(),
}
(k, n)
})
}
}
impl<K, N, M> fmt::Debug for KeyNodeList<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_list().entries(self).finish()
}
}
impl<K, N, M> Default for KeyNodeList<K, N, M>
where
M: Default,
{
#[inline]
fn default() -> Self {
KeyNodeList {
nodes: M::default(),
head: None,
tail: None,
phantom: PhantomData,
}
}
}
impl<'a, K, T, N, M> Extend<(&'a K, &'a T)> for KeyNodeList<K, N, M>
where
K: Eq + Hash + Copy,
T: Into<N> + Copy,
N: Node<Key = K> + Copy,
M: Map<K, N>,
{
fn extend<I: IntoIterator<Item = (&'a K, &'a T)>>(&mut self, iter: I) {
self.extend(iter.into_iter().map(|(k, n)| (*k, *n)))
}
}
impl<'a, K: 'a, N, M> Extend<&'a K> for KeyNodeList<K, N, M>
where
K: Eq + Hash + Copy,
(): Into<N>,
N: Node<Key = K> + Copy,
M: Map<K, N>,
{
fn extend<I: IntoIterator<Item = &'a K>>(&mut self, iter: I) {
self.extend(iter.into_iter().copied())
}
}
impl<K, T, N, M> Extend<(K, T)> for KeyNodeList<K, N, M>
where
K: Eq + Hash + Clone,
T: Into<N>,
N: Node<Key = K>,
M: Map<K, N>,
{
fn extend<I: IntoIterator<Item = (K, T)>>(&mut self, iter: I) {
iter.into_iter().for_each(|(k, n)| {
let _ = self.push_back(k, n);
});
}
}
impl<K, N, M> Extend<K> for KeyNodeList<K, N, M>
where
K: Eq + Hash + Clone,
(): Into<N>,
N: Node<Key = K>,
M: Map<K, N>,
{
fn extend<I: IntoIterator<Item = K>>(&mut self, iter: I) {
iter.into_iter().for_each(|k| {
let _ = self.push_key_back(k);
});
}
}
impl<K, T, N, M, const LEN: usize> From<[(K, T); LEN]> for KeyNodeList<K, N, M>
where
K: Eq + Hash + Clone,
T: Into<N>,
N: Node<Key = K>,
M: Map<K, N> + Default,
{
fn from(arr: [(K, T); LEN]) -> Self {
IntoIterator::into_iter(arr).collect()
}
}
impl<K, T, N, M> FromIterator<(K, T)> for KeyNodeList<K, N, M>
where
K: Eq + Hash + Clone,
T: Into<N>,
N: Node<Key = K>,
M: Map<K, N> + Default,
{
fn from_iter<I: IntoIterator<Item = (K, T)>>(iter: I) -> Self {
let mut list = Self::new();
list.extend(iter);
list
}
}
impl<K, N, M> FromIterator<K> for KeyNodeList<K, N, M>
where
K: Eq + Hash + Clone,
(): Into<N>,
N: Node<Key = K>,
M: Map<K, N> + Default,
{
fn from_iter<I: IntoIterator<Item = K>>(iter: I) -> Self {
let mut list = Self::new();
list.extend(iter);
list
}
}
impl<'a, K, Q, N, M> Index<&'a Q> for KeyNodeList<K, N, M>
where
K: Hash + Eq + Borrow<Q>,
Q: ?Sized + Hash + Eq,
M: Map<K, N>,
{
type Output = N;
#[inline]
fn index(&self, key: &'a Q) -> &Self::Output {
self.nodes.get(key).expect("no entry found for key")
}
}
impl<K, N, M> IntoIterator for KeyNodeList<K, N, M>
where
K: Hash + Eq + Clone,
N: Node<Key = K>,
M: Map<K, N>,
{
type Item = (K, N);
type IntoIter = IntoIter<K, N, M>;
fn into_iter(self) -> Self::IntoIter {
IntoIter { list: self }
}
}
impl<'a, K, N, M> IntoIterator for &'a KeyNodeList<K, N, M>
where
K: Hash + Eq,
N: Node<Key = K>,
M: Map<K, N>,
{
type Item = (&'a K, &'a N);
type IntoIter = Iter<'a, K, N, M>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<K, N, M> PartialEq<KeyNodeList<K, N, M>> for KeyNodeList<K, N, M>
where
M: PartialEq,
{
fn eq(&self, other: &KeyNodeList<K, N, M>) -> bool {
self.nodes == other.nodes
}
}
impl<K, N, M> Eq for KeyNodeList<K, N, M> where M: PartialEq {}