Skip to main content

libspot_rs/
config.rs

1//! Configuration types for SPOT detector
2
3/// Configuration parameters for SPOT detector
4///
5/// # Serialization
6///
7/// When the `serde` feature is enabled, this struct can be serialized and deserialized.
8/// This is useful for saving detector configurations or loading them from files.
9///
10/// # Example with serde (requires `serde` feature)
11///
12/// ```ignore
13/// use libspot_rs::SpotConfig;
14/// use serde_json;
15///
16/// let config = SpotConfig::default();
17/// let json = serde_json::to_string(&config).unwrap();
18/// let loaded: SpotConfig = serde_json::from_str(&json).unwrap();
19/// ```
20#[derive(Debug, Clone, PartialEq)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22pub struct SpotConfig {
23    /// Anomaly probability threshold (must be between 0 and 1-level)
24    pub q: f64,
25    /// Whether to observe lower tail (false = upper tail, true = lower tail)
26    pub low_tail: bool,
27    /// Whether to discard anomalies from model updates
28    pub discard_anomalies: bool,
29    /// Excess level - high quantile that delimits the tail (must be between 0 and 1)
30    pub level: f64,
31    /// Maximum number of excess data points to keep
32    pub max_excess: usize,
33}
34
35impl Default for SpotConfig {
36    /// Default configuration that matches the C implementation
37    fn default() -> Self {
38        Self {
39            q: 0.0001,
40            low_tail: false,
41            discard_anomalies: true,
42            level: 0.998,
43            max_excess: 200,
44        }
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51    use approx::assert_relative_eq;
52
53    #[test]
54    fn test_spot_config_default() {
55        let config = SpotConfig::default();
56
57        assert_relative_eq!(config.q, 0.0001);
58        assert!(!config.low_tail);
59        assert!(config.discard_anomalies);
60        assert_relative_eq!(config.level, 0.998);
61        assert_eq!(config.max_excess, 200);
62    }
63
64    #[test]
65    fn test_spot_config_clone() {
66        let config1 = SpotConfig::default();
67        let config2 = config1.clone();
68
69        assert_relative_eq!(config1.q, config2.q);
70        assert_eq!(config1.low_tail, config2.low_tail);
71        assert_eq!(config1.discard_anomalies, config2.discard_anomalies);
72        assert_relative_eq!(config1.level, config2.level);
73        assert_eq!(config1.max_excess, config2.max_excess);
74    }
75}