use line_span::LineSpans;
use std::ops::{Index, Range};
pub struct CachedLines {
pub content: String,
pub splits: Vec<Range<usize>>,
}
impl CachedLines {
#[must_use]
pub fn without_ending(content: String) -> Self {
let splits = content.line_spans().map(|s| s.range()).collect::<Vec<_>>();
Self { content, splits }
}
#[must_use]
pub fn iter(&self) -> LineIter<'_> {
LineIter {
payload: self,
current: 0,
}
}
#[must_use]
pub fn get(&self, index: usize) -> Option<&str> {
let range = self.splits.get(index)?.clone();
Some(&self.content[range])
}
}
impl Index<usize> for CachedLines {
type Output = str;
fn index(&self, index: usize) -> &Self::Output {
&self.content[self.splits[index].clone()]
}
}
pub struct LineIter<'a> {
payload: &'a CachedLines,
current: usize,
}
impl<'a> IntoIterator for &'a CachedLines {
type Item = &'a str;
type IntoIter = LineIter<'a>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
impl<'a> Iterator for LineIter<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<Self::Item> {
self.current += 1;
self.payload.get(self.current - 1)
}
}