use core::num::NonZeroU64;
use super::{
ElapsedTimerTokens, EmptyElapsedTimerTokens, Timer, TimerIn, TimerOut, TimerToken, WakeAfter,
};
use crate::Participant;
const fn nonzero(value: u64) -> Result<NonZeroU64, &'static str> {
match NonZeroU64::new(value) {
Some(value) => Ok(value),
None => Err("zero was not positive"),
}
}
#[test]
fn wake_after_preserves_the_declared_precision() -> Result<(), &'static str> {
let seconds = WakeAfter::seconds(nonzero(5)?);
let milliseconds = WakeAfter::milliseconds(nonzero(5_000)?);
assert_eq!(seconds.checked_nanoseconds(), nonzero(5_000_000_000).ok());
assert_eq!(
milliseconds.checked_nanoseconds(),
seconds.checked_nanoseconds()
);
assert_ne!(seconds, milliseconds);
assert_eq!(seconds.ticks(), nonzero(5)?);
assert_eq!(
seconds.precision().nanoseconds_per_tick(),
nonzero(1_000_000_000)?
);
Ok(())
}
#[test]
fn wake_after_reports_nanosecond_overflow() -> Result<(), &'static str> {
let after = WakeAfter::seconds(nonzero(u64::MAX)?);
assert_eq!(after.checked_nanoseconds(), None);
Ok(())
}
#[test]
fn elapsed_batches_are_nonempty() {
assert_eq!(
ElapsedTimerTokens::<u8>::try_new(&[]),
Err(EmptyElapsedTimerTokens)
);
let tokens = [3, 5, 8];
let Ok(elapsed) = ElapsedTimerTokens::try_new(&tokens) else {
return;
};
assert_eq!(elapsed.tokens(), &tokens);
}
#[test]
fn timer_protocol_preserves_arm_cancel_and_elapsed_facts() -> Result<(), &'static str> {
fn accepts_timer_input(_input: <Timer<u64> as Participant>::In<'_>) {}
fn accepts_timer_output(_output: <Timer<u64> as Participant>::Out<'_>) {}
let after = WakeAfter::milliseconds(nonzero(25)?);
accepts_timer_input(TimerIn::Arm { token: 7, after });
accepts_timer_input(TimerIn::Cancel { token: 7 });
let tokens = [7, 9];
let elapsed = ElapsedTimerTokens::try_new(&tokens).map_err(|_| "batch was empty")?;
accepts_timer_output(TimerOut::Elapsed { tokens: elapsed });
Ok(())
}
#[test]
fn timer_tokens_preserve_their_nonzero_value() -> Result<(), &'static str> {
let timer_token = TimerToken::from_nonzero(nonzero(17)?);
assert_eq!(timer_token.value(), nonzero(17)?);
Ok(())
}