• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013-2014 The Rust Project Developers.
2 // Copyright 2018 The Uuid Project Developers.
3 //
4 // See the COPYRIGHT file at the top-level directory of this distribution.
5 //
6 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
7 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
9 // option. This file may not be copied, modified, or distributed
10 // except according to those terms.
11 
12 //! Generate and parse universally unique identifiers (UUIDs).
13 //!
14 //! Here's an example of a UUID:
15 //!
16 //! ```text
17 //! 67e55044-10b1-426f-9247-bb680e5fe0c8
18 //! ```
19 //!
20 //! A UUID is a unique 128-bit value, stored as 16 octets, and regularly
21 //! formatted as a hex string in five groups. UUIDs are used to assign unique
22 //! identifiers to entities without requiring a central allocating authority.
23 //!
24 //! They are particularly useful in distributed systems, though can be used in
25 //! disparate areas, such as databases and network protocols.  Typically a UUID
26 //! is displayed in a readable string form as a sequence of hexadecimal digits,
27 //! separated into groups by hyphens.
28 //!
29 //! The uniqueness property is not strictly guaranteed, however for all
30 //! practical purposes, it can be assumed that an unintentional collision would
31 //! be extremely unlikely.
32 //!
33 //! UUIDs have a number of standardized encodings that are specified in [RFC 9562](https://www.ietf.org/rfc/rfc9562.html).
34 //!
35 //! # Getting started
36 //!
37 //! Add the following to your `Cargo.toml`:
38 //!
39 //! ```toml
40 //! [dependencies.uuid]
41 //! version = "1.12.1"
42 //! features = [
43 //!     "v4",                # Lets you generate random UUIDs
44 //!     "fast-rng",          # Use a faster (but still sufficiently random) RNG
45 //!     "macro-diagnostics", # Enable better diagnostics for compile-time UUIDs
46 //! ]
47 //! ```
48 //!
49 //! When you want a UUID, you can generate one:
50 //!
51 //! ```
52 //! # fn main() {
53 //! # #[cfg(feature = "v4")]
54 //! # {
55 //! use uuid::Uuid;
56 //!
57 //! let id = Uuid::new_v4();
58 //! # }
59 //! # }
60 //! ```
61 //!
62 //! If you have a UUID value, you can use its string literal form inline:
63 //!
64 //! ```
65 //! use uuid::{uuid, Uuid};
66 //!
67 //! const ID: Uuid = uuid!("67e55044-10b1-426f-9247-bb680e5fe0c8");
68 //! ```
69 //!
70 //! # Working with different UUID versions
71 //!
72 //! This library supports all standardized methods for generating UUIDs through individual Cargo features.
73 //!
74 //! By default, this crate depends on nothing but the Rust standard library and can parse and format
75 //! UUIDs, but cannot generate them. Depending on the kind of UUID you'd like to work with, there
76 //! are Cargo features that enable generating them:
77 //!
78 //! * `v1` - Version 1 UUIDs using a timestamp and monotonic counter.
79 //! * `v3` - Version 3 UUIDs based on the MD5 hash of some data.
80 //! * `v4` - Version 4 UUIDs with random data.
81 //! * `v5` - Version 5 UUIDs based on the SHA1 hash of some data.
82 //! * `v6` - Version 6 UUIDs using a timestamp and monotonic counter.
83 //! * `v7` - Version 7 UUIDs using a Unix timestamp.
84 //! * `v8` - Version 8 UUIDs using user-defined data.
85 //!
86 //! This library also includes a [`Builder`] type that can be used to help construct UUIDs of any
87 //! version without any additional dependencies or features. It's a lower-level API than [`Uuid`]
88 //! that can be used when you need control over implicit requirements on things like a source
89 //! of randomness.
90 //!
91 //! ## Which UUID version should I use?
92 //!
93 //! If you just want to generate unique identifiers then consider version 4 (`v4`) UUIDs. If you want
94 //! to use UUIDs as database keys or need to sort them then consider version 7 (`v7`) UUIDs.
95 //! Other versions should generally be avoided unless there's an existing need for them.
96 //!
97 //! Some UUID versions supersede others. Prefer version 6 over version 1 and version 5 over version 3.
98 //!
99 //! # Other features
100 //!
101 //! Other crate features can also be useful beyond the version support:
102 //!
103 //! * `macro-diagnostics` - enhances the diagnostics of `uuid!` macro.
104 //! * `serde` - adds the ability to serialize and deserialize a UUID using
105 //!   `serde`.
106 //! * `borsh` - adds the ability to serialize and deserialize a UUID using
107 //!   `borsh`.
108 //! * `arbitrary` - adds an `Arbitrary` trait implementation to `Uuid` for
109 //!   fuzzing.
110 //! * `fast-rng` - uses a faster algorithm for generating random UUIDs.
111 //!   This feature requires more dependencies to compile, but is just as suitable for
112 //!   UUIDs as the default algorithm.
113 //! * `bytemuck` - adds a `Pod` trait implementation to `Uuid` for byte manipulation
114 //!
115 //! # Unstable features
116 //!
117 //! Some features are unstable. They may be incomplete or depend on other
118 //! unstable libraries. These include:
119 //!
120 //! * `zerocopy` - adds support for zero-copy deserialization using the
121 //!   `zerocopy` library.
122 //!
123 //! Unstable features may break between minor releases.
124 //!
125 //! To allow unstable features, you'll need to enable the Cargo feature as
126 //! normal, but also pass an additional flag through your environment to opt-in
127 //! to unstable `uuid` features:
128 //!
129 //! ```text
130 //! RUSTFLAGS="--cfg uuid_unstable"
131 //! ```
132 //!
133 //! # Building for other targets
134 //!
135 //! ## WebAssembly
136 //!
137 //! For WebAssembly, enable the `js` feature:
138 //!
139 //! ```toml
140 //! [dependencies.uuid]
141 //! version = "1.12.1"
142 //! features = [
143 //!     "v4",
144 //!     "v7",
145 //!     "js",
146 //! ]
147 //! ```
148 //!
149 //! ## Embedded
150 //!
151 //! For embedded targets without the standard library, you'll need to
152 //! disable default features when building `uuid`:
153 //!
154 //! ```toml
155 //! [dependencies.uuid]
156 //! version = "1.12.1"
157 //! default-features = false
158 //! ```
159 //!
160 //! Some additional features are supported in no-std environments:
161 //!
162 //! * `v1`, `v3`, `v5`, `v6`, and `v8`.
163 //! * `serde`.
164 //!
165 //! If you need to use `v4` or `v7` in a no-std environment, you'll need to
166 //! follow [`getrandom`'s docs] on configuring a source of randomness
167 //! on currently unsupported targets. Alternatively, you can produce
168 //! random bytes yourself and then pass them to [`Builder::from_random_bytes`]
169 //! without enabling the `v4` or `v7` features.
170 //!
171 //! # Examples
172 //!
173 //! Parse a UUID given in the simple format and print it as a URN:
174 //!
175 //! ```
176 //! # use uuid::Uuid;
177 //! # fn main() -> Result<(), uuid::Error> {
178 //! let my_uuid = Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8")?;
179 //!
180 //! println!("{}", my_uuid.urn());
181 //! # Ok(())
182 //! # }
183 //! ```
184 //!
185 //! Generate a random UUID and print it out in hexadecimal form:
186 //!
187 //! ```
188 //! // Note that this requires the `v4` feature to be enabled.
189 //! # use uuid::Uuid;
190 //! # fn main() {
191 //! # #[cfg(feature = "v4")] {
192 //! let my_uuid = Uuid::new_v4();
193 //!
194 //! println!("{}", my_uuid);
195 //! # }
196 //! # }
197 //! ```
198 //!
199 //! # References
200 //!
201 //! * [Wikipedia: Universally Unique Identifier](http://en.wikipedia.org/wiki/Universally_unique_identifier)
202 //! * [RFC 9562: Universally Unique IDentifiers (UUID)](https://www.ietf.org/rfc/rfc9562.html).
203 //!
204 //! [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
205 //! [`cargo-web`]: https://crates.io/crates/cargo-web
206 //! [`getrandom`'s docs]: https://docs.rs/getrandom
207 
208 #![no_std]
209 #![deny(missing_debug_implementations, missing_docs)]
210 #![allow(clippy::mixed_attributes_style)]
211 #![doc(
212     html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
213     html_favicon_url = "https://www.rust-lang.org/favicon.ico",
214     html_root_url = "https://docs.rs/uuid/1.12.1"
215 )]
216 
217 #[cfg(any(feature = "std", test))]
218 #[macro_use]
219 extern crate std;
220 
221 #[cfg(all(not(feature = "std"), not(test)))]
222 #[macro_use]
223 extern crate core as std;
224 
225 mod builder;
226 mod error;
227 mod non_nil;
228 mod parser;
229 
230 pub mod fmt;
231 pub mod timestamp;
232 
233 pub use timestamp::{context::NoContext, ClockSequence, Timestamp};
234 
235 #[cfg(any(feature = "v1", feature = "v6"))]
236 pub use timestamp::context::Context;
237 
238 #[cfg(feature = "v7")]
239 pub use timestamp::context::ContextV7;
240 
241 #[cfg(feature = "v1")]
242 #[doc(hidden)]
243 // Soft-deprecated (Rust doesn't support deprecating re-exports)
244 // Use `Context` from the crate root instead
245 pub mod v1;
246 #[cfg(feature = "v3")]
247 mod v3;
248 #[cfg(feature = "v4")]
249 mod v4;
250 #[cfg(feature = "v5")]
251 mod v5;
252 #[cfg(feature = "v6")]
253 mod v6;
254 #[cfg(feature = "v7")]
255 mod v7;
256 #[cfg(feature = "v8")]
257 mod v8;
258 
259 #[cfg(feature = "md5")]
260 mod md5;
261 #[cfg(feature = "rng")]
262 mod rng;
263 #[cfg(feature = "sha1")]
264 mod sha1;
265 
266 mod external;
267 
268 #[macro_use]
269 mod macros;
270 
271 #[doc(hidden)]
272 #[cfg(feature = "macro-diagnostics")]
273 pub extern crate uuid_macro_internal;
274 
275 #[doc(hidden)]
276 pub mod __macro_support {
277     pub use crate::std::result::Result::{Err, Ok};
278 }
279 
280 use crate::std::convert;
281 
282 pub use crate::{builder::Builder, error::Error, non_nil::NonNilUuid};
283 
284 /// A 128-bit (16 byte) buffer containing the UUID.
285 ///
286 /// # ABI
287 ///
288 /// The `Bytes` type is always guaranteed to be have the same ABI as [`Uuid`].
289 pub type Bytes = [u8; 16];
290 
291 /// The version of the UUID, denoting the generating algorithm.
292 ///
293 /// # References
294 ///
295 /// * [Version Field in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-4.2)
296 #[derive(Clone, Copy, Debug, PartialEq)]
297 #[non_exhaustive]
298 #[repr(u8)]
299 pub enum Version {
300     /// The "nil" (all zeros) UUID.
301     Nil = 0u8,
302     /// Version 1: Timestamp and node ID.
303     Mac = 1,
304     /// Version 2: DCE Security.
305     Dce = 2,
306     /// Version 3: MD5 hash.
307     Md5 = 3,
308     /// Version 4: Random.
309     Random = 4,
310     /// Version 5: SHA-1 hash.
311     Sha1 = 5,
312     /// Version 6: Sortable Timestamp and node ID.
313     SortMac = 6,
314     /// Version 7: Timestamp and random.
315     SortRand = 7,
316     /// Version 8: Custom.
317     Custom = 8,
318     /// The "max" (all ones) UUID.
319     Max = 0xff,
320 }
321 
322 /// The reserved variants of UUIDs.
323 ///
324 /// # References
325 ///
326 /// * [Variant Field in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-4.1)
327 #[derive(Clone, Copy, Debug, PartialEq)]
328 #[non_exhaustive]
329 #[repr(u8)]
330 pub enum Variant {
331     /// Reserved by the NCS for backward compatibility.
332     NCS = 0u8,
333     /// As described in the RFC 9562 Specification (default).
334     /// (for backward compatibility it is not yet renamed)
335     RFC4122,
336     /// Reserved by Microsoft for backward compatibility.
337     Microsoft,
338     /// Reserved for future expansion.
339     Future,
340 }
341 
342 /// A Universally Unique Identifier (UUID).
343 ///
344 /// # Examples
345 ///
346 /// Parse a UUID given in the simple format and print it as a urn:
347 ///
348 /// ```
349 /// # use uuid::Uuid;
350 /// # fn main() -> Result<(), uuid::Error> {
351 /// let my_uuid = Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8")?;
352 ///
353 /// println!("{}", my_uuid.urn());
354 /// # Ok(())
355 /// # }
356 /// ```
357 ///
358 /// Create a new random (V4) UUID and print it out in hexadecimal form:
359 ///
360 /// ```
361 /// // Note that this requires the `v4` feature enabled in the uuid crate.
362 /// # use uuid::Uuid;
363 /// # fn main() {
364 /// # #[cfg(feature = "v4")] {
365 /// let my_uuid = Uuid::new_v4();
366 ///
367 /// println!("{}", my_uuid);
368 /// # }
369 /// # }
370 /// ```
371 ///
372 /// # Formatting
373 ///
374 /// A UUID can be formatted in one of a few ways:
375 ///
376 /// * [`simple`](#method.simple): `a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8`.
377 /// * [`hyphenated`](#method.hyphenated):
378 ///   `a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8`.
379 /// * [`urn`](#method.urn): `urn:uuid:A1A2A3A4-B1B2-C1C2-D1D2-D3D4D5D6D7D8`.
380 /// * [`braced`](#method.braced): `{a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8}`.
381 ///
382 /// The default representation when formatting a UUID with `Display` is
383 /// hyphenated:
384 ///
385 /// ```
386 /// # use uuid::Uuid;
387 /// # fn main() -> Result<(), uuid::Error> {
388 /// let my_uuid = Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8")?;
389 ///
390 /// assert_eq!(
391 ///     "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
392 ///     my_uuid.to_string(),
393 /// );
394 /// # Ok(())
395 /// # }
396 /// ```
397 ///
398 /// Other formats can be specified using adapter methods on the UUID:
399 ///
400 /// ```
401 /// # use uuid::Uuid;
402 /// # fn main() -> Result<(), uuid::Error> {
403 /// let my_uuid = Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8")?;
404 ///
405 /// assert_eq!(
406 ///     "urn:uuid:a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
407 ///     my_uuid.urn().to_string(),
408 /// );
409 /// # Ok(())
410 /// # }
411 /// ```
412 ///
413 /// # Endianness
414 ///
415 /// The specification for UUIDs encodes the integer fields that make up the
416 /// value in big-endian order. This crate assumes integer inputs are already in
417 /// the correct order by default, regardless of the endianness of the
418 /// environment. Most methods that accept integers have a `_le` variant (such as
419 /// `from_fields_le`) that assumes any integer values will need to have their
420 /// bytes flipped, regardless of the endianness of the environment.
421 ///
422 /// Most users won't need to worry about endianness unless they need to operate
423 /// on individual fields (such as when converting between Microsoft GUIDs). The
424 /// important things to remember are:
425 ///
426 /// - The endianness is in terms of the fields of the UUID, not the environment.
427 /// - The endianness is assumed to be big-endian when there's no `_le` suffix
428 ///   somewhere.
429 /// - Byte-flipping in `_le` methods applies to each integer.
430 /// - Endianness roundtrips, so if you create a UUID with `from_fields_le`
431 ///   you'll get the same values back out with `to_fields_le`.
432 ///
433 /// # ABI
434 ///
435 /// The `Uuid` type is always guaranteed to be have the same ABI as [`Bytes`].
436 #[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
437 #[repr(transparent)]
438 // NOTE: Also check `NonNilUuid` when ading new derives here
439 #[cfg_attr(
440     all(uuid_unstable, feature = "zerocopy"),
441     derive(zerocopy::IntoBytes, zerocopy::FromBytes, zerocopy::KnownLayout, zerocopy::Immutable, zerocopy::Unaligned)
442 )]
443 #[cfg_attr(
444     feature = "borsh",
445     derive(borsh_derive::BorshDeserialize, borsh_derive::BorshSerialize)
446 )]
447 #[cfg_attr(
448     feature = "bytemuck",
449     derive(bytemuck::Zeroable, bytemuck::Pod, bytemuck::TransparentWrapper)
450 )]
451 pub struct Uuid(Bytes);
452 
453 impl Uuid {
454     /// UUID namespace for Domain Name System (DNS).
455     pub const NAMESPACE_DNS: Self = Uuid([
456         0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
457         0xc8,
458     ]);
459 
460     /// UUID namespace for ISO Object Identifiers (OIDs).
461     pub const NAMESPACE_OID: Self = Uuid([
462         0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
463         0xc8,
464     ]);
465 
466     /// UUID namespace for Uniform Resource Locators (URLs).
467     pub const NAMESPACE_URL: Self = Uuid([
468         0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
469         0xc8,
470     ]);
471 
472     /// UUID namespace for X.500 Distinguished Names (DNs).
473     pub const NAMESPACE_X500: Self = Uuid([
474         0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
475         0xc8,
476     ]);
477 
478     /// Returns the variant of the UUID structure.
479     ///
480     /// This determines the interpretation of the structure of the UUID.
481     /// This method simply reads the value of the variant byte. It doesn't
482     /// validate the rest of the UUID as conforming to that variant.
483     ///
484     /// # Examples
485     ///
486     /// Basic usage:
487     ///
488     /// ```
489     /// # use uuid::{Uuid, Variant};
490     /// # fn main() -> Result<(), uuid::Error> {
491     /// let my_uuid = Uuid::parse_str("02f09a3f-1624-3b1d-8409-44eff7708208")?;
492     ///
493     /// assert_eq!(Variant::RFC4122, my_uuid.get_variant());
494     /// # Ok(())
495     /// # }
496     /// ```
497     ///
498     /// # References
499     ///
500     /// * [Variant Field in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-4.1)
get_variant(&self) -> Variant501     pub const fn get_variant(&self) -> Variant {
502         match self.as_bytes()[8] {
503             x if x & 0x80 == 0x00 => Variant::NCS,
504             x if x & 0xc0 == 0x80 => Variant::RFC4122,
505             x if x & 0xe0 == 0xc0 => Variant::Microsoft,
506             x if x & 0xe0 == 0xe0 => Variant::Future,
507             // The above match arms are actually exhaustive
508             // We just return `Future` here because we can't
509             // use `unreachable!()` in a `const fn`
510             _ => Variant::Future,
511         }
512     }
513 
514     /// Returns the version number of the UUID.
515     ///
516     /// This represents the algorithm used to generate the value.
517     /// This method is the future-proof alternative to [`Uuid::get_version`].
518     ///
519     /// # Examples
520     ///
521     /// Basic usage:
522     ///
523     /// ```
524     /// # use uuid::Uuid;
525     /// # fn main() -> Result<(), uuid::Error> {
526     /// let my_uuid = Uuid::parse_str("02f09a3f-1624-3b1d-8409-44eff7708208")?;
527     ///
528     /// assert_eq!(3, my_uuid.get_version_num());
529     /// # Ok(())
530     /// # }
531     /// ```
532     ///
533     /// # References
534     ///
535     /// * [Version Field in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-4.2)
get_version_num(&self) -> usize536     pub const fn get_version_num(&self) -> usize {
537         (self.as_bytes()[6] >> 4) as usize
538     }
539 
540     /// Returns the version of the UUID.
541     ///
542     /// This represents the algorithm used to generate the value.
543     /// If the version field doesn't contain a recognized version then `None`
544     /// is returned. If you're trying to read the version for a future extension
545     /// you can also use [`Uuid::get_version_num`] to unconditionally return a
546     /// number. Future extensions may start to return `Some` once they're
547     /// standardized and supported.
548     ///
549     /// # Examples
550     ///
551     /// Basic usage:
552     ///
553     /// ```
554     /// # use uuid::{Uuid, Version};
555     /// # fn main() -> Result<(), uuid::Error> {
556     /// let my_uuid = Uuid::parse_str("02f09a3f-1624-3b1d-8409-44eff7708208")?;
557     ///
558     /// assert_eq!(Some(Version::Md5), my_uuid.get_version());
559     /// # Ok(())
560     /// # }
561     /// ```
562     ///
563     /// # References
564     ///
565     /// * [Version Field in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-4.2)
get_version(&self) -> Option<Version>566     pub const fn get_version(&self) -> Option<Version> {
567         match self.get_version_num() {
568             0 if self.is_nil() => Some(Version::Nil),
569             1 => Some(Version::Mac),
570             2 => Some(Version::Dce),
571             3 => Some(Version::Md5),
572             4 => Some(Version::Random),
573             5 => Some(Version::Sha1),
574             6 => Some(Version::SortMac),
575             7 => Some(Version::SortRand),
576             8 => Some(Version::Custom),
577             0xf => Some(Version::Max),
578             _ => None,
579         }
580     }
581 
582     /// Returns the four field values of the UUID.
583     ///
584     /// These values can be passed to the [`Uuid::from_fields`] method to get
585     /// the original `Uuid` back.
586     ///
587     /// * The first field value represents the first group of (eight) hex
588     ///   digits, taken as a big-endian `u32` value.  For V1 UUIDs, this field
589     ///   represents the low 32 bits of the timestamp.
590     /// * The second field value represents the second group of (four) hex
591     ///   digits, taken as a big-endian `u16` value.  For V1 UUIDs, this field
592     ///   represents the middle 16 bits of the timestamp.
593     /// * The third field value represents the third group of (four) hex digits,
594     ///   taken as a big-endian `u16` value.  The 4 most significant bits give
595     ///   the UUID version, and for V1 UUIDs, the last 12 bits represent the
596     ///   high 12 bits of the timestamp.
597     /// * The last field value represents the last two groups of four and twelve
598     ///   hex digits, taken in order.  The first 1-3 bits of this indicate the
599     ///   UUID variant, and for V1 UUIDs, the next 13-15 bits indicate the clock
600     ///   sequence and the last 48 bits indicate the node ID.
601     ///
602     /// # Examples
603     ///
604     /// ```
605     /// # use uuid::Uuid;
606     /// # fn main() -> Result<(), uuid::Error> {
607     /// let uuid = Uuid::nil();
608     ///
609     /// assert_eq!(uuid.as_fields(), (0, 0, 0, &[0u8; 8]));
610     ///
611     /// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?;
612     ///
613     /// assert_eq!(
614     ///     uuid.as_fields(),
615     ///     (
616     ///         0xa1a2a3a4,
617     ///         0xb1b2,
618     ///         0xc1c2,
619     ///         &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8],
620     ///     )
621     /// );
622     /// # Ok(())
623     /// # }
624     /// ```
as_fields(&self) -> (u32, u16, u16, &[u8; 8])625     pub fn as_fields(&self) -> (u32, u16, u16, &[u8; 8]) {
626         let bytes = self.as_bytes();
627 
628         let d1 = (bytes[0] as u32) << 24
629             | (bytes[1] as u32) << 16
630             | (bytes[2] as u32) << 8
631             | (bytes[3] as u32);
632 
633         let d2 = (bytes[4] as u16) << 8 | (bytes[5] as u16);
634 
635         let d3 = (bytes[6] as u16) << 8 | (bytes[7] as u16);
636 
637         let d4: &[u8; 8] = convert::TryInto::try_into(&bytes[8..16]).unwrap();
638         (d1, d2, d3, d4)
639     }
640 
641     /// Returns the four field values of the UUID in little-endian order.
642     ///
643     /// The bytes in the returned integer fields will be converted from
644     /// big-endian order. This is based on the endianness of the UUID,
645     /// rather than the target environment so bytes will be flipped on both
646     /// big and little endian machines.
647     ///
648     /// # Examples
649     ///
650     /// ```
651     /// use uuid::Uuid;
652     ///
653     /// # fn main() -> Result<(), uuid::Error> {
654     /// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?;
655     ///
656     /// assert_eq!(
657     ///     uuid.to_fields_le(),
658     ///     (
659     ///         0xa4a3a2a1,
660     ///         0xb2b1,
661     ///         0xc2c1,
662     ///         &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8],
663     ///     )
664     /// );
665     /// # Ok(())
666     /// # }
667     /// ```
to_fields_le(&self) -> (u32, u16, u16, &[u8; 8])668     pub fn to_fields_le(&self) -> (u32, u16, u16, &[u8; 8]) {
669         let d1 = (self.as_bytes()[0] as u32)
670             | (self.as_bytes()[1] as u32) << 8
671             | (self.as_bytes()[2] as u32) << 16
672             | (self.as_bytes()[3] as u32) << 24;
673 
674         let d2 = (self.as_bytes()[4] as u16) | (self.as_bytes()[5] as u16) << 8;
675 
676         let d3 = (self.as_bytes()[6] as u16) | (self.as_bytes()[7] as u16) << 8;
677 
678         let d4: &[u8; 8] = convert::TryInto::try_into(&self.as_bytes()[8..16]).unwrap();
679         (d1, d2, d3, d4)
680     }
681 
682     /// Returns a 128bit value containing the value.
683     ///
684     /// The bytes in the UUID will be packed directly into a `u128`.
685     ///
686     /// # Examples
687     ///
688     /// ```
689     /// # use uuid::Uuid;
690     /// # fn main() -> Result<(), uuid::Error> {
691     /// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?;
692     ///
693     /// assert_eq!(
694     ///     uuid.as_u128(),
695     ///     0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8,
696     /// );
697     /// # Ok(())
698     /// # }
699     /// ```
as_u128(&self) -> u128700     pub const fn as_u128(&self) -> u128 {
701         u128::from_be_bytes(*self.as_bytes())
702     }
703 
704     /// Returns a 128bit little-endian value containing the value.
705     ///
706     /// The bytes in the `u128` will be flipped to convert into big-endian
707     /// order. This is based on the endianness of the UUID, rather than the
708     /// target environment so bytes will be flipped on both big and little
709     /// endian machines.
710     ///
711     /// Note that this will produce a different result than
712     /// [`Uuid::to_fields_le`], because the entire UUID is reversed, rather
713     /// than reversing the individual fields in-place.
714     ///
715     /// # Examples
716     ///
717     /// ```
718     /// # use uuid::Uuid;
719     /// # fn main() -> Result<(), uuid::Error> {
720     /// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?;
721     ///
722     /// assert_eq!(
723     ///     uuid.to_u128_le(),
724     ///     0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1,
725     /// );
726     /// # Ok(())
727     /// # }
728     /// ```
to_u128_le(&self) -> u128729     pub const fn to_u128_le(&self) -> u128 {
730         u128::from_le_bytes(*self.as_bytes())
731     }
732 
733     /// Returns two 64bit values containing the value.
734     ///
735     /// The bytes in the UUID will be split into two `u64`.
736     /// The first u64 represents the 64 most significant bits,
737     /// the second one represents the 64 least significant.
738     ///
739     /// # Examples
740     ///
741     /// ```
742     /// # use uuid::Uuid;
743     /// # fn main() -> Result<(), uuid::Error> {
744     /// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?;
745     /// assert_eq!(
746     ///     uuid.as_u64_pair(),
747     ///     (0xa1a2a3a4b1b2c1c2, 0xd1d2d3d4d5d6d7d8),
748     /// );
749     /// # Ok(())
750     /// # }
751     /// ```
as_u64_pair(&self) -> (u64, u64)752     pub const fn as_u64_pair(&self) -> (u64, u64) {
753         let value = self.as_u128();
754         ((value >> 64) as u64, value as u64)
755     }
756 
757     /// Returns a slice of 16 octets containing the value.
758     ///
759     /// This method borrows the underlying byte value of the UUID.
760     ///
761     /// # Examples
762     ///
763     /// ```
764     /// # use uuid::Uuid;
765     /// let bytes1 = [
766     ///     0xa1, 0xa2, 0xa3, 0xa4,
767     ///     0xb1, 0xb2,
768     ///     0xc1, 0xc2,
769     ///     0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
770     /// ];
771     /// let uuid1 = Uuid::from_bytes_ref(&bytes1);
772     ///
773     /// let bytes2 = uuid1.as_bytes();
774     /// let uuid2 = Uuid::from_bytes_ref(bytes2);
775     ///
776     /// assert_eq!(uuid1, uuid2);
777     ///
778     /// assert!(std::ptr::eq(
779     ///     uuid2 as *const Uuid as *const u8,
780     ///     &bytes1 as *const [u8; 16] as *const u8,
781     /// ));
782     /// ```
783     #[inline]
as_bytes(&self) -> &Bytes784     pub const fn as_bytes(&self) -> &Bytes {
785         &self.0
786     }
787 
788     /// Consumes self and returns the underlying byte value of the UUID.
789     ///
790     /// # Examples
791     ///
792     /// ```
793     /// # use uuid::Uuid;
794     /// let bytes = [
795     ///     0xa1, 0xa2, 0xa3, 0xa4,
796     ///     0xb1, 0xb2,
797     ///     0xc1, 0xc2,
798     ///     0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
799     /// ];
800     /// let uuid = Uuid::from_bytes(bytes);
801     /// assert_eq!(bytes, uuid.into_bytes());
802     /// ```
803     #[inline]
into_bytes(self) -> Bytes804     pub const fn into_bytes(self) -> Bytes {
805         self.0
806     }
807 
808     /// Returns the bytes of the UUID in little-endian order.
809     ///
810     /// The bytes will be flipped to convert into little-endian order. This is
811     /// based on the endianness of the UUID, rather than the target environment
812     /// so bytes will be flipped on both big and little endian machines.
813     ///
814     /// # Examples
815     ///
816     /// ```
817     /// use uuid::Uuid;
818     ///
819     /// # fn main() -> Result<(), uuid::Error> {
820     /// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?;
821     ///
822     /// assert_eq!(
823     ///     uuid.to_bytes_le(),
824     ///     ([
825     ///         0xa4, 0xa3, 0xa2, 0xa1, 0xb2, 0xb1, 0xc2, 0xc1, 0xd1, 0xd2,
826     ///         0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8
827     ///     ])
828     /// );
829     /// # Ok(())
830     /// # }
831     /// ```
to_bytes_le(&self) -> Bytes832     pub const fn to_bytes_le(&self) -> Bytes {
833         [
834             self.0[3], self.0[2], self.0[1], self.0[0], self.0[5], self.0[4], self.0[7], self.0[6],
835             self.0[8], self.0[9], self.0[10], self.0[11], self.0[12], self.0[13], self.0[14],
836             self.0[15],
837         ]
838     }
839 
840     /// Tests if the UUID is nil (all zeros).
is_nil(&self) -> bool841     pub const fn is_nil(&self) -> bool {
842         self.as_u128() == u128::MIN
843     }
844 
845     /// Tests if the UUID is max (all ones).
is_max(&self) -> bool846     pub const fn is_max(&self) -> bool {
847         self.as_u128() == u128::MAX
848     }
849 
850     /// A buffer that can be used for `encode_...` calls, that is
851     /// guaranteed to be long enough for any of the format adapters.
852     ///
853     /// # Examples
854     ///
855     /// ```
856     /// # use uuid::Uuid;
857     /// let uuid = Uuid::nil();
858     ///
859     /// assert_eq!(
860     ///     uuid.simple().encode_lower(&mut Uuid::encode_buffer()),
861     ///     "00000000000000000000000000000000"
862     /// );
863     ///
864     /// assert_eq!(
865     ///     uuid.hyphenated()
866     ///         .encode_lower(&mut Uuid::encode_buffer()),
867     ///     "00000000-0000-0000-0000-000000000000"
868     /// );
869     ///
870     /// assert_eq!(
871     ///     uuid.urn().encode_lower(&mut Uuid::encode_buffer()),
872     ///     "urn:uuid:00000000-0000-0000-0000-000000000000"
873     /// );
874     /// ```
encode_buffer() -> [u8; fmt::Urn::LENGTH]875     pub const fn encode_buffer() -> [u8; fmt::Urn::LENGTH] {
876         [0; fmt::Urn::LENGTH]
877     }
878 
879     /// If the UUID is the correct version (v1, v6, or v7) this will return
880     /// the timestamp in a version-agnostic [`Timestamp`]. For other versions
881     /// this will return `None`.
882     ///
883     /// # Roundtripping
884     ///
885     /// This method is unlikely to roundtrip a timestamp in a UUID due to the way
886     /// UUIDs encode timestamps. The timestamp returned from this method will be truncated to
887     /// 100ns precision for version 1 and 6 UUIDs, and to millisecond precision for version 7 UUIDs.
get_timestamp(&self) -> Option<Timestamp>888     pub const fn get_timestamp(&self) -> Option<Timestamp> {
889         match self.get_version() {
890             Some(Version::Mac) => {
891                 let (ticks, counter) = timestamp::decode_gregorian_timestamp(self);
892 
893                 Some(Timestamp::from_gregorian(ticks, counter))
894             }
895             Some(Version::SortMac) => {
896                 let (ticks, counter) = timestamp::decode_sorted_gregorian_timestamp(self);
897 
898                 Some(Timestamp::from_gregorian(ticks, counter))
899             }
900             Some(Version::SortRand) => {
901                 let millis = timestamp::decode_unix_timestamp_millis(self);
902 
903                 let seconds = millis / 1000;
904                 let nanos = ((millis % 1000) * 1_000_000) as u32;
905 
906                 Some(Timestamp::from_unix_time(seconds, nanos, 0, 0))
907             }
908             _ => None,
909         }
910     }
911 
912     /// If the UUID is the correct version (v1, or v6) this will return the
913     /// node value as a 6-byte array. For other versions this will return `None`.
get_node_id(&self) -> Option<[u8; 6]>914     pub const fn get_node_id(&self) -> Option<[u8; 6]> {
915         match self.get_version() {
916             Some(Version::Mac) | Some(Version::SortMac) => {
917                 let mut node_id = [0; 6];
918 
919                 node_id[0] = self.0[10];
920                 node_id[1] = self.0[11];
921                 node_id[2] = self.0[12];
922                 node_id[3] = self.0[13];
923                 node_id[4] = self.0[14];
924                 node_id[5] = self.0[15];
925 
926                 Some(node_id)
927             }
928             _ => None,
929         }
930     }
931 }
932 
933 impl Default for Uuid {
934     #[inline]
default() -> Self935     fn default() -> Self {
936         Uuid::nil()
937     }
938 }
939 
940 impl AsRef<Uuid> for Uuid {
941     #[inline]
as_ref(&self) -> &Uuid942     fn as_ref(&self) -> &Uuid {
943         self
944     }
945 }
946 
947 impl AsRef<[u8]> for Uuid {
948     #[inline]
as_ref(&self) -> &[u8]949     fn as_ref(&self) -> &[u8] {
950         &self.0
951     }
952 }
953 
954 #[cfg(feature = "std")]
955 impl From<Uuid> for std::vec::Vec<u8> {
from(value: Uuid) -> Self956     fn from(value: Uuid) -> Self {
957         value.0.to_vec()
958     }
959 }
960 
961 #[cfg(feature = "std")]
962 impl std::convert::TryFrom<std::vec::Vec<u8>> for Uuid {
963     type Error = Error;
964 
try_from(value: std::vec::Vec<u8>) -> Result<Self, Self::Error>965     fn try_from(value: std::vec::Vec<u8>) -> Result<Self, Self::Error> {
966         Uuid::from_slice(&value)
967     }
968 }
969 
970 #[cfg(feature = "serde")]
971 pub mod serde {
972     //! Adapters for alternative `serde` formats.
973     //!
974     //! This module contains adapters you can use with [`#[serde(with)]`](https://serde.rs/field-attrs.html#with)
975     //! to change the way a [`Uuid`](../struct.Uuid.html) is serialized
976     //! and deserialized.
977 
978     pub use crate::external::serde_support::{braced, compact, simple, urn};
979 }
980 
981 #[cfg(test)]
982 mod tests {
983     use super::*;
984 
985     use crate::std::string::{String, ToString};
986 
987     #[cfg(all(
988         target_arch = "wasm32",
989         target_vendor = "unknown",
990         target_os = "unknown"
991     ))]
992     use wasm_bindgen_test::*;
993 
994     macro_rules! check {
995         ($buf:ident, $format:expr, $target:expr, $len:expr, $cond:expr) => {
996             $buf.clear();
997             write!($buf, $format, $target).unwrap();
998             assert!($buf.len() == $len);
999             assert!($buf.chars().all($cond), "{}", $buf);
1000         };
1001     }
1002 
new() -> Uuid1003     pub const fn new() -> Uuid {
1004         Uuid::from_bytes([
1005             0xF9, 0x16, 0x8C, 0x5E, 0xCE, 0xB2, 0x4F, 0xAA, 0xB6, 0xBF, 0x32, 0x9B, 0xF3, 0x9F,
1006             0xA1, 0xE4,
1007         ])
1008     }
1009 
new2() -> Uuid1010     pub const fn new2() -> Uuid {
1011         Uuid::from_bytes([
1012             0xF9, 0x16, 0x8C, 0x5E, 0xCE, 0xB2, 0x4F, 0xAB, 0xB6, 0xBF, 0x32, 0x9B, 0xF3, 0x9F,
1013             0xA1, 0xE4,
1014         ])
1015     }
1016 
1017     #[test]
1018     #[cfg_attr(
1019         all(
1020             target_arch = "wasm32",
1021             target_vendor = "unknown",
1022             target_os = "unknown"
1023         ),
1024         wasm_bindgen_test
1025     )]
test_uuid_compare()1026     fn test_uuid_compare() {
1027         let uuid1 = new();
1028         let uuid2 = new2();
1029 
1030         assert_eq!(uuid1, uuid1);
1031         assert_eq!(uuid2, uuid2);
1032 
1033         assert_ne!(uuid1, uuid2);
1034         assert_ne!(uuid2, uuid1);
1035     }
1036 
1037     #[test]
1038     #[cfg_attr(
1039         all(
1040             target_arch = "wasm32",
1041             target_vendor = "unknown",
1042             target_os = "unknown"
1043         ),
1044         wasm_bindgen_test
1045     )]
test_uuid_default()1046     fn test_uuid_default() {
1047         let default_uuid = Uuid::default();
1048         let nil_uuid = Uuid::nil();
1049 
1050         assert_eq!(default_uuid, nil_uuid);
1051     }
1052 
1053     #[test]
1054     #[cfg_attr(
1055         all(
1056             target_arch = "wasm32",
1057             target_vendor = "unknown",
1058             target_os = "unknown"
1059         ),
1060         wasm_bindgen_test
1061     )]
test_uuid_display()1062     fn test_uuid_display() {
1063         use crate::std::fmt::Write;
1064 
1065         let uuid = new();
1066         let s = uuid.to_string();
1067         let mut buffer = String::new();
1068 
1069         assert_eq!(s, uuid.hyphenated().to_string());
1070 
1071         check!(buffer, "{}", uuid, 36, |c| c.is_lowercase()
1072             || c.is_digit(10)
1073             || c == '-');
1074     }
1075 
1076     #[test]
1077     #[cfg_attr(
1078         all(
1079             target_arch = "wasm32",
1080             target_vendor = "unknown",
1081             target_os = "unknown"
1082         ),
1083         wasm_bindgen_test
1084     )]
test_uuid_lowerhex()1085     fn test_uuid_lowerhex() {
1086         use crate::std::fmt::Write;
1087 
1088         let mut buffer = String::new();
1089         let uuid = new();
1090 
1091         check!(buffer, "{:x}", uuid, 36, |c| c.is_lowercase()
1092             || c.is_digit(10)
1093             || c == '-');
1094     }
1095 
1096     // noinspection RsAssertEqual
1097     #[test]
1098     #[cfg_attr(
1099         all(
1100             target_arch = "wasm32",
1101             target_vendor = "unknown",
1102             target_os = "unknown"
1103         ),
1104         wasm_bindgen_test
1105     )]
test_uuid_operator_eq()1106     fn test_uuid_operator_eq() {
1107         let uuid1 = new();
1108         let uuid1_dup = uuid1.clone();
1109         let uuid2 = new2();
1110 
1111         assert!(uuid1 == uuid1);
1112         assert!(uuid1 == uuid1_dup);
1113         assert!(uuid1_dup == uuid1);
1114 
1115         assert!(uuid1 != uuid2);
1116         assert!(uuid2 != uuid1);
1117         assert!(uuid1_dup != uuid2);
1118         assert!(uuid2 != uuid1_dup);
1119     }
1120 
1121     #[test]
1122     #[cfg_attr(
1123         all(
1124             target_arch = "wasm32",
1125             target_vendor = "unknown",
1126             target_os = "unknown"
1127         ),
1128         wasm_bindgen_test
1129     )]
test_uuid_to_string()1130     fn test_uuid_to_string() {
1131         use crate::std::fmt::Write;
1132 
1133         let uuid = new();
1134         let s = uuid.to_string();
1135         let mut buffer = String::new();
1136 
1137         assert_eq!(s.len(), 36);
1138 
1139         check!(buffer, "{}", s, 36, |c| c.is_lowercase()
1140             || c.is_digit(10)
1141             || c == '-');
1142     }
1143 
1144     #[test]
1145     #[cfg_attr(
1146         all(
1147             target_arch = "wasm32",
1148             target_vendor = "unknown",
1149             target_os = "unknown"
1150         ),
1151         wasm_bindgen_test
1152     )]
test_non_conforming()1153     fn test_non_conforming() {
1154         let from_bytes =
1155             Uuid::from_bytes([4, 54, 67, 12, 43, 2, 2, 76, 32, 50, 87, 5, 1, 33, 43, 87]);
1156 
1157         assert_eq!(from_bytes.get_version(), None);
1158     }
1159 
1160     #[test]
1161     #[cfg_attr(
1162         all(
1163             target_arch = "wasm32",
1164             target_vendor = "unknown",
1165             target_os = "unknown"
1166         ),
1167         wasm_bindgen_test
1168     )]
test_nil()1169     fn test_nil() {
1170         let nil = Uuid::nil();
1171         let not_nil = new();
1172 
1173         assert!(nil.is_nil());
1174         assert!(!not_nil.is_nil());
1175 
1176         assert_eq!(nil.get_version(), Some(Version::Nil));
1177         assert_eq!(not_nil.get_version(), Some(Version::Random));
1178 
1179         assert_eq!(
1180             nil,
1181             Builder::from_bytes([0; 16])
1182                 .with_version(Version::Nil)
1183                 .into_uuid()
1184         );
1185     }
1186 
1187     #[test]
1188     #[cfg_attr(
1189         all(
1190             target_arch = "wasm32",
1191             target_vendor = "unknown",
1192             target_os = "unknown"
1193         ),
1194         wasm_bindgen_test
1195     )]
test_max()1196     fn test_max() {
1197         let max = Uuid::max();
1198         let not_max = new();
1199 
1200         assert!(max.is_max());
1201         assert!(!not_max.is_max());
1202 
1203         assert_eq!(max.get_version(), Some(Version::Max));
1204         assert_eq!(not_max.get_version(), Some(Version::Random));
1205 
1206         assert_eq!(
1207             max,
1208             Builder::from_bytes([0xff; 16])
1209                 .with_version(Version::Max)
1210                 .into_uuid()
1211         );
1212     }
1213 
1214     #[test]
1215     #[cfg_attr(
1216         all(
1217             target_arch = "wasm32",
1218             target_vendor = "unknown",
1219             target_os = "unknown"
1220         ),
1221         wasm_bindgen_test
1222     )]
test_predefined_namespaces()1223     fn test_predefined_namespaces() {
1224         assert_eq!(
1225             Uuid::NAMESPACE_DNS.hyphenated().to_string(),
1226             "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
1227         );
1228         assert_eq!(
1229             Uuid::NAMESPACE_URL.hyphenated().to_string(),
1230             "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
1231         );
1232         assert_eq!(
1233             Uuid::NAMESPACE_OID.hyphenated().to_string(),
1234             "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
1235         );
1236         assert_eq!(
1237             Uuid::NAMESPACE_X500.hyphenated().to_string(),
1238             "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
1239         );
1240     }
1241 
1242     #[cfg(feature = "v3")]
1243     #[test]
1244     #[cfg_attr(
1245         all(
1246             target_arch = "wasm32",
1247             target_vendor = "unknown",
1248             target_os = "unknown"
1249         ),
1250         wasm_bindgen_test
1251     )]
test_get_version_v3()1252     fn test_get_version_v3() {
1253         let uuid = Uuid::new_v3(&Uuid::NAMESPACE_DNS, "rust-lang.org".as_bytes());
1254 
1255         assert_eq!(uuid.get_version().unwrap(), Version::Md5);
1256         assert_eq!(uuid.get_version_num(), 3);
1257     }
1258 
1259     #[test]
1260     #[cfg_attr(
1261         all(
1262             target_arch = "wasm32",
1263             target_vendor = "unknown",
1264             target_os = "unknown"
1265         ),
1266         wasm_bindgen_test
1267     )]
test_get_timestamp_unsupported_version()1268     fn test_get_timestamp_unsupported_version() {
1269         let uuid = new();
1270 
1271         assert_ne!(Version::Mac, uuid.get_version().unwrap());
1272         assert_ne!(Version::SortMac, uuid.get_version().unwrap());
1273         assert_ne!(Version::SortRand, uuid.get_version().unwrap());
1274 
1275         assert!(uuid.get_timestamp().is_none());
1276     }
1277 
1278     #[test]
1279     #[cfg_attr(
1280         all(
1281             target_arch = "wasm32",
1282             target_vendor = "unknown",
1283             target_os = "unknown"
1284         ),
1285         wasm_bindgen_test
1286     )]
test_get_node_id_unsupported_version()1287     fn test_get_node_id_unsupported_version() {
1288         let uuid = new();
1289 
1290         assert_ne!(Version::Mac, uuid.get_version().unwrap());
1291         assert_ne!(Version::SortMac, uuid.get_version().unwrap());
1292 
1293         assert!(uuid.get_node_id().is_none());
1294     }
1295 
1296     #[test]
1297     #[cfg_attr(
1298         all(
1299             target_arch = "wasm32",
1300             target_vendor = "unknown",
1301             target_os = "unknown"
1302         ),
1303         wasm_bindgen_test
1304     )]
test_get_variant()1305     fn test_get_variant() {
1306         let uuid1 = new();
1307         let uuid2 = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
1308         let uuid3 = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap();
1309         let uuid4 = Uuid::parse_str("936DA01F9ABD4d9dC0C702AF85C822A8").unwrap();
1310         let uuid5 = Uuid::parse_str("F9168C5E-CEB2-4faa-D6BF-329BF39FA1E4").unwrap();
1311         let uuid6 = Uuid::parse_str("f81d4fae-7dec-11d0-7765-00a0c91e6bf6").unwrap();
1312 
1313         assert_eq!(uuid1.get_variant(), Variant::RFC4122);
1314         assert_eq!(uuid2.get_variant(), Variant::RFC4122);
1315         assert_eq!(uuid3.get_variant(), Variant::RFC4122);
1316         assert_eq!(uuid4.get_variant(), Variant::Microsoft);
1317         assert_eq!(uuid5.get_variant(), Variant::Microsoft);
1318         assert_eq!(uuid6.get_variant(), Variant::NCS);
1319     }
1320 
1321     #[test]
1322     #[cfg_attr(
1323         all(
1324             target_arch = "wasm32",
1325             target_vendor = "unknown",
1326             target_os = "unknown"
1327         ),
1328         wasm_bindgen_test
1329     )]
test_to_simple_string()1330     fn test_to_simple_string() {
1331         let uuid1 = new();
1332         let s = uuid1.simple().to_string();
1333 
1334         assert_eq!(s.len(), 32);
1335         assert!(s.chars().all(|c| c.is_digit(16)));
1336     }
1337 
1338     #[test]
1339     #[cfg_attr(
1340         all(
1341             target_arch = "wasm32",
1342             target_vendor = "unknown",
1343             target_os = "unknown"
1344         ),
1345         wasm_bindgen_test
1346     )]
test_hyphenated_string()1347     fn test_hyphenated_string() {
1348         let uuid1 = new();
1349         let s = uuid1.hyphenated().to_string();
1350 
1351         assert_eq!(36, s.len());
1352         assert!(s.chars().all(|c| c.is_digit(16) || c == '-'));
1353     }
1354 
1355     #[test]
1356     #[cfg_attr(
1357         all(
1358             target_arch = "wasm32",
1359             target_vendor = "unknown",
1360             target_os = "unknown"
1361         ),
1362         wasm_bindgen_test
1363     )]
test_upper_lower_hex()1364     fn test_upper_lower_hex() {
1365         use std::fmt::Write;
1366 
1367         let mut buf = String::new();
1368         let u = new();
1369 
1370         macro_rules! check {
1371             ($buf:ident, $format:expr, $target:expr, $len:expr, $cond:expr) => {
1372                 $buf.clear();
1373                 write!($buf, $format, $target).unwrap();
1374                 assert_eq!($len, buf.len());
1375                 assert!($buf.chars().all($cond), "{}", $buf);
1376             };
1377         }
1378 
1379         check!(buf, "{:x}", u, 36, |c| c.is_lowercase()
1380             || c.is_digit(10)
1381             || c == '-');
1382         check!(buf, "{:X}", u, 36, |c| c.is_uppercase()
1383             || c.is_digit(10)
1384             || c == '-');
1385         check!(buf, "{:#x}", u, 36, |c| c.is_lowercase()
1386             || c.is_digit(10)
1387             || c == '-');
1388         check!(buf, "{:#X}", u, 36, |c| c.is_uppercase()
1389             || c.is_digit(10)
1390             || c == '-');
1391 
1392         check!(buf, "{:X}", u.hyphenated(), 36, |c| c.is_uppercase()
1393             || c.is_digit(10)
1394             || c == '-');
1395         check!(buf, "{:X}", u.simple(), 32, |c| c.is_uppercase()
1396             || c.is_digit(10));
1397         check!(buf, "{:#X}", u.hyphenated(), 36, |c| c.is_uppercase()
1398             || c.is_digit(10)
1399             || c == '-');
1400         check!(buf, "{:#X}", u.simple(), 32, |c| c.is_uppercase()
1401             || c.is_digit(10));
1402 
1403         check!(buf, "{:x}", u.hyphenated(), 36, |c| c.is_lowercase()
1404             || c.is_digit(10)
1405             || c == '-');
1406         check!(buf, "{:x}", u.simple(), 32, |c| c.is_lowercase()
1407             || c.is_digit(10));
1408         check!(buf, "{:#x}", u.hyphenated(), 36, |c| c.is_lowercase()
1409             || c.is_digit(10)
1410             || c == '-');
1411         check!(buf, "{:#x}", u.simple(), 32, |c| c.is_lowercase()
1412             || c.is_digit(10));
1413     }
1414 
1415     #[test]
1416     #[cfg_attr(
1417         all(
1418             target_arch = "wasm32",
1419             target_vendor = "unknown",
1420             target_os = "unknown"
1421         ),
1422         wasm_bindgen_test
1423     )]
test_to_urn_string()1424     fn test_to_urn_string() {
1425         let uuid1 = new();
1426         let ss = uuid1.urn().to_string();
1427         let s = &ss[9..];
1428 
1429         assert!(ss.starts_with("urn:uuid:"));
1430         assert_eq!(s.len(), 36);
1431         assert!(s.chars().all(|c| c.is_digit(16) || c == '-'));
1432     }
1433 
1434     #[test]
1435     #[cfg_attr(
1436         all(
1437             target_arch = "wasm32",
1438             target_vendor = "unknown",
1439             target_os = "unknown"
1440         ),
1441         wasm_bindgen_test
1442     )]
test_to_simple_string_matching()1443     fn test_to_simple_string_matching() {
1444         let uuid1 = new();
1445 
1446         let hs = uuid1.hyphenated().to_string();
1447         let ss = uuid1.simple().to_string();
1448 
1449         let hsn = hs.chars().filter(|&c| c != '-').collect::<String>();
1450 
1451         assert_eq!(hsn, ss);
1452     }
1453 
1454     #[test]
1455     #[cfg_attr(
1456         all(
1457             target_arch = "wasm32",
1458             target_vendor = "unknown",
1459             target_os = "unknown"
1460         ),
1461         wasm_bindgen_test
1462     )]
test_string_roundtrip()1463     fn test_string_roundtrip() {
1464         let uuid = new();
1465 
1466         let hs = uuid.hyphenated().to_string();
1467         let uuid_hs = Uuid::parse_str(&hs).unwrap();
1468         assert_eq!(uuid_hs, uuid);
1469 
1470         let ss = uuid.to_string();
1471         let uuid_ss = Uuid::parse_str(&ss).unwrap();
1472         assert_eq!(uuid_ss, uuid);
1473     }
1474 
1475     #[test]
1476     #[cfg_attr(
1477         all(
1478             target_arch = "wasm32",
1479             target_vendor = "unknown",
1480             target_os = "unknown"
1481         ),
1482         wasm_bindgen_test
1483     )]
test_from_fields()1484     fn test_from_fields() {
1485         let d1: u32 = 0xa1a2a3a4;
1486         let d2: u16 = 0xb1b2;
1487         let d3: u16 = 0xc1c2;
1488         let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
1489 
1490         let u = Uuid::from_fields(d1, d2, d3, &d4);
1491 
1492         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1493         let result = u.simple().to_string();
1494         assert_eq!(result, expected);
1495     }
1496 
1497     #[test]
1498     #[cfg_attr(
1499         all(
1500             target_arch = "wasm32",
1501             target_vendor = "unknown",
1502             target_os = "unknown"
1503         ),
1504         wasm_bindgen_test
1505     )]
test_from_fields_le()1506     fn test_from_fields_le() {
1507         let d1: u32 = 0xa4a3a2a1;
1508         let d2: u16 = 0xb2b1;
1509         let d3: u16 = 0xc2c1;
1510         let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
1511 
1512         let u = Uuid::from_fields_le(d1, d2, d3, &d4);
1513 
1514         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1515         let result = u.simple().to_string();
1516         assert_eq!(result, expected);
1517     }
1518 
1519     #[test]
1520     #[cfg_attr(
1521         all(
1522             target_arch = "wasm32",
1523             target_vendor = "unknown",
1524             target_os = "unknown"
1525         ),
1526         wasm_bindgen_test
1527     )]
test_as_fields()1528     fn test_as_fields() {
1529         let u = new();
1530         let (d1, d2, d3, d4) = u.as_fields();
1531 
1532         assert_ne!(d1, 0);
1533         assert_ne!(d2, 0);
1534         assert_ne!(d3, 0);
1535         assert_eq!(d4.len(), 8);
1536         assert!(!d4.iter().all(|&b| b == 0));
1537     }
1538 
1539     #[test]
1540     #[cfg_attr(
1541         all(
1542             target_arch = "wasm32",
1543             target_vendor = "unknown",
1544             target_os = "unknown"
1545         ),
1546         wasm_bindgen_test
1547     )]
test_fields_roundtrip()1548     fn test_fields_roundtrip() {
1549         let d1_in: u32 = 0xa1a2a3a4;
1550         let d2_in: u16 = 0xb1b2;
1551         let d3_in: u16 = 0xc1c2;
1552         let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
1553 
1554         let u = Uuid::from_fields(d1_in, d2_in, d3_in, d4_in);
1555         let (d1_out, d2_out, d3_out, d4_out) = u.as_fields();
1556 
1557         assert_eq!(d1_in, d1_out);
1558         assert_eq!(d2_in, d2_out);
1559         assert_eq!(d3_in, d3_out);
1560         assert_eq!(d4_in, d4_out);
1561     }
1562 
1563     #[test]
1564     #[cfg_attr(
1565         all(
1566             target_arch = "wasm32",
1567             target_vendor = "unknown",
1568             target_os = "unknown"
1569         ),
1570         wasm_bindgen_test
1571     )]
test_fields_le_roundtrip()1572     fn test_fields_le_roundtrip() {
1573         let d1_in: u32 = 0xa4a3a2a1;
1574         let d2_in: u16 = 0xb2b1;
1575         let d3_in: u16 = 0xc2c1;
1576         let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
1577 
1578         let u = Uuid::from_fields_le(d1_in, d2_in, d3_in, d4_in);
1579         let (d1_out, d2_out, d3_out, d4_out) = u.to_fields_le();
1580 
1581         assert_eq!(d1_in, d1_out);
1582         assert_eq!(d2_in, d2_out);
1583         assert_eq!(d3_in, d3_out);
1584         assert_eq!(d4_in, d4_out);
1585     }
1586 
1587     #[test]
1588     #[cfg_attr(
1589         all(
1590             target_arch = "wasm32",
1591             target_vendor = "unknown",
1592             target_os = "unknown"
1593         ),
1594         wasm_bindgen_test
1595     )]
test_fields_le_are_actually_le()1596     fn test_fields_le_are_actually_le() {
1597         let d1_in: u32 = 0xa1a2a3a4;
1598         let d2_in: u16 = 0xb1b2;
1599         let d3_in: u16 = 0xc1c2;
1600         let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
1601 
1602         let u = Uuid::from_fields(d1_in, d2_in, d3_in, d4_in);
1603         let (d1_out, d2_out, d3_out, d4_out) = u.to_fields_le();
1604 
1605         assert_eq!(d1_in, d1_out.swap_bytes());
1606         assert_eq!(d2_in, d2_out.swap_bytes());
1607         assert_eq!(d3_in, d3_out.swap_bytes());
1608         assert_eq!(d4_in, d4_out);
1609     }
1610 
1611     #[test]
1612     #[cfg_attr(
1613         all(
1614             target_arch = "wasm32",
1615             target_vendor = "unknown",
1616             target_os = "unknown"
1617         ),
1618         wasm_bindgen_test
1619     )]
test_from_u128()1620     fn test_from_u128() {
1621         let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8;
1622 
1623         let u = Uuid::from_u128(v_in);
1624 
1625         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1626         let result = u.simple().to_string();
1627         assert_eq!(result, expected);
1628     }
1629 
1630     #[test]
1631     #[cfg_attr(
1632         all(
1633             target_arch = "wasm32",
1634             target_vendor = "unknown",
1635             target_os = "unknown"
1636         ),
1637         wasm_bindgen_test
1638     )]
test_from_u128_le()1639     fn test_from_u128_le() {
1640         let v_in: u128 = 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1;
1641 
1642         let u = Uuid::from_u128_le(v_in);
1643 
1644         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1645         let result = u.simple().to_string();
1646         assert_eq!(result, expected);
1647     }
1648 
1649     #[test]
1650     #[cfg_attr(
1651         all(
1652             target_arch = "wasm32",
1653             target_vendor = "unknown",
1654             target_os = "unknown"
1655         ),
1656         wasm_bindgen_test
1657     )]
test_from_u64_pair()1658     fn test_from_u64_pair() {
1659         let high_in: u64 = 0xa1a2a3a4b1b2c1c2;
1660         let low_in: u64 = 0xd1d2d3d4d5d6d7d8;
1661 
1662         let u = Uuid::from_u64_pair(high_in, low_in);
1663 
1664         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1665         let result = u.simple().to_string();
1666         assert_eq!(result, expected);
1667     }
1668 
1669     #[test]
1670     #[cfg_attr(
1671         all(
1672             target_arch = "wasm32",
1673             target_vendor = "unknown",
1674             target_os = "unknown"
1675         ),
1676         wasm_bindgen_test
1677     )]
test_u128_roundtrip()1678     fn test_u128_roundtrip() {
1679         let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8;
1680 
1681         let u = Uuid::from_u128(v_in);
1682         let v_out = u.as_u128();
1683 
1684         assert_eq!(v_in, v_out);
1685     }
1686 
1687     #[test]
1688     #[cfg_attr(
1689         all(
1690             target_arch = "wasm32",
1691             target_vendor = "unknown",
1692             target_os = "unknown"
1693         ),
1694         wasm_bindgen_test
1695     )]
test_u128_le_roundtrip()1696     fn test_u128_le_roundtrip() {
1697         let v_in: u128 = 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1;
1698 
1699         let u = Uuid::from_u128_le(v_in);
1700         let v_out = u.to_u128_le();
1701 
1702         assert_eq!(v_in, v_out);
1703     }
1704 
1705     #[test]
1706     #[cfg_attr(
1707         all(
1708             target_arch = "wasm32",
1709             target_vendor = "unknown",
1710             target_os = "unknown"
1711         ),
1712         wasm_bindgen_test
1713     )]
test_u64_pair_roundtrip()1714     fn test_u64_pair_roundtrip() {
1715         let high_in: u64 = 0xa1a2a3a4b1b2c1c2;
1716         let low_in: u64 = 0xd1d2d3d4d5d6d7d8;
1717 
1718         let u = Uuid::from_u64_pair(high_in, low_in);
1719         let (high_out, low_out) = u.as_u64_pair();
1720 
1721         assert_eq!(high_in, high_out);
1722         assert_eq!(low_in, low_out);
1723     }
1724 
1725     #[test]
1726     #[cfg_attr(
1727         all(
1728             target_arch = "wasm32",
1729             target_vendor = "unknown",
1730             target_os = "unknown"
1731         ),
1732         wasm_bindgen_test
1733     )]
test_u128_le_is_actually_le()1734     fn test_u128_le_is_actually_le() {
1735         let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8;
1736 
1737         let u = Uuid::from_u128(v_in);
1738         let v_out = u.to_u128_le();
1739 
1740         assert_eq!(v_in, v_out.swap_bytes());
1741     }
1742 
1743     #[test]
1744     #[cfg_attr(
1745         all(
1746             target_arch = "wasm32",
1747             target_vendor = "unknown",
1748             target_os = "unknown"
1749         ),
1750         wasm_bindgen_test
1751     )]
test_from_slice()1752     fn test_from_slice() {
1753         let b = [
1754             0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
1755             0xd7, 0xd8,
1756         ];
1757 
1758         let u = Uuid::from_slice(&b).unwrap();
1759         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1760 
1761         assert_eq!(u.simple().to_string(), expected);
1762     }
1763 
1764     #[test]
1765     #[cfg_attr(
1766         all(
1767             target_arch = "wasm32",
1768             target_vendor = "unknown",
1769             target_os = "unknown"
1770         ),
1771         wasm_bindgen_test
1772     )]
test_from_bytes()1773     fn test_from_bytes() {
1774         let b = [
1775             0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
1776             0xd7, 0xd8,
1777         ];
1778 
1779         let u = Uuid::from_bytes(b);
1780         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1781 
1782         assert_eq!(u.simple().to_string(), expected);
1783     }
1784 
1785     #[test]
1786     #[cfg_attr(
1787         all(
1788             target_arch = "wasm32",
1789             target_vendor = "unknown",
1790             target_os = "unknown"
1791         ),
1792         wasm_bindgen_test
1793     )]
test_as_bytes()1794     fn test_as_bytes() {
1795         let u = new();
1796         let ub = u.as_bytes();
1797         let ur: &[u8] = u.as_ref();
1798 
1799         assert_eq!(ub.len(), 16);
1800         assert_eq!(ur.len(), 16);
1801         assert!(!ub.iter().all(|&b| b == 0));
1802         assert!(!ur.iter().all(|&b| b == 0));
1803     }
1804 
1805     #[test]
1806     #[cfg(feature = "std")]
1807     #[cfg_attr(
1808         all(
1809             target_arch = "wasm32",
1810             target_vendor = "unknown",
1811             target_os = "unknown"
1812         ),
1813         wasm_bindgen_test
1814     )]
test_convert_vec()1815     fn test_convert_vec() {
1816         use crate::std::{convert::TryInto, vec::Vec};
1817 
1818         let u = new();
1819         let ub: &[u8] = u.as_ref();
1820 
1821         let v: Vec<u8> = u.into();
1822 
1823         assert_eq!(&v, ub);
1824 
1825         let uv: Uuid = v.try_into().unwrap();
1826 
1827         assert_eq!(uv, u);
1828     }
1829 
1830     #[test]
1831     #[cfg_attr(
1832         all(
1833             target_arch = "wasm32",
1834             target_vendor = "unknown",
1835             target_os = "unknown"
1836         ),
1837         wasm_bindgen_test
1838     )]
test_bytes_roundtrip()1839     fn test_bytes_roundtrip() {
1840         let b_in: crate::Bytes = [
1841             0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
1842             0xd7, 0xd8,
1843         ];
1844 
1845         let u = Uuid::from_slice(&b_in).unwrap();
1846 
1847         let b_out = u.as_bytes();
1848 
1849         assert_eq!(&b_in, b_out);
1850     }
1851 
1852     #[test]
1853     #[cfg_attr(
1854         all(
1855             target_arch = "wasm32",
1856             target_vendor = "unknown",
1857             target_os = "unknown"
1858         ),
1859         wasm_bindgen_test
1860     )]
test_bytes_le_roundtrip()1861     fn test_bytes_le_roundtrip() {
1862         let b = [
1863             0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
1864             0xd7, 0xd8,
1865         ];
1866 
1867         let u1 = Uuid::from_bytes(b);
1868 
1869         let b_le = u1.to_bytes_le();
1870 
1871         let u2 = Uuid::from_bytes_le(b_le);
1872 
1873         assert_eq!(u1, u2);
1874     }
1875 
1876     #[test]
1877     #[cfg_attr(
1878         all(
1879             target_arch = "wasm32",
1880             target_vendor = "unknown",
1881             target_os = "unknown"
1882         ),
1883         wasm_bindgen_test
1884     )]
test_iterbytes_impl_for_uuid()1885     fn test_iterbytes_impl_for_uuid() {
1886         let mut set = std::collections::HashSet::new();
1887         let id1 = new();
1888         let id2 = new2();
1889         set.insert(id1.clone());
1890 
1891         assert!(set.contains(&id1));
1892         assert!(!set.contains(&id2));
1893     }
1894 }
1895