anode/
deadline.rs

1use std::time::{Duration, Instant};
2
3#[derive(Debug)]
4pub enum Deadline {
5    Point(Instant),
6    Forever,
7    Uninitialized(Duration),
8    Elapsed,
9}
10
11impl Deadline {
12    #[inline(always)]
13    pub fn lazy_after(duration: Duration) -> Self {
14        Self::Uninitialized(duration)
15    }
16
17    #[inline(always)]
18    pub fn after(duration: Duration) -> Self {
19        let mut deadline = Self::lazy_after(duration);
20        deadline.ensure_initialized();
21        deadline
22    }
23
24    #[inline(always)]
25    fn saturating_add(instant: Instant, duration: Duration) -> Self {
26        match instant.checked_add(duration) {
27            None => Deadline::Forever,
28            Some(instant) => Deadline::Point(instant),
29        }
30    }
31
32    #[inline(always)]
33    fn ensure_initialized(&mut self) {
34        if let Self::Uninitialized(duration) = self {
35            if duration == &Duration::MAX {
36                *self = Deadline::Forever;
37            } else if duration ==  &Duration::ZERO {
38                *self = Deadline::Elapsed;
39            } else {
40                *self = Self::saturating_add(Instant::now(), *duration);
41            }
42        }
43    }
44
45    #[inline(always)]
46    pub fn remaining(&mut self) -> Duration {
47        self.ensure_initialized();
48
49        match self {
50            Deadline::Point(instant) => *instant - Instant::now(),
51            Deadline::Forever => Duration::MAX,
52            Deadline::Elapsed => Duration::ZERO,
53            _ => unreachable!(),
54        }
55    }
56}