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