use std::fmt;
use std::fmt::Debug;
use super::transition::Transition;
#[derive(Debug)]
pub struct TransitionError<S, E>
where
S: Eq,
E: Eq,
{
error_type: TransitionErrorType,
pub transition: Transition<S, E>,
}
#[derive(Debug, Clone)]
pub enum TransitionErrorType {
AlreadyExists,
NondeterministicTransition,
CannotApply,
NotAllowed,
}
impl<S, E> TransitionError<S, E>
where
S: Eq + Copy,
E: Eq + Copy,
{
pub fn already_exists(input: S, event: E, output: S) -> TransitionError<S, E> {
Self {
error_type: TransitionErrorType::AlreadyExists,
transition: Transition::new(input, event, output),
}
}
pub fn nondeterministic(input: S, event: E, output: S) -> TransitionError<S, E> {
Self {
error_type: TransitionErrorType::NondeterministicTransition,
transition: Transition::new(input, event, output),
}
}
pub fn cannot_apply(input: S, event: E) -> TransitionError<S, E> {
Self {
error_type: TransitionErrorType::CannotApply,
transition: Transition::new(input, event, input), }
}
pub fn not_allowed(input: S, event: E, output: S) -> TransitionError<S, E> {
Self {
error_type: TransitionErrorType::NotAllowed,
transition: Transition::new(input, event, output),
}
}
}
impl<S, E> fmt::Display for TransitionError<S, E>
where
S: Eq + Debug,
E: Eq + Debug,
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.error_type {
TransitionErrorType::AlreadyExists => {
write!(f, "Transition {:?} is already defined in this State Machine (no duplicates).", self.transition)
}
TransitionErrorType::NondeterministicTransition => {
write!(f, "Two different transitions exist with [input={:?}, event={:?}], leading to non-deterministic state machine", self.transition.state_in, self.transition.event)
}
TransitionErrorType::CannotApply => {
write!(f, "Cannot apply [event={:?}] on [input_state={:?}] (unknown transition)", self.transition.event, self.transition.state_in)
}
TransitionErrorType::NotAllowed => {
write!(f, "Cannot apply [transition={:?}], the guard function does not allow it", self.transition)
}
}
}
}