fsm_rust_jb/
types.rs

1use std::hash::Hash;
2
3/// Input character validator
4pub type Predicate = fn(ch: char) -> bool;
5
6/// Transition to next state which is validated by condition
7pub struct Transition<State, Effect> 
8    where State: Eq + PartialEq + Copy,
9          Effect: Copy
10{
11    /// Predicate that validates current character of stream.
12    /// If None then transition is unconditional (i.e. succeeds for every input character)
13    pub condition: Option<Predicate>,
14    /// Next state
15    pub to: State,
16    /// Side effect that is generated after successful validation of transition
17    /// If None then no effect is generated
18    pub effect: Option<Effect>
19}
20
21/// Pair of states ("from", "to")
22#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
23pub struct StatesConnection<State> 
24    where State: Eq + PartialEq + Copy + Hash,
25{
26    pub from: State,
27    pub to: State
28}
29
30impl<State, Effect> Transition<State, Effect> 
31    where State: Eq + PartialEq + Copy,
32          Effect: Copy
33{
34    /// Creates new transition
35    /// - to: next state,
36    /// - condition: predicate for character,
37    /// - effect: side effect
38    pub fn new(to: State, condition: Option<Predicate>, effect: Option<Effect>) -> Self {
39        Self {
40            to,
41            condition,
42            effect
43        }
44    }
45
46    /// Matches next state and side effect for current character
47    /// - ch: current character (of stream) 
48    pub fn transit(&self, ch: char) -> (Option<State>, Option<Effect>) {
49        match self.condition {
50            Some(condition) => {
51                if condition(ch) {
52                    (Some(self.to), self.effect)
53                } else {
54                    (None, None)
55                }
56            },
57            None => (Some(self.to), self.effect)
58        }
59    }
60}
61
62/// Information for debugging and effects
63#[derive(Copy, Clone, Debug)]
64pub struct StreamData<'a> {
65    /// Reference to input string
66    pub string: &'a String,
67    /// Current character position in input string
68    pub index: usize,
69    /// Current character in input string
70    pub character: char
71}
72
73/// Generic type for executor of side effects 
74/// applied to some persistent data
75pub trait Effector<Effect> 
76    where Effect: Copy
77{
78    /// Applies side effect to mutate some data
79    /// - effect: side effect,
80    /// - input_data: additional dependencies for effects
81    fn dispatch(&mut self, effect: Effect, input_data: StreamData);
82}