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}