derive_finite_automaton/
lib.rs1use std::fmt::{self, Display};
2
3pub use derive_finite_automaton_derive::FiniteAutomataConstructor;
4
5pub trait FiniteAutomata<T>: Sized {
6 type State;
8 fn get_next(self, c: char) -> GetNextResult<T, Self>;
9}
10
11pub trait FiniteAutomataConstructor: Sized {
13 type FiniteAutomata: FiniteAutomata<Self>;
14 fn new_automaton() -> Self::FiniteAutomata;
15}
16
17#[derive(Debug, PartialEq, Eq)]
20pub enum GetNextResult<T, FA: FiniteAutomata<T>> {
21 Result {
22 result: T,
23 ate_character: bool,
25 },
26 NewState(FA),
27 InvalidCharacter(InvalidCharacter),
28}
29
30pub type GetAutomataStateForValue<T> =
31 <<T as FiniteAutomataConstructor>::FiniteAutomata as FiniteAutomata<T>>::State;
32
33#[derive(Debug, PartialEq, Eq)]
35pub struct InvalidCharacter {
36 pub received: char,
37 pub expected: &'static [char],
38}
39
40impl Display for InvalidCharacter {
41 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42 f.write_str("Expected ")?;
43 match self.expected {
44 [] => unreachable!(),
45 [a] => f.write_fmt(format_args!("{:?}", a)),
46 [a, b] => f.write_fmt(format_args!("{:?} or {:?}", a, b)),
47 [head @ .., end] => f.write_fmt(format_args!(
48 "{} or {:?}",
49 head.iter()
50 .map(|chr| format!("{:?}", chr))
51 .reduce(|mut a, b| {
52 a.push_str(", ");
53 a.push_str(&b);
54 a
55 })
56 .unwrap(),
57 end
58 )),
59 }?;
60 write!(f, " found {:?}", self.received)
61 }
62}
63
64impl std::error::Error for InvalidCharacter {}