Skip to main content

mecha10_behavior_runtime/
status.rs

1//! Node status types for behavior execution
2//!
3//! This module defines the possible states a behavior node can be in during execution.
4
5use serde::{Deserialize, Serialize};
6use std::fmt;
7
8/// Status returned by behavior nodes after each tick.
9///
10/// This follows the standard behavior tree status model with three states.
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
12pub enum NodeStatus {
13    /// The behavior completed successfully.
14    ///
15    /// For example:
16    /// - A movement command reached its goal
17    /// - An object was successfully detected
18    /// - A message was successfully sent
19    Success,
20
21    /// The behavior failed and cannot recover.
22    ///
23    /// For example:
24    /// - An object was not found after extensive searching
25    /// - A connection could not be established
26    /// - A safety constraint was violated
27    ///
28    /// Note: Use this for logical failures, not exceptions.
29    /// Throw errors for exceptional conditions.
30    Failure,
31
32    /// The behavior is still executing and needs more ticks.
33    ///
34    /// For example:
35    /// - A robot is still moving to a goal
36    /// - Waiting for a sensor reading
37    /// - Processing a long-running computation
38    #[default]
39    Running,
40}
41
42impl NodeStatus {
43    /// Returns true if the status indicates completion (Success or Failure).
44    ///
45    /// # Example
46    ///
47    /// ```rust
48    /// use mecha10_behavior_runtime::NodeStatus;
49    ///
50    /// assert!(NodeStatus::Success.is_complete());
51    /// assert!(NodeStatus::Failure.is_complete());
52    /// assert!(!NodeStatus::Running.is_complete());
53    /// ```
54    pub fn is_complete(&self) -> bool {
55        matches!(self, NodeStatus::Success | NodeStatus::Failure)
56    }
57
58    /// Returns true if the status is Success.
59    pub fn is_success(&self) -> bool {
60        matches!(self, NodeStatus::Success)
61    }
62
63    /// Returns true if the status is Failure.
64    pub fn is_failure(&self) -> bool {
65        matches!(self, NodeStatus::Failure)
66    }
67
68    /// Returns true if the status is Running.
69    pub fn is_running(&self) -> bool {
70        matches!(self, NodeStatus::Running)
71    }
72}
73
74// duplicate: false positive — matches `ControllerState`'s (packages/controllers/src/lib.rs),
75// `HealthPriority`'s (packages/core/src/node.rs), `LogLevel`'s
76// (packages/core/src/messages/system.rs), and `ComponentType`'s
77// (packages/mecha10-cli-core/src/component_catalog/types.rs) `Display` impls on AST shape only:
78// a `match self { Variant => write!(f, "..."), ... }` with 3-5 arms. Every enum here models a
79// different, unrelated concept (behavior-tree node outcome, controller lifecycle state, log
80// severity, catalog entry kind) with its own variant set and display strings, so there's no
81// shared behavior to factor out beyond what `#[derive]`-based crates like `strum` already exist
82// for — not something worth introducing just to satisfy this scan.
83impl fmt::Display for NodeStatus {
84    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85        match self {
86            NodeStatus::Success => write!(f, "Success"),
87            NodeStatus::Failure => write!(f, "Failure"),
88            NodeStatus::Running => write!(f, "Running"),
89        }
90    }
91}