1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
use crate::op_tree::OpTreeNode;
use crate::query::OpSetMetadata;
use crate::query::{QueryResult, TreeQuery};
use crate::types::{Clock, Key, Op};
use std::cmp::Ordering;
use std::fmt::Debug;

#[derive(Debug, Clone, PartialEq)]
pub(crate) struct Prop<'a> {
    clock: Option<Clock>,
    key: Key,
    pub(crate) pos: usize,
    pub(crate) ops: Vec<&'a Op>,
    pub(crate) ops_pos: Vec<usize>,
}

impl<'a> Prop<'a> {
    pub(crate) fn new(key: Key, clock: Option<Clock>) -> Self {
        Prop {
            clock,
            key,
            pos: 0,
            ops: vec![],
            ops_pos: vec![],
        }
    }
}

impl<'a> TreeQuery<'a> for Prop<'a> {
    fn query_node_with_metadata(
        &mut self,
        child: &OpTreeNode,
        m: &OpSetMetadata,
        ops: &[Op],
    ) -> QueryResult {
        let cmp = m.key_cmp(&ops[child.last()].key, &self.key);
        if cmp == Ordering::Less
            || (cmp == Ordering::Equal
                && self.clock.is_none()
                && !child.index.has_visible(&self.key))
        {
            self.pos += child.len();
            QueryResult::Next
        } else {
            QueryResult::Descend
        }
    }

    fn query_element_with_metadata(&mut self, element: &'a Op, m: &OpSetMetadata) -> QueryResult {
        match m.key_cmp(&element.key, &self.key) {
            Ordering::Greater => QueryResult::Finish,
            Ordering::Equal => {
                if element.visible_at(self.clock.as_ref()) {
                    self.ops.push(element);
                    self.ops_pos.push(self.pos);
                }
                self.pos += 1;
                QueryResult::Next
            }
            Ordering::Less => {
                self.pos += 1;
                QueryResult::Next
            }
        }
    }
}