Skip to main content

pipecircuit/timer/
wake_after.rs

1use core::num::NonZeroU64;
2
3#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
4pub enum WakePrecision {
5    Nanosecond,
6    Microsecond,
7    Millisecond,
8    Second,
9}
10
11impl WakePrecision {
12    pub const fn nanoseconds_per_tick(self) -> NonZeroU64 {
13        match self {
14            Self::Nanosecond => NonZeroU64::MIN,
15            Self::Microsecond => const { NonZeroU64::MIN.saturating_add(999) },
16            Self::Millisecond => const { NonZeroU64::MIN.saturating_add(999_999) },
17            Self::Second => const { NonZeroU64::MIN.saturating_add(999_999_999) },
18        }
19    }
20}
21
22#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
23pub struct WakeAfter {
24    ticks: NonZeroU64,
25    precision: WakePrecision,
26}
27
28impl WakeAfter {
29    pub const fn nanoseconds(ticks: NonZeroU64) -> Self {
30        Self::new(ticks, WakePrecision::Nanosecond)
31    }
32
33    pub const fn microseconds(ticks: NonZeroU64) -> Self {
34        Self::new(ticks, WakePrecision::Microsecond)
35    }
36
37    pub const fn milliseconds(ticks: NonZeroU64) -> Self {
38        Self::new(ticks, WakePrecision::Millisecond)
39    }
40
41    pub const fn seconds(ticks: NonZeroU64) -> Self {
42        Self::new(ticks, WakePrecision::Second)
43    }
44
45    pub const fn new(ticks: NonZeroU64, precision: WakePrecision) -> Self {
46        Self { ticks, precision }
47    }
48
49    pub const fn ticks(self) -> NonZeroU64 {
50        self.ticks
51    }
52
53    pub const fn precision(self) -> WakePrecision {
54        self.precision
55    }
56
57    pub const fn checked_nanoseconds(self) -> Option<NonZeroU64> {
58        let nanoseconds = self
59            .ticks
60            .get()
61            .checked_mul(self.precision.nanoseconds_per_tick().get());
62        match nanoseconds {
63            Some(nanoseconds) => NonZeroU64::new(nanoseconds),
64            None => None,
65        }
66    }
67}