gregex_logic/translation/
setterminal.rs1use std::hash::{Hash, Hasher};
4
5#[derive(Debug)]
7pub enum SetTerminal {
8 SingleElement(char, u32), DoubleElement(char, u32, char, u32), Epsilon, Empty, }
13
14impl SetTerminal {
15 pub fn product(&self, other: &SetTerminal) -> SetTerminal {
17 match (self, other) {
18 (SetTerminal::SingleElement(a, a_code), SetTerminal::SingleElement(b, b_code)) => {
19 SetTerminal::DoubleElement(*a, *a_code, *b, *b_code)
20 }
21 (SetTerminal::SingleElement(a, a_code), SetTerminal::Epsilon) => {
22 SetTerminal::SingleElement(*a, *a_code)
23 }
24 (SetTerminal::Epsilon, SetTerminal::SingleElement(b, b_code)) => {
25 SetTerminal::SingleElement(*b, *b_code)
26 }
27 (SetTerminal::Epsilon, SetTerminal::Epsilon) => SetTerminal::Epsilon,
28 (SetTerminal::Empty, _) => SetTerminal::Empty,
29 (_, SetTerminal::Empty) => SetTerminal::Empty,
30 _ => unreachable!("Invalid product"),
31 }
32 }
33}
34
35impl PartialEq for SetTerminal {
36 fn eq(&self, other: &Self) -> bool {
37 match (self, other) {
38 (SetTerminal::SingleElement(a, a_code), SetTerminal::SingleElement(b, b_code)) => {
39 a == b && a_code == b_code
40 }
41 (
42 SetTerminal::DoubleElement(a, a_code, b, b_code),
43 SetTerminal::DoubleElement(c, c_code, d, d_code),
44 ) => a == c && a_code == c_code && b == d && b_code == d_code,
45 (SetTerminal::Epsilon, SetTerminal::Epsilon) => true,
46 (SetTerminal::Empty, SetTerminal::Empty) => true,
47 _ => false,
48 }
49 }
50}
51
52impl Eq for SetTerminal {}
53
54impl Hash for SetTerminal {
55 fn hash<H: Hasher>(&self, state: &mut H) {
56 match self {
57 SetTerminal::SingleElement(a, a_code) => {
58 a.hash(state);
59 a_code.hash(state);
60 }
61 SetTerminal::DoubleElement(a, a_code, b, b_code) => {
62 a.hash(state);
63 a_code.hash(state);
64 b.hash(state);
65 b_code.hash(state);
66 }
67 SetTerminal::Epsilon => {
68 "Epsilon".hash(state);
69 }
70 SetTerminal::Empty => {
71 "Empty".hash(state);
72 }
73 }
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn test_product() {
83 let a = SetTerminal::SingleElement('a', 1);
84 let b = SetTerminal::SingleElement('b', 2);
85 let c = SetTerminal::Epsilon;
86 let d = SetTerminal::Empty;
87
88 assert_eq!(a.product(&b), SetTerminal::DoubleElement('a', 1, 'b', 2));
89 assert_eq!(a.product(&c), SetTerminal::SingleElement('a', 1));
90 assert_eq!(c.product(&b), SetTerminal::SingleElement('b', 2));
91 assert_eq!(c.product(&c), SetTerminal::Epsilon);
92 assert_eq!(d.product(&a), SetTerminal::Empty);
93 assert_eq!(b.product(&d), SetTerminal::Empty);
94 }
95}