use super::super::types::{
GraphStepStatus, SequentialGraphState, SequentialGraphStepDefinition, SequentialGraphStepState,
};
use super::index::SequentialGraphStepIndex;
pub(super) fn retry_budget_exhausted(
step_state: &SequentialGraphStepState,
step_definition: &SequentialGraphStepDefinition,
) -> bool {
step_state.status == GraphStepStatus::Failed
&& step_state.attempts
>= step_definition
.retry
.as_ref()
.map_or(1, |retry| retry.max_attempts)
}
fn missing_context(
state: &SequentialGraphState,
step_index: &SequentialGraphStepIndex,
step_definition: &SequentialGraphStepDefinition,
) -> Option<String> {
step_definition
.context_from
.as_deref()
.unwrap_or(&[])
.iter()
.find(|step_id| {
step_index
.state_for(state, step_id)
.is_none_or(|step| step.status != GraphStepStatus::Succeeded)
})
.cloned()
}
pub(super) fn missing_context_at(
state: &SequentialGraphState,
step_index: &SequentialGraphStepIndex,
definition_index: usize,
step_definition: &SequentialGraphStepDefinition,
) -> Option<String> {
let Some(context_sources) = step_index.context_sources_at(definition_index) else {
return missing_context(state, step_index, step_definition);
};
if context_sources.is_empty() {
return None;
}
context_sources
.iter()
.find(|source| {
source
.position
.and_then(|position| state.steps.get(position))
.filter(|step| step.step_id == source.step_id)
.is_none_or(|step| step.status != GraphStepStatus::Succeeded)
})
.map(|source| source.step_id.clone())
}