Finite state machines in rust; bendns fork to add types.
enhance undos
| -rw-r--r-- | rust-fsm/src/lib.rs | 22 | ||||
| -rw-r--r-- | rust-fsm/tests/circuit_breaker_dsl.rs | 2 | ||||
| -rw-r--r-- | rust-fsm/tests/circuit_breaker_dsl_custom_types.rs | 6 |
3 files changed, 19 insertions, 11 deletions
diff --git a/rust-fsm/src/lib.rs b/rust-fsm/src/lib.rs index 3240fdd..e894ee9 100644 --- a/rust-fsm/src/lib.rs +++ b/rust-fsm/src/lib.rs @@ -229,7 +229,7 @@ You can see an example of the Circuit Breaker state machine in the #![cfg_attr(not(feature = "std"), no_std)] -use core::fmt; +use core::fmt::{self, Debug, Display}; #[cfg(feature = "std")] use std::error::Error; @@ -262,14 +262,17 @@ pub trait StateMachineImpl: Sized { fn consume( &mut self, input: Self::Input, - ) -> Result<Option<Self::Output>, TransitionImpossibleError> + ) -> Result<Option<Self::Output>, TransitionImpossibleError<Self, Self::Input>> where Self::Input: Clone, Self: Clone, { self.clone() .transition(input.clone()) - .ok_or(TransitionImpossibleError) + .ok_or_else(|| TransitionImpossibleError { + state: self.clone(), + input: input.clone(), + }) .map(|state| std::mem::replace(self, state).output(input)) } } @@ -277,19 +280,24 @@ pub trait StateMachineImpl: Sized { #[derive(Debug, Clone)] /// An error type that represents that the state transition is impossible given /// the current combination of state and input. -pub struct TransitionImpossibleError; +pub struct TransitionImpossibleError<S, I> { + state: S, + input: I, +} -impl fmt::Display for TransitionImpossibleError { +impl<S: Debug, I: Debug> fmt::Display for TransitionImpossibleError<S, I> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, - "cannot perform a state transition from the current state with the provided input" + "cannot perform a state transition from the current state ({:?}) with the provided input ({:?})", + self.state, + self.input ) } } #[cfg(feature = "std")] -impl Error for TransitionImpossibleError { +impl<S: Debug, I: Debug> Error for TransitionImpossibleError<S, I> { fn source(&self) -> Option<&(dyn Error + 'static)> { None } diff --git a/rust-fsm/tests/circuit_breaker_dsl.rs b/rust-fsm/tests/circuit_breaker_dsl.rs index c49787e..61b82fc 100644 --- a/rust-fsm/tests/circuit_breaker_dsl.rs +++ b/rust-fsm/tests/circuit_breaker_dsl.rs @@ -9,7 +9,7 @@ state_machine! { /// A dummy implementation of the Circuit Breaker pattern to demonstrate /// capabilities of its library DSL for defining finite state machines. /// https://martinfowler.com/bliki/CircuitBreaker.html - #[derive(Clone, Copy)] + #[derive(Clone, Copy, Debug)] pub CircuitBreaker => Result => Action Closed => Unsuccessful => Open [SetupTimer], diff --git a/rust-fsm/tests/circuit_breaker_dsl_custom_types.rs b/rust-fsm/tests/circuit_breaker_dsl_custom_types.rs index 4b22e08..72c5f34 100644 --- a/rust-fsm/tests/circuit_breaker_dsl_custom_types.rs +++ b/rust-fsm/tests/circuit_breaker_dsl_custom_types.rs @@ -5,21 +5,21 @@ use rust_fsm::*; use std::sync::{Arc, Mutex}; use std::time::Duration; -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub enum Input { Successful, Unsuccessful, TimerTriggered, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub enum State { Closed, HalfOpen, Open, } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub enum Output { SetupTimer, } |