use std::time::{Duration, SystemTime, UNIX_EPOCH};
pub fn unix_ms_after(duration: Duration) -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis()
.saturating_add(duration.as_millis())
.min(u64::MAX as u128) as u64
}
pub const MAX_DEADLINE_HORIZON: Duration = Duration::from_secs(300);
pub fn clamp_unix_ms(deadline_unix_ms: u64) -> u64 {
unix_ms_after(MAX_DEADLINE_HORIZON).min(deadline_unix_ms)
}
pub fn duration_until_unix_ms(deadline_unix_ms: u64) -> Duration {
let now_ms = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis()
.min(u64::MAX as u128) as u64;
Duration::from_millis(deadline_unix_ms.saturating_sub(now_ms)).min(MAX_DEADLINE_HORIZON)
}
#[cfg(feature = "tokio")]
pub(crate) fn instant_from_unix_ms(deadline_unix_ms: u64) -> tokio::time::Instant {
tokio::time::Instant::now() + duration_until_unix_ms(deadline_unix_ms)
}
#[cfg(feature = "tokio")]
pub(crate) fn unix_ms_from_instant(deadline: tokio::time::Instant) -> u64 {
let remaining = deadline.saturating_duration_since(tokio::time::Instant::now());
unix_ms_after(remaining)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn generated_deadline_is_not_in_the_past() {
let before = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_millis() as u64;
assert!(unix_ms_after(Duration::from_secs(1)) >= before.saturating_add(1_000));
}
#[cfg(feature = "tokio")]
#[tokio::test]
async fn far_future_deadlines_are_clamped_to_the_horizon() {
let saturated = instant_from_unix_ms(u64::MAX);
let far = instant_from_unix_ms(unix_ms_after(Duration::from_secs(86_400)));
let ceiling = tokio::time::Instant::now() + MAX_DEADLINE_HORIZON;
assert!(saturated <= ceiling);
assert!(far <= ceiling);
}
#[cfg(feature = "tokio")]
#[tokio::test]
async fn deadlines_inside_the_horizon_are_preserved() {
let floor = tokio::time::Instant::now() + Duration::from_secs(25);
let instant = instant_from_unix_ms(unix_ms_after(Duration::from_secs(30)));
let ceiling = tokio::time::Instant::now() + Duration::from_secs(31);
assert!(instant > floor);
assert!(instant <= ceiling);
}
#[cfg(feature = "tokio")]
#[test]
fn clamping_a_wire_deadline_is_idempotent_and_bounded() {
let clamped = clamp_unix_ms(u64::MAX);
assert!(clamped <= unix_ms_after(MAX_DEADLINE_HORIZON));
let near = unix_ms_after(Duration::from_secs(5));
assert_eq!(clamp_unix_ms(near), near);
}
#[test]
fn horizon_covers_the_documented_operation_timeout() {
assert!(MAX_DEADLINE_HORIZON >= Duration::from_secs(30));
}
}