1use std::cmp::{max, min};
22use xi_rope::{RopeDelta, Transformer};
23
24pub struct IndexSet {
25 ranges: Vec<(usize, usize)>,
26}
27
28pub fn remove_n_at<T: Clone>(v: &mut Vec<T>, index: usize, n: usize) {
29 if n == 1 {
30 v.remove(index);
31 } else if n > 1 {
32 let new_len = v.len() - n;
33 for i in index..new_len {
34 v[i] = v[i + n].clone();
35 }
36 v.truncate(new_len);
37 }
38}
39
40impl IndexSet {
41 pub fn new() -> IndexSet {
43 IndexSet { ranges: Vec::new() }
44 }
45
46 pub fn clear(&mut self) {
48 self.ranges.clear();
49 }
50
51 pub fn union_one_range(&mut self, start: usize, end: usize) {
53 for i in 0..self.ranges.len() {
54 let (istart, iend) = self.ranges[i];
55 if start > iend {
56 continue;
57 } else if end < istart {
58 self.ranges.insert(i, (start, end));
59 return;
60 } else {
61 self.ranges[i].0 = min(start, istart);
62 let mut j = i;
63 while j + 1 < self.ranges.len() && end >= self.ranges[j + 1].0 {
64 j += 1;
65 }
66 self.ranges[i].1 = max(end, self.ranges[j].1);
67 remove_n_at(&mut self.ranges, i + 1, j - i);
68 return;
69 }
70 }
71 self.ranges.push((start, end));
72 }
73
74 pub fn delete_range(&mut self, start: usize, end: usize) {
76 let mut ix = match self.ranges.binary_search_by(|r| r.1.cmp(&start)) {
77 Ok(ix) => ix,
78 Err(ix) => ix,
79 };
80
81 let mut del_from = None;
82 let mut del_len = 0;
83 while ix < self.ranges.len() {
84 if self.ranges[ix].0 >= end {
85 break;
86 }
87
88 if self.ranges[ix].0 < start {
89 if self.ranges[ix].1 > end {
90 let range = (end, self.ranges[ix].1);
91 self.ranges.insert(ix + 1, range);
92 }
93 self.ranges[ix].1 = start;
94 } else if self.ranges[ix].1 > end {
95 self.ranges[ix].0 = end;
96 } else {
97 if del_from.is_none() {
98 del_from = Some(ix);
99 }
100 del_len += 1;
101 }
102
103 ix += 1;
104 }
105
106 if let Some(del_from) = del_from {
107 remove_n_at(&mut self.ranges, del_from, del_len);
108 }
109 }
110
111 pub fn minus_one_range(&self, start: usize, end: usize) -> MinusIter {
113 let mut ranges = &self.ranges[..];
114 while !ranges.is_empty() && start >= ranges[0].1 {
115 ranges = &ranges[1..];
116 }
117 MinusIter { ranges, start, end }
118 }
119
120 pub fn apply_delta(&self, delta: &RopeDelta) -> IndexSet {
123 let mut ranges: Vec<(usize, usize)> = Vec::new();
124 let mut transformer = Transformer::new(delta);
125 for &(start, end) in &self.ranges {
126 let new_range =
127 (transformer.transform(start, false), transformer.transform(end, false));
128 if new_range.0 == new_range.1 {
129 continue; }
131 if !ranges.is_empty() {
132 let ix = ranges.len() - 1;
133 if ranges[ix].1 == new_range.0 {
134 ranges[ix] = (ranges[ix].0, new_range.1);
135 continue;
136 }
137 }
138 ranges.push(new_range);
139 }
140 IndexSet { ranges }
141 }
142
143 #[cfg(test)]
144 fn get_ranges(&self) -> &[(usize, usize)] {
145 &self.ranges
146 }
147}
148
149pub struct MinusIter<'a> {
151 ranges: &'a [(usize, usize)],
152 start: usize,
153 end: usize,
154}
155
156impl<'a> Iterator for MinusIter<'a> {
157 type Item = (usize, usize);
158
159 fn next(&mut self) -> Option<(usize, usize)> {
160 while self.start < self.end {
161 if self.ranges.is_empty() || self.end <= self.ranges[0].0 {
162 let result = (self.start, self.end);
163 self.start = self.end;
164 return Some(result);
165 }
166 let result = (self.start, self.ranges[0].0);
167 self.start = self.ranges[0].1;
168 self.ranges = &self.ranges[1..];
169 if result.1 > result.0 {
170 return Some(result);
171 }
172 }
173 None
174 }
175}
176
177impl<'a> DoubleEndedIterator for MinusIter<'a> {
178 fn next_back(&mut self) -> Option<Self::Item> {
179 while self.start < self.end {
180 if self.ranges.is_empty() || self.ranges[self.ranges.len() - 1].1 <= self.start {
181 let result = (self.start, self.end);
182 self.start = self.end;
183 return Some(result);
184 }
185 let last_ix = self.ranges.len() - 1;
186 let result = (self.ranges[last_ix].1, self.end);
187 self.end = self.ranges[last_ix].0;
188 self.ranges = &self.ranges[..last_ix];
189 if result.1 > result.0 {
190 return Some(result);
191 }
192 }
193 None
194 }
195}
196
197#[cfg(test)]
198mod tests {
199 use super::IndexSet;
200
201 #[test]
202 fn empty_behavior() {
203 let e = IndexSet::new();
204 assert_eq!(e.minus_one_range(0, 0).collect::<Vec<_>>(), vec![]);
205 assert_eq!(e.minus_one_range(3, 5).collect::<Vec<_>>(), vec![(3, 5)]);
206 }
207
208 #[test]
209 fn single_range_behavior() {
210 let mut e = IndexSet::new();
211 e.union_one_range(3, 5);
212 assert_eq!(e.minus_one_range(0, 0).collect::<Vec<_>>(), vec![]);
213 assert_eq!(e.minus_one_range(3, 5).collect::<Vec<_>>(), vec![]);
214 assert_eq!(e.minus_one_range(0, 3).collect::<Vec<_>>(), vec![(0, 3)]);
215 assert_eq!(e.minus_one_range(0, 4).collect::<Vec<_>>(), vec![(0, 3)]);
216 assert_eq!(e.minus_one_range(4, 10).collect::<Vec<_>>(), vec![(5, 10)]);
217 assert_eq!(e.minus_one_range(5, 10).collect::<Vec<_>>(), vec![(5, 10)]);
218 assert_eq!(e.minus_one_range(0, 10).collect::<Vec<_>>(), vec![(0, 3), (5, 10)]);
219 }
220
221 #[test]
222 fn two_range_minus() {
223 let mut e = IndexSet::new();
224 e.union_one_range(3, 5);
225 e.union_one_range(7, 9);
226 assert_eq!(e.minus_one_range(0, 0).collect::<Vec<_>>(), vec![]);
227 assert_eq!(e.minus_one_range(3, 5).collect::<Vec<_>>(), vec![]);
228 assert_eq!(e.minus_one_range(0, 3).collect::<Vec<_>>(), vec![(0, 3)]);
229 assert_eq!(e.minus_one_range(0, 4).collect::<Vec<_>>(), vec![(0, 3)]);
230 assert_eq!(e.minus_one_range(4, 10).collect::<Vec<_>>(), vec![(5, 7), (9, 10)]);
231 assert_eq!(e.minus_one_range(5, 10).collect::<Vec<_>>(), vec![(5, 7), (9, 10)]);
232 assert_eq!(e.minus_one_range(8, 10).collect::<Vec<_>>(), vec![(9, 10)]);
233 assert_eq!(e.minus_one_range(0, 10).collect::<Vec<_>>(), vec![(0, 3), (5, 7), (9, 10)]);
234 }
235
236 #[test]
237 fn minus_one_range_double_ended_iter() {
238 let mut e = IndexSet::new();
239 e.union_one_range(3, 5);
240 e.union_one_range(7, 9);
241 e.union_one_range(12, 15);
242
243 let mut iter = e.minus_one_range(4, 13);
244 assert_eq!(iter.next(), Some((5, 7)));
245 assert_eq!(iter.next(), Some((9, 12)));
246 assert_eq!(iter.next(), None);
247
248 let mut iter = e.minus_one_range(4, 13);
249 assert_eq!(iter.next_back(), Some((9, 12)));
250 assert_eq!(iter.next_back(), Some((5, 7)));
251 assert_eq!(iter.next_back(), None);
252
253 let mut iter = e.minus_one_range(4, 13);
254 assert_eq!(iter.next_back(), Some((9, 12)));
255 assert_eq!(iter.next(), Some((5, 7)));
256 assert_eq!(iter.next_back(), None);
257 assert_eq!(iter.next(), None);
258 }
259
260 #[test]
261 fn unions() {
262 let mut e = IndexSet::new();
263 e.union_one_range(3, 5);
264 assert_eq!(e.get_ranges(), &[(3, 5)]);
265 e.union_one_range(7, 9);
266 assert_eq!(e.get_ranges(), &[(3, 5), (7, 9)]);
267 e.union_one_range(1, 2);
268 assert_eq!(e.get_ranges(), &[(1, 2), (3, 5), (7, 9)]);
269 e.union_one_range(2, 3);
270 assert_eq!(e.get_ranges(), &[(1, 5), (7, 9)]);
271 e.union_one_range(4, 6);
272 assert_eq!(e.get_ranges(), &[(1, 6), (7, 9)]);
273 assert_eq!(e.minus_one_range(0, 10).collect::<Vec<_>>(), vec![(0, 1), (6, 7), (9, 10)]);
274
275 e.clear();
276 assert_eq!(e.get_ranges(), &[]);
277 e.union_one_range(3, 4);
278 assert_eq!(e.get_ranges(), &[(3, 4)]);
279 e.union_one_range(5, 6);
280 assert_eq!(e.get_ranges(), &[(3, 4), (5, 6)]);
281 e.union_one_range(7, 8);
282 assert_eq!(e.get_ranges(), &[(3, 4), (5, 6), (7, 8)]);
283 e.union_one_range(9, 10);
284 assert_eq!(e.get_ranges(), &[(3, 4), (5, 6), (7, 8), (9, 10)]);
285 e.union_one_range(11, 12);
286 assert_eq!(e.get_ranges(), &[(3, 4), (5, 6), (7, 8), (9, 10), (11, 12)]);
287 e.union_one_range(2, 10);
288 assert_eq!(e.get_ranges(), &[(2, 10), (11, 12)]);
289 }
290
291 #[test]
292 fn delete_range() {
293 let mut e = IndexSet::new();
294 e.union_one_range(1, 2);
295 e.union_one_range(4, 6);
296 e.union_one_range(6, 7);
297 e.union_one_range(8, 8);
298 e.union_one_range(10, 12);
299 e.union_one_range(13, 14);
300 e.delete_range(5, 11);
301 assert_eq!(e.get_ranges(), &[(1, 2), (4, 5), (11, 12), (13, 14)]);
302
303 let mut e = IndexSet::new();
304 e.union_one_range(1, 2);
305 e.union_one_range(4, 6);
306 e.delete_range(2, 4);
307 assert_eq!(e.get_ranges(), &[(1, 2), (4, 6)]);
308
309 let mut e = IndexSet::new();
310 e.union_one_range(0, 10);
311 e.delete_range(4, 6);
312 assert_eq!(e.get_ranges(), &[(0, 4), (6, 10)]);
313 }
314
315 #[test]
316 fn apply_delta() {
317 use xi_rope::{Delta, Interval, Rope};
318
319 let mut e = IndexSet::new();
320 e.union_one_range(1, 3);
321 e.union_one_range(5, 9);
322
323 let d = Delta::simple_edit(Interval::new(2, 2), Rope::from("..."), 10);
324 let s = e.apply_delta(&d);
325 assert_eq!(s.get_ranges(), &[(1, 6), (8, 12)]);
326
327 let d = Delta::simple_edit(Interval::new(0, 3), Rope::from(""), 10);
328 let s = e.apply_delta(&d);
329 assert_eq!(s.get_ranges(), &[(2, 6)]);
330
331 let d = Delta::simple_edit(Interval::new(2, 6), Rope::from(""), 10);
332 let s = e.apply_delta(&d);
333 assert_eq!(s.get_ranges(), &[(1, 5)]);
334 }
335}