use std::collections::VecDeque;
use std::time::{Duration, Instant, SystemTime};
use crate::dev::{Recorded, RecordedResult};
use crate::error::Result;
use super::DEFAULT_HISTORY_DEPTH;
pub(super) struct History<T> {
entries: VecDeque<RecordedResult<T>>,
depth: usize,
expire: Option<Instant>,
}
impl<T: Clone> History<T> {
pub fn new() -> Self {
Self {
entries: VecDeque::new(),
depth: DEFAULT_HISTORY_DEPTH,
expire: None,
}
}
pub fn push(&mut self, time: SystemTime, result: Result<T>, valid_for: Option<Duration>) {
self.entries.push_back(Recorded::new(time, result));
while self.entries.len() > self.depth {
self.entries.pop_front();
}
self.expire = valid_for.map(|valid_for| Instant::now() + valid_for);
}
pub fn is_empty(&self) -> bool {
self.entries.is_empty()
}
pub fn latest(&self) -> Option<&Result<T>> {
let entry = self.entries.back()?;
match self.expire {
Some(expire) if expire <= Instant::now() => None,
_ => Some(&entry.value),
}
}
pub fn entries(&self, max: usize) -> Vec<RecordedResult<T>> {
let skip = self.entries.len().saturating_sub(max);
self.entries.iter().skip(skip).cloned().collect()
}
pub fn clear(&mut self) {
self.entries.clear();
self.expire = None;
}
pub fn depth(&self) -> usize {
self.depth
}
pub fn set_depth(&mut self, depth: usize) {
self.depth = depth;
while self.entries.len() > depth {
self.entries.pop_front();
}
}
}