nautilus_network/ratelimiter/
nanos.rs1use std::{
19 fmt::Debug,
20 ops::{Add, Div, Mul},
21 prelude::v1::*,
22 time::Duration,
23};
24
25use super::clock;
26
27#[derive(PartialEq, Eq, Default, Clone, Copy, PartialOrd, Ord)]
32pub struct Nanos(u64);
33
34impl Nanos {
35 pub const fn as_u64(self) -> u64 {
36 self.0
37 }
38}
39
40#[cfg(feature = "std")]
42impl Nanos {
43 pub const fn new(u: u64) -> Self {
44 Self(u)
45 }
46}
47
48impl From<Duration> for Nanos {
49 fn from(d: Duration) -> Self {
50 Self(
52 d.as_nanos()
53 .try_into()
54 .expect("Duration is longer than 584 years"),
55 )
56 }
57}
58
59impl Debug for Nanos {
60 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
61 let d = Duration::from_nanos(self.0);
62 write!(f, "Nanos({d:?})")
63 }
64}
65
66impl Add<Self> for Nanos {
67 type Output = Self;
68
69 fn add(self, rhs: Self) -> Self::Output {
70 Self(self.0 + rhs.0)
71 }
72}
73
74impl Mul<u64> for Nanos {
75 type Output = Self;
76
77 fn mul(self, rhs: u64) -> Self::Output {
78 Self(self.0 * rhs)
79 }
80}
81
82impl Div<Self> for Nanos {
83 type Output = u64;
84
85 fn div(self, rhs: Self) -> Self::Output {
86 self.0 / rhs.0
87 }
88}
89
90impl From<u64> for Nanos {
91 fn from(u: u64) -> Self {
92 Self(u)
93 }
94}
95
96impl From<Nanos> for u64 {
97 fn from(n: Nanos) -> Self {
98 n.0
99 }
100}
101
102impl From<Nanos> for Duration {
103 fn from(n: Nanos) -> Self {
104 Self::from_nanos(n.0)
105 }
106}
107
108impl Nanos {
109 #[inline]
110 pub const fn saturating_sub(self, rhs: Self) -> Self {
111 Self(self.0.saturating_sub(rhs.0))
112 }
113}
114
115impl clock::Reference for Nanos {
116 #[inline]
117 fn duration_since(&self, earlier: Self) -> Nanos {
118 (*self as Self).saturating_sub(earlier)
119 }
120
121 #[inline]
122 fn saturating_sub(&self, duration: Nanos) -> Self {
123 (*self as Self).saturating_sub(duration)
124 }
125}
126
127impl Add<Duration> for Nanos {
128 type Output = Self;
129
130 fn add(self, other: Duration) -> Self {
131 let other: Self = other.into();
132 self + other
133 }
134}
135
136#[cfg(all(feature = "std", test))]
140mod test {
141 use std::time::Duration;
142
143 use super::*;
144
145 #[test]
146 fn nanos_impls() {
147 let n = Nanos::new(20);
148 assert_eq!("Nanos(20ns)", format!("{n:?}"));
149 }
150
151 #[test]
152 fn nanos_arith_coverage() {
153 let n = Nanos::new(20);
154 let n_half = Nanos::new(10);
155 assert_eq!(n / n_half, 2);
156 assert_eq!(30, (n + Duration::from_nanos(10)).as_u64());
157
158 assert_eq!(n_half.saturating_sub(n), Nanos::new(0));
159 assert_eq!(n.saturating_sub(n_half), n_half);
160 assert_eq!(clock::Reference::saturating_sub(&n_half, n), Nanos::new(0));
161 }
162}