nstack/annotation/
index.rs1use crate::annotation::Cardinality;
8use crate::NStack;
9
10use core::borrow::Borrow;
11
12use microkelvin::{Branch, BranchMut, Child, Step, Walk, Walker};
13use ranno::Annotation;
14
15impl<T, A> NStack<T, A>
16where
17 A: Annotation<Self> + Borrow<Cardinality>,
18{
19 pub fn nth(&self, index: u64) -> Option<Branch<Self, A>> {
21 Branch::walk(self, Index(index))
22 }
23
24 pub fn nth_mut(&mut self, index: u64) -> Option<BranchMut<Self, A>> {
26 BranchMut::walk(self, Index(index))
27 }
28}
29
30struct Index(u64);
31
32impl<T, A> Walker<NStack<T, A>, A> for Index
33where
34 A: Annotation<NStack<T, A>> + Borrow<Cardinality>,
35{
36 fn walk(&mut self, walk: Walk<NStack<T, A>, A>) -> Step {
37 for i in 0.. {
38 match walk.child(i) {
39 Child::Leaf(_) => {
40 if self.0 == 0 {
41 return Step::Found(i);
42 } else {
43 self.0 -= 1
44 }
45 }
46 Child::Node(node) => {
47 let anno = node.anno();
48 let c = (*anno).borrow();
49
50 let c = **c;
51
52 if self.0 < c {
53 return Step::Into(i);
54 }
55
56 self.0 -= c;
57 }
58 Child::Empty => (),
59 Child::EndOfNode => return Step::Abort,
60 }
61 }
62 unreachable!()
63 }
64}