crux_time/protocol/
duration.rs1use serde::{Deserialize, Serialize};
2
3const NANOS_PER_SEC: u32 = 1_000_000_000;
5const NANOS_PER_MILLI: u32 = 1_000_000;
7
8#[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 #[must_use]
18 pub fn new(nanos: u64) -> Self {
19 Self { nanos }
20 }
21
22 #[must_use]
27 pub fn from_millis(millis: u64) -> Self {
28 let nanos = millis
29 .checked_mul(u64::from(NANOS_PER_MILLI))
30 .expect("millis overflow");
31 Self { nanos }
32 }
33
34 #[must_use]
39 pub fn from_secs(seconds: u64) -> Self {
40 let nanos = seconds
41 .checked_mul(u64::from(NANOS_PER_SEC))
42 .expect("seconds overflow");
43 Self { nanos }
44 }
45}
46
47impl From<std::time::Duration> for Duration {
48 fn from(duration: std::time::Duration) -> Self {
49 Duration {
50 #[allow(clippy::cast_possible_truncation)]
52 nanos: duration.as_nanos() as u64,
53 }
54 }
55}
56
57impl From<Duration> for std::time::Duration {
58 fn from(duration: Duration) -> Self {
59 std::time::Duration::from_nanos(duration.nanos)
60 }
61}
62
63#[cfg(test)]
64mod test {
65 use super::Duration;
66 use std::time::Duration as StdDuration;
67
68 #[test]
69 fn duration_from_millis() {
70 let duration = Duration::from_millis(1_000);
71 assert_eq!(duration.nanos, 1_000_000_000);
72 }
73
74 #[test]
75 fn duration_from_secs() {
76 let duration = Duration::from_secs(1);
77 assert_eq!(duration.nanos, 1_000_000_000);
78 }
79
80 #[test]
81 fn std_into_duration() {
82 let actual: Duration = StdDuration::from_millis(100).into();
83 let expected = Duration { nanos: 100_000_000 };
84 assert_eq!(actual, expected);
85 }
86
87 #[test]
88 fn duration_into_std() {
89 let actual: StdDuration = Duration { nanos: 100_000_000 }.into();
90 let expected = StdDuration::from_nanos(100_000_000);
91 assert_eq!(actual, expected);
92 }
93}