Skip to main content

karbon_framework/validation/constraints/comparison/
less_than.rs

1use crate::validation::constraints::{ConstraintResult, ConstraintViolation, NumericConstraint};
2
3/// Validates that a value is less than a given number.
4///
5/// Equivalent to Symfony's `LessThan` constraint.
6pub struct LessThan {
7    pub value: f64,
8    pub message: String,
9    pub or_equal: bool,
10}
11
12impl LessThan {
13    pub fn new(value: f64) -> Self {
14        Self {
15            value,
16            message: "This value should be less than {{ compared_value }}.".to_string(),
17            or_equal: false,
18        }
19    }
20
21    /// LessThanOrEqual variant
22    pub fn or_equal(value: f64) -> Self {
23        Self {
24            value,
25            message: "This value should be less than or equal to {{ compared_value }}.".to_string(),
26            or_equal: true,
27        }
28    }
29
30    pub fn with_message(mut self, message: impl Into<String>) -> Self {
31        self.message = message.into();
32        self
33    }
34}
35
36impl NumericConstraint for LessThan {
37    fn validate_f64(&self, value: f64) -> ConstraintResult {
38        let valid = if self.or_equal {
39            value <= self.value
40        } else {
41            value < self.value
42        };
43
44        if !valid {
45            return Err(ConstraintViolation::new(
46                self.name(),
47                self.message
48                    .replace("{{ compared_value }}", &self.value.to_string()),
49                value.to_string(),
50            ));
51        }
52        Ok(())
53    }
54
55    fn name(&self) -> &'static str {
56        "LessThan"
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::*;
63
64    #[test]
65    fn test_less_than() {
66        let constraint = LessThan::new(10.0);
67        assert!(constraint.validate_f64(9.0).is_ok());
68        assert!(constraint.validate_f64(0.0).is_ok());
69        assert!(constraint.validate_f64(10.0).is_err()); // not strictly less
70        assert!(constraint.validate_f64(11.0).is_err());
71    }
72
73    #[test]
74    fn test_less_than_or_equal() {
75        let constraint = LessThan::or_equal(10.0);
76        assert!(constraint.validate_f64(10.0).is_ok());
77        assert!(constraint.validate_f64(9.0).is_ok());
78        assert!(constraint.validate_f64(11.0).is_err());
79    }
80
81    #[test]
82    fn test_with_negative_values() {
83        let constraint = LessThan::new(0.0);
84        assert!(constraint.validate_f64(-1.0).is_ok());
85        assert!(constraint.validate_f64(-100.0).is_ok());
86        assert!(constraint.validate_f64(0.0).is_err());
87        assert!(constraint.validate_f64(1.0).is_err());
88    }
89}