From de50f2091f05a973b4e8ca2f7eddd03459b1b680 Mon Sep 17 00:00:00 2001 From: Peter MIKOLA Date: Mon, 24 Jun 2024 13:44:12 +0200 Subject: [PATCH 1/2] renaming rfc4122 functions --- src/builder.rs | 34 ++++++++++++++++++++++++---- src/lib.rs | 8 +++---- src/timestamp.rs | 58 +++++++++++++++++++++++++++++++----------------- src/v1.rs | 8 +++---- src/v6.rs | 8 +++---- 5 files changed, 80 insertions(+), 36 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 880327bb..4bef7421 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -550,8 +550,10 @@ impl Builder { } /// Creates a `Builder` for a version 1 UUID using the supplied timestamp and node ID. - pub const fn from_rfc4122_timestamp(ticks: u64, counter: u16, node_id: &[u8; 6]) -> Self { - Builder(timestamp::encode_rfc4122_timestamp(ticks, counter, node_id)) + pub const fn from_gregorian_timestamp(ticks: u64, counter: u16, node_id: &[u8; 6]) -> Self { + Builder(timestamp::encode_gregorian_timestamp( + ticks, counter, node_id, + )) } /// Creates a `Builder` for a version 3 UUID using the supplied MD5 hashed bytes. @@ -599,12 +601,12 @@ impl Builder { /// Creates a `Builder` for a version 6 UUID using the supplied timestamp and node ID. /// /// This method will encode the ticks, counter, and node ID in a sortable UUID. - pub const fn from_sorted_rfc4122_timestamp( + pub const fn from_sorted_gregorian_timestamp( ticks: u64, counter: u16, node_id: &[u8; 6], ) -> Self { - Builder(timestamp::encode_sorted_rfc4122_timestamp( + Builder(timestamp::encode_sorted_gregorian_timestamp( ticks, counter, node_id, )) } @@ -903,3 +905,27 @@ impl Builder { self.0 } } + +// Deprecations. Remove when major version changes (2.0.0) +#[doc(hidden)] +impl Builder { + #[deprecated( + since = "1.10.0", + note = "Deprecated! Use `from_gregorian_timestamp()` instead!" + )] + pub const fn from_rfc4122_timestamp(ticks: u64, counter: u16, node_id: &[u8; 6]) -> Self { + Builder::from_gregorian_timestamp(ticks, counter, node_id) + } + + #[deprecated( + since = "1.10.0", + note = "Deprecated! Use `from_sorted_gregorian_timestamp()` instead!" + )] + pub const fn from_sorted_rfc4122_timestamp( + ticks: u64, + counter: u16, + node_id: &[u8; 6], + ) -> Self { + Builder::from_sorted_gregorian_timestamp(ticks, counter, node_id) + } +} diff --git a/src/lib.rs b/src/lib.rs index bad57bf1..140f5571 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -889,14 +889,14 @@ impl Uuid { pub const fn get_timestamp(&self) -> Option { match self.get_version() { Some(Version::Mac) => { - let (ticks, counter) = timestamp::decode_rfc4122_timestamp(self); + let (ticks, counter) = timestamp::decode_gregorian_timestamp(self); - Some(Timestamp::from_rfc4122(ticks, counter)) + Some(Timestamp::from_gregorian(ticks, counter)) } Some(Version::SortMac) => { - let (ticks, counter) = timestamp::decode_sorted_rfc4122_timestamp(self); + let (ticks, counter) = timestamp::decode_sorted_gregorian_timestamp(self); - Some(Timestamp::from_rfc4122(ticks, counter)) + Some(Timestamp::from_gregorian(ticks, counter)) } Some(Version::SortRand) => { let millis = timestamp::decode_unix_timestamp_millis(self); diff --git a/src/timestamp.rs b/src/timestamp.rs index 6fb56a6e..5db89ac3 100644 --- a/src/timestamp.rs +++ b/src/timestamp.rs @@ -79,8 +79,8 @@ impl Timestamp { /// /// If conversion from RFC 9562 ticks to the internal timestamp format would overflow /// it will wrap. - pub const fn from_rfc4122(ticks: u64, counter: u16) -> Self { - let (seconds, subsec_nanos) = Self::rfc4122_to_unix(ticks); + pub const fn from_gregorian(ticks: u64, counter: u16) -> Self { + let (seconds, subsec_nanos) = Self::gregorian_to_unix(ticks); Timestamp { seconds, @@ -131,9 +131,9 @@ impl Timestamp { /// /// If conversion from RFC 9562 ticks to the internal timestamp format would overflow /// it will wrap. - pub const fn to_rfc4122(&self) -> (u64, u16) { + pub const fn to_gregorian(&self) -> (u64, u16) { ( - Self::unix_to_rfc4122_ticks(self.seconds, self.subsec_nanos), + Self::unix_to_gregorian_ticks(self.seconds, self.subsec_nanos), (self.counter as u16) & 0x3FFF, ) } @@ -150,31 +150,49 @@ impl Timestamp { (self.seconds, self.subsec_nanos) } - const fn unix_to_rfc4122_ticks(seconds: u64, nanos: u32) -> u64 { + const fn unix_to_gregorian_ticks(seconds: u64, nanos: u32) -> u64 { UUID_TICKS_BETWEEN_EPOCHS .wrapping_add(seconds.wrapping_mul(10_000_000)) .wrapping_add(nanos as u64 / 100) } - const fn rfc4122_to_unix(ticks: u64) -> (u64, u32) { + const fn gregorian_to_unix(ticks: u64) -> (u64, u32) { ( ticks.wrapping_sub(UUID_TICKS_BETWEEN_EPOCHS) / 10_000_000, (ticks.wrapping_sub(UUID_TICKS_BETWEEN_EPOCHS) % 10_000_000) as u32 * 100, ) } +} + +// Deprecations. Remove when major version changes (2.0.0) +#[doc(hidden)] +impl Timestamp { + #[deprecated(since = "1.10.0", note = "Deprecated! Use `from_gregorian()` instead!")] + pub const fn from_rfc4122(ticks: u64, counter: u16) -> Self { + Timestamp::from_gregorian(ticks, counter) + } + + #[deprecated(since = "1.10.0", note = "Deprecated! Use `to_gregorian()` instead!")] + pub const fn to_rfc4122(&self) -> (u64, u16) { + self.to_gregorian() + } - #[deprecated(note = "use `to_unix` instead; this method will be removed in a future release")] /// Get the number of fractional nanoseconds in the Unix timestamp. /// /// This method is deprecated and probably doesn't do what you're expecting it to. /// It doesn't return the timestamp as nanoseconds since the Unix epoch, it returns /// the fractional seconds of the timestamp. + #[deprecated(since = "1.2.0", note = "Deprecated! Use `to_unix()` instead!")] pub const fn to_unix_nanos(&self) -> u32 { panic!("`Timestamp::to_unix_nanos` is deprecated and will be removed: use `Timestamp::to_unix` instead") } } -pub(crate) const fn encode_rfc4122_timestamp(ticks: u64, counter: u16, node_id: &[u8; 6]) -> Uuid { +pub(crate) const fn encode_gregorian_timestamp( + ticks: u64, + counter: u16, + node_id: &[u8; 6], +) -> Uuid { let time_low = (ticks & 0xFFFF_FFFF) as u32; let time_mid = ((ticks >> 32) & 0xFFFF) as u16; let time_high_and_version = (((ticks >> 48) & 0x0FFF) as u16) | (1 << 12); @@ -193,7 +211,7 @@ pub(crate) const fn encode_rfc4122_timestamp(ticks: u64, counter: u16, node_id: Uuid::from_fields(time_low, time_mid, time_high_and_version, &d4) } -pub(crate) const fn decode_rfc4122_timestamp(uuid: &Uuid) -> (u64, u16) { +pub(crate) const fn decode_gregorian_timestamp(uuid: &Uuid) -> (u64, u16) { let bytes = uuid.as_bytes(); let ticks: u64 = ((bytes[6] & 0x0F) as u64) << 56 @@ -210,7 +228,7 @@ pub(crate) const fn decode_rfc4122_timestamp(uuid: &Uuid) -> (u64, u16) { (ticks, counter) } -pub(crate) const fn encode_sorted_rfc4122_timestamp( +pub(crate) const fn encode_sorted_gregorian_timestamp( ticks: u64, counter: u16, node_id: &[u8; 6], @@ -233,7 +251,7 @@ pub(crate) const fn encode_sorted_rfc4122_timestamp( Uuid::from_fields(time_high, time_mid, time_low_and_version, &d4) } -pub(crate) const fn decode_sorted_rfc4122_timestamp(uuid: &Uuid) -> (u64, u16) { +pub(crate) const fn decode_sorted_gregorian_timestamp(uuid: &Uuid) -> (u64, u16) { let bytes = uuid.as_bytes(); let ticks: u64 = ((bytes[0]) as u64) << 52 @@ -500,7 +518,7 @@ pub mod context { type Output = u16; fn generate_sequence(&self, _seconds: u64, _nanos: u32) -> Self::Output { - // RFC4122 reserves 2 bits of the clock sequence so the actual + // RFC 9562 reserves 2 bits of the clock sequence so the actual // maximum value is smaller than `u16::MAX`. Since we unconditionally // increment the clock sequence we want to wrap once it becomes larger // than what we can represent in a "u14". Otherwise there'd be patches @@ -935,13 +953,13 @@ mod tests { ), wasm_bindgen_test )] - fn rfc4122_unix_does_not_panic() { + fn gregorian_unix_does_not_panic() { // Ensure timestamp conversions never panic - Timestamp::unix_to_rfc4122_ticks(u64::MAX, 0); - Timestamp::unix_to_rfc4122_ticks(0, u32::MAX); - Timestamp::unix_to_rfc4122_ticks(u64::MAX, u32::MAX); + Timestamp::unix_to_gregorian_ticks(u64::MAX, 0); + Timestamp::unix_to_gregorian_ticks(0, u32::MAX); + Timestamp::unix_to_gregorian_ticks(u64::MAX, u32::MAX); - Timestamp::rfc4122_to_unix(u64::MAX); + Timestamp::gregorian_to_unix(u64::MAX); } #[test] @@ -953,9 +971,9 @@ mod tests { ), wasm_bindgen_test )] - fn to_rfc4122_truncates_to_usable_bits() { - let ts = Timestamp::from_rfc4122(123, u16::MAX); + fn to_gregorian_truncates_to_usable_bits() { + let ts = Timestamp::from_gregorian(123, u16::MAX); - assert_eq!((123, u16::MAX >> 2), ts.to_rfc4122()); + assert_eq!((123, u16::MAX >> 2), ts.to_gregorian()); } } diff --git a/src/v1.rs b/src/v1.rs index dc8dd80f..cdd63332 100644 --- a/src/v1.rs +++ b/src/v1.rs @@ -71,7 +71,7 @@ impl Uuid { /// ``` /// # use uuid::{Uuid, Timestamp, Context, ClockSequence}; /// let context = Context::new(42); - /// let ts = Timestamp::from_rfc4122(14976234442241191232, context.generate_sequence(0, 0)); + /// let ts = Timestamp::from_gregorian(14976234442241191232, context.generate_sequence(0, 0)); /// /// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]); /// @@ -89,9 +89,9 @@ impl Uuid { /// [`ClockSequence`]: v1/trait.ClockSequence.html /// [`Context`]: v1/struct.Context.html pub fn new_v1(ts: Timestamp, node_id: &[u8; 6]) -> Self { - let (ticks, counter) = ts.to_rfc4122(); + let (ticks, counter) = ts.to_gregorian(); - Builder::from_rfc4122_timestamp(ticks, counter, node_id).into_uuid() + Builder::from_gregorian_timestamp(ticks, counter, node_id).into_uuid() } } @@ -131,7 +131,7 @@ mod tests { "20616934-4ba2-11e7-8000-010203040506" ); - let ts = uuid.get_timestamp().unwrap().to_rfc4122(); + let ts = uuid.get_timestamp().unwrap().to_gregorian(); assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460); diff --git a/src/v6.rs b/src/v6.rs index 02db3e9e..05f27dba 100644 --- a/src/v6.rs +++ b/src/v6.rs @@ -72,7 +72,7 @@ impl Uuid { /// # use uuid::{Uuid, Timestamp, Context, ClockSequence}; /// # fn random_seed() -> u16 { 42 } /// let context = Context::new(random_seed()); - /// let ts = Timestamp::from_rfc4122(14976241191231231313, context.generate_sequence(0, 0) ); + /// let ts = Timestamp::from_gregorian(14976241191231231313, context.generate_sequence(0, 0)); /// /// let uuid = Uuid::new_v6(ts, &[1, 2, 3, 4, 5, 6]); /// @@ -90,9 +90,9 @@ impl Uuid { /// [`ClockSequence`]: timestamp/trait.ClockSequence.html /// [`Context`]: timestamp/context/struct.Context.html pub fn new_v6(ts: Timestamp, node_id: &[u8; 6]) -> Self { - let (ticks, counter) = ts.to_rfc4122(); + let (ticks, counter) = ts.to_gregorian(); - Builder::from_sorted_rfc4122_timestamp(ticks, counter, node_id).into_uuid() + Builder::from_sorted_gregorian_timestamp(ticks, counter, node_id).into_uuid() } } @@ -133,7 +133,7 @@ mod tests { "1e74ba22-0616-6934-8000-010203040506" ); - let ts = uuid.get_timestamp().unwrap().to_rfc4122(); + let ts = uuid.get_timestamp().unwrap().to_gregorian(); assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460); From 3d5384da4bfb2f35ad4426440d285e4a13c8c011 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Tue, 9 Jul 2024 08:35:04 +1000 Subject: [PATCH 2/2] update docs and deprecation messages for timestamp fns --- src/builder.rs | 9 ++++----- src/timestamp.rs | 33 +++++++++++++-------------------- 2 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 4bef7421..6a07a303 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -549,7 +549,7 @@ impl Builder { Builder(Uuid::from_bytes_le(b)) } - /// Creates a `Builder` for a version 1 UUID using the supplied timestamp and node ID. + /// Creates a `Builder` for a version 1 UUID using the supplied timestamp, counter, and node ID. pub const fn from_gregorian_timestamp(ticks: u64, counter: u16, node_id: &[u8; 6]) -> Self { Builder(timestamp::encode_gregorian_timestamp( ticks, counter, node_id, @@ -598,7 +598,7 @@ impl Builder { .with_version(Version::Sha1) } - /// Creates a `Builder` for a version 6 UUID using the supplied timestamp and node ID. + /// Creates a `Builder` for a version 6 UUID using the supplied timestamp, counter, and node ID. /// /// This method will encode the ticks, counter, and node ID in a sortable UUID. pub const fn from_sorted_gregorian_timestamp( @@ -906,12 +906,11 @@ impl Builder { } } -// Deprecations. Remove when major version changes (2.0.0) #[doc(hidden)] impl Builder { #[deprecated( since = "1.10.0", - note = "Deprecated! Use `from_gregorian_timestamp()` instead!" + note = "use `Builder::from_gregorian_timestamp(ticks, counter, node_id)`" )] pub const fn from_rfc4122_timestamp(ticks: u64, counter: u16, node_id: &[u8; 6]) -> Self { Builder::from_gregorian_timestamp(ticks, counter, node_id) @@ -919,7 +918,7 @@ impl Builder { #[deprecated( since = "1.10.0", - note = "Deprecated! Use `from_sorted_gregorian_timestamp()` instead!" + note = "use `Builder::from_sorted_gregorian_timestamp(ticks, counter, node_id)`" )] pub const fn from_sorted_rfc4122_timestamp( ticks: u64, diff --git a/src/timestamp.rs b/src/timestamp.rs index 5db89ac3..a17aedc0 100644 --- a/src/timestamp.rs +++ b/src/timestamp.rs @@ -51,10 +51,6 @@ impl Timestamp { /// Get a timestamp representing the current system time and up to a 128-bit counter. /// /// This method defers to the standard library's `SystemTime` type. - /// - /// # Panics - /// - /// This method will panic if calculating the elapsed time since the Unix epoch fails. #[cfg(feature = "std")] pub fn now(context: impl ClockSequence>) -> Self { let (seconds, subsec_nanos) = now(); @@ -72,8 +68,9 @@ impl Timestamp { } } - /// Construct a `Timestamp` from an RFC 9562 timestamp and 14-bit counter, as used - /// in versions 1 and 6 UUIDs. + /// Construct a `Timestamp` from the number of 100 nanosecond ticks since 00:00:00.00, + /// 15 October 1582 (the date of Gregorian reform to the Christian calendar) and a 14-bit + /// counter, as used in versions 1 and 6 UUIDs. /// /// # Overflow /// @@ -124,13 +121,15 @@ impl Timestamp { } } - /// Get the value of the timestamp as an RFC 9562 timestamp and counter, - /// as used in versions 1 and 6 UUIDs. + /// Get the value of the timestamp as the number of 100 nanosecond ticks since 00:00:00.00, + /// 15 October 1582 and a 14-bit counter, as used in versions 1 and 6 UUIDs. /// /// # Overflow /// - /// If conversion from RFC 9562 ticks to the internal timestamp format would overflow - /// it will wrap. + /// If conversion from the internal timestamp format to ticks would overflow + /// then it will wrap. + /// + /// If the internal counter is wider than 14 bits then it will be truncated to 14 bits. pub const fn to_gregorian(&self) -> (u64, u16) { ( Self::unix_to_gregorian_ticks(self.seconds, self.subsec_nanos), @@ -164,27 +163,21 @@ impl Timestamp { } } -// Deprecations. Remove when major version changes (2.0.0) #[doc(hidden)] impl Timestamp { - #[deprecated(since = "1.10.0", note = "Deprecated! Use `from_gregorian()` instead!")] + #[deprecated(since = "1.10.0", note = "use `Timestamp::from_gregorian(ticks, counter)`")] pub const fn from_rfc4122(ticks: u64, counter: u16) -> Self { Timestamp::from_gregorian(ticks, counter) } - #[deprecated(since = "1.10.0", note = "Deprecated! Use `to_gregorian()` instead!")] + #[deprecated(since = "1.10.0", note = "use `Timestamp::to_gregorian()`")] pub const fn to_rfc4122(&self) -> (u64, u16) { self.to_gregorian() } - /// Get the number of fractional nanoseconds in the Unix timestamp. - /// - /// This method is deprecated and probably doesn't do what you're expecting it to. - /// It doesn't return the timestamp as nanoseconds since the Unix epoch, it returns - /// the fractional seconds of the timestamp. - #[deprecated(since = "1.2.0", note = "Deprecated! Use `to_unix()` instead!")] + #[deprecated(since = "1.2.0", note = "`Timestamp::to_unix_nanos()` is deprecated and will be removed: use `Timestamp::to_unix()`")] pub const fn to_unix_nanos(&self) -> u32 { - panic!("`Timestamp::to_unix_nanos` is deprecated and will be removed: use `Timestamp::to_unix` instead") + panic!("`Timestamp::to_unix_nanos()` is deprecated and will be removed: use `Timestamp::to_unix()`") } }