crap_core/domain/
threshold.rs1pub const STRICT_THRESHOLD: f64 = 15.0;
5
6pub const DEFAULT_THRESHOLD: f64 = 25.0;
8
9pub const LENIENT_THRESHOLD: f64 = 40.0;
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum ThresholdPreset {
15 Strict,
17 Default,
19 Lenient,
21}
22
23impl ThresholdPreset {
24 pub fn threshold(self) -> f64 {
26 match self {
27 Self::Strict => STRICT_THRESHOLD,
28 Self::Default => DEFAULT_THRESHOLD,
29 Self::Lenient => LENIENT_THRESHOLD,
30 }
31 }
32}
33
34pub fn is_valid_threshold(value: f64) -> bool {
36 value.is_finite() && value > 0.0
37}
38
39#[derive(Debug, Clone, PartialEq)]
41pub struct ThresholdOverride {
42 pub pattern: String,
44 pub threshold: f64,
46}
47
48#[derive(Debug, Clone, PartialEq)]
54pub struct ThresholdConfig {
55 pub global: f64,
57 pub overrides: Vec<ThresholdOverride>,
59}
60
61impl Default for ThresholdConfig {
62 fn default() -> Self {
63 Self {
64 global: DEFAULT_THRESHOLD,
65 overrides: Vec::new(),
66 }
67 }
68}
69
70impl ThresholdConfig {
71 pub fn has_overrides(&self) -> bool {
73 !self.overrides.is_empty()
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80
81 #[test]
82 fn threshold_constants() {
83 assert_eq!(DEFAULT_THRESHOLD, 25.0);
84 assert_eq!(STRICT_THRESHOLD, 15.0);
85 assert_eq!(LENIENT_THRESHOLD, 40.0);
86 }
87
88 #[test]
89 fn preset_to_threshold() {
90 assert_eq!(ThresholdPreset::Strict.threshold(), STRICT_THRESHOLD);
91 assert_eq!(ThresholdPreset::Default.threshold(), DEFAULT_THRESHOLD);
92 assert_eq!(ThresholdPreset::Lenient.threshold(), LENIENT_THRESHOLD);
93 }
94
95 #[test]
96 fn default_config_uses_default_threshold() {
97 let config = ThresholdConfig::default();
98 assert_eq!(config.global, DEFAULT_THRESHOLD);
99 assert!(config.overrides.is_empty());
100 }
101
102 #[test]
103 fn has_overrides_false_when_empty() {
104 let config = ThresholdConfig::default();
105 assert!(!config.has_overrides());
106 }
107
108 #[test]
109 fn has_overrides_true_when_present() {
110 let config = ThresholdConfig {
111 global: DEFAULT_THRESHOLD,
112 overrides: vec![ThresholdOverride {
113 pattern: "domain/**".to_string(),
114 threshold: 5.0,
115 }],
116 };
117 assert!(config.has_overrides());
118 }
119
120 #[test]
121 fn is_valid_threshold_accepts_positive_finite() {
122 assert!(is_valid_threshold(1.0));
123 assert!(is_valid_threshold(0.001));
124 assert!(is_valid_threshold(DEFAULT_THRESHOLD));
125 assert!(is_valid_threshold(100.0));
126 }
127
128 #[test]
129 fn is_valid_threshold_rejects_invalid() {
130 assert!(!is_valid_threshold(0.0));
131 assert!(!is_valid_threshold(-1.0));
132 assert!(!is_valid_threshold(f64::NAN));
133 assert!(!is_valid_threshold(f64::INFINITY));
134 assert!(!is_valid_threshold(f64::NEG_INFINITY));
135 }
136
137 #[test]
138 fn threshold_override_equality() {
139 let a = ThresholdOverride {
140 pattern: "src/**".to_string(),
141 threshold: 10.0,
142 };
143 let b = ThresholdOverride {
144 pattern: "src/**".to_string(),
145 threshold: 10.0,
146 };
147 assert_eq!(a, b);
148 }
149}