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}