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}