new streams

This commit is contained in:
Jana Dönszelmann 2026-02-24 12:41:00 +01:00
parent 3963fc50c3
commit c73be7166f
No known key found for this signature in database
13 changed files with 748 additions and 174 deletions

View file

@ -1,4 +1,5 @@
use std::{
cell::RefCell,
fs::File,
io::{self, BufRead, BufReader},
mem,
@ -8,35 +9,36 @@ use std::{
};
use crate::tui::{
filter::{Filter, FilterKind},
model::{LogEntry, RawLogEntry},
processing::LogStream,
};
pub struct LogfileReader {
struct Inner {
pub path: PathBuf,
file: BufReader<File>,
entries: Vec<Rc<LogEntry>>,
filters: Vec<Rc<Filter>>,
file: BufReader<File>,
cached_entries: Vec<Rc<LogEntry>>,
}
#[derive(Clone)]
pub struct LogfileReader(Rc<RefCell<Inner>>);
impl LogfileReader {
pub fn new(p: &Path) -> io::Result<Self> {
Ok(Self {
Ok(Self(Rc::new(RefCell::new(Inner {
file: BufReader::new(File::open(p)?),
path: p.to_path_buf(),
entries: Vec::new(),
filters: Vec::new(),
})
cached_entries: Vec::new(),
}))))
}
pub fn add_filter(&mut self, filter: Filter) {
self.filters.push(Rc::new(filter));
pub fn path(&self) -> PathBuf {
self.0.borrow().path.clone()
}
fn next_line(&mut self) -> Option<String> {
let mut res = String::new();
match self.file.read_line(&mut res) {
match self.0.borrow_mut().file.read_line(&mut res) {
Err(e) => {
eprintln!("error: {e:?}");
None
@ -93,71 +95,51 @@ impl LogfileReader {
}
}
pub fn iter_from(&mut self, start: usize) -> FilterAdapter<EntryIterator<'_>> {
FilterAdapter {
filters: self.filters.clone(),
inner: EntryIterator {
curr: start,
reader: self,
},
fn fill_buf_to_access_index(&mut self, n: usize) -> Option<Rc<LogEntry>> {
while self.0.borrow().cached_entries.len() <= n {
let entry = self.next_entry()?;
self.0.borrow_mut().cached_entries.push(entry);
}
Some(Rc::clone(&self.0.borrow().cached_entries[n]))
}
fn add_next_entry(&mut self) -> Option<()> {
let entry = self.next_entry()?;
self.entries.push(entry);
Some(())
pub fn iter(&self) -> LogFileReaderStream {
LogFileReaderStream {
reader: self.clone(),
curr: 0,
}
}
}
pub struct EntryIterator<'a> {
pub struct LogFileReaderStream {
reader: LogfileReader,
curr: usize,
reader: &'a mut LogfileReader,
}
impl<'a> Iterator for EntryIterator<'a> {
type Item = Rc<LogEntry>;
fn next(&mut self) -> Option<Self::Item> {
while self.reader.entries.len() <= self.curr {
self.reader.add_next_entry()?;
}
let res = Rc::clone(&self.reader.entries[self.curr]);
impl LogStream for LogFileReaderStream {
fn next(&mut self) -> Option<Rc<LogEntry>> {
let entry = self.reader.fill_buf_to_access_index(self.curr)?;
self.curr += 1;
Some(res)
Some(entry)
}
}
pub struct FilterAdapter<I> {
filters: Vec<Rc<Filter>>,
inner: I,
}
impl<I: IntoIterator> FilterAdapter<I> {
pub fn new(file: &LogfileReader, inner: I) -> FilterAdapter<I::IntoIter> {
Self {
filters: file.filters.clone(),
inner: inner.into_iter(),
}
}
}
impl<I: Iterator> Iterator for FilterAdapter<I> {
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
'next_entry: loop {
let res = self.inner.next()?;
for filter in &self.reader.filters {
if let FilterKind::Remove = filter.kind
&& filter.matcher.matches(&res)
{
continue 'next_entry;
}
}
break Some(res);
fn prev(&mut self) -> Option<Rc<LogEntry>> {
if self.curr == 0 {
return None;
}
let entry = self.reader.fill_buf_to_access_index(self.curr)?;
self.curr -= 1;
Some(entry)
}
fn clone(&self) -> Box<dyn LogStream> {
Box::new(Self {
reader: self.reader.clone(),
curr: self.curr,
})
}
}