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
use std::mem::take;
use std::ops::RangeBounds;
use crate::intern::Token;
use crate::myers::preprocess::PreprocessedFile;
use crate::util::common_edges;
#[derive(Default)]
pub struct FileSlice<'a> {
pub tokens: &'a [Token],
indices: &'a [u32],
changed: &'a mut [bool],
}
impl<'a> FileSlice<'a> {
pub fn new(file: &'a mut PreprocessedFile) -> Self {
Self { tokens: &file.tokens, indices: &file.indices, changed: &mut file.is_changed }
}
pub fn mark_changed(&mut self) {
for &i in self.indices {
self.changed[i as usize] = true;
}
}
pub fn borrow(&mut self) -> FileSlice {
FileSlice { tokens: self.tokens, changed: self.changed, indices: self.indices }
}
pub fn slice<R: RangeBounds<u32>>(self, range: R) -> Self {
let start = match range.start_bound() {
std::ops::Bound::Included(&start) => start,
std::ops::Bound::Excluded(&start) => start + 1,
std::ops::Bound::Unbounded => 0,
};
let end = match range.end_bound() {
std::ops::Bound::Included(&end) => end + 1,
std::ops::Bound::Excluded(&end) => end,
std::ops::Bound::Unbounded => self.len(),
};
Self {
tokens: &self.tokens[start as usize..end as usize],
changed: self.changed,
indices: &self.indices[start as usize..end as usize],
}
}
pub fn strip_common(&mut self, other: &mut Self) {
let (start, common_postfix) = common_edges(self.tokens, other.tokens);
let end = self.len() - common_postfix;
*self = take(self).slice(start..end);
let end = other.len() - common_postfix;
*other = take(other).slice(start..end)
}
pub fn len(&self) -> u32 {
self.tokens.len() as u32
}
pub fn is_empty(&self) -> bool {
self.tokens.is_empty()
}
}