Skip to main content

qubit_state_machine/
state_machine_build_error.rs

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