Coverage Report

Created: 2025-07-23 07:29

/rust/registry/src/index.crates.io-6f17d22bba15001f/uuid-0.8.2/src/lib.rs
Line
Count
Source (jump to first uncovered line)
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)
294
0
    pub fn get_variant(&self) -> Option<Variant> {
295
0
        match self.as_bytes()[8] {
296
0
            x if x & 0x80 == 0x00 => Some(Variant::NCS),
297
0
            x if x & 0xc0 == 0x80 => Some(Variant::RFC4122),
298
0
            x if x & 0xe0 == 0xc0 => Some(Variant::Microsoft),
299
0
            x if x & 0xe0 == 0xe0 => Some(Variant::Future),
300
0
            _ => None,
301
        }
302
0
    }
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)
315
0
    pub const fn get_version_num(&self) -> usize {
316
0
        (self.as_bytes()[6] >> 4) as usize
317
0
    }
318
319
    /// Returns the version of the UUID.
320
    ///
321
    /// This represents the algorithm used to generate the contents
322
0
    pub fn get_version(&self) -> Option<Version> {
323
0
        let v = self.as_bytes()[6] >> 4;
324
0
        match v {
325
0
            0 if self.is_nil() => Some(Version::Nil),
326
0
            1 => Some(Version::Mac),
327
0
            2 => Some(Version::Dce),
328
0
            3 => Some(Version::Md5),
329
0
            4 => Some(Version::Random),
330
0
            5 => Some(Version::Sha1),
331
0
            _ => None,
332
        }
333
0
    }
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
    /// ```
378
0
    pub fn as_fields(&self) -> (u32, u16, u16, &[u8; 8]) {
379
0
        let d1 = u32::from(self.as_bytes()[0]) << 24
380
0
            | u32::from(self.as_bytes()[1]) << 16
381
0
            | u32::from(self.as_bytes()[2]) << 8
382
0
            | u32::from(self.as_bytes()[3]);
383
0
384
0
        let d2 =
385
0
            u16::from(self.as_bytes()[4]) << 8 | u16::from(self.as_bytes()[5]);
386
0
387
0
        let d3 =
388
0
            u16::from(self.as_bytes()[6]) << 8 | u16::from(self.as_bytes()[7]);
389
0
390
0
        let d4: &[u8; 8] =
391
0
            unsafe { &*(self.as_bytes()[8..16].as_ptr() as *const [u8; 8]) };
392
0
        (d1, d2, d3, d4)
393
0
    }
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
    /// ```
419
0
    pub fn to_fields_le(&self) -> (u32, u16, u16, &[u8; 8]) {
420
0
        let d1 = u32::from(self.as_bytes()[0])
421
0
            | u32::from(self.as_bytes()[1]) << 8
422
0
            | u32::from(self.as_bytes()[2]) << 16
423
0
            | u32::from(self.as_bytes()[3]) << 24;
424
0
425
0
        let d2 =
426
0
            u16::from(self.as_bytes()[4]) | u16::from(self.as_bytes()[5]) << 8;
427
0
428
0
        let d3 =
429
0
            u16::from(self.as_bytes()[6]) | u16::from(self.as_bytes()[7]) << 8;
430
0
431
0
        let d4: &[u8; 8] =
432
0
            unsafe { &*(self.as_bytes()[8..16].as_ptr() as *const [u8; 8]) };
433
0
        (d1, d2, d3, d4)
434
0
    }
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
    /// ```
455
0
    pub fn as_u128(&self) -> u128 {
456
0
        u128::from(self.as_bytes()[0]) << 120
457
0
            | u128::from(self.as_bytes()[1]) << 112
458
0
            | u128::from(self.as_bytes()[2]) << 104
459
0
            | u128::from(self.as_bytes()[3]) << 96
460
0
            | u128::from(self.as_bytes()[4]) << 88
461
0
            | u128::from(self.as_bytes()[5]) << 80
462
0
            | u128::from(self.as_bytes()[6]) << 72
463
0
            | u128::from(self.as_bytes()[7]) << 64
464
0
            | u128::from(self.as_bytes()[8]) << 56
465
0
            | u128::from(self.as_bytes()[9]) << 48
466
0
            | u128::from(self.as_bytes()[10]) << 40
467
0
            | u128::from(self.as_bytes()[11]) << 32
468
0
            | u128::from(self.as_bytes()[12]) << 24
469
0
            | u128::from(self.as_bytes()[13]) << 16
470
0
            | u128::from(self.as_bytes()[14]) << 8
471
0
            | u128::from(self.as_bytes()[15])
472
0
    }
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
    /// ```
496
0
    pub fn to_u128_le(&self) -> u128 {
497
0
        u128::from(self.as_bytes()[0])
498
0
            | u128::from(self.as_bytes()[1]) << 8
499
0
            | u128::from(self.as_bytes()[2]) << 16
500
0
            | u128::from(self.as_bytes()[3]) << 24
501
0
            | u128::from(self.as_bytes()[4]) << 32
502
0
            | u128::from(self.as_bytes()[5]) << 40
503
0
            | u128::from(self.as_bytes()[6]) << 48
504
0
            | u128::from(self.as_bytes()[7]) << 56
505
0
            | u128::from(self.as_bytes()[8]) << 64
506
0
            | u128::from(self.as_bytes()[9]) << 72
507
0
            | u128::from(self.as_bytes()[10]) << 80
508
0
            | u128::from(self.as_bytes()[11]) << 88
509
0
            | u128::from(self.as_bytes()[12]) << 96
510
0
            | u128::from(self.as_bytes()[13]) << 104
511
0
            | u128::from(self.as_bytes()[14]) << 112
512
0
            | u128::from(self.as_bytes()[15]) << 120
513
0
    }
514
515
    /// Returns an array of 16 octets containing the UUID data.
516
80.0k
    pub const fn as_bytes(&self) -> &Bytes {
517
80.0k
        &self.0
518
80.0k
    }
519
520
    /// Tests if the UUID is nil.
521
0
    pub fn is_nil(&self) -> bool {
522
0
        self.as_bytes().iter().all(|&b| b == 0)
523
0
    }
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
    /// ```
551
0
    pub const fn encode_buffer() -> [u8; adapter::Urn::LENGTH] {
552
0
        [0; adapter::Urn::LENGTH]
553
0
    }
554
}
555
556
impl fmt::Debug for Uuid {
557
    #[inline]
558
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
559
0
        fmt::LowerHex::fmt(self, f)
560
0
    }
561
}
562
563
impl fmt::Display for Uuid {
564
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
565
0
        fmt::LowerHex::fmt(self, f)
566
0
    }
567
}
568
569
impl fmt::Display for Variant {
570
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
571
0
        match *self {
572
0
            Variant::NCS => write!(f, "NCS"),
573
0
            Variant::RFC4122 => write!(f, "RFC4122"),
574
0
            Variant::Microsoft => write!(f, "Microsoft"),
575
0
            Variant::Future => write!(f, "Future"),
576
        }
577
0
    }
578
}
579
580
impl fmt::LowerHex for Uuid {
581
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
582
0
        fmt::LowerHex::fmt(&self.to_hyphenated_ref(), f)
583
0
    }
584
}
585
586
impl fmt::UpperHex for Uuid {
587
    #[inline]
588
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
589
0
        fmt::UpperHex::fmt(&self.to_hyphenated_ref(), f)
590
0
    }
591
}
592
593
impl str::FromStr for Uuid {
594
    type Err = Error;
595
596
0
    fn from_str(uuid_str: &str) -> Result<Self, Self::Err> {
597
0
        Uuid::parse_str(uuid_str)
598
0
    }
599
}
600
601
impl Default for Uuid {
602
    #[inline]
603
0
    fn default() -> Self {
604
0
        Uuid::nil()
605
0
    }
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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]
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
}