Playground
use std::iter::IntoIterator;
use std::marker::PhantomData;
let _execution_state = ExecutionState::clean_slate(
true);
let execution_state = ExecutionState::PreviousState {
step_ids_done:
vec![
1,
2],
step_ids_not_done:
vec![
3],
step_values:
vec![
Box::new(
234u32),
Box::new(
3.5f64)],
match execute::<
String>(execution_state, Receiver::new(
3)) {
Ok(value) =>
println!(
"main: {}", value),
Err(InterruptSignal) =>
println!(
"main: interrupted!"),
execution_state: ExecutionState,
mut interrupt_rx: Receiver<InterruptSignal>,
) ->
Result<T, InterruptSignal>
let steps =
vec![step(
1, step_1), step(
2, step_2), step(
3, step_3)];
let (steps_to_execute, params) = filter_what_to_do(execution_state, steps);
.try_fold(params, |last_param, step| {
interruptibility_check(&
mut interrupt_rx)?;
Ok(step.exec(last_param))
.map(|boxed_any| *boxed_any.downcast().unwrap())
execution_state: ExecutionState,
mut steps:
Vec<
Box<
dyn StepErased>>,
) -> (
Vec<
Box<
dyn StepErased>>,
Box<
dyn Any>) {
ExecutionState::CleanSlate { params } => (steps, params),
ExecutionState::PreviousState {
steps.retain(|step| step_ids_not_done.contains(&step.id()));
let params = step_values.pop().unwrap();
fn step_1(takes_bool:
bool) ->
u32 {
println!(
"step_1 ({takes_bool}: bool) -> {number}");
fn step_2(takes_u32:
u32) ->
f64 {
println!(
"step_2 ({takes_u32}: u32) -> {float}");
fn step_3(takes_f64:
f64) ->
String {
let string =
String::from(
"magic");
println!(
"step_3 ({takes_f64}: f64) -> {string}");
fn step<F, I, O>(id: u32, f: F) -> Box<dyn StepErased>
Box::new(StepWrapper::new(id, f))
fn exec(&self, input: Self::Input) -> Self::Output;
impl<F, I, O> Step for StepWrapper<F, I, O>
fn exec(&self, input: Self::Input) -> Self::Output {
fn exec(&self, input: Box<dyn Any>) -> Box<dyn Any>;
struct StepWrapper<F, I, O>(u32, F, PhantomData<(I, O)>);
impl<F, I, O> StepWrapper<F, I, O> {
fn new(id: u32, f: F) -> Self {
impl<F, I, O> StepErased for StepWrapper<F, I, O>
StepWrapper<F, I, O>: Step<Input = I, Output = O>,
fn exec(&self, input: Box<dyn Any>) -> Box<dyn Any> {
let input = *input.downcast::<I>().unwrap();
let output = Step::exec(self, input);
struct Receiver<T>(u32, PhantomData<T>);
pub fn new(n: u32) -> Self {
fn interruptibility_check(rx: &mut Receiver<InterruptSignal>) -> Result<(), InterruptSignal> {
step_ids_not_done:
Vec<
u32>,
step_values:
Vec<
Box<
dyn Any>>,
fn clean_slate<I>(i: I) -> Self
ExecutionState::CleanSlate {