• 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 UUIDs.
13 //!
14 //! Provides support for Universally Unique Identifiers (UUIDs). A UUID is a
15 //! unique 128-bit number, stored as 16 octets. UUIDs are used to  assign
16 //! unique identifiers to entities without requiring a central allocating
17 //! authority.
18 //!
19 //! They are particularly useful in distributed systems, though can be used in
20 //! disparate areas, such as databases and network protocols.  Typically a UUID
21 //! is displayed in a readable string form as a sequence of hexadecimal digits,
22 //! separated into groups by hyphens.
23 //!
24 //! The uniqueness property is not strictly guaranteed, however for all
25 //! practical purposes, it can be assumed that an unintentional collision would
26 //! be extremely unlikely.
27 //!
28 //! # Dependencies
29 //!
30 //! By default, this crate depends on nothing but `std` and cannot generate
31 //! UUIDs. You need to enable the following Cargo features to enable
32 //! various pieces of functionality:
33 //!
34 //! * `v1` - adds the [`Uuid::new_v1`] function and the ability to create a V1
35 //!   using an implementation of [`v1::ClockSequence`] (usually
36 //! [`v1::Context`]) and a timestamp from `time::timespec`.
37 //! * `v3` - adds the [`Uuid::new_v3`] function and the ability to create a V3
38 //!   UUID based on the MD5 hash of some data.
39 //! * `v4` - adds the [`Uuid::new_v4`] function and the ability to randomly
40 //!   generate a UUID.
41 //! * `v5` - adds the [`Uuid::new_v5`] function and the ability to create a V5
42 //!   UUID based on the SHA1 hash of some data.
43 //! * `serde` - adds the ability to serialize and deserialize a UUID using the
44 //!   `serde` crate.
45 //!
46 //! For WebAssembly, enable one of the following features depending
47 //! on your JavaScript interop toolchain of choice:
48 //!
49 //! * `stdweb` - for [`stdweb`] combined with [`cargo-web`]
50 //! * `wasm-bindgen` - for [`wasm-bindgen`]
51 //!
52 //! By default, `uuid` can be depended on with:
53 //!
54 //! ```toml
55 //! [dependencies]
56 //! uuid = "0.8"
57 //! ```
58 //!
59 //! To activate various features, use syntax like:
60 //!
61 //! ```toml
62 //! [dependencies]
63 //! uuid = { version = "0.8", features = ["serde", "v4"] }
64 //! ```
65 //!
66 //! You can disable default features with:
67 //!
68 //! ```toml
69 //! [dependencies]
70 //! uuid = { version = "0.8", default-features = false }
71 //! ```
72 //!
73 //! # Examples
74 //!
75 //! To parse a UUID given in the simple format and print it as a urn:
76 //!
77 //! ```rust
78 //! use uuid::Uuid;
79 //!
80 //! fn main() -> Result<(), uuid::Error> {
81 //!     let my_uuid =
82 //!         Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8")?;
83 //!     println!("{}", my_uuid.to_urn());
84 //!     Ok(())
85 //! }
86 //! ```
87 //!
88 //! To create a new random (V4) UUID and print it out in hexadecimal form:
89 //!
90 //! ```ignore,rust
91 //! // Note that this requires the `v4` feature enabled in the uuid crate.
92 //!
93 //! use uuid::Uuid;
94 //!
95 //! fn main() -> Result<(), Box<dyn std::error::Error>> {
96 //!     #[cfg(feature = "v4")] {
97 //!         let my_uuid = Uuid::new_v4()?;
98 //!         println!("{}", my_uuid);
99 //!     }
100 //!     Ok(())
101 //! }
102 //! ```
103 //!
104 //! # Strings
105 //!
106 //! Examples of string representations:
107 //!
108 //! * simple: `936DA01F9ABD4d9d80C702AF85C822A8`
109 //! * hyphenated: `550e8400-e29b-41d4-a716-446655440000`
110 //! * urn: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4`
111 //!
112 //! # References
113 //!
114 //! * [Wikipedia: Universally Unique Identifier](http://en.wikipedia.org/wiki/Universally_unique_identifier)
115 //! * [RFC4122: A Universally Unique IDentifier (UUID) URN Namespace](http://tools.ietf.org/html/rfc4122)
116 //!
117 //! [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen
118 //! [`cargo-web`]: https://crates.io/crates/cargo-web
119 //! [`stdweb`]: https://crates.io/crates/stdweb
120 //! [`Uuid`]: struct.Uuid.html
121 //! [`Uuid::new_v1`]: struct.Uuid.html#method.new_v1
122 //! [`Uuid::new_v3`]: struct.Uuid.html#method.new_v3
123 //! [`Uuid::new_v4`]: struct.Uuid.html#method.new_v4
124 //! [`Uuid::new_v5`]: struct.Uuid.html#method.new_v5
125 //! [`v1::ClockSequence`]: v1/trait.ClockSequence.html
126 //! [`v1::Context`]: v1/struct.Context.html
127 
128 #![no_std]
129 #![deny(missing_debug_implementations, missing_docs)]
130 #![doc(
131     html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
132     html_favicon_url = "https://www.rust-lang.org/favicon.ico",
133     html_root_url = "https://docs.rs/uuid/0.8.2"
134 )]
135 
136 #[cfg(any(feature = "std", test))]
137 #[macro_use]
138 extern crate std;
139 
140 #[cfg(all(not(feature = "std"), not(test)))]
141 #[macro_use]
142 extern crate core as std;
143 
144 mod builder;
145 mod error;
146 mod parser;
147 mod prelude;
148 
149 pub mod adapter;
150 #[cfg(feature = "v1")]
151 pub mod v1;
152 
153 #[cfg(feature = "serde")]
154 mod serde_support;
155 #[cfg(feature = "slog")]
156 mod slog_support;
157 #[cfg(test)]
158 mod test_util;
159 #[cfg(all(
160     feature = "v3",
161     any(
162         not(target_arch = "wasm32"),
163         target_os = "wasi",
164         all(
165             target_arch = "wasm32",
166             any(feature = "stdweb", feature = "wasm-bindgen")
167         )
168     )
169 ))]
170 mod v3;
171 #[cfg(all(
172     feature = "v4",
173     any(
174         not(target_arch = "wasm32"),
175         target_os = "wasi",
176         all(
177             target_arch = "wasm32",
178             any(feature = "stdweb", feature = "wasm-bindgen")
179         )
180     )
181 ))]
182 mod v4;
183 #[cfg(all(
184     feature = "v5",
185     any(
186         not(target_arch = "wasm32"),
187         target_os = "wasi",
188         all(
189             target_arch = "wasm32",
190             any(feature = "stdweb", feature = "wasm-bindgen")
191         )
192     )
193 ))]
194 mod v5;
195 #[cfg(all(windows, feature = "winapi"))]
196 mod winapi_support;
197 
198 use crate::std::{fmt, str};
199 
200 pub use crate::error::Error;
201 
202 /// A builder struct for creating a UUID.
203 ///
204 /// # Examples
205 ///
206 /// Creating a v4 UUID from externally generated bytes:
207 ///
208 /// ```
209 /// use uuid::{Builder, Variant, Version};
210 ///
211 /// # let rng = || [
212 /// #     70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90,
213 /// # 145, 63, 62,
214 /// # ];
215 /// let random_bytes = rng();
216 /// let uuid = Builder::from_bytes(random_bytes)
217 ///     .set_variant(Variant::RFC4122)
218 ///     .set_version(Version::Random)
219 ///     .build();
220 /// ```
221 #[allow(missing_copy_implementations)]
222 #[derive(Debug)]
223 pub struct Builder(Bytes);
224 
225 /// A 128-bit (16 byte) buffer containing the ID.
226 pub type Bytes = [u8; 16];
227 
228 /// The version of the UUID, denoting the generating algorithm.
229 #[derive(Clone, Copy, Debug, PartialEq)]
230 pub enum Version {
231     /// Special case for `nil` UUID.
232     Nil = 0,
233     /// Version 1: MAC address.
234     Mac,
235     /// Version 2: DCE Security.
236     Dce,
237     /// Version 3: MD5 hash.
238     Md5,
239     /// Version 4: Random.
240     Random,
241     /// Version 5: SHA-1 hash.
242     Sha1,
243 }
244 
245 /// The reserved variants of UUIDs.
246 #[derive(Clone, Copy, Debug, PartialEq)]
247 pub enum Variant {
248     /// Reserved by the NCS for backward compatibility.
249     NCS = 0,
250     /// As described in the RFC4122 Specification (default).
251     RFC4122,
252     /// Reserved by Microsoft for backward compatibility.
253     Microsoft,
254     /// Reserved for future expansion.
255     Future,
256 }
257 
258 /// A Universally Unique Identifier (UUID).
259 #[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
260 #[repr(transparent)]
261 pub struct Uuid(Bytes);
262 
263 impl Uuid {
264     /// UUID namespace for Domain Name System (DNS).
265     pub const NAMESPACE_DNS: Self = Uuid([
266         0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0,
267         0x4f, 0xd4, 0x30, 0xc8,
268     ]);
269 
270     /// UUID namespace for ISO Object Identifiers (OIDs).
271     pub const NAMESPACE_OID: Self = Uuid([
272         0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0,
273         0x4f, 0xd4, 0x30, 0xc8,
274     ]);
275 
276     /// UUID namespace for Uniform Resource Locators (URLs).
277     pub const NAMESPACE_URL: Self = Uuid([
278         0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0,
279         0x4f, 0xd4, 0x30, 0xc8,
280     ]);
281 
282     /// UUID namespace for X.500 Distinguished Names (DNs).
283     pub const NAMESPACE_X500: Self = Uuid([
284         0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0,
285         0x4f, 0xd4, 0x30, 0xc8,
286     ]);
287 
288     /// Returns the variant of the UUID structure.
289     ///
290     /// This determines the interpretation of the structure of the UUID.
291     /// Currently only the RFC4122 variant is generated by this module.
292     ///
293     /// * [Variant Reference](http://tools.ietf.org/html/rfc4122#section-4.1.1)
get_variant(&self) -> Option<Variant>294     pub fn get_variant(&self) -> Option<Variant> {
295         match self.as_bytes()[8] {
296             x if x & 0x80 == 0x00 => Some(Variant::NCS),
297             x if x & 0xc0 == 0x80 => Some(Variant::RFC4122),
298             x if x & 0xe0 == 0xc0 => Some(Variant::Microsoft),
299             x if x & 0xe0 == 0xe0 => Some(Variant::Future),
300             _ => None,
301         }
302     }
303 
304     /// Returns the version number of the UUID.
305     ///
306     /// This represents the algorithm used to generate the contents.
307     ///
308     /// Currently only the Random (V4) algorithm is supported by this
309     /// module.  There are security and privacy implications for using
310     /// older versions - see [Wikipedia: Universally Unique Identifier](
311     /// http://en.wikipedia.org/wiki/Universally_unique_identifier) for
312     /// details.
313     ///
314     /// * [Version Reference](http://tools.ietf.org/html/rfc4122#section-4.1.3)
get_version_num(&self) -> usize315     pub const fn get_version_num(&self) -> usize {
316         (self.as_bytes()[6] >> 4) as usize
317     }
318 
319     /// Returns the version of the UUID.
320     ///
321     /// This represents the algorithm used to generate the contents
get_version(&self) -> Option<Version>322     pub fn get_version(&self) -> Option<Version> {
323         let v = self.as_bytes()[6] >> 4;
324         match v {
325             0 if self.is_nil() => Some(Version::Nil),
326             1 => Some(Version::Mac),
327             2 => Some(Version::Dce),
328             3 => Some(Version::Md5),
329             4 => Some(Version::Random),
330             5 => Some(Version::Sha1),
331             _ => None,
332         }
333     }
334 
335     /// Returns the four field values of the UUID in big-endian order.
336     ///
337     /// These values can be passed to the `from_fields()` method to get the
338     /// original `Uuid` back.
339     ///
340     /// * The first field value represents the first group of (eight) hex
341     ///   digits, taken as a big-endian `u32` value.  For V1 UUIDs, this field
342     ///   represents the low 32 bits of the timestamp.
343     /// * The second field value represents the second group of (four) hex
344     ///   digits, taken as a big-endian `u16` value.  For V1 UUIDs, this field
345     ///   represents the middle 16 bits of the timestamp.
346     /// * The third field value represents the third group of (four) hex digits,
347     ///   taken as a big-endian `u16` value.  The 4 most significant bits give
348     ///   the UUID version, and for V1 UUIDs, the last 12 bits represent the
349     ///   high 12 bits of the timestamp.
350     /// * The last field value represents the last two groups of four and twelve
351     ///   hex digits, taken in order.  The first 1-3 bits of this indicate the
352     ///   UUID variant, and for V1 UUIDs, the next 13-15 bits indicate the clock
353     ///   sequence and the last 48 bits indicate the node ID.
354     ///
355     /// # Examples
356     ///
357     /// ```
358     /// use uuid::Uuid;
359     ///
360     /// fn main() -> Result<(), uuid::Error> {
361     ///     let uuid = Uuid::nil();
362     ///     assert_eq!(uuid.as_fields(), (0, 0, 0, &[0u8; 8]));
363     ///
364     ///     let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?;
365     ///     assert_eq!(
366     ///         uuid.as_fields(),
367     ///         (
368     ///             0x936DA01F,
369     ///             0x9ABD,
370     ///             0x4D9D,
371     ///             b"\x80\xC7\x02\xAF\x85\xC8\x22\xA8"
372     ///         )
373     ///     );
374     ///
375     ///     Ok(())
376     /// }
377     /// ```
as_fields(&self) -> (u32, u16, u16, &[u8; 8])378     pub fn as_fields(&self) -> (u32, u16, u16, &[u8; 8]) {
379         let d1 = u32::from(self.as_bytes()[0]) << 24
380             | u32::from(self.as_bytes()[1]) << 16
381             | u32::from(self.as_bytes()[2]) << 8
382             | u32::from(self.as_bytes()[3]);
383 
384         let d2 =
385             u16::from(self.as_bytes()[4]) << 8 | u16::from(self.as_bytes()[5]);
386 
387         let d3 =
388             u16::from(self.as_bytes()[6]) << 8 | u16::from(self.as_bytes()[7]);
389 
390         let d4: &[u8; 8] =
391             unsafe { &*(self.as_bytes()[8..16].as_ptr() as *const [u8; 8]) };
392         (d1, d2, d3, d4)
393     }
394 
395     /// Returns the four field values of the UUID in little-endian order.
396     ///
397     /// The bytes in the returned integer fields will
398     /// be converted from big-endian order.
399     ///
400     /// # Examples
401     ///
402     /// ```
403     /// use uuid::Uuid;
404     ///
405     /// fn main() -> Result<(), uuid::Error> {
406     ///     let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?;
407     ///     assert_eq!(
408     ///         uuid.to_fields_le(),
409     ///         (
410     ///             0x1FA06D93,
411     ///             0xBD9A,
412     ///             0x9D4D,
413     ///             b"\x80\xC7\x02\xAF\x85\xC8\x22\xA8"
414     ///         )
415     ///     );
416     ///     Ok(())
417     /// }
418     /// ```
to_fields_le(&self) -> (u32, u16, u16, &[u8; 8])419     pub fn to_fields_le(&self) -> (u32, u16, u16, &[u8; 8]) {
420         let d1 = u32::from(self.as_bytes()[0])
421             | u32::from(self.as_bytes()[1]) << 8
422             | u32::from(self.as_bytes()[2]) << 16
423             | u32::from(self.as_bytes()[3]) << 24;
424 
425         let d2 =
426             u16::from(self.as_bytes()[4]) | u16::from(self.as_bytes()[5]) << 8;
427 
428         let d3 =
429             u16::from(self.as_bytes()[6]) | u16::from(self.as_bytes()[7]) << 8;
430 
431         let d4: &[u8; 8] =
432             unsafe { &*(self.as_bytes()[8..16].as_ptr() as *const [u8; 8]) };
433         (d1, d2, d3, d4)
434     }
435 
436     /// Returns a 128bit value containing the UUID data.
437     ///
438     /// The bytes in the UUID will be packed into a `u128`, like the
439     /// [`Uuid::as_bytes`] method.
440     ///
441     /// # Examples
442     ///
443     /// ```
444     /// use uuid::Uuid;
445     ///
446     /// fn main() -> Result<(), uuid::Error> {
447     ///     let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?;
448     ///     assert_eq!(
449     ///         uuid.as_u128(),
450     ///         0x936DA01F9ABD4D9D80C702AF85C822A8,
451     ///     );
452     ///     Ok(())
453     /// }
454     /// ```
as_u128(&self) -> u128455     pub fn as_u128(&self) -> u128 {
456         u128::from(self.as_bytes()[0]) << 120
457             | u128::from(self.as_bytes()[1]) << 112
458             | u128::from(self.as_bytes()[2]) << 104
459             | u128::from(self.as_bytes()[3]) << 96
460             | u128::from(self.as_bytes()[4]) << 88
461             | u128::from(self.as_bytes()[5]) << 80
462             | u128::from(self.as_bytes()[6]) << 72
463             | u128::from(self.as_bytes()[7]) << 64
464             | u128::from(self.as_bytes()[8]) << 56
465             | u128::from(self.as_bytes()[9]) << 48
466             | u128::from(self.as_bytes()[10]) << 40
467             | u128::from(self.as_bytes()[11]) << 32
468             | u128::from(self.as_bytes()[12]) << 24
469             | u128::from(self.as_bytes()[13]) << 16
470             | u128::from(self.as_bytes()[14]) << 8
471             | u128::from(self.as_bytes()[15])
472     }
473 
474     /// Returns a 128bit little-endian value containing the UUID data.
475     ///
476     /// The bytes in the UUID will be reversed and packed into a `u128`.
477     /// Note that this will produce a different result than
478     /// [`Uuid::to_fields_le`], because the entire UUID is reversed, rather
479     /// than reversing the individual fields in-place.
480     ///
481     /// # Examples
482     ///
483     /// ```
484     /// use uuid::Uuid;
485     ///
486     /// fn main() -> Result<(), uuid::Error> {
487     ///     let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?;
488     ///
489     ///     assert_eq!(
490     ///         uuid.to_u128_le(),
491     ///         0xA822C885AF02C7809D4DBD9A1FA06D93,
492     ///     );
493     ///     Ok(())
494     /// }
495     /// ```
to_u128_le(&self) -> u128496     pub fn to_u128_le(&self) -> u128 {
497         u128::from(self.as_bytes()[0])
498             | u128::from(self.as_bytes()[1]) << 8
499             | u128::from(self.as_bytes()[2]) << 16
500             | u128::from(self.as_bytes()[3]) << 24
501             | u128::from(self.as_bytes()[4]) << 32
502             | u128::from(self.as_bytes()[5]) << 40
503             | u128::from(self.as_bytes()[6]) << 48
504             | u128::from(self.as_bytes()[7]) << 56
505             | u128::from(self.as_bytes()[8]) << 64
506             | u128::from(self.as_bytes()[9]) << 72
507             | u128::from(self.as_bytes()[10]) << 80
508             | u128::from(self.as_bytes()[11]) << 88
509             | u128::from(self.as_bytes()[12]) << 96
510             | u128::from(self.as_bytes()[13]) << 104
511             | u128::from(self.as_bytes()[14]) << 112
512             | u128::from(self.as_bytes()[15]) << 120
513     }
514 
515     /// Returns an array of 16 octets containing the UUID data.
as_bytes(&self) -> &Bytes516     pub const fn as_bytes(&self) -> &Bytes {
517         &self.0
518     }
519 
520     /// Tests if the UUID is nil.
is_nil(&self) -> bool521     pub fn is_nil(&self) -> bool {
522         self.as_bytes().iter().all(|&b| b == 0)
523     }
524 
525     /// A buffer that can be used for `encode_...` calls, that is
526     /// guaranteed to be long enough for any of the adapters.
527     ///
528     /// # Examples
529     ///
530     /// ```rust
531     /// use uuid::Uuid;
532     ///
533     /// let uuid = Uuid::nil();
534     ///
535     /// assert_eq!(
536     ///     uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()),
537     ///     "00000000000000000000000000000000"
538     /// );
539     ///
540     /// assert_eq!(
541     ///     uuid.to_hyphenated()
542     ///         .encode_lower(&mut Uuid::encode_buffer()),
543     ///     "00000000-0000-0000-0000-000000000000"
544     /// );
545     ///
546     /// assert_eq!(
547     ///     uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()),
548     ///     "urn:uuid:00000000-0000-0000-0000-000000000000"
549     /// );
550     /// ```
encode_buffer() -> [u8; adapter::Urn::LENGTH]551     pub const fn encode_buffer() -> [u8; adapter::Urn::LENGTH] {
552         [0; adapter::Urn::LENGTH]
553     }
554 }
555 
556 impl fmt::Debug for Uuid {
557     #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result558     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
559         fmt::LowerHex::fmt(self, f)
560     }
561 }
562 
563 impl fmt::Display for Uuid {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result564     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
565         fmt::LowerHex::fmt(self, f)
566     }
567 }
568 
569 impl fmt::Display for Variant {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result570     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
571         match *self {
572             Variant::NCS => write!(f, "NCS"),
573             Variant::RFC4122 => write!(f, "RFC4122"),
574             Variant::Microsoft => write!(f, "Microsoft"),
575             Variant::Future => write!(f, "Future"),
576         }
577     }
578 }
579 
580 impl fmt::LowerHex for Uuid {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result581     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
582         fmt::LowerHex::fmt(&self.to_hyphenated_ref(), f)
583     }
584 }
585 
586 impl fmt::UpperHex for Uuid {
587     #[inline]
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result588     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
589         fmt::UpperHex::fmt(&self.to_hyphenated_ref(), f)
590     }
591 }
592 
593 impl str::FromStr for Uuid {
594     type Err = Error;
595 
from_str(uuid_str: &str) -> Result<Self, Self::Err>596     fn from_str(uuid_str: &str) -> Result<Self, Self::Err> {
597         Uuid::parse_str(uuid_str)
598     }
599 }
600 
601 impl Default for Uuid {
602     #[inline]
default() -> Self603     fn default() -> Self {
604         Uuid::nil()
605     }
606 }
607 
608 #[cfg(test)]
609 mod tests {
610     use crate::{
611         prelude::*,
612         std::string::{String, ToString},
613         test_util,
614     };
615 
616     macro_rules! check {
617         ($buf:ident, $format:expr, $target:expr, $len:expr, $cond:expr) => {
618             $buf.clear();
619             write!($buf, $format, $target).unwrap();
620             assert!($buf.len() == $len);
621             assert!($buf.chars().all($cond), "{}", $buf);
622         };
623     }
624 
625     #[test]
test_uuid_compare()626     fn test_uuid_compare() {
627         let uuid1 = test_util::new();
628         let uuid2 = test_util::new2();
629 
630         assert_eq!(uuid1, uuid1);
631         assert_eq!(uuid2, uuid2);
632 
633         assert_ne!(uuid1, uuid2);
634         assert_ne!(uuid2, uuid1);
635     }
636 
637     #[test]
test_uuid_default()638     fn test_uuid_default() {
639         let default_uuid = Uuid::default();
640         let nil_uuid = Uuid::nil();
641 
642         assert_eq!(default_uuid, nil_uuid);
643     }
644 
645     #[test]
test_uuid_display()646     fn test_uuid_display() {
647         use super::fmt::Write;
648 
649         let uuid = test_util::new();
650         let s = uuid.to_string();
651         let mut buffer = String::new();
652 
653         assert_eq!(s, uuid.to_hyphenated().to_string());
654 
655         check!(buffer, "{}", uuid, 36, |c| c.is_lowercase()
656             || c.is_digit(10)
657             || c == '-');
658     }
659 
660     #[test]
test_uuid_lowerhex()661     fn test_uuid_lowerhex() {
662         use super::fmt::Write;
663 
664         let mut buffer = String::new();
665         let uuid = test_util::new();
666 
667         check!(buffer, "{:x}", uuid, 36, |c| c.is_lowercase()
668             || c.is_digit(10)
669             || c == '-');
670     }
671 
672     // noinspection RsAssertEqual
673     #[test]
test_uuid_operator_eq()674     fn test_uuid_operator_eq() {
675         let uuid1 = test_util::new();
676         let uuid1_dup = uuid1.clone();
677         let uuid2 = test_util::new2();
678 
679         assert!(uuid1 == uuid1);
680         assert!(uuid1 == uuid1_dup);
681         assert!(uuid1_dup == uuid1);
682 
683         assert!(uuid1 != uuid2);
684         assert!(uuid2 != uuid1);
685         assert!(uuid1_dup != uuid2);
686         assert!(uuid2 != uuid1_dup);
687     }
688 
689     #[test]
test_uuid_to_string()690     fn test_uuid_to_string() {
691         use super::fmt::Write;
692 
693         let uuid = test_util::new();
694         let s = uuid.to_string();
695         let mut buffer = String::new();
696 
697         assert_eq!(s.len(), 36);
698 
699         check!(buffer, "{}", s, 36, |c| c.is_lowercase()
700             || c.is_digit(10)
701             || c == '-');
702     }
703 
704     #[test]
test_uuid_upperhex()705     fn test_uuid_upperhex() {
706         use super::fmt::Write;
707 
708         let mut buffer = String::new();
709         let uuid = test_util::new();
710 
711         check!(buffer, "{:X}", uuid, 36, |c| c.is_uppercase()
712             || c.is_digit(10)
713             || c == '-');
714     }
715 
716     #[test]
test_nil()717     fn test_nil() {
718         let nil = Uuid::nil();
719         let not_nil = test_util::new();
720         let from_bytes = Uuid::from_bytes([
721             4, 54, 67, 12, 43, 2, 2, 76, 32, 50, 87, 5, 1, 33, 43, 87,
722         ]);
723 
724         assert_eq!(from_bytes.get_version(), None);
725 
726         assert!(nil.is_nil());
727         assert!(!not_nil.is_nil());
728 
729         assert_eq!(nil.get_version(), Some(Version::Nil));
730         assert_eq!(not_nil.get_version(), Some(Version::Random))
731     }
732 
733     #[test]
test_predefined_namespaces()734     fn test_predefined_namespaces() {
735         assert_eq!(
736             Uuid::NAMESPACE_DNS.to_hyphenated().to_string(),
737             "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
738         );
739         assert_eq!(
740             Uuid::NAMESPACE_URL.to_hyphenated().to_string(),
741             "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
742         );
743         assert_eq!(
744             Uuid::NAMESPACE_OID.to_hyphenated().to_string(),
745             "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
746         );
747         assert_eq!(
748             Uuid::NAMESPACE_X500.to_hyphenated().to_string(),
749             "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
750         );
751     }
752 
753     #[cfg(feature = "v3")]
754     #[test]
test_get_version_v3()755     fn test_get_version_v3() {
756         let uuid =
757             Uuid::new_v3(&Uuid::NAMESPACE_DNS, "rust-lang.org".as_bytes());
758 
759         assert_eq!(uuid.get_version().unwrap(), Version::Md5);
760         assert_eq!(uuid.get_version_num(), 3);
761     }
762 
763     #[test]
test_get_variant()764     fn test_get_variant() {
765         let uuid1 = test_util::new();
766         let uuid2 =
767             Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
768         let uuid3 =
769             Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap();
770         let uuid4 =
771             Uuid::parse_str("936DA01F9ABD4d9dC0C702AF85C822A8").unwrap();
772         let uuid5 =
773             Uuid::parse_str("F9168C5E-CEB2-4faa-D6BF-329BF39FA1E4").unwrap();
774         let uuid6 =
775             Uuid::parse_str("f81d4fae-7dec-11d0-7765-00a0c91e6bf6").unwrap();
776 
777         assert_eq!(uuid1.get_variant().unwrap(), Variant::RFC4122);
778         assert_eq!(uuid2.get_variant().unwrap(), Variant::RFC4122);
779         assert_eq!(uuid3.get_variant().unwrap(), Variant::RFC4122);
780         assert_eq!(uuid4.get_variant().unwrap(), Variant::Microsoft);
781         assert_eq!(uuid5.get_variant().unwrap(), Variant::Microsoft);
782         assert_eq!(uuid6.get_variant().unwrap(), Variant::NCS);
783     }
784 
785     #[test]
test_to_simple_string()786     fn test_to_simple_string() {
787         let uuid1 = test_util::new();
788         let s = uuid1.to_simple().to_string();
789 
790         assert_eq!(s.len(), 32);
791         assert!(s.chars().all(|c| c.is_digit(16)));
792     }
793 
794     #[test]
test_to_hyphenated_string()795     fn test_to_hyphenated_string() {
796         let uuid1 = test_util::new();
797         let s = uuid1.to_hyphenated().to_string();
798 
799         assert!(s.len() == 36);
800         assert!(s.chars().all(|c| c.is_digit(16) || c == '-'));
801     }
802 
803     #[test]
test_upper_lower_hex()804     fn test_upper_lower_hex() {
805         use std::fmt::Write;
806 
807         let mut buf = String::new();
808         let u = test_util::new();
809 
810         macro_rules! check {
811             ($buf:ident, $format:expr, $target:expr, $len:expr, $cond:expr) => {
812                 $buf.clear();
813                 write!($buf, $format, $target).unwrap();
814                 assert!(buf.len() == $len);
815                 assert!($buf.chars().all($cond), "{}", $buf);
816             };
817         }
818 
819         check!(buf, "{:X}", u, 36, |c| c.is_uppercase()
820             || c.is_digit(10)
821             || c == '-');
822         check!(buf, "{:X}", u.to_hyphenated(), 36, |c| c.is_uppercase()
823             || c.is_digit(10)
824             || c == '-');
825         check!(buf, "{:X}", u.to_simple(), 32, |c| c.is_uppercase()
826             || c.is_digit(10));
827 
828         check!(buf, "{:x}", u.to_hyphenated(), 36, |c| c.is_lowercase()
829             || c.is_digit(10)
830             || c == '-');
831         check!(buf, "{:x}", u.to_simple(), 32, |c| c.is_lowercase()
832             || c.is_digit(10));
833     }
834 
835     #[test]
test_to_urn_string()836     fn test_to_urn_string() {
837         let uuid1 = test_util::new();
838         let ss = uuid1.to_urn().to_string();
839         let s = &ss[9..];
840 
841         assert!(ss.starts_with("urn:uuid:"));
842         assert_eq!(s.len(), 36);
843         assert!(s.chars().all(|c| c.is_digit(16) || c == '-'));
844     }
845 
846     #[test]
test_to_simple_string_matching()847     fn test_to_simple_string_matching() {
848         let uuid1 = test_util::new();
849 
850         let hs = uuid1.to_hyphenated().to_string();
851         let ss = uuid1.to_simple().to_string();
852 
853         let hsn = hs.chars().filter(|&c| c != '-').collect::<String>();
854 
855         assert_eq!(hsn, ss);
856     }
857 
858     #[test]
test_string_roundtrip()859     fn test_string_roundtrip() {
860         let uuid = test_util::new();
861 
862         let hs = uuid.to_hyphenated().to_string();
863         let uuid_hs = Uuid::parse_str(&hs).unwrap();
864         assert_eq!(uuid_hs, uuid);
865 
866         let ss = uuid.to_string();
867         let uuid_ss = Uuid::parse_str(&ss).unwrap();
868         assert_eq!(uuid_ss, uuid);
869     }
870 
871     #[test]
test_from_fields()872     fn test_from_fields() {
873         let d1: u32 = 0xa1a2a3a4;
874         let d2: u16 = 0xb1b2;
875         let d3: u16 = 0xc1c2;
876         let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
877 
878         let u = Uuid::from_fields(d1, d2, d3, &d4).unwrap();
879 
880         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
881         let result = u.to_simple().to_string();
882         assert_eq!(result, expected);
883     }
884 
885     #[test]
test_from_fields_le()886     fn test_from_fields_le() {
887         let d1: u32 = 0xa4a3a2a1;
888         let d2: u16 = 0xb2b1;
889         let d3: u16 = 0xc2c1;
890         let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
891 
892         let u = Uuid::from_fields_le(d1, d2, d3, &d4).unwrap();
893 
894         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
895         let result = u.to_simple().to_string();
896         assert_eq!(result, expected);
897     }
898 
899     #[test]
test_as_fields()900     fn test_as_fields() {
901         let u = test_util::new();
902         let (d1, d2, d3, d4) = u.as_fields();
903 
904         assert_ne!(d1, 0);
905         assert_ne!(d2, 0);
906         assert_ne!(d3, 0);
907         assert_eq!(d4.len(), 8);
908         assert!(!d4.iter().all(|&b| b == 0));
909     }
910 
911     #[test]
test_fields_roundtrip()912     fn test_fields_roundtrip() {
913         let d1_in: u32 = 0xa1a2a3a4;
914         let d2_in: u16 = 0xb1b2;
915         let d3_in: u16 = 0xc1c2;
916         let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
917 
918         let u = Uuid::from_fields(d1_in, d2_in, d3_in, d4_in).unwrap();
919         let (d1_out, d2_out, d3_out, d4_out) = u.as_fields();
920 
921         assert_eq!(d1_in, d1_out);
922         assert_eq!(d2_in, d2_out);
923         assert_eq!(d3_in, d3_out);
924         assert_eq!(d4_in, d4_out);
925     }
926 
927     #[test]
test_fields_le_roundtrip()928     fn test_fields_le_roundtrip() {
929         let d1_in: u32 = 0xa4a3a2a1;
930         let d2_in: u16 = 0xb2b1;
931         let d3_in: u16 = 0xc2c1;
932         let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
933 
934         let u = Uuid::from_fields_le(d1_in, d2_in, d3_in, d4_in).unwrap();
935         let (d1_out, d2_out, d3_out, d4_out) = u.to_fields_le();
936 
937         assert_eq!(d1_in, d1_out);
938         assert_eq!(d2_in, d2_out);
939         assert_eq!(d3_in, d3_out);
940         assert_eq!(d4_in, d4_out);
941     }
942 
943     #[test]
test_fields_le_are_actually_le()944     fn test_fields_le_are_actually_le() {
945         let d1_in: u32 = 0xa1a2a3a4;
946         let d2_in: u16 = 0xb1b2;
947         let d3_in: u16 = 0xc1c2;
948         let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
949 
950         let u = Uuid::from_fields(d1_in, d2_in, d3_in, d4_in).unwrap();
951         let (d1_out, d2_out, d3_out, d4_out) = u.to_fields_le();
952 
953         assert_eq!(d1_in, d1_out.swap_bytes());
954         assert_eq!(d2_in, d2_out.swap_bytes());
955         assert_eq!(d3_in, d3_out.swap_bytes());
956         assert_eq!(d4_in, d4_out);
957     }
958 
959     #[test]
test_from_u128()960     fn test_from_u128() {
961         let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8;
962 
963         let u = Uuid::from_u128(v_in);
964 
965         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
966         let result = u.to_simple().to_string();
967         assert_eq!(result, expected);
968     }
969 
970     #[test]
test_from_u128_le()971     fn test_from_u128_le() {
972         let v_in: u128 = 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1;
973 
974         let u = Uuid::from_u128_le(v_in);
975 
976         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
977         let result = u.to_simple().to_string();
978         assert_eq!(result, expected);
979     }
980 
981     #[test]
test_u128_roundtrip()982     fn test_u128_roundtrip() {
983         let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8;
984 
985         let u = Uuid::from_u128(v_in);
986         let v_out = u.as_u128();
987 
988         assert_eq!(v_in, v_out);
989     }
990 
991     #[test]
test_u128_le_roundtrip()992     fn test_u128_le_roundtrip() {
993         let v_in: u128 = 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1;
994 
995         let u = Uuid::from_u128_le(v_in);
996         let v_out = u.to_u128_le();
997 
998         assert_eq!(v_in, v_out);
999     }
1000 
1001     #[test]
test_u128_le_is_actually_le()1002     fn test_u128_le_is_actually_le() {
1003         let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8;
1004 
1005         let u = Uuid::from_u128(v_in);
1006         let v_out = u.to_u128_le();
1007 
1008         assert_eq!(v_in, v_out.swap_bytes());
1009     }
1010 
1011     #[test]
test_from_slice()1012     fn test_from_slice() {
1013         let b = [
1014             0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3,
1015             0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
1016         ];
1017 
1018         let u = Uuid::from_slice(&b).unwrap();
1019         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1020 
1021         assert_eq!(u.to_simple().to_string(), expected);
1022     }
1023 
1024     #[test]
test_from_bytes()1025     fn test_from_bytes() {
1026         let b = [
1027             0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3,
1028             0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
1029         ];
1030 
1031         let u = Uuid::from_bytes(b);
1032         let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1033 
1034         assert_eq!(u.to_simple().to_string(), expected);
1035     }
1036 
1037     #[test]
test_as_bytes()1038     fn test_as_bytes() {
1039         let u = test_util::new();
1040         let ub = u.as_bytes();
1041 
1042         assert_eq!(ub.len(), 16);
1043         assert!(!ub.iter().all(|&b| b == 0));
1044     }
1045 
1046     #[test]
test_bytes_roundtrip()1047     fn test_bytes_roundtrip() {
1048         let b_in: crate::Bytes = [
1049             0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3,
1050             0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
1051         ];
1052 
1053         let u = Uuid::from_slice(&b_in).unwrap();
1054 
1055         let b_out = u.as_bytes();
1056 
1057         assert_eq!(&b_in, b_out);
1058     }
1059 
1060     #[test]
test_iterbytes_impl_for_uuid()1061     fn test_iterbytes_impl_for_uuid() {
1062         let mut set = std::collections::HashSet::new();
1063         let id1 = test_util::new();
1064         let id2 = test_util::new2();
1065         set.insert(id1.clone());
1066 
1067         assert!(set.contains(&id1));
1068         assert!(!set.contains(&id2));
1069     }
1070 }
1071