term_guard/constraints/
assertion.rs1use serde::{Deserialize, Serialize};
4use std::fmt;
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
27pub enum Assertion {
28 Equals(f64),
30 NotEquals(f64),
32 GreaterThan(f64),
34 GreaterThanOrEqual(f64),
36 LessThan(f64),
38 LessThanOrEqual(f64),
40 Between(f64, f64),
42 NotBetween(f64, f64),
44}
45
46impl Assertion {
47 pub fn evaluate(&self, value: f64) -> bool {
49 const EPSILON: f64 = 1e-10;
50
51 match self {
52 Assertion::Equals(expected) => (value - expected).abs() < EPSILON,
53 Assertion::NotEquals(expected) => (value - expected).abs() >= EPSILON,
54 Assertion::GreaterThan(threshold) => value > *threshold,
55 Assertion::GreaterThanOrEqual(threshold) => value >= *threshold,
56 Assertion::LessThan(threshold) => value < *threshold,
57 Assertion::LessThanOrEqual(threshold) => value <= *threshold,
58 Assertion::Between(min, max) => value >= *min && value <= *max,
59 Assertion::NotBetween(min, max) => value < *min || value > *max,
60 }
61 }
62
63 pub fn description(&self) -> String {
65 match self {
66 Assertion::Equals(v) => format!("equals {v}"),
67 Assertion::NotEquals(v) => format!("not equals {v}"),
68 Assertion::GreaterThan(v) => format!("greater than {v}"),
69 Assertion::GreaterThanOrEqual(v) => format!("greater than or equal to {v}"),
70 Assertion::LessThan(v) => format!("less than {v}"),
71 Assertion::LessThanOrEqual(v) => format!("less than or equal to {v}"),
72 Assertion::Between(min, max) => format!("between {min} and {max}"),
73 Assertion::NotBetween(min, max) => format!("not between {min} and {max}"),
74 }
75 }
76}
77
78impl fmt::Display for Assertion {
79 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
80 write!(f, "{}", self.description())
81 }
82}
83
84#[cfg(test)]
85mod tests {
86 use super::*;
87
88 #[test]
89 fn test_equals() {
90 let assertion = Assertion::Equals(10.0);
91 assert!(assertion.evaluate(10.0));
92 assert!(!assertion.evaluate(10.1));
93 }
94
95 #[test]
96 fn test_not_equals() {
97 let assertion = Assertion::NotEquals(10.0);
98 assert!(!assertion.evaluate(10.0));
99 assert!(assertion.evaluate(10.1));
100 }
101
102 #[test]
103 fn test_greater_than() {
104 let assertion = Assertion::GreaterThan(10.0);
105 assert!(assertion.evaluate(10.1));
106 assert!(!assertion.evaluate(10.0));
107 assert!(!assertion.evaluate(9.9));
108 }
109
110 #[test]
111 fn test_between() {
112 let assertion = Assertion::Between(10.0, 20.0);
113 assert!(assertion.evaluate(15.0));
114 assert!(assertion.evaluate(10.0));
115 assert!(assertion.evaluate(20.0));
116 assert!(!assertion.evaluate(9.9));
117 assert!(!assertion.evaluate(20.1));
118 }
119
120 #[test]
121 fn test_description() {
122 assert_eq!(Assertion::Equals(10.0).description(), "equals 10");
123 assert_eq!(Assertion::GreaterThan(5.0).description(), "greater than 5");
124 assert_eq!(
125 Assertion::Between(1.0, 10.0).description(),
126 "between 1 and 10"
127 );
128 }
129}