Skip to main content

qubit_state_machine/
state_machine_build_error.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2026.
4 *    Haixing Hu, Qubit Co. Ltd.
5 *
6 *    All rights reserved.
7 *
8 ******************************************************************************/
9//! Validation errors returned when building a state machine.
10
11use std::error::Error;
12use std::fmt::{self, Debug, Display, Formatter};
13
14/// Error returned when state machine rules are internally inconsistent.
15///
16/// `S` is the state type and `E` is the event type.
17#[derive(Debug, Clone, Copy, Eq, PartialEq)]
18pub enum StateMachineBuildError<S, E> {
19    /// An initial state was configured but not registered as a state.
20    InitialStateNotRegistered {
21        /// The unregistered initial state.
22        state: S,
23    },
24    /// A final state was configured but not registered as a state.
25    FinalStateNotRegistered {
26        /// The unregistered final state.
27        state: S,
28    },
29    /// A transition source was not registered as a state.
30    TransitionSourceNotRegistered {
31        /// Source state of the invalid transition.
32        source: S,
33        /// Event of the invalid transition.
34        event: E,
35        /// Target state of the invalid transition.
36        target: S,
37    },
38    /// A transition target was not registered as a state.
39    TransitionTargetNotRegistered {
40        /// Source state of the invalid transition.
41        source: S,
42        /// Event of the invalid transition.
43        event: E,
44        /// Target state of the invalid transition.
45        target: S,
46    },
47    /// Two transitions use the same `(source, event)` with different targets.
48    DuplicateTransition {
49        /// Source state shared by both transitions.
50        source: S,
51        /// Event shared by both transitions.
52        event: E,
53        /// Target registered first.
54        existing_target: S,
55        /// Conflicting target registered later.
56        new_target: S,
57    },
58}
59
60impl<S, E> Display for StateMachineBuildError<S, E>
61where
62    S: Debug,
63    E: Debug,
64{
65    /// Formats the validation error with the offending state or transition.
66    fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
67        match self {
68            Self::InitialStateNotRegistered { state } => {
69                write!(formatter, "initial state is not registered: {state:?}")
70            }
71            Self::FinalStateNotRegistered { state } => {
72                write!(formatter, "final state is not registered: {state:?}")
73            }
74            Self::TransitionSourceNotRegistered {
75                source,
76                event,
77                target,
78            } => write!(
79                formatter,
80                "transition source is not registered: {source:?} --{event:?}--> {target:?}"
81            ),
82            Self::TransitionTargetNotRegistered {
83                source,
84                event,
85                target,
86            } => write!(
87                formatter,
88                "transition target is not registered: {source:?} --{event:?}--> {target:?}"
89            ),
90            Self::DuplicateTransition {
91                source,
92                event,
93                existing_target,
94                new_target,
95            } => write!(
96                formatter,
97                "duplicate transition target: {source:?} --{event:?}--> \
98                 {existing_target:?} conflicts with {new_target:?}"
99            ),
100        }
101    }
102}
103
104impl<S, E> Error for StateMachineBuildError<S, E>
105where
106    S: Debug,
107    E: Debug,
108{
109}