time: Add saturating arithmetic for SystemTime
This commit implements the following methods: * `SystemTime::saturating_add` * `SystemTime::saturating_sub` * `SystemTime::saturating_duration_since` The implementation of these methods is rather trivial, as the main logic lies behind the constants `SystemTime::MIN` and `SystemTime::MAX`.
This commit is contained in:
parent
bcf787a780
commit
567b569e2b
2 changed files with 89 additions and 0 deletions
|
|
@ -682,6 +682,56 @@ impl SystemTime {
|
|||
pub fn checked_sub(&self, duration: Duration) -> Option<SystemTime> {
|
||||
self.0.checked_sub_duration(&duration).map(SystemTime)
|
||||
}
|
||||
|
||||
/// Saturating [`SystemTime`] addition, computing `self + duration`,
|
||||
/// returning [`SystemTime::MAX`] if overflow occurred.
|
||||
///
|
||||
/// In the case that the `duration` is smaller than the time precision of
|
||||
/// the operating system, `self` will be returned.
|
||||
#[unstable(feature = "time_saturating_systemtime", issue = "151199")]
|
||||
pub fn saturating_add(&self, duration: Duration) -> SystemTime {
|
||||
self.checked_add(duration).unwrap_or(SystemTime::MAX)
|
||||
}
|
||||
|
||||
/// Saturating [`SystemTime`] subtraction, computing `self - duration`,
|
||||
/// returning [`SystemTime::MIN`] if overflow occurred.
|
||||
///
|
||||
/// In the case that the `duration` is smaller than the time precision of
|
||||
/// the operating system, `self` will be returned.
|
||||
#[unstable(feature = "time_saturating_systemtime", issue = "151199")]
|
||||
pub fn saturating_sub(&self, duration: Duration) -> SystemTime {
|
||||
self.checked_sub(duration).unwrap_or(SystemTime::MIN)
|
||||
}
|
||||
|
||||
/// Saturating computation of time elapsed from an earlier point in time,
|
||||
/// returning [`Duration::ZERO`] in the case that `earlier` is later or
|
||||
/// equal to `self`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
/// #![feature(time_saturating_systemtime)]
|
||||
/// use std::time::{Duration, SystemTime};
|
||||
///
|
||||
/// let now = SystemTime::now();
|
||||
/// let prev = now.saturating_sub(Duration::new(1, 0));
|
||||
///
|
||||
/// // now - prev should return non-zero.
|
||||
/// assert_eq!(now.saturating_duration_since(prev), Duration::new(1, 0));
|
||||
/// assert!(now.duration_since(prev).is_ok());
|
||||
///
|
||||
/// // prev - now should return zero (and fail with the non-saturating).
|
||||
/// assert_eq!(prev.saturating_duration_since(now), Duration::ZERO);
|
||||
/// assert!(prev.duration_since(now).is_err());
|
||||
///
|
||||
/// // now - now should return zero (and work with the non-saturating).
|
||||
/// assert_eq!(now.saturating_duration_since(now), Duration::ZERO);
|
||||
/// assert!(now.duration_since(now).is_ok());
|
||||
/// ```
|
||||
#[unstable(feature = "time_saturating_systemtime", issue = "151199")]
|
||||
pub fn saturating_duration_since(&self, earlier: SystemTime) -> Duration {
|
||||
self.duration_since(earlier).unwrap_or(Duration::ZERO)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "time2", since = "1.8.0")]
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#![feature(duration_constants)]
|
||||
#![feature(time_systemtime_limits)]
|
||||
#![feature(time_saturating_systemtime)]
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH};
|
||||
|
|
@ -269,3 +270,41 @@ fn system_time_max_min() {
|
|||
assert!(SystemTime::MIN.checked_add(MIN_INTERVAL).is_some());
|
||||
assert!(SystemTime::MIN.checked_sub(MIN_INTERVAL).is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn system_time_saturating() {
|
||||
// Perform saturating addition on SystemTime::MAX to see how it behaves.
|
||||
assert_eq!(SystemTime::MAX.saturating_add(Duration::ZERO), SystemTime::MAX);
|
||||
assert_eq!(SystemTime::MAX.saturating_add(Duration::new(1, 0)), SystemTime::MAX);
|
||||
assert!(SystemTime::MAX.checked_add(Duration::new(1, 0)).is_none());
|
||||
assert_eq!(
|
||||
SystemTime::MAX.saturating_sub(Duration::new(1, 0)),
|
||||
SystemTime::MAX.checked_sub(Duration::new(1, 0)).unwrap()
|
||||
);
|
||||
|
||||
// Perform saturating subtraction on SystemTime::MIn to see how it behaves.
|
||||
assert_eq!(SystemTime::MIN.saturating_sub(Duration::ZERO), SystemTime::MIN);
|
||||
assert_eq!(SystemTime::MIN.saturating_sub(Duration::new(1, 0)), SystemTime::MIN);
|
||||
assert!(SystemTime::MIN.checked_sub(Duration::new(1, 0)).is_none());
|
||||
assert_eq!(
|
||||
SystemTime::MIN.saturating_add(Duration::new(1, 0)),
|
||||
SystemTime::MIN.checked_add(Duration::new(1, 0)).unwrap()
|
||||
);
|
||||
|
||||
// Check saturating_duration_since with various constant values.
|
||||
assert!(SystemTime::MAX.saturating_duration_since(SystemTime::MIN) >= Duration::ZERO);
|
||||
assert_eq!(SystemTime::MAX.saturating_duration_since(SystemTime::MAX), Duration::ZERO);
|
||||
assert!(SystemTime::MAX.duration_since(SystemTime::MAX).is_ok());
|
||||
assert_eq!(SystemTime::MIN.saturating_duration_since(SystemTime::MAX), Duration::ZERO);
|
||||
assert!(SystemTime::MIN.duration_since(SystemTime::MAX).is_err());
|
||||
assert_eq!(
|
||||
(SystemTime::UNIX_EPOCH + Duration::new(1, 0))
|
||||
.saturating_duration_since(SystemTime::UNIX_EPOCH),
|
||||
Duration::new(1, 0)
|
||||
);
|
||||
assert_eq!(
|
||||
SystemTime::UNIX_EPOCH
|
||||
.saturating_duration_since(SystemTime::UNIX_EPOCH + Duration::new(1, 0)),
|
||||
Duration::ZERO
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue