apalis_workflow/
step.rs

1use apalis_core::{backend::BackendExt, error::BoxDynError};
2
3use crate::router::WorkflowRouter;
4
5/// A layer to wrap a step
6pub trait Layer<S> {
7    /// The resulting step type after layering.
8    type Step;
9    /// Wrap the given step with this layer.
10    fn layer(&self, step: S) -> Self::Step;
11}
12
13/// A workflow step
14///
15/// A single unit of work in a workflow pipeline.
16pub trait Step<Input, B>
17where
18    B: BackendExt,
19{
20    /// The response type produced by the step.
21    type Response;
22    /// The error type produced by the step.
23    type Error;
24
25    /// Register the step with the workflow router.
26    fn register(&mut self, router: &mut WorkflowRouter<B>) -> Result<(), BoxDynError>;
27}
28
29/// A no-op identity layer.
30#[derive(Clone, Debug)]
31pub struct Identity;
32
33impl<S> Layer<S> for Identity {
34    type Step = S;
35
36    fn layer(&self, step: S) -> Self::Step {
37        step
38    }
39}
40
41/// Two steps chained together.
42#[derive(Clone, Debug)]
43pub struct Stack<Inner, Outer> {
44    inner: Inner,
45    outer: Outer,
46}
47impl<Inner, Outer> Stack<Inner, Outer> {
48    /// Create a new `Stack`.
49    pub const fn new(inner: Inner, outer: Outer) -> Self {
50        Self { inner, outer }
51    }
52}
53
54impl<S, Inner, Outer> Layer<S> for Stack<Inner, Outer>
55where
56    Inner: Layer<S>,
57    Outer: Layer<Inner::Step>,
58{
59    type Step = Outer::Step;
60
61    fn layer(&self, service: S) -> Self::Step {
62        let inner = self.inner.layer(service);
63
64        self.outer.layer(inner)
65    }
66}