pub(super) struct Selection {
pub(super) start: usize,
pub(super) end: usize,
pub(super) offset: u64,
pub(super) returned: u64,
pub(super) total: u64,
}
impl Selection {
pub(super) fn note(&self) -> String {
let mut note = format!(
"read_file: {} of {} lines from offset {}",
self.returned, self.total, self.offset
);
let next = self.offset.saturating_add(self.returned);
if next <= self.total {
note.push_str(&format!("; continue with offset {next}"));
}
note.push('\n');
note
}
}
pub(super) fn select(content: &[u8], offset: u64, limit: Option<u64>) -> Selection {
let last = limit.map(|l| offset.saturating_add(l).saturating_sub(1));
let mut total: u64 = 0;
let mut returned: u64 = 0;
let mut start: Option<usize> = None;
let mut end: usize = 0;
let mut begin: usize = 0;
while begin < content.len() {
let stop = content[begin..]
.iter()
.position(|b| *b == b'\n')
.map_or(content.len(), |p| begin + p + 1);
total = total.saturating_add(1);
if total >= offset && last.is_none_or(|l| total <= l) {
if start.is_none() {
start = Some(begin);
}
end = stop;
returned = returned.saturating_add(1);
}
begin = stop;
}
let start = start.unwrap_or(0);
Selection {
start,
end,
offset,
returned,
total,
}
}