Skip to main content

isothrum_runner/
state.rs

1//! The words for what a run is doing and where it stands, shared by the API, the record and the
2//! event stream.
3
4use std::fmt;
5
6use serde::{Deserialize, Serialize};
7
8/// An operation on a run.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize, schemars::JsonSchema)]
10#[serde(rename_all = "snake_case")]
11#[non_exhaustive]
12pub enum Op {
13    /// Start the run.
14    Up,
15    /// Remove everything the run created.
16    Down,
17    /// Stop the run, keeping what it created.
18    Park,
19    /// Start a parked run again.
20    Resume,
21    /// Run the lab's checks.
22    Check,
23    /// Run the set-up again on running machines.
24    Provision,
25}
26
27impl Op {
28    /// The operation as written in events (`up`).
29    #[must_use]
30    pub fn as_str(self) -> &'static str {
31        match self {
32            Op::Up => "up",
33            Op::Down => "down",
34            Op::Park => "park",
35            Op::Resume => "resume",
36            Op::Check => "check",
37            Op::Provision => "provision",
38        }
39    }
40
41    /// The state a run is in while this operation runs.
42    pub(crate) fn during(self) -> Option<RunState> {
43        match self {
44            Op::Up => Some(RunState::Starting),
45            Op::Down => Some(RunState::Stopping),
46            Op::Park => Some(RunState::Parking),
47            Op::Resume => Some(RunState::Resuming),
48            Op::Check | Op::Provision => None,
49        }
50    }
51}
52
53impl fmt::Display for Op {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        f.write_str(self.as_str())
56    }
57}
58
59/// Where a run stands.
60#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, schemars::JsonSchema)]
61#[serde(rename_all = "snake_case")]
62#[non_exhaustive]
63pub enum RunState {
64    /// Being started.
65    Starting,
66    /// Up, every target machine running.
67    Ready,
68    /// Something of it exists, but not every target machine runs (a failed start, a machine down).
69    Failed,
70    /// Being parked.
71    Parking,
72    /// Parked: stopped, what it created kept.
73    Parked,
74    /// Being resumed.
75    Resuming,
76    /// Being removed.
77    Stopping,
78    /// Nothing of it exists.
79    Absent,
80}
81
82impl RunState {
83    /// The state as written in events (`ready`).
84    #[must_use]
85    pub fn as_str(self) -> &'static str {
86        match self {
87            RunState::Starting => "starting",
88            RunState::Ready => "ready",
89            RunState::Failed => "failed",
90            RunState::Parking => "parking",
91            RunState::Parked => "parked",
92            RunState::Resuming => "resuming",
93            RunState::Stopping => "stopping",
94            RunState::Absent => "absent",
95        }
96    }
97}
98
99impl fmt::Display for RunState {
100    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
101        f.write_str(self.as_str())
102    }
103}
104
105/// How a run is parked: the manifest's `lifecycle.park.pause` or `.shutdown` steps.
106#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
107#[serde(rename_all = "snake_case")]
108#[non_exhaustive]
109pub enum Park {
110    /// Suspended, memory kept where the target can (Docker: stopped).
111    Pause,
112    /// Shut down.
113    Shutdown,
114}
115
116impl Park {
117    /// The mode as the manifest names it.
118    #[must_use]
119    pub fn as_str(self) -> &'static str {
120        match self {
121            Park::Pause => "pause",
122            Park::Shutdown => "shutdown",
123        }
124    }
125}
126
127impl fmt::Display for Park {
128    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129        f.write_str(self.as_str())
130    }
131}