aviso_validators/
float.rs1use anyhow::{Context, Result, bail};
12
13pub struct FloatHandler;
15
16impl FloatHandler {
17 pub fn validate_and_canonicalize(
26 value: &str,
27 range: Option<&[f64; 2]>,
28 field_name: &str,
29 ) -> Result<String> {
30 let parsed_value: f64 = value.parse().context(format!(
31 "Field '{}' must be a valid number, got: '{}'",
32 field_name, value
33 ))?;
34
35 if !parsed_value.is_finite() {
36 bail!(
37 "Field '{}' must be a finite number, got: '{}'",
38 field_name,
39 value
40 );
41 }
42
43 if let Some([min, max]) = range {
44 if parsed_value < *min || parsed_value > *max {
45 bail!(
46 "Field '{}' value {} is outside allowed range [{}, {}]",
47 field_name,
48 parsed_value,
49 min,
50 max
51 );
52 }
53 }
54
55 Ok(parsed_value.to_string())
56 }
57}
58
59#[cfg(test)]
60mod tests {
61 use super::FloatHandler;
62
63 #[test]
64 fn valid_float_without_range() {
65 let result = FloatHandler::validate_and_canonicalize("12.5", None, "severity");
66 assert!(result.is_ok());
67 assert_eq!(result.expect("value should be valid"), "12.5");
68 }
69
70 #[test]
71 fn valid_float_with_range() {
72 let result = FloatHandler::validate_and_canonicalize("3.4", Some(&[1.0, 7.0]), "level");
73 assert!(result.is_ok());
74 }
75
76 #[test]
77 fn invalid_float_format() {
78 let result = FloatHandler::validate_and_canonicalize("abc", None, "level");
79 assert!(result.is_err());
80 }
81
82 #[test]
83 fn float_outside_range() {
84 let result = FloatHandler::validate_and_canonicalize("9.1", Some(&[1.0, 7.0]), "level");
85 assert!(result.is_err());
86 }
87
88 #[test]
89 fn rejects_nan() {
90 let result = FloatHandler::validate_and_canonicalize("NaN", None, "level");
91 assert!(result.is_err());
92 }
93
94 #[test]
95 fn rejects_positive_infinity() {
96 let result = FloatHandler::validate_and_canonicalize("inf", None, "level");
97 assert!(result.is_err());
98 }
99
100 #[test]
101 fn rejects_negative_infinity() {
102 let result = FloatHandler::validate_and_canonicalize("-inf", None, "level");
103 assert!(result.is_err());
104 }
105}