use crate::error::{TraceSnapshotError, TraceSnapshotRunError, TracedRunError};
use crate::execution::RunSession;
use crate::runtime::RuntimeInput;
use crate::trace::{BorrowedTraceEvent, TraceSnapshotEvent};
use super::Program;
use super::limits::{RunLimits, TraceSnapshotLimits};
use super::result::RunResult;
enum SnapshotTraceCallbackError<E> {
Snapshot(TraceSnapshotError),
Trace(E),
}
impl Program {
pub fn run_with_trace_snapshots<'program, F, E>(
&'program self,
input: RuntimeInput,
limits: TraceSnapshotLimits,
mut trace: F,
) -> Result<RunResult, TraceSnapshotRunError<E>>
where
F: FnMut(TraceSnapshotEvent<'program>) -> Result<(), E>,
{
let result = self.run_with_borrowed_trace(input, limits.run_limits(), |event| {
let snapshot = event
.to_snapshot(limits.snapshot_byte_limit())
.map_err(SnapshotTraceCallbackError::Snapshot)?;
trace(snapshot).map_err(SnapshotTraceCallbackError::Trace)
});
match result {
Ok(result) => Ok(result),
Err(TracedRunError::Run(error)) => Err(TraceSnapshotRunError::Run(error)),
Err(TracedRunError::Trace(SnapshotTraceCallbackError::Snapshot(error))) => {
Err(TraceSnapshotRunError::Snapshot(error))
}
Err(TracedRunError::Trace(SnapshotTraceCallbackError::Trace(error))) => {
Err(TraceSnapshotRunError::Trace(error))
}
}
}
pub fn run_with_borrowed_trace<'program, F, E>(
&'program self,
input: RuntimeInput,
limits: RunLimits,
trace: F,
) -> Result<RunResult, TracedRunError<E>>
where
F: for<'run> FnMut(BorrowedTraceEvent<'program, 'run>) -> Result<(), E>,
{
RunSession::new(self, input, limits)
.map_err(TracedRunError::Run)?
.run_with_borrowed_trace(trace)
}
}