tcrm_task/tasks/state.rs
1/// Execution state of a task throughout its lifecycle
2///
3/// `TaskState` tracks the progression of a task from creation through completion.
4/// States transition in a defined order, enabling event-driven tasks execution.
5///
6/// # State Transitions
7///
8/// ```text
9/// Pending → Initiating → Running → [Ready] → Finished
10/// ↘
11/// → Finished
12/// ```
13///
14/// The Ready state is optional and only occurs for long-running processes
15/// with a configured ready indicator.
16///
17/// # Examples
18///
19/// ## State Monitoring
20/// ```rust
21/// use tcrm_task::tasks::{config::TaskConfig, tokio::executor::TaskExecutor, state::TaskState, control::TaskStatusInfo};
22/// use tokio::sync::mpsc;
23///
24/// #[tokio::main]
25/// async fn main() {
26/// #[cfg(windows)]
27/// let config = TaskConfig::new("cmd").args(["/C", "echo", "hello"]);
28/// #[cfg(unix)]
29/// let config = TaskConfig::new("echo").args(["hello"]);
30///
31/// let (tx, _rx) = mpsc::channel(100);
32/// let executor = TaskExecutor::new(config, tx);
33///
34/// // Initially pending
35/// assert_eq!(executor.get_task_state(), TaskState::Pending);
36///
37/// // After calling coordinate_start(), state will progress through:
38/// // Pending → Initiating → Running → Finished
39/// }
40/// ```
41///
42/// ## Basic State Checking
43/// ```rust
44/// use tcrm_task::tasks::{
45/// config::TaskConfig,
46/// tokio::executor::TaskExecutor,
47/// state::TaskState,
48/// control::TaskStatusInfo
49/// };
50/// use tokio::sync::mpsc;
51///
52/// #[tokio::main]
53/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
54/// #[cfg(windows)]
55/// let config = TaskConfig::new("cmd").args(["/C", "echo", "hello"]);
56/// #[cfg(unix)]
57/// let config = TaskConfig::new("echo").args(["hello"]);
58///
59/// let (tx, _rx) = mpsc::channel(100);
60/// let executor = TaskExecutor::new(config, tx);
61///
62/// // Check initial state
63/// let state = executor.get_task_state();
64/// assert_eq!(state, TaskState::Pending);
65/// println!("Task is in {:?} state", state);
66///
67/// Ok(())
68/// }
69/// ```
70#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
71#[repr(u8)]
72#[derive(Debug, Clone, Copy, PartialEq, Eq)]
73pub enum TaskState {
74 /// Task has been created but not yet started
75 ///
76 /// Initial state when `TaskSpawner` is created. The task configuration
77 /// exists but no process has been spawned yet.
78 Pending = 0,
79
80 /// Task is being initialized and validated
81 ///
82 /// Transitional state during `start_direct()` when configuration is being
83 /// validated and the process is being prepared for spawning.
84 Initiating = 1,
85
86 /// Process is running and executing
87 ///
88 /// The system process has been spawned and is actively executing.
89 /// Output events may be emitted during this state.
90 Running = 2,
91
92 /// Process is running and executing
93 ///
94 /// Only reached by long-running processes that have a ready indicator
95 /// configured. Indicates the process has completed initialization
96 /// and is ready for work (e.g., web server listening on port).
97 /// Useful when orchestrating dependent tasks.
98 Ready = 3,
99
100 /// Task execution has completed
101 ///
102 /// Final state reached when the process exits normally, is terminated,
103 /// or encounters an error. No further state transitions occur.
104 Finished = 4,
105
106 /// Invalid state (should not occur)
107 ///
108 /// This state indicates an error in state management. It should not be
109 /// possible to reach this state during normal operation.
110 ///
111 /// Internal use only.
112 Invalid = 127,
113}
114
115impl From<u8> for TaskState {
116 /// Converts a `u8` value to a `TaskState` enum.
117 ///
118 /// Returns `TaskState::Invalid` for unknown values.
119 fn from(value: u8) -> Self {
120 match value {
121 0 => TaskState::Pending,
122 1 => TaskState::Initiating,
123 2 => TaskState::Running,
124 3 => TaskState::Ready,
125 4 => TaskState::Finished,
126 _ => TaskState::Invalid,
127 }
128 }
129}
130
131impl From<TaskState> for u8 {
132 /// Converts a `TaskState` enum to its corresponding `u8` value.
133 fn from(state: TaskState) -> Self {
134 state as u8
135 }
136}
137
138/// Represents the state of a spawned process during its lifecycle.
139///
140/// `ProcessState` is used to track whether a process is running, paused, or stopped.
141#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
142#[derive(Debug, Clone, Copy, PartialEq, Eq)]
143pub enum ProcessState {
144 /// The process is not running.
145 Stopped = 0,
146
147 /// The process is running.
148 Running = 1,
149
150 /// The process is paused.
151 Pause = 2,
152
153 /// Invalid state (should not occur).
154 Invalid = 127,
155}
156
157impl From<u8> for ProcessState {
158 /// Converts a `u8` value to a `ProcessState` enum.
159 ///
160 /// Returns `ProcessState::Stopped` for unknown values.
161 fn from(value: u8) -> Self {
162 match value {
163 0 => ProcessState::Stopped,
164 1 => ProcessState::Running,
165 2 => ProcessState::Pause,
166 _ => ProcessState::Invalid,
167 }
168 }
169}
170
171impl From<ProcessState> for u8 {
172 /// Converts a `ProcessState` enum to its corresponding `u8` value.
173 fn from(state: ProcessState) -> Self {
174 state as u8
175 }
176}