use std::num::ParseIntError;
use apalis_core::{
backend::WireFormatBackend,
task::metadata::{Metadata, MetadataError, MetadataStore},
};
use serde::{Deserialize, Serialize};
#[derive(Debug)]
pub struct StepContext<B>
where
B: WireFormatBackend,
{
pub current_step: usize,
pub backend: B,
pub has_next: bool,
}
impl<B> Clone for StepContext<B>
where
B: WireFormatBackend + Clone,
{
fn clone(&self) -> Self {
Self {
current_step: self.current_step,
backend: self.backend.clone(),
has_next: self.has_next,
}
}
}
impl<B> StepContext<B>
where
B: WireFormatBackend,
{
pub fn new(backend: B, idx: usize, has_next: bool) -> Self {
Self {
current_step: idx,
backend,
has_next,
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct WorkflowContext {
pub step_index: usize,
}
#[non_exhaustive]
#[derive(Debug, thiserror::Error)]
pub enum WorkflowContextError {
#[error("the data for key {WORKFLOW_CONTEXT_KEY} is missing")]
MissingKey,
#[error("Could not parse key {WORKFLOW_CONTEXT_KEY}")]
Parse(#[from] ParseIntError),
#[error("Duplicate entry: {0}")]
DuplicateEntry(#[from] MetadataError),
}
const WORKFLOW_CONTEXT_KEY: &str = "apalis_workflow.context.step_index";
impl Metadata for WorkflowContext {
type Error = WorkflowContextError;
fn extract(map: &MetadataStore) -> Result<Self, Self::Error> {
let step_index = map
.get(WORKFLOW_CONTEXT_KEY)
.ok_or(WorkflowContextError::MissingKey)?
.parse::<usize>()
.map_err(WorkflowContextError::Parse)?;
Ok(Self { step_index })
}
fn inject(&self, map: &mut MetadataStore) -> Result<(), WorkflowContextError> {
map.insert(WORKFLOW_CONTEXT_KEY, self.step_index.to_string())?;
Ok(())
}
}