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 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}