use super::Trace;
use super::trace::{apply, valid_mapping_ends};
use crate::base::Context;
#[derive(Debug)]
pub struct Replay {
trace: Trace,
context: Context,
next: usize,
}
impl Replay {
pub fn new(trace: Trace) -> Self {
Self {
context: trace.initial.clone(),
trace,
next: 0,
}
}
pub fn trace(&self) -> &Trace {
&self.trace
}
pub fn context_at(&mut self, step: Option<usize>) -> Option<&Context> {
let end = match step {
Some(step) => step.checked_add(1)?,
None => 0,
};
if end > self.trace.steps.len() {
return None;
}
if end < self.next {
self.context = self.trace.initial.clone();
self.next = 0;
}
for step in &self.trace.steps[self.next..end] {
for change in &step.changes {
apply(&mut self.context.root, change);
}
}
self.next = end;
Some(&self.context)
}
pub fn mapping_context_at(&mut self, step: usize, mapping: usize) -> Option<Context> {
let at = self.trace.steps.get(step)?;
if !valid_mapping_ends(at) {
return None;
}
let end = *at.mapping_ends.get(mapping)? as usize;
let mut context = self.context_at(step.checked_sub(1))?.clone();
for change in &self.trace.steps[step].changes[..end] {
apply(&mut context.root, change);
}
Some(context)
}
}