1 use crate::Duration; 2 use core::{ 3 cmp::{Ord, Ordering, PartialEq, PartialOrd}, 4 ops::{Add, AddAssign, Sub, SubAssign}, 5 time::Duration as StdDuration, 6 }; 7 use standback::convert::{TryFrom, TryInto}; 8 use std::time::Instant as StdInstant; 9 10 /// A measurement of a monotonically non-decreasing clock. Opaque and useful 11 /// only with [`Duration`]. 12 /// 13 /// Instants are always guaranteed to be no less than any previously measured 14 /// instant when created, and are often useful for tasks such as measuring 15 /// benchmarks or timing how long an operation takes. 16 /// 17 /// Note, however, that instants are not guaranteed to be **steady**. In other 18 /// words, each tick of the underlying clock may not be the same length (e.g. 19 /// some seconds may be longer than others). An instant may jump forwards or 20 /// experience time dilation (slow down or speed up), but it will never go 21 /// backwards. 22 /// 23 /// Instants are opaque types that can only be compared to one another. There is 24 /// no method to get "the number of seconds" from an instant. Instead, it only 25 /// allows measuring the duration between two instants (or comparing two 26 /// instants). 27 /// 28 /// This implementation allows for operations with signed [`Duration`]s, but is 29 /// otherwise identical to [`std::time::Instant`]. 30 #[cfg_attr(__time_02_docs, doc(cfg(feature = "std")))] 31 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 32 pub struct Instant { 33 /// Inner representation, using `std::time::Instant`. 34 inner: StdInstant, 35 } 36 37 impl Instant { 38 /// Returns an `Instant` corresponding to "now". 39 /// 40 /// ```rust 41 /// # use time::Instant; 42 /// println!("{:?}", Instant::now()); 43 /// ``` now() -> Self44 pub fn now() -> Self { 45 Self { 46 inner: StdInstant::now(), 47 } 48 } 49 50 /// Returns the amount of time elapsed since this instant was created. The 51 /// duration will always be nonnegative if the instant is not synthetically 52 /// created. 53 /// 54 /// ```rust 55 /// # use time::{Instant, prelude::*}; 56 /// # use std::thread; 57 /// let instant = Instant::now(); 58 /// thread::sleep(1.std_milliseconds()); 59 /// assert!(instant.elapsed() >= 1.milliseconds()); 60 /// ``` elapsed(self) -> Duration61 pub fn elapsed(self) -> Duration { 62 Self::now() - self 63 } 64 65 /// Returns `Some(t)` where `t` is the time `self + duration` if `t` can be 66 /// represented as `Instant` (which means it's inside the bounds of the 67 /// underlying data structure), `None` otherwise. 68 /// 69 /// ```rust 70 /// # use time::{Instant, prelude::*}; 71 /// let now = Instant::now(); 72 /// assert_eq!( 73 /// now.checked_add(5.seconds()), 74 /// Some(now + 5.seconds()) 75 /// ); 76 /// assert_eq!( 77 /// now.checked_add((-5).seconds()), 78 /// Some(now + (-5).seconds()) 79 /// ); 80 /// ``` 81 /// 82 /// This function is only present when using rustc >= 1.34.0. 83 #[cfg(__time_02_instant_checked_ops)] checked_add(self, duration: Duration) -> Option<Self>84 pub fn checked_add(self, duration: Duration) -> Option<Self> { 85 if duration.is_zero() { 86 Some(self) 87 } else if duration.is_positive() { 88 self.inner.checked_add(duration.abs_std()).map(From::from) 89 } else { 90 // duration.is_negative() 91 self.inner.checked_sub(duration.abs_std()).map(From::from) 92 } 93 } 94 95 /// Returns `Some(t)` where `t` is the time `self - duration` if `t` can be 96 /// represented as `Instant` (which means it's inside the bounds of the 97 /// underlying data structure), `None` otherwise. 98 /// 99 /// ```rust 100 /// # use time::{Instant, prelude::*}; 101 /// let now = Instant::now(); 102 /// assert_eq!( 103 /// now.checked_sub(5.seconds()), 104 /// Some(now - 5.seconds()) 105 /// ); 106 /// assert_eq!( 107 /// now.checked_sub((-5).seconds()), 108 /// Some(now - (-5).seconds()) 109 /// ); 110 /// ``` 111 /// 112 /// This function is only present when using rustc >= 1.34.0. 113 #[cfg(__time_02_instant_checked_ops)] checked_sub(self, duration: Duration) -> Option<Self>114 pub fn checked_sub(self, duration: Duration) -> Option<Self> { 115 self.checked_add(-duration) 116 } 117 } 118 119 #[allow(clippy::missing_docs_in_private_items)] 120 impl Instant { 121 #[cfg(feature = "deprecated")] 122 #[deprecated(since = "0.2.0", note = "Use `rhs - lhs`")] to(&self, later: Self) -> Duration123 pub fn to(&self, later: Self) -> Duration { 124 later - *self 125 } 126 } 127 128 impl From<StdInstant> for Instant { from(instant: StdInstant) -> Self129 fn from(instant: StdInstant) -> Self { 130 Self { inner: instant } 131 } 132 } 133 134 impl From<Instant> for StdInstant { from(instant: Instant) -> Self135 fn from(instant: Instant) -> Self { 136 instant.inner 137 } 138 } 139 140 impl Sub for Instant { 141 type Output = Duration; 142 sub(self, other: Self) -> Self::Output143 fn sub(self, other: Self) -> Self::Output { 144 match self.inner.cmp(&other.inner) { 145 Ordering::Equal => Duration::zero(), 146 Ordering::Greater => (self.inner - other.inner) 147 .try_into() 148 .expect("overflow converting `std::time::Duration` to `time::Duration`"), 149 Ordering::Less => -Duration::try_from(other.inner - self.inner) 150 .expect("overflow converting `std::time::Duration` to `time::Duration`"), 151 } 152 } 153 } 154 155 impl Sub<StdInstant> for Instant { 156 type Output = Duration; 157 sub(self, other: StdInstant) -> Self::Output158 fn sub(self, other: StdInstant) -> Self::Output { 159 self - Self::from(other) 160 } 161 } 162 163 impl Sub<Instant> for StdInstant { 164 type Output = Duration; 165 sub(self, other: Instant) -> Self::Output166 fn sub(self, other: Instant) -> Self::Output { 167 Instant::from(self) - other 168 } 169 } 170 171 impl Add<Duration> for Instant { 172 type Output = Self; 173 add(self, duration: Duration) -> Self::Output174 fn add(self, duration: Duration) -> Self::Output { 175 if duration.is_positive() { 176 (self.inner + duration.abs_std()).into() 177 } else if duration.is_negative() { 178 (self.inner - duration.abs_std()).into() 179 } else { 180 self 181 } 182 } 183 } 184 185 impl Add<Duration> for StdInstant { 186 type Output = Self; 187 add(self, duration: Duration) -> Self::Output188 fn add(self, duration: Duration) -> Self::Output { 189 (Instant::from(self) + duration).into() 190 } 191 } 192 193 impl Add<StdDuration> for Instant { 194 type Output = Self; 195 add(self, duration: StdDuration) -> Self::Output196 fn add(self, duration: StdDuration) -> Self::Output { 197 Self { 198 inner: self.inner + duration, 199 } 200 } 201 } 202 203 impl AddAssign<Duration> for Instant { add_assign(&mut self, duration: Duration)204 fn add_assign(&mut self, duration: Duration) { 205 *self = *self + duration; 206 } 207 } 208 209 impl AddAssign<Duration> for StdInstant { add_assign(&mut self, duration: Duration)210 fn add_assign(&mut self, duration: Duration) { 211 *self = *self + duration; 212 } 213 } 214 215 impl AddAssign<StdDuration> for Instant { add_assign(&mut self, duration: StdDuration)216 fn add_assign(&mut self, duration: StdDuration) { 217 *self = *self + duration; 218 } 219 } 220 221 impl Sub<Duration> for Instant { 222 type Output = Self; 223 sub(self, duration: Duration) -> Self::Output224 fn sub(self, duration: Duration) -> Self::Output { 225 self + -duration 226 } 227 } 228 229 impl Sub<Duration> for StdInstant { 230 type Output = Self; 231 sub(self, duration: Duration) -> Self::Output232 fn sub(self, duration: Duration) -> Self::Output { 233 (Instant::from(self) - duration).into() 234 } 235 } 236 237 impl Sub<StdDuration> for Instant { 238 type Output = Self; 239 sub(self, duration: StdDuration) -> Self::Output240 fn sub(self, duration: StdDuration) -> Self::Output { 241 Self { 242 inner: self.inner - duration, 243 } 244 } 245 } 246 247 impl SubAssign<Duration> for Instant { sub_assign(&mut self, duration: Duration)248 fn sub_assign(&mut self, duration: Duration) { 249 *self = *self - duration; 250 } 251 } 252 253 impl SubAssign<Duration> for StdInstant { sub_assign(&mut self, duration: Duration)254 fn sub_assign(&mut self, duration: Duration) { 255 *self = *self - duration; 256 } 257 } 258 259 impl SubAssign<StdDuration> for Instant { sub_assign(&mut self, duration: StdDuration)260 fn sub_assign(&mut self, duration: StdDuration) { 261 *self = *self - duration; 262 } 263 } 264 265 impl PartialEq<StdInstant> for Instant { eq(&self, rhs: &StdInstant) -> bool266 fn eq(&self, rhs: &StdInstant) -> bool { 267 self.inner.eq(rhs) 268 } 269 } 270 271 impl PartialEq<Instant> for StdInstant { eq(&self, rhs: &Instant) -> bool272 fn eq(&self, rhs: &Instant) -> bool { 273 self.eq(&rhs.inner) 274 } 275 } 276 277 impl PartialOrd<StdInstant> for Instant { partial_cmp(&self, rhs: &StdInstant) -> Option<Ordering>278 fn partial_cmp(&self, rhs: &StdInstant) -> Option<Ordering> { 279 self.inner.partial_cmp(rhs) 280 } 281 } 282 283 impl PartialOrd<Instant> for StdInstant { partial_cmp(&self, rhs: &Instant) -> Option<Ordering>284 fn partial_cmp(&self, rhs: &Instant) -> Option<Ordering> { 285 self.partial_cmp(&rhs.inner) 286 } 287 } 288