1use core::time::Duration;
4
5pub trait Resolution {
11 const MAX_DURATION: Duration;
14
15 fn cycle_steps(duration: &Duration, upper_bound: bool) -> u32;
20
21 fn whole_steps(duration: &Duration) -> u64;
24
25 fn steps_as_duration(steps: u64) -> Duration;
27}
28
29#[derive(Debug)]
31pub enum MicrosecondResolution {}
32
33impl Resolution for MicrosecondResolution {
34 const MAX_DURATION: Duration = Duration::from_micros(u32::MAX as u64);
35
36 #[allow(clippy::cast_possible_truncation)]
37 #[inline]
38 fn cycle_steps(duration: &Duration, upper_bound: bool) -> u32 {
39 let mut steps = (duration.as_secs() * 1_000_000) as u32;
40 let micros = duration.subsec_micros();
41 steps += micros;
42 if upper_bound && duration.subsec_nanos() % 1_000 > 0 {
43 steps = steps.saturating_add(1);
44 }
45 steps
46 }
47
48 #[inline]
49 fn steps_as_duration(steps: u64) -> Duration {
50 Duration::from_micros(steps)
51 }
52
53 #[inline]
54 #[allow(clippy::cast_possible_truncation)]
55 fn whole_steps(duration: &Duration) -> u64 {
56 (duration.as_nanos() / 1_000) as u64
57 }
58}
59
60#[derive(Debug)]
62pub enum MillisecondResolution {}
63
64impl Resolution for MillisecondResolution {
65 const MAX_DURATION: Duration = Duration::from_millis(u32::MAX as u64);
66
67 #[allow(clippy::cast_possible_truncation)]
68 #[inline]
69 fn cycle_steps(duration: &Duration, upper_bound: bool) -> u32 {
70 let mut steps = (duration.as_secs() * 1000) as u32;
71 let ms = duration.subsec_millis();
72 steps += ms;
73
74 if upper_bound && duration.subsec_nanos() % 1_000_000 > 0 {
75 steps = steps.saturating_add(1);
76 }
77
78 steps
79 }
80
81 #[inline]
82 fn steps_as_duration(steps: u64) -> Duration {
83 Duration::from_millis(steps)
84 }
85
86 #[inline]
87 #[allow(clippy::cast_possible_truncation)]
88 fn whole_steps(duration: &Duration) -> u64 {
89 duration.as_millis() as u64
90 }
91}
92
93#[derive(Debug)]
95pub enum SecondResolution {}
96
97impl Resolution for SecondResolution {
98 const MAX_DURATION: Duration = Duration::from_secs(u32::MAX as u64);
99
100 #[allow(clippy::cast_possible_truncation)]
101 #[inline]
102 fn cycle_steps(duration: &Duration, upper_bound: bool) -> u32 {
103 let mut steps = duration.as_secs() as u32;
104 if upper_bound && duration.subsec_nanos() > 0 {
105 steps = steps.saturating_add(1);
106 }
107 steps
108 }
109
110 #[inline]
111 fn steps_as_duration(steps: u64) -> Duration {
112 Duration::from_secs(steps)
113 }
114
115 #[inline]
116 fn whole_steps(duration: &Duration) -> u64 {
117 duration.as_secs()
118 }
119}