use std::task::Waker;
use std::time::Instant;
pub struct TimerFutureState {
pub completed: bool,
pub waker: Option<Waker>,
pub expiration: Instant,
}
impl TimerFutureState {
pub fn new(expiration: Instant) -> TimerFutureState {
TimerFutureState {
completed: false,
waker: None,
expiration,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::atomic::{AtomicBool, Ordering};
use std::task::Wake;
use std::time::Duration;
struct TestWaker {
woken: std::sync::Arc<AtomicBool>,
}
impl Wake for TestWaker {
fn wake(self: std::sync::Arc<Self>) {
self.woken.store(true, Ordering::SeqCst);
}
}
#[test]
fn test_new_timer_future_state() {
let now = Instant::now();
let state = TimerFutureState::new(now);
assert!(!state.completed);
assert!(state.waker.is_none());
assert_eq!(state.expiration, now);
}
#[test]
fn test_timer_future_state_with_future_expiration() {
let now = Instant::now();
let future_time = now + Duration::from_secs(5);
let state = TimerFutureState::new(future_time);
assert!(!state.completed);
assert!(state.waker.is_none());
assert_eq!(state.expiration, future_time);
assert!(state.expiration > now);
}
#[test]
fn test_timer_future_state_with_past_expiration() {
let now = Instant::now();
let past_time = now - Duration::from_secs(5);
let state = TimerFutureState::new(past_time);
assert!(!state.completed);
assert!(state.waker.is_none());
assert_eq!(state.expiration, past_time);
assert!(state.expiration < now);
}
#[test]
fn test_timer_future_state_waker_setting() {
let now = Instant::now();
let mut state = TimerFutureState::new(now);
assert!(state.waker.is_none());
let woken = std::sync::Arc::new(AtomicBool::new(false));
let waker = std::sync::Arc::new(TestWaker {
woken: woken.clone(),
});
let waker = std::task::Waker::from(waker);
state.waker = Some(waker);
assert!(state.waker.is_some());
assert!(!woken.load(Ordering::SeqCst));
}
#[test]
fn test_timer_future_state_completion() {
let now = Instant::now();
let mut state = TimerFutureState::new(now);
assert!(!state.completed);
state.completed = true;
assert!(state.completed);
}
#[test]
fn test_timer_future_state_expiration_comparison() {
let now = Instant::now();
let state1 = TimerFutureState::new(now);
let state2 = TimerFutureState::new(now + Duration::from_secs(1));
let state3 = TimerFutureState::new(now - Duration::from_secs(1));
assert_eq!(state1.expiration, now);
assert!(state2.expiration > state1.expiration);
assert!(state3.expiration < state1.expiration);
}
}