use crate::annotation::Cardinality;
use crate::NStack;
use core::borrow::Borrow;
use microkelvin::{Branch, BranchMut, Child, Step, Walk, Walker};
use ranno::Annotation;
impl<T, A> NStack<T, A>
where
A: Annotation<Self> + Borrow<Cardinality>,
{
pub fn nth(&self, index: u64) -> Option<Branch<Self, A>> {
Branch::walk(self, Index(index))
}
pub fn nth_mut(&mut self, index: u64) -> Option<BranchMut<Self, A>> {
BranchMut::walk(self, Index(index))
}
}
struct Index(u64);
impl<T, A> Walker<NStack<T, A>, A> for Index
where
A: Annotation<NStack<T, A>> + Borrow<Cardinality>,
{
fn walk(&mut self, walk: Walk<NStack<T, A>, A>) -> Step {
for i in 0.. {
match walk.child(i) {
Child::Leaf(_) => {
if self.0 == 0 {
return Step::Found(i);
} else {
self.0 -= 1
}
}
Child::Node(node) => {
let anno = node.anno();
let c = (*anno).borrow();
let c = **c;
if self.0 < c {
return Step::Into(i);
}
self.0 -= c;
}
Child::Empty => (),
Child::EndOfNode => return Step::Abort,
}
}
unreachable!()
}
}