use crate::fs::common::LogFile;
use crate::fs::{LogFSError, Unblocker};
use crate::io::{LogIOError, LogPath};
use crate::logs::LogEvent;
use serde::de::DeserializeOwned;
use std::sync::Arc;
pub struct NewestFile<R = LogEvent>
where
R: DeserializeOwned,
{
current_path: Option<LogPath>,
current_file: Option<LogFile<R>>,
unblocker: Arc<dyn Unblocker>,
}
impl NewestFile {
pub fn new(blocker: impl Into<Arc<dyn Unblocker>>) -> NewestFile<LogEvent> {
NewestFile::new_typed::<LogEvent>(blocker)
}
pub fn new_raw(blocker: impl Into<Arc<dyn Unblocker>>) -> NewestFile<serde_json::Value> {
NewestFile::new_typed::<serde_json::Value>(blocker)
}
pub fn new_typed<R>(blocker: impl Into<Arc<dyn Unblocker>>) -> NewestFile<R>
where
R: DeserializeOwned,
{
NewestFile {
current_path: None,
current_file: None,
unblocker: blocker.into(),
}
}
}
impl<R> NewestFile<R>
where
R: DeserializeOwned,
{
pub fn maybe_new(&mut self, path: &LogPath) -> Result<bool, LogFSError> {
if self.current_path.is_none()
|| self
.current_path
.as_ref()
.is_some_and(|current| path > current)
{
self.current_path = Some(path.clone());
self.current_file = Some(LogFile::new_typed::<R, _>(path, self.unblocker.clone())?);
return Ok(true);
}
Ok(false)
}
}
impl<R> Iterator for NewestFile<R>
where
R: DeserializeOwned,
{
type Item = Result<R, LogIOError>;
fn next(&mut self) -> Option<Self::Item> {
self.current_file.as_mut()?.next()
}
}