From f116c18829aececcdbd1e879b0e0baa6e45ee075 Mon Sep 17 00:00:00 2001 From: Neil Isaac <111217+neilisaac@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:46:06 -0500 Subject: [PATCH] Add From and Into support for SystemTime using references Enable conversions between Timestamp and SystemTime using references without cloning, and add support for SystemTime::from(Timestamp) in addition to Into (which is derived from the From implementations) Refer to the note in https://doc.rust-lang.org/std/convert/trait.Into.html --- .../src/well_known_types_util/timestamp.rs | 40 +++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/protobuf/src/well_known_types_util/timestamp.rs b/protobuf/src/well_known_types_util/timestamp.rs index 0429fcfa1..c4949ca41 100644 --- a/protobuf/src/well_known_types_util/timestamp.rs +++ b/protobuf/src/well_known_types_util/timestamp.rs @@ -23,8 +23,8 @@ impl Timestamp { /// # Panics /// /// This function panics if given `SystemTime` is outside of `Timestamp` range. -impl From for Timestamp { - fn from(time: SystemTime) -> Self { +impl From<&SystemTime> for Timestamp { + fn from(time: &SystemTime) -> Self { match time.duration_since(SystemTime::UNIX_EPOCH) { Ok(since_epoch) => Timestamp { seconds: since_epoch.as_secs() as i64, @@ -44,6 +44,17 @@ impl From for Timestamp { } } +/// Convert from [`Timestamp`]. +/// +/// # Panics +/// +/// This function panics if given `SystemTime` is outside of `Timestamp` range. +impl From for Timestamp { + fn from(time: SystemTime) -> Self { + Self::from(&time) + } +} + /// Convert into [`SystemTime`]. /// /// The conversion could be lossy if `SystemTime` precision is smaller than nanoseconds. @@ -53,20 +64,35 @@ impl From for Timestamp { /// This function panics: /// * if given `Timestamp` is outside of `SystemTime` range /// * if `Timestamp` is malformed -impl Into for Timestamp { - fn into(self) -> SystemTime { - if self.seconds >= 0 { +impl From<&Timestamp> for SystemTime { + fn from(time: &Timestamp) -> SystemTime { + if time.seconds >= 0 { let duration = - Duration::from_secs(self.seconds as u64) + Duration::from_nanos(self.nanos as u64); + Duration::from_secs(time.seconds as u64) + Duration::from_nanos(time.nanos as u64); SystemTime::UNIX_EPOCH + duration } else { let duration = - Duration::from_secs(-self.seconds as u64) - Duration::from_nanos(self.nanos as u64); + Duration::from_secs(-time.seconds as u64) - Duration::from_nanos(time.nanos as u64); SystemTime::UNIX_EPOCH - duration } } } +/// Convert into [`SystemTime`]. +/// +/// The conversion could be lossy if `SystemTime` precision is smaller than nanoseconds. +/// +/// # Panics +/// +/// This function panics: +/// * if given `Timestamp` is outside of `SystemTime` range +/// * if `Timestamp` is malformed +impl From for SystemTime { + fn from(time: Timestamp) -> SystemTime { + SystemTime::from(&time) + } +} + #[cfg(test)] mod test { use std::time::Duration;