use crate::CancellationGuard;
use std::ops::Deref;
pub trait Procedure<P> {
type Output;
type State;
const NAME: &'static str;
fn initialise(&self, _problem: &mut P, _state: &mut Self::State) {}
fn step(&self, problem: &mut P, state: &mut Self::State, guard: CancellationGuard<'_>);
fn finalise(&self, problem: &mut P, state: &Self::State) -> Self::Output;
}
pub trait FallibleProcedure<P> {
type Error: std::error::Error + 'static + Send + Sync;
type Output;
type State;
const NAME: &'static str;
fn initialise_fallible(
&self,
_problem: &mut P,
_state: &mut Self::State,
) -> Result<(), Self::Error>;
fn step_fallible(
&self,
problem: &mut P,
state: &mut Self::State,
guard: CancellationGuard<'_>,
) -> Result<(), Self::Error>;
fn finalise_fallible(
&self,
problem: &mut P,
state: &Self::State,
) -> Result<Self::Output, Self::Error>;
}
pub struct Infallible<Proc>(pub Proc);
impl<Proc> Deref for Infallible<Proc> {
type Target = Proc;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<Proc, P> FallibleProcedure<P> for Infallible<Proc>
where
Proc: Procedure<P>,
{
const NAME: &'static str = <Proc as Procedure<P>>::NAME;
type State = <Proc as Procedure<P>>::State;
type Output = <Proc as Procedure<P>>::Output;
type Error = std::convert::Infallible;
fn initialise_fallible(
&self,
problem: &mut P,
state: &mut Self::State,
) -> Result<(), Self::Error> {
let _: () = self.initialise(problem, state);
Ok(())
}
fn step_fallible(
&self,
problem: &mut P,
state: &mut Self::State,
guard: CancellationGuard<'_>,
) -> Result<(), Self::Error> {
let _: () = self.step(problem, state, guard);
Ok(())
}
fn finalise_fallible(
&self,
problem: &mut P,
state: &Self::State,
) -> Result<Self::Output, Self::Error> {
Ok(self.finalise(problem, state))
}
}