use std::sync::Arc;
use crate::tokio::step::{AsyncStep, DeciderCallback, DynAsyncCallback};
use crate::tokio::step::step_builder::AsyncStepBuilderTrait;
pub trait AsyncSimpleStepBuilderTrait<I, O> {
fn tasklet(self, step_callback: Box<DynAsyncCallback<()>>) -> Self;
}
pub struct AsyncSimpleStepBuilder {
callback: Option<Box<DynAsyncCallback<()>>>,
step: AsyncStep,
}
impl AsyncStepBuilderTrait for AsyncSimpleStepBuilder {
fn decider(self, decider: DeciderCallback) -> Self {
AsyncSimpleStepBuilder {
callback: self.callback,
step: AsyncStep {
decider: Some(decider),
..self.step
}
}
}
fn throw_tolerant(self) -> Self {
AsyncSimpleStepBuilder {
callback: self.callback,
step: AsyncStep {
throw_tolerant: Some(true),
..self.step
}
}
}
#[inline]
fn get(name: String) -> Self {
AsyncSimpleStepBuilder {
callback: None,
step: AsyncStep {
name,
callback: None,
decider: None,
throw_tolerant: None,
}
}
}
fn validate(self) -> Self {
if self.callback.is_none() {
panic!("Tasklet is required");
}
if self.step.name.is_empty() {
panic!("Name is required");
}
return self;
}
fn build(self) -> AsyncStep {
let current_self = self.validate();
let mut step = current_self.step;
let callback = Arc::new(current_self.callback.unwrap());
step.callback = Some(Box::new(move || {
let callback = Arc::clone(&callback);
return Box::pin(async move {
let callback = callback;
callback().await;
return Ok(());
});
}));
return step;
}
}
impl AsyncSimpleStepBuilderTrait<fn(), fn()> for AsyncSimpleStepBuilder {
fn tasklet(self, step_callback: Box<DynAsyncCallback<()>>) -> Self {
return AsyncSimpleStepBuilder {
callback: Some(step_callback),
step: AsyncStep {
..self.step
}
};
}
}
pub fn get(name: String) -> AsyncSimpleStepBuilder {
AsyncSimpleStepBuilder::get(name)
}