Skip to main content

ed_journals/modules/fs/models/common/
log_file.rs

1use crate::fs::{FileWatcher, LogFSError, Unblocker};
2use crate::io::{LogIOError, LogIter};
3use crate::logs::LogEvent;
4use serde::de::DeserializeOwned;
5use std::fs::File;
6use std::io::BufReader;
7use std::path::Path;
8use std::sync::Arc;
9
10/// Holds both a watcher and an iterator over for the given path. Calling [Iterator::next] on this
11/// will call the inner iterator.
12#[derive(Debug)]
13pub struct LogFile<R = LogEvent>
14where
15    R: DeserializeOwned,
16{
17    iter: LogIter<BufReader<File>, R>,
18    _w: FileWatcher,
19}
20
21impl LogFile {
22    pub fn new<P: AsRef<Path>>(
23        path: P,
24        blocker: impl Into<Arc<dyn Unblocker>>,
25    ) -> Result<LogFile<LogEvent>, LogFSError> {
26        LogFile::new_typed::<LogEvent, _>(path, blocker)
27    }
28
29    pub fn new_raw<P: AsRef<Path>>(
30        path: P,
31        blocker: impl Into<Arc<dyn Unblocker>>,
32    ) -> Result<LogFile<serde_json::Value>, LogFSError> {
33        LogFile::new_typed::<serde_json::Value, _>(path, blocker)
34    }
35
36    pub fn new_typed<R, P>(
37        path: P,
38        blocker: impl Into<Arc<dyn Unblocker>>,
39    ) -> Result<LogFile<R>, LogFSError>
40    where
41        R: DeserializeOwned,
42        P: AsRef<Path>,
43    {
44        let path = path.as_ref();
45        let watcher = FileWatcher::new(path, blocker)?;
46        let file = File::open(path)?;
47        let reader = BufReader::new(file);
48        let iter = LogIter::from(reader);
49
50        Ok(LogFile { _w: watcher, iter })
51    }
52}
53
54impl<R> Iterator for LogFile<R>
55where
56    R: DeserializeOwned,
57{
58    type Item = Result<R, LogIOError>;
59
60    fn next(&mut self) -> Option<Self::Item> {
61        self.iter.next()
62    }
63}