use std::future::Future;
use std::pin::Pin;
use std::sync::Arc;
use tokio::sync::Semaphore;
use blazen_events::AnyEvent;
use crate::context::Context;
use crate::error::WorkflowError;
#[derive(Debug)]
pub enum StepOutput {
Single(Box<dyn AnyEvent>),
Multiple(Vec<Box<dyn AnyEvent>>),
None,
}
pub type StepFn = Arc<
dyn Fn(
Box<dyn AnyEvent>,
Context,
) -> Pin<Box<dyn Future<Output = Result<StepOutput, WorkflowError>> + Send>>
+ Send
+ Sync,
>;
#[derive(Clone)]
pub struct StepRegistration {
pub name: String,
pub accepts: Vec<&'static str>,
pub emits: Vec<&'static str>,
pub handler: StepFn,
pub max_concurrency: usize,
pub semaphore: Option<Arc<Semaphore>>,
}
impl std::fmt::Debug for StepRegistration {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("StepRegistration")
.field("name", &self.name)
.field("accepts", &self.accepts)
.field("emits", &self.emits)
.field("max_concurrency", &self.max_concurrency)
.finish_non_exhaustive()
}
}
impl StepRegistration {
#[must_use]
pub fn new(
name: String,
accepts: Vec<&'static str>,
emits: Vec<&'static str>,
handler: StepFn,
max_concurrency: usize,
) -> Self {
let semaphore = if max_concurrency > 0 {
Some(Arc::new(Semaphore::new(max_concurrency)))
} else {
None
};
Self {
name,
accepts,
emits,
handler,
max_concurrency,
semaphore,
}
}
}