use core::fmt;
use super::{LeafNode, NodePtr};
type LeafPtr<K, V, const PREFIX_LEN: usize> = NodePtr<PREFIX_LEN, LeafNode<K, V, PREFIX_LEN>>;
struct RawIteratorInner<K, V, const PREFIX_LEN: usize> {
start: LeafPtr<K, V, PREFIX_LEN>,
end: LeafPtr<K, V, PREFIX_LEN>,
}
impl<K, V, const PREFIX_LEN: usize> Copy for RawIteratorInner<K, V, PREFIX_LEN> {}
impl<K, V, const PREFIX_LEN: usize> Clone for RawIteratorInner<K, V, PREFIX_LEN> {
fn clone(&self) -> Self {
*self
}
}
impl<K, V, const PREFIX_LEN: usize> fmt::Debug for RawIteratorInner<K, V, PREFIX_LEN> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawIteratorInner")
.field("start", &self.start)
.field("end", &self.end)
.finish()
}
}
pub struct RawIterator<K, V, const PREFIX_LEN: usize> {
state: Option<RawIteratorInner<K, V, PREFIX_LEN>>,
}
impl<K, V, const PREFIX_LEN: usize> Copy for RawIterator<K, V, PREFIX_LEN> {}
impl<K, V, const PREFIX_LEN: usize> Clone for RawIterator<K, V, PREFIX_LEN> {
fn clone(&self) -> Self {
*self
}
}
impl<K, V, const PREFIX_LEN: usize> fmt::Debug for RawIterator<K, V, PREFIX_LEN> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RawIterator")
.field("state", &self.state)
.finish()
}
}
impl<K, V, const PREFIX_LEN: usize> RawIterator<K, V, PREFIX_LEN> {
pub unsafe fn new(start: LeafPtr<K, V, PREFIX_LEN>, end: LeafPtr<K, V, PREFIX_LEN>) -> Self {
Self {
state: Some(RawIteratorInner { start, end }),
}
}
pub fn empty() -> Self {
Self { state: None }
}
pub unsafe fn next(&mut self) -> Option<LeafPtr<K, V, PREFIX_LEN>> {
match &mut self.state {
None => None,
Some(RawIteratorInner { start, end }) => {
let is_singleton = start == end;
let next = *start;
if is_singleton {
self.state = None;
} else {
let start_leaf = unsafe { start.as_ref() };
*start = start_leaf.next.unwrap();
}
Some(next)
},
}
}
pub unsafe fn next_back(&mut self) -> Option<LeafPtr<K, V, PREFIX_LEN>> {
match &mut self.state {
None => None,
Some(RawIteratorInner { start, end }) => {
let is_singleton = start == end;
let next_back = *end;
if is_singleton {
self.state = None;
} else {
let end_leaf = unsafe { end.as_ref() };
*end = end_leaf.previous.unwrap();
}
Some(next_back)
},
}
}
}