actionqueue_core/run/
transitions.rs1use crate::run::state::RunState;
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum RunTransitionError {
11 InvalidTransition {
13 from: RunState,
15 to: RunState,
17 },
18}
19
20impl std::fmt::Display for RunTransitionError {
21 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
22 match self {
23 Self::InvalidTransition { from, to } => {
24 write!(f, "invalid run transition: {from:?} -> {to:?}")
25 }
26 }
27 }
28}
29
30impl std::error::Error for RunTransitionError {}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34#[must_use]
35pub struct Transition {
36 from: RunState,
37 to: RunState,
38}
39
40impl Transition {
41 pub fn new(from: RunState, to: RunState) -> Result<Self, RunTransitionError> {
44 if is_valid_transition(from, to) {
45 Ok(Transition { from, to })
46 } else {
47 Err(RunTransitionError::InvalidTransition { from, to })
48 }
49 }
50
51 pub fn from(&self) -> RunState {
53 self.from
54 }
55
56 pub fn to(&self) -> RunState {
58 self.to
59 }
60}
61
62pub fn is_valid_transition(from: RunState, to: RunState) -> bool {
85 if from.is_terminal() {
87 return false;
88 }
89
90 matches!(
91 (from, to),
92 (RunState::Scheduled, RunState::Ready)
93 | (RunState::Scheduled, RunState::Canceled)
94 | (RunState::Ready, RunState::Leased)
95 | (RunState::Ready, RunState::Canceled)
96 | (RunState::Leased, RunState::Running)
97 | (RunState::Leased, RunState::Ready)
98 | (RunState::Leased, RunState::Canceled)
99 | (RunState::Running, RunState::RetryWait)
100 | (RunState::Running, RunState::Suspended)
101 | (RunState::Running, RunState::Completed)
102 | (RunState::Running, RunState::Failed)
103 | (RunState::Running, RunState::Canceled)
104 | (RunState::RetryWait, RunState::Ready)
105 | (RunState::RetryWait, RunState::Failed)
106 | (RunState::RetryWait, RunState::Canceled)
107 | (RunState::Suspended, RunState::Ready)
108 | (RunState::Suspended, RunState::Canceled)
109 )
110}
111
112pub fn valid_transitions(from: RunState) -> Vec<RunState> {
114 let states = [
115 RunState::Scheduled,
116 RunState::Ready,
117 RunState::Leased,
118 RunState::Running,
119 RunState::RetryWait,
120 RunState::Suspended,
121 RunState::Completed,
122 RunState::Failed,
123 RunState::Canceled,
124 ];
125
126 states.into_iter().filter(|&to| is_valid_transition(from, to)).collect()
127}