statime/time/interval.rs
1#[allow(unused_imports)]
2use crate::float_polyfill::FloatPolyfill;
3
4/// A log2 representation of seconds used to describe the pacing of events in
5/// PTP
6#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
7pub struct Interval(i8);
8
9impl core::fmt::Debug for Interval {
10 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
11 f.debug_struct("Interval")
12 .field("seconds", &self.as_f64())
13 .field("log_base_2", &self.0)
14 .finish()
15 }
16}
17
18impl Interval {
19 /// An Interval of one second
20 pub const ONE_SECOND: Self = Self(0);
21
22 /// An Interval of two seconds
23 pub const TWO_SECONDS: Self = Self(1);
24
25 /// Construct an [`Interval`] from log2 seconds.
26 ///
27 /// # Example
28 /// ```
29 /// # use std::time::Duration;
30 /// # use statime::time::Interval;
31 /// assert_eq!(Interval::from_log_2(2).as_core_duration(), Duration::from_secs(4));
32 /// assert_eq!(Interval::from_log_2(-2).as_core_duration(), Duration::from_millis(250));
33 /// ```
34 pub const fn from_log_2(log_2: i8) -> Self {
35 Self(log_2)
36 }
37
38 /// Turn `self` into a number of seconds as [`f64`]
39 ///
40 /// # Example
41 /// ```
42 /// # use statime::time::Interval;
43 /// assert_eq!(Interval::from_log_2(1).seconds(), 2.0);
44 /// assert_eq!(Interval::from_log_2(-1).seconds(), 0.5);
45 /// ```
46 pub fn seconds(self) -> f64 {
47 self.as_f64()
48 }
49
50 /// Turn this into a [`statime::time::Duration`](`crate::time::Duration`)
51 ///
52 /// # Example
53 /// ```
54 /// # use statime::time::{Duration, Interval};
55 /// assert_eq!(Interval::from_log_2(3).as_duration(), Duration::from_secs(8));
56 /// assert_eq!(Interval::from_log_2(-3).as_duration(), Duration::from_millis(125));
57 /// ```
58 pub fn as_duration(self) -> super::Duration {
59 super::Duration::from_interval(self)
60 }
61
62 /// Turn this into a [`core::time::Duration`]
63 ///
64 /// # Example
65 /// ```
66 /// # use statime::time::{Interval};
67 /// use core::time::Duration;
68 /// assert_eq!(Interval::from_log_2(3).as_core_duration(), Duration::from_secs(8));
69 /// assert_eq!(Interval::from_log_2(-3).as_core_duration(), Duration::from_millis(125));
70 /// ```
71 pub fn as_core_duration(self) -> core::time::Duration {
72 core::time::Duration::from_secs_f64(self.seconds())
73 }
74
75 fn as_f64(self) -> f64 {
76 2.0f64.powi(self.0 as i32)
77 }
78
79 /// Get the log2 of the numbers of seconds of this [`Interval`]
80 ///
81 /// # Example
82 /// ```
83 /// # use statime::time::{Interval};
84 /// use core::time::Duration;
85 /// assert_eq!(Interval::ONE_SECOND.as_log_2(), 0);
86 /// assert_eq!(Interval::TWO_SECONDS.as_log_2(), 1);
87 /// ```
88 pub fn as_log_2(self) -> i8 {
89 self.0
90 }
91}
92
93impl From<i8> for Interval {
94 fn from(value: i8) -> Self {
95 Self::from_log_2(value)
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn two() {
105 assert_eq!(Interval::TWO_SECONDS.as_f64(), 2.0f64)
106 }
107}