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