loro_delta/
iter.rs

1use generic_btree::{Cursor, LeafIndex};
2
3use crate::{
4    delta_trait::{DeltaAttr, DeltaValue},
5    DeltaItem, DeltaRope,
6};
7
8pub struct Iter<'a, V: DeltaValue, Attr: DeltaAttr> {
9    delta: &'a DeltaRope<V, Attr>,
10    cursor: Option<LeafIndex>,
11    current: Option<DeltaItem<V, Attr>>,
12}
13
14impl<'a, V: DeltaValue, Attr: DeltaAttr> Iter<'a, V, Attr> {
15    pub fn new(delta: &'a DeltaRope<V, Attr>) -> Self {
16        let leaf = delta.tree.first_leaf();
17        let mut current = None;
18        if let Some(leaf) = leaf {
19            current = delta.tree.get_elem(leaf).cloned();
20        }
21
22        Self {
23            delta,
24            cursor: leaf,
25            current,
26        }
27    }
28
29    pub fn peek(&self) -> Option<&'_ DeltaItem<V, Attr>> {
30        self.current.as_ref()
31    }
32
33    pub fn peek_is_replace(&self) -> bool {
34        self.peek().map(|x| x.is_replace()).unwrap_or(false)
35    }
36
37    pub fn peek_is_insert(&self) -> bool {
38        self.peek().map(|x| x.is_insert()).unwrap_or(false)
39    }
40
41    pub fn peek_is_delete(&self) -> bool {
42        self.peek().map(|x| x.is_delete()).unwrap_or(false)
43    }
44
45    pub fn peek_is_retain(&self) -> bool {
46        self.peek().map(|x| x.is_retain()).unwrap_or(false)
47    }
48
49    pub fn peek_length(&self) -> usize {
50        self.peek().map(|x| x.delta_len()).unwrap_or(usize::MAX)
51    }
52
53    pub fn peek_insert_length(&self) -> usize {
54        self.peek()
55            .map(|x| match x {
56                DeltaItem::Retain { .. } => 0,
57                DeltaItem::Replace { value, .. } => value.rle_len(),
58            })
59            .unwrap_or(0)
60    }
61
62    pub fn next_with(&mut self, mut len: usize) -> Result<(), usize> {
63        while len > 0 {
64            let Some(current) = self.current.as_mut() else {
65                return Err(len);
66            };
67
68            if len >= current.delta_len() {
69                len -= current.delta_len();
70                self.cursor = self
71                    .delta
72                    .tree
73                    .next_elem(Cursor {
74                        leaf: self.cursor.unwrap(),
75                        offset: 0,
76                    })
77                    .map(|x| x.leaf);
78                if let Some(leaf) = self.cursor {
79                    self.current = self.delta.tree.get_elem(leaf).cloned();
80                } else {
81                    self.current = None;
82                }
83            } else {
84                match current {
85                    DeltaItem::Retain {
86                        len: retain,
87                        attr: _,
88                    } => {
89                        *retain -= len;
90                    }
91                    DeltaItem::Replace {
92                        value,
93                        attr: _,
94                        delete,
95                    } => {
96                        if value.rle_len() > 0 {
97                            value.slice_(len..);
98                        } else {
99                            *delete -= len;
100                        }
101                    }
102                }
103                len = 0;
104            }
105        }
106
107        Ok(())
108    }
109
110    /// Consume next `len` deletions in the current item
111    pub(crate) fn next_with_del(&mut self, mut len: usize) -> Result<(), usize> {
112        let Some(current) = self.current.as_mut() else {
113            return Err(len);
114        };
115
116        match current {
117            DeltaItem::Retain { .. } => return Err(len),
118            DeltaItem::Replace { delete, .. } => {
119                if *delete >= len {
120                    *delete -= len;
121                    len = 0;
122                } else {
123                    len -= *delete;
124                    *delete = 0;
125                }
126            }
127        }
128
129        if current.delta_len() == 0 {
130            self.next();
131        }
132
133        if len > 0 {
134            Err(len)
135        } else {
136            Ok(())
137        }
138    }
139}
140
141impl<V: DeltaValue, Attr: DeltaAttr> Iterator for Iter<'_, V, Attr> {
142    type Item = DeltaItem<V, Attr>;
143
144    fn next(&mut self) -> Option<Self::Item> {
145        self.cursor = self
146            .delta
147            .tree
148            .next_elem(Cursor {
149                leaf: self.cursor.unwrap(),
150                offset: 0,
151            })
152            .map(|x| x.leaf);
153        let old_current = std::mem::take(&mut self.current);
154        if let Some(c) = self.cursor {
155            self.current = self.delta.tree.get_elem(c).cloned();
156        } else {
157            self.current = None;
158        }
159        old_current
160    }
161}