crux_time/protocol/
duration.rs

1use serde::{Deserialize, Serialize};
2
3/// The number of nanoseconds in seconds.
4const NANOS_PER_SEC: u32 = 1_000_000_000;
5/// The number of nanoseconds in a millisecond.
6const NANOS_PER_MILLI: u32 = 1_000_000;
7
8/// Represents a duration of time, internally stored as nanoseconds
9#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase")]
11pub struct Duration {
12    pub(crate) nanos: u64,
13}
14
15impl Duration {
16    /// Create a new `Duration` from the given number of nanoseconds.
17    pub fn new(nanos: u64) -> Self {
18        Self { nanos }
19    }
20
21    /// Create a new `Duration` from the given number of milliseconds.
22    ///
23    /// Panics if the number of milliseconds
24    /// would overflow when converted to nanoseconds.
25    pub fn from_millis(millis: u64) -> Self {
26        let nanos = millis
27            .checked_mul(NANOS_PER_MILLI as u64)
28            .expect("millis overflow");
29        Self { nanos }
30    }
31
32    /// Create a new `Duration` from the given number of seconds.
33    ///
34    /// Panics if the number of seconds
35    /// would overflow when converted to nanoseconds.
36    pub fn from_secs(seconds: u64) -> Self {
37        let nanos = seconds
38            .checked_mul(NANOS_PER_SEC as u64)
39            .expect("seconds overflow");
40        Self { nanos }
41    }
42}
43
44impl From<std::time::Duration> for Duration {
45    fn from(duration: std::time::Duration) -> Self {
46        Duration {
47            nanos: duration.as_nanos() as u64,
48        }
49    }
50}
51
52impl From<Duration> for std::time::Duration {
53    fn from(duration: Duration) -> Self {
54        std::time::Duration::from_nanos(duration.nanos)
55    }
56}
57
58#[cfg(test)]
59mod test {
60    use super::Duration;
61    use std::time::Duration as StdDuration;
62
63    #[test]
64    fn duration_from_millis() {
65        let duration = Duration::from_millis(1_000);
66        assert_eq!(duration.nanos, 1_000_000_000);
67    }
68
69    #[test]
70    fn duration_from_secs() {
71        let duration = Duration::from_secs(1);
72        assert_eq!(duration.nanos, 1_000_000_000);
73    }
74
75    #[test]
76    fn std_into_duration() {
77        let actual: Duration = StdDuration::from_millis(100).into();
78        let expected = Duration { nanos: 100_000_000 };
79        assert_eq!(actual, expected);
80    }
81
82    #[test]
83    fn duration_into_std() {
84        let actual: StdDuration = Duration { nanos: 100_000_000 }.into();
85        let expected = StdDuration::from_nanos(100_000_000);
86        assert_eq!(actual, expected);
87    }
88}