Skip to main content

ready_active_safe/
error.rs

1//! Crate-level error types.
2
3use core::fmt;
4
5/// Errors that can occur during lifecycle operations.
6///
7/// All variants include enough context to diagnose the failure without
8/// a debugger. Uses `#[non_exhaustive]` so new variants can be added
9/// in minor versions without breaking downstream code.
10///
11/// # Examples
12///
13/// ```
14/// use ready_active_safe::LifecycleError;
15///
16/// let err: LifecycleError<&str> = LifecycleError::TransitionDenied {
17///     from: "active",
18///     to: "ready",
19///     reason: "backward transitions are not allowed",
20/// };
21/// assert_eq!(
22///     err.to_string(),
23///     "transition denied from active to ready: backward transitions are not allowed",
24/// );
25/// ```
26#[derive(Debug, Clone, PartialEq, Eq)]
27#[non_exhaustive]
28pub enum LifecycleError<M> {
29    /// A mode transition was rejected by the [`Policy`](crate::Policy).
30    TransitionDenied {
31        /// The mode the system was in when the transition was attempted.
32        from: M,
33        /// The mode the system attempted to transition to.
34        to: M,
35        /// A human-readable explanation of why the transition was denied.
36        reason: &'static str,
37    },
38}
39
40impl<M: fmt::Display> fmt::Display for LifecycleError<M> {
41    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42        match self {
43            Self::TransitionDenied { from, to, reason } => {
44                write!(f, "transition denied from {from} to {to}: {reason}")
45            }
46        }
47    }
48}
49
50#[cfg(feature = "std")]
51impl<M: fmt::Debug + fmt::Display> std::error::Error for LifecycleError<M> {}