use std::time::Duration;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub struct HedgeThreshold(Duration);
impl HedgeThreshold {
pub const fn new(duration: Duration) -> Option<Self> {
if duration.is_zero() {
None
} else {
Some(Self(duration))
}
}
pub const fn get(self) -> Duration {
self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub struct HedgingStrategy {
threshold: HedgeThreshold,
}
impl HedgingStrategy {
pub const fn new(threshold: HedgeThreshold) -> Self {
Self { threshold }
}
pub const fn threshold(&self) -> HedgeThreshold {
self.threshold
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum AvailabilityStrategy {
Hedging(HedgingStrategy),
Disabled,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn hedge_threshold_rejects_zero() {
assert!(HedgeThreshold::new(Duration::ZERO).is_none());
}
#[test]
fn hedge_threshold_accepts_positive() {
let t = HedgeThreshold::new(Duration::from_millis(1)).expect("1ms is a valid threshold");
assert_eq!(t.get(), Duration::from_millis(1));
}
#[test]
fn hedge_threshold_get_roundtrip() {
let original = Duration::from_secs(2);
let t = HedgeThreshold::new(original).expect("non-zero");
assert_eq!(t.get(), original);
}
#[test]
fn hedging_strategy_exposes_threshold() {
let t = HedgeThreshold::new(Duration::from_millis(750)).unwrap();
let s = HedgingStrategy::new(t);
assert_eq!(s.threshold(), t);
}
#[test]
fn availability_strategy_equality() {
let t = HedgeThreshold::new(Duration::from_millis(500)).unwrap();
let a = AvailabilityStrategy::Hedging(HedgingStrategy::new(t));
let b = AvailabilityStrategy::Hedging(HedgingStrategy::new(t));
assert_eq!(a, b);
assert_ne!(a, AvailabilityStrategy::Disabled);
}
}