#[derive(Clone, Serialize, Deserialize, Debug, Default)]
#[serde(transparent)]
pub struct BoundedExecutionHistory(std::collections::VecDeque<ExecutionStep>);
impl BoundedExecutionHistory {
#[must_use]
pub const fn new() -> Self {
Self(std::collections::VecDeque::new())
}
#[must_use]
pub fn len(&self) -> usize {
self.0.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
#[must_use]
pub fn iter(&self) -> std::collections::vec_deque::Iter<'_, ExecutionStep> {
self.0.iter()
}
#[must_use]
pub const fn as_deque(&self) -> &std::collections::VecDeque<ExecutionStep> {
&self.0
}
#[must_use]
pub fn with_step(self, step: ExecutionStep, limit: usize) -> Self {
let current_len = self.0.len();
let excess = current_len.saturating_add(1).saturating_sub(limit);
let new_deque: std::collections::VecDeque<_> = self
.0
.into_iter()
.chain(std::iter::once(step))
.skip(excess)
.collect();
Self(new_deque)
}
#[must_use]
pub fn with_replaced(self, history: std::collections::VecDeque<ExecutionStep>, limit: usize) -> Self {
let excess = history.len().saturating_sub(limit);
Self(history.into_iter().skip(excess).collect())
}
}
impl std::ops::Deref for BoundedExecutionHistory {
type Target = std::collections::VecDeque<ExecutionStep>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<'a> IntoIterator for &'a BoundedExecutionHistory {
type Item = &'a ExecutionStep;
type IntoIter = std::collections::vec_deque::Iter<'a, ExecutionStep>;
fn into_iter(self) -> Self::IntoIter {
self.0.iter()
}
}