rust_supervisor/child_runner/run_exit.rs
1//! Task run exit classification.
2//!
3//! This module converts task results and runtime failures into a typed exit
4//! model that policy code can consume without string parsing.
5
6use crate::error::types::{TaskFailure, TaskFailureKind};
7use crate::task::factory::TaskResult;
8use serde::{Deserialize, Serialize};
9
10/// Exit classification for one task run.
11#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
12pub enum TaskExit {
13 /// The task returned success.
14 Succeeded,
15 /// The task returned cancellation.
16 Cancelled,
17 /// The task returned a typed failure.
18 Failed(TaskFailure),
19 /// The task panicked before returning a result.
20 Panicked(String),
21 /// The task timed out.
22 TimedOut,
23}
24
25impl TaskExit {
26 /// Converts a task result into an exit classification.
27 ///
28 /// # Arguments
29 ///
30 /// - `result`: Task result returned by the task future.
31 ///
32 /// # Returns
33 ///
34 /// Returns the corresponding [`TaskExit`].
35 ///
36 /// # Examples
37 ///
38 /// ```
39 /// let exit = rust_supervisor::child_runner::run_exit::TaskExit::from_task_result(
40 /// rust_supervisor::task::factory::TaskResult::Succeeded,
41 /// );
42 /// assert!(exit.is_success());
43 /// ```
44 pub fn from_task_result(result: TaskResult) -> Self {
45 match result {
46 TaskResult::Succeeded => Self::Succeeded,
47 TaskResult::Cancelled => Self::Cancelled,
48 TaskResult::Failed(failure) => Self::Failed(failure),
49 }
50 }
51
52 /// Returns whether this exit represents a successful task.
53 ///
54 /// # Arguments
55 ///
56 /// This function has no arguments.
57 ///
58 /// # Returns
59 ///
60 /// Returns `true` only for [`TaskExit::Succeeded`].
61 pub fn is_success(&self) -> bool {
62 matches!(self, Self::Succeeded)
63 }
64
65 /// Returns the failure kind for policy evaluation.
66 ///
67 /// # Arguments
68 ///
69 /// This function has no arguments.
70 ///
71 /// # Returns
72 ///
73 /// Returns `None` for successful exits.
74 pub fn failure_kind(&self) -> Option<TaskFailureKind> {
75 match self {
76 Self::Succeeded => None,
77 Self::Cancelled => Some(TaskFailureKind::Cancelled),
78 Self::Failed(failure) => Some(failure.kind.clone()),
79 Self::Panicked(_message) => Some(TaskFailureKind::Panic),
80 Self::TimedOut => Some(TaskFailureKind::Timeout),
81 }
82 }
83}