1pub mod sync {
24 use std::fmt::Debug;
25 use std::{collections::HashMap, hash::Hash};
26
27 pub trait FsmEnum<S, CTX, E> {
29 fn create(enum_value: &S) -> Box<dyn Stateful<S, CTX, E> + Send>;
30 }
31
32 pub trait Stateful<S: Hash + PartialEq + Eq + Clone, CTX, E: Debug> {
34 fn on_enter(&mut self, context: &mut CTX) -> Response<S>;
35 fn on_event(&mut self, event: &E, context: &mut CTX) -> Response<S>;
36 fn on_exit(&mut self, context: &mut CTX);
37 }
38
39 pub trait EventHandler<S: Hash + PartialEq + Eq + Clone, CTX, E: Debug> {
41 fn on_event(&mut self, event: &E, context: &mut CTX) -> Response<S>;
42 }
43
44 pub enum Response<S> {
46 Handled,
47 Transition(S),
48 }
49
50 #[derive(Debug)]
52 pub enum Error {
53 StateNotFound(String),
54 StateMachineNotInitialized,
55 }
56
57 pub struct StateMachine<S: Hash + PartialEq + Eq + Clone + FsmEnum<S, CTX, E>, CTX, E: Debug> {
59 states: HashMap<S, Box<dyn Stateful<S, CTX, E> + Send>>,
60 current_state: Option<S>,
61 context: CTX,
62 global_event_handler: Option<Box<dyn EventHandler<S, CTX, E> + Send>>,
63 }
64
65 impl<S: Hash + PartialEq + Eq + Clone + FsmEnum<S, CTX, E>, CTX, E: Debug> StateMachine<S, CTX, E> {
67 pub fn new(context: CTX, handler: Option<Box<dyn EventHandler<S, CTX, E> + Send>>) -> Self {
69 let states = HashMap::<S, Box<dyn Stateful<S, CTX, E> + Send>>::new();
70 Self {
71 states,
72 current_state: None,
73 context,
74 global_event_handler: handler,
75 }
76 }
77
78 pub fn get_current_state(&self) -> Option<&S> {
80 self.current_state.as_ref()
81 }
82
83 pub fn get_context(&self) -> &CTX {
85 &self.context
86 }
87
88 pub fn init(&mut self, initial_state: S) -> Result<(), Error> {
91 if self.current_state.is_none() {
92 self.current_state = Some(initial_state);
93 loop {
94 let current_state_ref = self.current_state.as_ref().unwrap();
95 let state = if let Some(existing_state) = self.states.get_mut(current_state_ref)
96 {
97 existing_state
98 } else {
99 let new_state = S::create(current_state_ref);
100 let current_state_clone = self.current_state.clone().unwrap();
101 self.states.entry(current_state_clone).or_insert(new_state)
102 };
103
104 match state.on_enter(&mut self.context) {
105 Response::Handled => break,
106 Response::Transition(s) => self.current_state = Some(s),
107 }
108 }
109 }
110 Ok(())
111 }
112
113 pub fn process_event(&mut self, event: &E) -> Result<(), Error> {
115 let c_state = match &self.current_state {
116 Some(state) => state,
117 None => return Err(Error::StateMachineNotInitialized),
118 };
119
120 if let Some(global_handler) = &mut self.global_event_handler {
121 match global_handler.on_event(event, &mut self.context) {
122 Response::Handled => {}
123 Response::Transition(new_state) => {
124 if new_state != *c_state {
125 return self.transition_to(new_state);
126 }
127 }
128 }
129 }
130
131 let current_state_ref = self.current_state.as_ref().unwrap();
132 let state = if let Some(existing_state) = self.states.get_mut(current_state_ref) {
133 existing_state
134 } else {
135 let new_state = S::create(current_state_ref);
136 let current_state_clone = self.current_state.clone().unwrap();
137 self.states.entry(current_state_clone).or_insert(new_state)
138 };
139 match state.on_event(event, &mut self.context) {
140 Response::Handled => {}
141 Response::Transition(new_state) => {
142 if new_state != *c_state {
143 self.transition_to(new_state)?;
144 }
145 }
146 }
147
148 Ok(())
149 }
150
151 fn transition_to(&mut self, new_state: S) -> Result<(), Error> {
153 let c_state = self.current_state.as_ref().unwrap();
154 let state = self.states.get_mut(&c_state).unwrap();
155 state.on_exit(&mut self.context);
156
157 self.current_state = Some(new_state.clone());
158 loop {
159 let current_state_ref = self.current_state.as_ref().unwrap();
160 let s = if let Some(existing_state) = self.states.get_mut(current_state_ref) {
161 existing_state
162 } else {
163 let new_state = S::create(current_state_ref);
164 let current_state_clone = self.current_state.clone().unwrap();
165 self.states.entry(current_state_clone).or_insert(new_state)
166 };
167 match s.on_enter(&mut self.context) {
168 Response::Handled => {
169 break;
170 }
171 Response::Transition(s) => {
172 if s == *self.current_state.as_ref().unwrap() {
173 break;
174 } else {
175 self.current_state = Some(s);
176 }
177 }
178 }
179 }
180
181 Ok(())
182 }
183 }
184}
185pub mod Async {
186 use std::fmt::Debug;
187 use std::{collections::HashMap, hash::Hash};
188
189 use async_trait::async_trait;
190
191 pub trait FsmEnum<S, CTX, E> {
193 fn create(enum_value: &S) -> Box<dyn Stateful<S, CTX, E> + Send>;
194 }
195
196 #[async_trait]
198 pub trait EventHandler<S: Hash + PartialEq + Eq + Clone, CTX, E: Debug> {
199 async fn on_event(&mut self, event: &E, context: &mut CTX) -> Response<S>;
200 }
201
202 #[async_trait]
204 pub trait Stateful<S: Hash + PartialEq + Eq + Clone, CTX, E: Debug> {
205 async fn on_enter(&mut self, context: &mut CTX) -> Response<S>;
206 async fn on_event(&mut self, event: &E, context: &mut CTX) -> Response<S>;
207 async fn on_exit(&mut self, context: &mut CTX);
208 }
209
210 pub enum Response<S> {
212 Handled,
213 Transition(S),
214 }
215
216 #[derive(Debug)]
218 pub enum Error {
219 StateNotFound(String),
220 StateMachineNotInitialized,
221 }
222
223 pub struct StateMachine<S: Hash + PartialEq + Eq + Clone + FsmEnum<S, CTX, E>, CTX, E: Debug> {
225 states: HashMap<S, Box<dyn Stateful<S, CTX, E> + Send>>,
226 current_state: Option<S>,
227 context: CTX,
228 global_event_handler: Option<Box<dyn EventHandler<S, CTX, E> + Send>>,
229 }
230
231 impl<S: Hash + PartialEq + Eq + Clone + FsmEnum<S, CTX, E>, CTX, E: Debug> StateMachine<S, CTX, E> {
233 pub fn new(
235 context: CTX,
236 global_handler: Option<Box<dyn EventHandler<S, CTX, E> + Send>>,
237 ) -> Self {
238 Self {
239 states: HashMap::new(),
240 current_state: None,
241 context,
242 global_event_handler: global_handler,
243 }
244 }
245
246 pub fn get_current_state(&self) -> Option<&S> {
248 self.current_state.as_ref()
249 }
250
251 pub fn get_context(&self) -> &CTX {
253 &self.context
254 }
255
256 pub async fn init(&mut self, initial_state: S) -> Result<(), Error> {
258 if self.current_state.is_none() {
259 self.current_state = Some(initial_state);
260 loop {
261 let current_state_ref = self.current_state.as_ref().unwrap();
262 let state = if let Some(existing_state) = self.states.get_mut(current_state_ref)
263 {
264 existing_state
265 } else {
266 let new_state = S::create(current_state_ref);
267 let current_state_clone = self.current_state.clone().unwrap();
268 self.states.entry(current_state_clone).or_insert(new_state)
269 };
270
271 match state.on_enter(&mut self.context).await {
272 Response::Handled => break,
273 Response::Transition(s) => self.current_state = Some(s),
274 }
275 }
276 }
277 Ok(())
278 }
279 pub async fn process_event(&mut self, event: &E) -> Result<(), Error> {
281 let c_state = match &self.current_state {
282 Some(state) => state,
283 None => return Err(Error::StateMachineNotInitialized),
284 };
285
286 if let Some(ref mut handler) = self.global_event_handler {
287 match handler.on_event(event, &mut self.context).await {
288 Response::Handled => {}
289 Response::Transition(new_state) => {
290 if new_state != *c_state {
291 self.transition_to(new_state).await;
292 return Ok(());
293 }
294 }
295 }
296 }
297
298 let current_state_ref = self.current_state.as_ref().unwrap();
299 let state = if let Some(existing_state) = self.states.get_mut(current_state_ref) {
300 existing_state
301 } else {
302 let new_state = S::create(current_state_ref);
303 let current_state_clone = self.current_state.clone().unwrap();
304 self.states.entry(current_state_clone).or_insert(new_state)
305 };
306
307 match state.on_event(event, &mut self.context).await {
308 Response::Handled => {}
309 Response::Transition(new_state) => {
310 if new_state != *c_state {
311 self.transition_to(new_state).await;
312 }
313 }
314 }
315
316 Ok(())
317 }
318
319 async fn transition_to(&mut self, new_state: S) {
320 let c_state = self.current_state.as_ref().unwrap();
321 let state = self.states.get_mut(&c_state).unwrap();
322 state.on_exit(&mut self.context).await;
323
324 self.current_state = Some(new_state);
325
326 loop {
327 let current_state_ref = self.current_state.as_ref().unwrap();
328 let s = if let Some(existing_state) = self.states.get_mut(current_state_ref) {
329 existing_state
330 } else {
331 let new_state = S::create(current_state_ref);
332 let current_state_clone = self.current_state.clone().unwrap();
333 self.states.entry(current_state_clone).or_insert(new_state)
334 };
335
336 match s.on_enter(&mut self.context).await {
337 Response::Handled => {
338 break;
339 }
340 Response::Transition(s) => {
341 if s == *current_state_ref {
342 break;
343 } else {
344 self.current_state = Some(s);
345 }
346 }
347 }
348 }
349 }
350 }
351}