1
1
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2
2
// SPDX-License-Identifier: Apache-2.0
3
3
4
- use std:: ops:: Deref ;
5
-
6
4
/// Simple abstraction of a state machine.
7
5
///
8
6
/// `StateMachine<T>` is a wrapper over `T` that also encodes state information for `T`.
@@ -13,8 +11,7 @@ use std::ops::Deref;
13
11
/// `StateFn<T>` returns exactly one other `StateMachine<T>` thus each state gets clearly
14
12
/// defined transitions to other states.
15
13
pub struct StateMachine < T > {
16
- function : StateFn < T > ,
17
- end_state : bool ,
14
+ function : Option < StateFn < T > > ,
18
15
}
19
16
20
17
/// Type representing a state handler of a `StateMachine<T>` machine. Each state handler
@@ -27,13 +24,9 @@ impl<T> StateMachine<T> {
27
24
/// # Arguments
28
25
///
29
26
/// `function` - the state handler for this state.
30
- /// `end_state` - whether this state is final.
31
27
///
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 }
37
30
}
38
31
39
32
/// Creates a new state wrapper that has further possible transitions.
@@ -43,7 +36,7 @@ impl<T> StateMachine<T> {
43
36
/// `function` - the state handler for this state.
44
37
///
45
38
pub fn next ( function : StateFn < T > ) -> StateMachine < T > {
46
- StateMachine :: new ( function, false )
39
+ StateMachine :: new ( Some ( function) )
47
40
}
48
41
49
42
/// Creates a new state wrapper that has no further transitions. The state machine
@@ -53,8 +46,8 @@ impl<T> StateMachine<T> {
53
46
///
54
47
/// `function` - the state handler for this last state.
55
48
///
56
- pub fn finish ( function : StateFn < T > ) -> StateMachine < T > {
57
- StateMachine :: new ( function , true )
49
+ pub fn finish ( ) -> StateMachine < T > {
50
+ StateMachine :: new ( None )
58
51
}
59
52
60
53
/// Runs a state machine for `T` starting from the provided state.
@@ -67,23 +60,15 @@ impl<T> StateMachine<T> {
67
60
///
68
61
pub fn run ( machine : & mut T , starting_state_fn : StateFn < T > ) {
69
62
// 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) ) ;
71
64
// 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 {
73
66
// Run the current state handler, and get the next one.
74
- sf = sf ( machine) ;
67
+ state_machine = state_fn ( machine) ;
75
68
}
76
69
}
77
70
}
78
71
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
-
87
72
#[ cfg( test) ]
88
73
mod tests {
89
74
use super :: * ;
@@ -141,7 +126,7 @@ mod tests {
141
126
assert ! ( !self . private_data_s3) ;
142
127
self . private_data_s3 = true ;
143
128
// The machine ends here, adding `s1` as next state to validate this.
144
- StateMachine :: finish ( Self :: s1 )
129
+ StateMachine :: finish ( )
145
130
}
146
131
}
147
132
0 commit comments