use std::time::{Duration, Instant};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Deadline {
instant: Instant,
}
impl Deadline {
#[must_use]
pub fn after(duration: Duration) -> Self {
Self {
instant: Instant::now() + duration,
}
}
#[must_use]
pub const fn at(instant: Instant) -> Self {
Self { instant }
}
#[must_use]
pub fn is_expired(&self) -> bool {
Instant::now() >= self.instant
}
#[must_use]
pub fn remaining(&self) -> Duration {
self.instant.saturating_duration_since(Instant::now())
}
#[must_use]
pub const fn instant(&self) -> Instant {
self.instant
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct DurationBudget {
pub millis: u64,
}
impl DurationBudget {
#[must_use]
pub const fn from_millis(millis: u64) -> Self {
Self { millis }
}
#[must_use]
pub const fn as_duration(self) -> Duration {
Duration::from_millis(self.millis)
}
#[must_use]
pub fn to_deadline(self) -> Deadline {
Deadline::after(self.as_duration())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn expired_zero() {
let d = Deadline::after(Duration::ZERO);
assert!(d.remaining().is_zero() || d.is_expired());
}
}