use crate::Value;
use core::fmt;
use std::error::Error;
use hashbrown::HashMap;
use crate::database::*;
#[derive(Debug,Copy,Clone,PartialEq,Eq,Hash)]
pub enum Event {
OnCreate,
OnDestroy,
Success,
Fail,
TimerExpired,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum State {
Closed,
HalfOpen,
Open,
Id(u64),
None,
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum TransitionError {
Impossible,
}
#[derive(Debug, PartialEq, Clone)]
pub enum Output {
Value(Value),
SetTimer(usize),
None,
}
#[derive(Debug, Clone)]
pub struct StateMachine {
state: State,
tables: Database,
transitions: HashMap<(State,Event),(State,Output)>
}
impl StateMachine {
pub fn new() -> Self {
StateMachine::from_state(State::Closed)
}
pub fn from_state(state: State) -> Self {
Self {
state,
tables: Database::new(),
transitions: HashMap::new()
}
}
pub fn consume(&mut self, event: Event) -> Result<Output, TransitionError> {
match self.transitions.get(&(self.state,event)) {
Some((state,output)) => {
self.state = *state;
Ok(output.clone())
}
None => {
Err(TransitionError::Impossible)
}
}
}
pub fn state(&self) -> &State {
&self.state
}
pub fn add_transition(&mut self, input: (State,Event), output: (State,Output)) -> Option<(State,Output)> {
self.transitions.insert(input,output)
}
pub fn transitions(&self) -> &HashMap<(State,Event),(State,Output)> {
&self.transitions
}
pub fn transitions_mut(&mut self) -> &mut HashMap<(State,Event),(State,Output)> {
&mut self.transitions
}
}
impl Default for StateMachine {
fn default() -> Self {
Self::new()
}
}