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