Skip to main content

rust_lstar/automata/
state.rs

1use super::transition::Transition;
2use crate::letter::Letter;
3use std::fmt;
4
5/// A state in an automaton.
6#[derive(Clone, Debug)]
7pub struct State {
8    /// Human-readable unique state name.
9    pub name: String,
10    /// Outgoing transitions from this state.
11    pub transitions: Vec<Transition>,
12}
13
14impl State {
15    /// Create a new state with no outgoing transitions.
16    pub fn new(name: String) -> Self {
17        State {
18            name,
19            transitions: Vec::new(),
20        }
21    }
22
23    /// Add an outgoing transition.
24    pub fn add_transition(&mut self, transition: Transition) {
25        self.transitions.push(transition);
26    }
27
28    /// Get a transition for a given input letter
29    pub fn get_transition(&self, input_letter: &Letter) -> Option<&Transition> {
30        self.transitions
31            .iter()
32            .find(|t| t.input_letter == *input_letter)
33    }
34
35    /// Follow a transition for the given input letter.
36    ///
37    /// Returns the emitted output letter and destination state when a matching
38    /// transition exists.
39    pub fn visit(&self, input_letter: &Letter) -> Option<(&Letter, &State)> {
40        for transition in &self.transitions {
41            if &transition.input_letter == input_letter {
42                return Some((&transition.output_letter, &transition.output_state));
43            }
44        }
45        None
46    }
47}
48
49impl PartialEq for State {
50    fn eq(&self, other: &Self) -> bool {
51        self.name == other.name
52    }
53}
54
55impl Eq for State {}
56
57impl fmt::Display for State {
58    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
59        write!(f, "{}", self.name)
60    }
61}