rs_teststand/expression/operator/
comparison.rs1use super::Arity;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
14pub enum ComparisonOperator {
15 Equal,
17 NotEqual,
19 Less,
21 Greater,
23 LessOrEqual,
25 GreaterOrEqual,
27}
28
29impl ComparisonOperator {
30 pub const ALL: [Self; 6] = [
32 Self::Equal,
33 Self::NotEqual,
34 Self::Less,
35 Self::Greater,
36 Self::LessOrEqual,
37 Self::GreaterOrEqual,
38 ];
39
40 #[must_use]
42 pub const fn symbol(self) -> &'static str {
43 match self {
44 Self::Equal => "==",
45 Self::NotEqual => "!=",
46 Self::Less => "<",
47 Self::Greater => ">",
48 Self::LessOrEqual => "<=",
49 Self::GreaterOrEqual => ">=",
50 }
51 }
52
53 #[must_use]
55 #[allow(
56 clippy::unused_self,
57 reason = "uniform surface across operator families"
58 )]
59 pub const fn arity(self) -> Arity {
60 Arity::Binary
61 }
62
63 #[must_use]
65 #[allow(
66 clippy::unused_self,
67 reason = "uniform surface across operator families"
68 )]
69 pub const fn precedence(self) -> u8 {
70 5
71 }
72}
73
74#[cfg(test)]
75mod tests {
76 use super::ComparisonOperator;
77
78 #[test]
79 fn all_comparisons_share_one_binding_level() {
80 let levels: Vec<u8> = ComparisonOperator::ALL
81 .iter()
82 .map(|op| op.precedence())
83 .collect();
84 assert!(levels.windows(2).all(|pair| pair.first() == pair.last()));
85 }
86
87 #[test]
88 fn every_comparison_has_a_distinct_symbol() {
89 let mut symbols: Vec<&str> = ComparisonOperator::ALL
90 .iter()
91 .map(|op| op.symbol())
92 .collect();
93 symbols.sort_unstable();
94 let count = symbols.len();
95 symbols.dedup();
96 assert_eq!(symbols.len(), count);
97 }
98}