nstack/annotation/
index.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7use 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    /// Construct a [`Branch`] pointing to the `nth` element, if any
20    pub fn nth(&self, index: u64) -> Option<Branch<Self, A>> {
21        Branch::walk(self, Index(index))
22    }
23
24    /// Construct a [`BranchMut`] pointing to the `nth` element, if any
25    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}