subtext/
sequence.rs

1use core::fmt::Debug;
2
3/**
4 * A basic state machine to track interesting sequences of values.
5 *
6 * The sequence is considered complete when its states have been traversed in
7 * order.
8 * The sequence becomes stuck when sent to an out-of-order state and won't be
9 * able to continue until it encounters the configured "reset" signal.
10 */
11#[derive(Debug)]
12pub struct Sequence<'a> {
13    states: &'a [char],
14    sent_to_state: bool,
15    reset_signal: Option<char>,
16    next_state: usize,
17}
18
19impl<'a> Sequence<'a> {
20    pub fn new(states: &'a [char], reset_signal: Option<char>) -> Self {
21        Sequence {
22            states,
23            sent_to_state: false,
24            reset_signal,
25            next_state: 0,
26        }
27    }
28
29    pub fn len(&self) -> usize {
30        self.states.len()
31    }
32
33    pub fn is_complete(&self) -> bool {
34        self.next_state == self.states.len()
35    }
36
37    pub fn can_advance(&self) -> bool {
38        match (self.sent_to_state, self.next_state > 0) {
39            (true, true) => true,
40            (false, false) => true,
41            _ => false,
42        }
43    }
44
45    pub fn go_to(&mut self, input: &char) -> bool {
46        let current_next_state = self.next_state;
47
48        if self.is_complete() {
49            self.next_state = 0;
50        }
51
52        if self.can_advance() {
53            if let Some(state) = self.states.get(self.next_state) {
54                if *state == *input {
55                    self.next_state += 1;
56                } else {
57                    self.next_state = 0;
58                }
59            }
60        }
61
62        let state_advanced = self.next_state > current_next_state;
63
64        let reset_signal_sent = match self.reset_signal.as_ref() {
65            Some(reset_signal) => *reset_signal == *input,
66            None => true,
67        };
68
69        self.sent_to_state = state_advanced || !reset_signal_sent;
70
71        state_advanced
72    }
73}