libspot_rs/
config.rs

1//! Configuration types for SPOT detector
2
3/// Configuration parameters for SPOT detector
4#[derive(Debug, Clone, PartialEq)]
5pub struct SpotConfig {
6    /// Anomaly probability threshold (must be between 0 and 1-level)
7    pub q: f64,
8    /// Whether to observe lower tail (false = upper tail, true = lower tail)
9    pub low_tail: bool,
10    /// Whether to discard anomalies from model updates
11    pub discard_anomalies: bool,
12    /// Excess level - high quantile that delimits the tail (must be between 0 and 1)
13    pub level: f64,
14    /// Maximum number of excess data points to keep
15    pub max_excess: usize,
16}
17
18impl Default for SpotConfig {
19    /// Default configuration that matches the C implementation
20    fn default() -> Self {
21        Self {
22            q: 0.0001,
23            low_tail: false,
24            discard_anomalies: true,
25            level: 0.998,
26            max_excess: 200,
27        }
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use super::*;
34    use approx::assert_relative_eq;
35
36    #[test]
37    fn test_spot_config_default() {
38        let config = SpotConfig::default();
39
40        assert_relative_eq!(config.q, 0.0001);
41        assert!(!config.low_tail);
42        assert!(config.discard_anomalies);
43        assert_relative_eq!(config.level, 0.998);
44        assert_eq!(config.max_excess, 200);
45    }
46
47    #[test]
48    fn test_spot_config_clone() {
49        let config1 = SpotConfig::default();
50        let config2 = config1.clone();
51
52        assert_relative_eq!(config1.q, config2.q);
53        assert_eq!(config1.low_tail, config2.low_tail);
54        assert_eq!(config1.discard_anomalies, config2.discard_anomalies);
55        assert_relative_eq!(config1.level, config2.level);
56        assert_eq!(config1.max_excess, config2.max_excess);
57    }
58}