use crate::error::RillError;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum DriftLevel {
#[default]
None,
Warning,
Drift,
}
impl DriftLevel {
pub const fn as_str(&self) -> &'static str {
match self {
DriftLevel::None => "none",
DriftLevel::Warning => "warning",
DriftLevel::Drift => "drift",
}
}
pub const fn is_change(self) -> bool {
matches!(self, DriftLevel::Warning | DriftLevel::Drift)
}
}
pub trait DriftDetector {
fn update(&mut self, value: f64) -> Result<DriftLevel, RillError>;
fn detected(&self) -> bool;
fn warning(&self) -> bool;
fn level(&self) -> DriftLevel;
fn samples_seen(&self) -> u64;
fn reset(&mut self);
fn last_value(&self) -> f64 {
0.0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn drift_level_as_str() {
assert_eq!(DriftLevel::None.as_str(), "none");
assert_eq!(DriftLevel::Warning.as_str(), "warning");
assert_eq!(DriftLevel::Drift.as_str(), "drift");
}
#[test]
fn drift_level_is_change() {
assert!(!DriftLevel::None.is_change());
assert!(DriftLevel::Warning.is_change());
assert!(DriftLevel::Drift.is_change());
}
#[test]
fn drift_level_default_is_none() {
assert_eq!(DriftLevel::default(), DriftLevel::None);
}
}