use std::slice;
use crate::{subtree_path::SubtreePath, util::CompactBytesIter};
#[derive(Debug)]
pub struct SubtreePathIter<'b, B> {
current_iter: CurrentSubtreePathIter<'b, B>,
next_subtree_path: Option<&'b SubtreePath<'b, B>>,
}
impl<'b, B> Clone for SubtreePathIter<'b, B> {
fn clone(&self) -> Self {
SubtreePathIter {
current_iter: self.current_iter.clone(),
next_subtree_path: self.next_subtree_path,
}
}
}
impl<'b, B> SubtreePathIter<'b, B> {
pub(crate) fn len(&self) -> usize {
self.current_iter.len() + self.next_subtree_path.map(|p| p.len()).unwrap_or_default()
}
pub(crate) fn new<I>(iter: I) -> Self
where
I: Into<CurrentSubtreePathIter<'b, B>>,
{
SubtreePathIter {
current_iter: iter.into(),
next_subtree_path: None,
}
}
pub(crate) fn new_with_next<I>(iter: I, next: &'b SubtreePath<'b, B>) -> Self
where
I: Into<CurrentSubtreePathIter<'b, B>>,
{
SubtreePathIter {
current_iter: iter.into(),
next_subtree_path: Some(next),
}
}
pub(crate) fn is_empty(&self) -> bool {
self.next_subtree_path.is_none()
&& match &self.current_iter {
CurrentSubtreePathIter::Single(_) => false,
CurrentSubtreePathIter::Slice(slice) => slice.len() == 0,
CurrentSubtreePathIter::OwnedBytes(bytes_iter) => bytes_iter.len() == 0,
}
}
}
impl<'b, B: AsRef<[u8]>> Iterator for SubtreePathIter<'b, B> {
type Item = &'b [u8];
fn next(&mut self) -> Option<Self::Item> {
match &mut self.current_iter {
CurrentSubtreePathIter::Single(item) => {
let path_segment = *item;
if let Some(next_path) = self.next_subtree_path {
*self = next_path.clone().into_reverse_iter();
}
Some(path_segment)
}
CurrentSubtreePathIter::Slice(slice_iter) => {
if let Some(item) = slice_iter.next_back() {
Some(item.as_ref())
} else if let Some(next_path) = self.next_subtree_path {
*self = next_path.clone().into_reverse_iter();
self.next()
} else {
None
}
}
CurrentSubtreePathIter::OwnedBytes(bytes_iter) => {
if let Some(item) = bytes_iter.next() {
Some(item)
} else if let Some(next_path) = self.next_subtree_path {
*self = next_path.clone().into_reverse_iter();
self.next()
} else {
None
}
}
}
}
}
#[derive(Debug)]
pub(crate) enum CurrentSubtreePathIter<'b, B> {
Single(&'b [u8]),
Slice(slice::Iter<'b, B>),
OwnedBytes(CompactBytesIter<'b>),
}
impl<B> CurrentSubtreePathIter<'_, B> {
pub fn len(&self) -> usize {
match self {
CurrentSubtreePathIter::Single(_) => 1,
CurrentSubtreePathIter::Slice(s) => s.len(),
CurrentSubtreePathIter::OwnedBytes(cb) => cb.len(),
}
}
}
impl<'b, B> Clone for CurrentSubtreePathIter<'b, B> {
fn clone(&self) -> Self {
match self {
CurrentSubtreePathIter::Single(x) => CurrentSubtreePathIter::Single(x),
CurrentSubtreePathIter::Slice(x) => CurrentSubtreePathIter::Slice(x.clone()),
CurrentSubtreePathIter::OwnedBytes(x) => CurrentSubtreePathIter::OwnedBytes(x.clone()),
}
}
}
impl<'b, B> From<CompactBytesIter<'b>> for CurrentSubtreePathIter<'b, B> {
fn from(value: CompactBytesIter<'b>) -> Self {
CurrentSubtreePathIter::<B>::OwnedBytes(value)
}
}
impl<'b, B> From<slice::Iter<'b, B>> for CurrentSubtreePathIter<'b, B> {
fn from(value: slice::Iter<'b, B>) -> Self {
CurrentSubtreePathIter::Slice(value)
}
}
impl<'b, B> From<&'b [u8]> for CurrentSubtreePathIter<'b, B> {
fn from(value: &'b [u8]) -> Self {
CurrentSubtreePathIter::Single(value)
}
}