Skip to main content

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

1use crate::fs::common::LogFile;
2use crate::fs::{LogFSError, Unblocker};
3use crate::io::{LogIOError, LogPath};
4use crate::logs::LogEvent;
5use serde::de::DeserializeOwned;
6use std::sync::Arc;
7
8/// Holds a [LogFile] which is changed when [NewestFile::maybe_next] is called with a [LogPath]
9/// which is newer than the current one. Calling [Iterator::next] on this type will call the inner file or
10/// return [None] if the file is not yet loaded.
11pub struct NewestFile<R = LogEvent>
12where
13    R: DeserializeOwned,
14{
15    current_path: Option<LogPath>,
16    current_file: Option<LogFile<R>>,
17    unblocker: Arc<dyn Unblocker>,
18}
19
20impl NewestFile {
21    pub fn new(blocker: impl Into<Arc<dyn Unblocker>>) -> NewestFile<LogEvent> {
22        NewestFile::new_typed::<LogEvent>(blocker)
23    }
24
25    pub fn new_raw(blocker: impl Into<Arc<dyn Unblocker>>) -> NewestFile<serde_json::Value> {
26        NewestFile::new_typed::<serde_json::Value>(blocker)
27    }
28
29    pub fn new_typed<R>(blocker: impl Into<Arc<dyn Unblocker>>) -> NewestFile<R>
30    where
31        R: DeserializeOwned,
32    {
33        NewestFile {
34            current_path: None,
35            current_file: None,
36            unblocker: blocker.into(),
37        }
38    }
39}
40
41impl<R> NewestFile<R>
42where
43    R: DeserializeOwned,
44{
45    /// Checks the provided path with the currently held path, and if the path is newer, open the
46    /// file and start reading events from it. Returns `true` if the file was changed.
47    pub fn maybe_new(&mut self, path: &LogPath) -> Result<bool, LogFSError> {
48        if self.current_path.is_none()
49            || self
50                .current_path
51                .as_ref()
52                .is_some_and(|current| path > current)
53        {
54            self.current_path = Some(path.clone());
55            self.current_file = Some(LogFile::new_typed::<R, _>(path, self.unblocker.clone())?);
56
57            return Ok(true);
58        }
59
60        Ok(false)
61    }
62}
63
64impl<R> Iterator for NewestFile<R>
65where
66    R: DeserializeOwned,
67{
68    type Item = Result<R, LogIOError>;
69
70    fn next(&mut self) -> Option<Self::Item> {
71        self.current_file.as_mut()?.next()
72    }
73}