use std::time::{Duration, Instant};
#[derive(Debug, PartialEq)]
pub enum FreezeTimeoutStatus {
NotFreezing,
StillFreezing,
Applied,
TimedOut {
has_proposals: bool,
},
}
#[derive(Debug, Clone, Default)]
pub struct PhaseTimer {
started_at: Option<Instant>,
}
impl PhaseTimer {
pub fn new() -> Self {
Self::default()
}
pub fn start(&mut self) {
self.started_at = Some(Instant::now());
}
pub fn clear(&mut self) {
self.started_at = None;
}
pub fn started_at(&self) -> Option<Instant> {
self.started_at
}
pub fn elapsed_since_anchor(&self, duration: Duration) -> bool {
match self.started_at {
Some(t) => Instant::now() >= t + duration,
None => false,
}
}
#[cfg(test)]
pub(crate) fn set_started_at_for_test(&mut self, anchor: Option<Instant>) {
self.started_at = anchor;
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn unset_never_elapsed() {
let pt = PhaseTimer::new();
assert!(!pt.elapsed_since_anchor(Duration::from_secs(1)));
}
#[test]
fn fresh_anchor_not_elapsed() {
let mut pt = PhaseTimer::new();
pt.start();
assert!(!pt.elapsed_since_anchor(Duration::from_secs(60)));
}
#[test]
fn elapsed_when_anchor_old_enough() {
let mut pt = PhaseTimer::new();
pt.started_at = Some(Instant::now() - Duration::from_secs(30));
assert!(pt.elapsed_since_anchor(Duration::from_secs(1)));
}
#[test]
fn clear_drops_anchor() {
let mut pt = PhaseTimer::new();
pt.start();
assert!(pt.started_at().is_some());
pt.clear();
assert!(pt.started_at().is_none());
}
}