imara_diff/myers/
slice.rs1use std::mem::take;
2use std::ops::RangeBounds;
3
4use crate::intern::Token;
5use crate::myers::preprocess::PreprocessedFile;
6use crate::util::common_edges;
7
8#[derive(Default)]
9pub struct FileSlice<'a> {
10 pub tokens: &'a [Token],
11 indices: &'a [u32],
12 changed: &'a mut [bool],
13}
14
15impl<'a> FileSlice<'a> {
16 pub fn new(file: &'a PreprocessedFile, changed: &'a mut [bool]) -> Self {
17 Self {
18 tokens: &file.tokens,
19 indices: &file.indices,
20 changed,
21 }
22 }
23
24 pub fn mark_changed(&mut self) {
25 for &i in self.indices {
26 self.changed[i as usize] = true;
27 }
28 }
29
30 pub fn borrow(&mut self) -> FileSlice {
31 FileSlice {
32 tokens: self.tokens,
33 changed: self.changed,
34 indices: self.indices,
35 }
36 }
37
38 pub fn slice<R: RangeBounds<u32>>(self, range: R) -> Self {
39 let start = match range.start_bound() {
40 std::ops::Bound::Included(&start) => start,
41 std::ops::Bound::Excluded(&start) => start + 1,
42 std::ops::Bound::Unbounded => 0,
43 };
44
45 let end = match range.end_bound() {
46 std::ops::Bound::Included(&end) => end + 1,
47 std::ops::Bound::Excluded(&end) => end,
48 std::ops::Bound::Unbounded => self.len(),
49 };
50
51 Self {
52 tokens: &self.tokens[start as usize..end as usize],
53 changed: self.changed,
54 indices: &self.indices[start as usize..end as usize],
55 }
56 }
57
58 pub fn strip_common(&mut self, other: &mut Self) {
59 let (start, common_postfix) = common_edges(self.tokens, other.tokens);
60 let end = self.len() - common_postfix;
61 *self = take(self).slice(start..end);
62 let end = other.len() - common_postfix;
63 *other = take(other).slice(start..end)
64 }
65
66 pub fn len(&self) -> u32 {
67 self.tokens.len() as u32
68 }
69
70 pub fn is_empty(&self) -> bool {
71 self.tokens.is_empty()
72 }
73}