11// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22// SPDX-License-Identifier: Apache-2.0
33
4- use std:: ops:: Deref ;
5-
64/// Simple abstraction of a state machine.
75///
86/// `StateMachine<T>` is a wrapper over `T` that also encodes state information for `T`.
@@ -13,8 +11,7 @@ use std::ops::Deref;
1311/// `StateFn<T>` returns exactly one other `StateMachine<T>` thus each state gets clearly
1412/// defined transitions to other states.
1513pub struct StateMachine < T > {
16- function : StateFn < T > ,
17- end_state : bool ,
14+ function : Option < StateFn < T > > ,
1815}
1916
2017/// Type representing a state handler of a `StateMachine<T>` machine. Each state handler
@@ -27,13 +24,9 @@ impl<T> StateMachine<T> {
2724 /// # Arguments
2825 ///
2926 /// `function` - the state handler for this state.
30- /// `end_state` - whether this state is final.
3127 ///
32- pub fn new ( function : StateFn < T > , end_state : bool ) -> StateMachine < T > {
33- StateMachine {
34- function,
35- end_state,
36- }
28+ pub fn new ( function : Option < StateFn < T > > ) -> StateMachine < T > {
29+ StateMachine { function }
3730 }
3831
3932 /// Creates a new state wrapper that has further possible transitions.
@@ -43,7 +36,7 @@ impl<T> StateMachine<T> {
4336 /// `function` - the state handler for this state.
4437 ///
4538 pub fn next ( function : StateFn < T > ) -> StateMachine < T > {
46- StateMachine :: new ( function, false )
39+ StateMachine :: new ( Some ( function) )
4740 }
4841
4942 /// Creates a new state wrapper that has no further transitions. The state machine
@@ -53,8 +46,8 @@ impl<T> StateMachine<T> {
5346 ///
5447 /// `function` - the state handler for this last state.
5548 ///
56- pub fn finish ( function : StateFn < T > ) -> StateMachine < T > {
57- StateMachine :: new ( function , true )
49+ pub fn finish ( ) -> StateMachine < T > {
50+ StateMachine :: new ( None )
5851 }
5952
6053 /// Runs a state machine for `T` starting from the provided state.
@@ -67,23 +60,15 @@ impl<T> StateMachine<T> {
6760 ///
6861 pub fn run ( machine : & mut T , starting_state_fn : StateFn < T > ) {
6962 // Start off in the `starting_state` state.
70- let mut sf = StateMachine :: new ( starting_state_fn, false ) ;
63+ let mut state_machine = StateMachine :: new ( Some ( starting_state_fn) ) ;
7164 // While current state is not a final/end state, keep churning.
72- while !sf . end_state {
65+ while let Some ( state_fn ) = state_machine . function {
7366 // Run the current state handler, and get the next one.
74- sf = sf ( machine) ;
67+ state_machine = state_fn ( machine) ;
7568 }
7669 }
7770}
7871
79- // Implement Deref of `StateMachine<T>` so that we can directly call its underlying state handler.
80- impl < T > Deref for StateMachine < T > {
81- type Target = StateFn < T > ;
82- fn deref ( & self ) -> & Self :: Target {
83- & self . function
84- }
85- }
86-
8772#[ cfg( test) ]
8873mod tests {
8974 use super :: * ;
@@ -141,7 +126,7 @@ mod tests {
141126 assert ! ( !self . private_data_s3) ;
142127 self . private_data_s3 = true ;
143128 // The machine ends here, adding `s1` as next state to validate this.
144- StateMachine :: finish ( Self :: s1 )
129+ StateMachine :: finish ( )
145130 }
146131 }
147132
0 commit comments