use {crate::mm::Edit, std::time::Instant};
#[derive(Debug, Clone)]
pub struct HistoryEntry {
edits: Vec<Edit>,
timestamp: Instant,
seq_num: u64,
}
impl HistoryEntry {
#[must_use]
pub fn edits(&self) -> &[Edit] {
&self.edits
}
#[must_use]
pub const fn timestamp(&self) -> Instant {
self.timestamp
}
#[must_use]
pub const fn seq_num(&self) -> u64 {
self.seq_num
}
}
#[derive(Debug)]
pub struct History {
entries: Vec<HistoryEntry>,
max_entries: usize,
seq_counter: u64,
}
impl Default for History {
fn default() -> Self {
Self::new()
}
}
impl History {
pub const DEFAULT_MAX_ENTRIES: usize = 10000;
#[must_use]
pub fn new() -> Self {
Self::with_max_entries(Self::DEFAULT_MAX_ENTRIES)
}
#[must_use]
pub fn with_max_entries(max_entries: usize) -> Self {
Self {
entries: Vec::new(),
max_entries: max_entries.max(1),
seq_counter: 0,
}
}
pub fn record(&mut self, edits: Vec<Edit>) {
if edits.is_empty() {
return;
}
self.seq_counter += 1;
let entry = HistoryEntry {
edits,
timestamp: Instant::now(),
seq_num: self.seq_counter,
};
self.entries.push(entry);
while self.entries.len() > self.max_entries {
self.entries.remove(0);
}
}
#[must_use]
pub fn entries(&self) -> &[HistoryEntry] {
&self.entries
}
#[must_use]
pub fn last(&self) -> Option<&HistoryEntry> {
self.entries.last()
}
#[must_use]
pub fn get(&self, index: usize) -> Option<&HistoryEntry> {
self.entries.get(index)
}
pub fn clear(&mut self) {
self.entries.clear();
}
#[must_use]
pub const fn len(&self) -> usize {
self.entries.len()
}
#[must_use]
pub const fn is_empty(&self) -> bool {
self.entries.is_empty()
}
#[must_use]
pub const fn max_entries(&self) -> usize {
self.max_entries
}
pub fn set_max_entries(&mut self, max: usize) {
self.max_entries = max.max(1);
while self.entries.len() > self.max_entries {
self.entries.remove(0);
}
}
#[must_use]
pub const fn seq_counter(&self) -> u64 {
self.seq_counter
}
#[must_use]
pub fn since(&self, seq_num: u64) -> Vec<&HistoryEntry> {
self.entries
.iter()
.filter(|e| e.seq_num > seq_num)
.collect()
}
#[must_use]
pub fn between(&self, start: Instant, end: Instant) -> Vec<&HistoryEntry> {
self.entries
.iter()
.filter(|e| e.timestamp >= start && e.timestamp <= end)
.collect()
}
}