use crate::error::{RunError, RunFinishError, RunStartError, TracedRunError};
use crate::input::RunSeed;
use crate::limits::{RuleAttemptCount, StepCount};
use crate::program::{Program, RunResult};
use crate::trace::{BorrowedTraceEvent, RuntimeStateView};
use super::admission::RuleAttemptSeed;
use super::construction::{RuleAttemptRunSession, StepwiseRunSession};
use super::engine::{AttemptSession, BorrowedProgram, OwnedProgram, Session};
use super::transition::{
BorrowedRuleAttemptTransition, BorrowedStepTransition, OwnedRuleAttemptTransition,
OwnedStepTransition,
};
pub struct BorrowedRunSession<'program> {
pub(super) session: Session<BorrowedProgram<'program>>,
}
pub struct OwnedRunSession {
pub(super) session: Session<OwnedProgram>,
}
pub struct BorrowedRuleAttemptSession<'program> {
pub(super) session: AttemptSession<BorrowedProgram<'program>>,
}
pub struct OwnedRuleAttemptSession {
pub(super) session: AttemptSession<OwnedProgram>,
}
pub(crate) fn finish_borrowed_run(program: &Program, seed: RunSeed) -> Result<RunResult, RunError> {
Session::new(BorrowedProgram { program }, seed)
.map_err(RunError::from)?
.finish()
.map_err(RunError::from)
}
pub(crate) fn run_with_borrowed_trace<'program, F, E>(
program: &'program Program,
seed: RunSeed,
trace: F,
) -> Result<RunResult, TracedRunError<E>>
where
F: for<'run> FnMut(BorrowedTraceEvent<'program, 'run>) -> Result<(), E>,
{
Session::new(BorrowedProgram { program }, seed)
.map_err(RunError::from)
.map_err(TracedRunError::Run)?
.run_with_borrowed_trace(trace)
}
impl<'program> BorrowedRunSession<'program> {
pub(crate) fn new(program: &'program Program, seed: RunSeed) -> Result<Self, RunStartError> {
Ok(Self {
session: Session::new(BorrowedProgram { program }, seed)?,
})
}
#[must_use]
pub const fn completed_steps(&self) -> StepCount {
self.session.completed_steps()
}
#[must_use]
pub fn program(&self) -> &'program Program {
self.session.program.program
}
#[must_use]
pub fn state(&self) -> RuntimeStateView<'_> {
self.session.state()
}
#[must_use]
pub fn step(self) -> BorrowedStepTransition<'program> {
self.step_transition()
}
pub fn finish(self) -> Result<RunResult, RunFinishError> {
self.session.finish()
}
}
impl<'program> BorrowedRuleAttemptSession<'program> {
pub(crate) fn new(
program: &'program Program,
seed: RuleAttemptSeed,
) -> Result<Self, RunStartError> {
let (seed, limit) = seed.into_parts();
Ok(Self {
session: AttemptSession::new(BorrowedProgram { program }, seed, limit)?,
})
}
#[must_use]
pub const fn completed_steps(&self) -> StepCount {
self.session.completed_steps()
}
#[must_use]
pub const fn completed_attempts(&self) -> RuleAttemptCount {
self.session.completed_attempts()
}
#[must_use]
pub fn program(&self) -> &'program Program {
self.session.program.program
}
#[must_use]
pub fn state(&self) -> RuntimeStateView<'_> {
self.session.state()
}
#[must_use]
pub fn step(self) -> BorrowedRuleAttemptTransition<'program> {
self.step_transition()
}
}
impl OwnedRunSession {
pub(crate) fn new(program: Program, seed: RunSeed) -> Result<Self, RunStartError> {
Ok(Self {
session: Session::new(OwnedProgram { program }, seed)?,
})
}
#[must_use]
pub const fn completed_steps(&self) -> StepCount {
self.session.completed_steps()
}
#[must_use]
pub fn program(&self) -> &Program {
self.session.program()
}
#[must_use]
pub fn into_program(self) -> Program {
let (program, _core) = self.session.into_program_core();
program
}
#[must_use]
pub fn state(&self) -> RuntimeStateView<'_> {
self.session.state()
}
#[must_use]
pub fn step(self) -> OwnedStepTransition {
self.step_transition()
}
pub fn finish(self) -> Result<RunResult, RunFinishError> {
self.session.finish()
}
}
impl OwnedRuleAttemptSession {
pub(crate) fn new(program: Program, seed: RuleAttemptSeed) -> Result<Self, RunStartError> {
let (seed, limit) = seed.into_parts();
Ok(Self {
session: AttemptSession::new(OwnedProgram { program }, seed, limit)?,
})
}
#[must_use]
pub const fn completed_steps(&self) -> StepCount {
self.session.completed_steps()
}
#[must_use]
pub const fn completed_attempts(&self) -> RuleAttemptCount {
self.session.completed_attempts()
}
#[must_use]
pub fn program(&self) -> &Program {
self.session.program()
}
#[must_use]
pub fn into_program(self) -> Program {
let (program, _core) = self.session.into_program_core();
program
}
#[must_use]
pub fn state(&self) -> RuntimeStateView<'_> {
self.session.state()
}
#[must_use]
pub fn step(self) -> OwnedRuleAttemptTransition {
self.step_transition()
}
}