summaryrefslogtreecommitdiffstats
path: root/vendor/uuid/src/v7.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/uuid/src/v7.rs')
-rw-r--r--vendor/uuid/src/v7.rs124
1 files changed, 124 insertions, 0 deletions
diff --git a/vendor/uuid/src/v7.rs b/vendor/uuid/src/v7.rs
new file mode 100644
index 000000000..4497ea3f5
--- /dev/null
+++ b/vendor/uuid/src/v7.rs
@@ -0,0 +1,124 @@
+//! The implementation for Version 7 UUIDs.
+//!
+//! Note that you need to enable the `v7` Cargo feature
+//! in order to use this module.
+
+use crate::{std::convert::TryInto, rng, timestamp::Timestamp, Builder, Uuid};
+
+impl Uuid {
+ /// Create a new version 7 UUID using the current time value and random bytes.
+ ///
+ /// This method is a convenient alternative to [`Uuid::new_v7`] that uses the current system time
+ /// as the source timestamp.
+ #[cfg(feature = "std")]
+ pub fn now_v7() -> Self {
+ Self::new_v7(Timestamp::now(crate::NoContext))
+ }
+
+ /// Create a new version 7 UUID using a time value and random bytes.
+ ///
+ /// When the `std` feature is enabled, you can also use [`Uuid::now_v7`].
+ ///
+ /// Note that usage of this method requires the `v7` feature of this crate
+ /// to be enabled.
+ ///
+ /// Also see [`Uuid::now_v7`] for a convenient way to generate version 7
+ /// UUIDs using the current system time.
+ ///
+ /// # Examples
+ ///
+ /// A v7 UUID can be created from a unix [`Timestamp`] plus a 128 bit
+ /// random number. When supplied as such, the data will be
+ ///
+ /// ```rust
+ /// # use uuid::{Uuid, Timestamp, NoContext};
+ /// let ts = Timestamp::from_unix(NoContext, 1497624119, 1234);
+ ///
+ /// let uuid = Uuid::new_v7(ts);
+ ///
+ /// assert!(
+ /// uuid.hyphenated().to_string().starts_with("015cb15a-86d8-7")
+ /// );
+ /// ```
+ ///
+ /// # References
+ ///
+ /// * [Version 7 UUIDs in Draft RFC: New UUID Formats, Version 4](https://datatracker.ietf.org/doc/html/draft-peabody-dispatch-new-uuid-format-04#section-5.2)
+ pub fn new_v7(ts: Timestamp) -> Self {
+ let (secs, nanos) = ts.to_unix();
+ let millis = (secs * 1000).saturating_add(nanos as u64 / 1_000_000);
+
+ Builder::from_unix_timestamp_millis(millis, &rng::bytes()[..10].try_into().unwrap())
+ .into_uuid()
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::{std::string::ToString, NoContext, Variant, Version};
+ #[cfg(target_arch = "wasm32")]
+ use wasm_bindgen_test::*;
+
+ #[test]
+ #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+ fn test_new() {
+ let ts: u64 = 1645557742000;
+
+ let seconds = ts / 1000;
+ let nanos = ((ts % 1000) * 1_000_000) as u32;
+
+ let uuid = Uuid::new_v7(Timestamp::from_unix(NoContext, seconds, nanos));
+ let uustr = uuid.hyphenated().to_string();
+
+ assert_eq!(uuid.get_version(), Some(Version::SortRand));
+ assert_eq!(uuid.get_variant(), Variant::RFC4122);
+ assert!(uuid.hyphenated().to_string().starts_with("017f22e2-79b0-7"));
+
+ // Ensure parsing the same UUID produces the same timestamp
+ let parsed = Uuid::parse_str(uustr.as_str()).unwrap();
+
+ assert_eq!(uuid, parsed);
+ }
+
+ #[test]
+ #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+ #[cfg(feature = "std")]
+ fn test_now() {
+ let uuid = Uuid::now_v7();
+
+ assert_eq!(uuid.get_version(), Some(Version::SortRand));
+ assert_eq!(uuid.get_variant(), Variant::RFC4122);
+ }
+
+ #[test]
+ #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+ fn test_sorting() {
+ let time1: u64 = 1_496_854_535;
+ let time_fraction1: u32 = 812_000_000;
+
+ let time2 = time1 + 4000;
+ let time_fraction2 = time_fraction1;
+
+ let uuid1 = Uuid::new_v7(Timestamp::from_unix(NoContext, time1, time_fraction1));
+ let uuid2 = Uuid::new_v7(Timestamp::from_unix(NoContext, time2, time_fraction2));
+
+ assert!(uuid1.as_bytes() < uuid2.as_bytes());
+ assert!(uuid1.to_string() < uuid2.to_string());
+ }
+
+ #[test]
+ #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)]
+ fn test_new_timestamp_roundtrip() {
+ let time: u64 = 1_496_854_535;
+ let time_fraction: u32 = 812_000_000;
+
+ let ts = Timestamp::from_unix(NoContext, time, time_fraction);
+
+ let uuid = Uuid::new_v7(ts);
+
+ let decoded_ts = uuid.get_timestamp().unwrap();
+
+ assert_eq!(ts.to_unix(), decoded_ts.to_unix());
+ }
+}