Skip to main content

runx_core/state_machine/sequential_graph/
index.rs

1use std::collections::BTreeMap;
2
3use super::super::types::{
4    SequentialGraphState, SequentialGraphStepDefinition, SequentialGraphStepState,
5};
6
7#[derive(Clone, Debug, Default, PartialEq, Eq)]
8pub struct SequentialGraphStepIndex {
9    positions: BTreeMap<String, usize>,
10    context_positions: Vec<Vec<ContextSourcePosition>>,
11}
12
13#[derive(Clone, Debug, PartialEq, Eq)]
14pub(super) struct ContextSourcePosition {
15    pub(super) step_id: String,
16    pub(super) position: Option<usize>,
17}
18
19impl SequentialGraphStepIndex {
20    #[must_use]
21    pub fn new(steps: &[SequentialGraphStepDefinition]) -> Self {
22        let positions = steps
23            .iter()
24            .enumerate()
25            .map(|(index, step)| (step.id.clone(), index))
26            .collect::<BTreeMap<_, _>>();
27        let context_positions = steps
28            .iter()
29            .map(|step| {
30                step.context_from
31                    .as_deref()
32                    .unwrap_or(&[])
33                    .iter()
34                    .map(|step_id| ContextSourcePosition {
35                        step_id: step_id.clone(),
36                        position: positions.get(step_id).copied(),
37                    })
38                    .collect()
39            })
40            .collect();
41        Self {
42            positions,
43            context_positions,
44        }
45    }
46
47    pub(super) fn state_for<'a>(
48        &self,
49        state: &'a SequentialGraphState,
50        step_id: &str,
51    ) -> Option<&'a SequentialGraphStepState> {
52        self.positions
53            .get(step_id)
54            .and_then(|index| state.steps.get(*index))
55            .filter(|step| step.step_id == step_id)
56    }
57
58    pub(super) fn state_at<'a>(
59        &self,
60        state: &'a SequentialGraphState,
61        position: usize,
62        step_id: &str,
63    ) -> Option<&'a SequentialGraphStepState> {
64        state
65            .steps
66            .get(position)
67            .filter(|step| step.step_id == step_id)
68            .or_else(|| self.state_for(state, step_id))
69    }
70
71    pub(super) fn context_sources_at(
72        &self,
73        definition_index: usize,
74    ) -> Option<&[ContextSourcePosition]> {
75        self.context_positions
76            .get(definition_index)
77            .map(Vec::as_slice)
78    }
79}
80
81#[must_use]
82pub fn create_sequential_graph_step_index(
83    steps: &[SequentialGraphStepDefinition],
84) -> SequentialGraphStepIndex {
85    SequentialGraphStepIndex::new(steps)
86}