Coverage Report

Created: 2025-10-13 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/uuid-1.18.1/src/fmt.rs
Line
Count
Source
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
//! Adapters for alternative string formats.
13
14
use core::{convert::TryInto as _, str::FromStr};
15
16
use crate::{
17
    std::{borrow::Borrow, fmt, str},
18
    Error, Uuid, Variant,
19
};
20
21
#[cfg(feature = "std")]
22
use crate::std::string::{String, ToString};
23
24
impl std::fmt::Debug for Uuid {
25
    #[inline]
26
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27
0
        fmt::LowerHex::fmt(self, f)
28
0
    }
Unexecuted instantiation: <uuid::Uuid as core::fmt::Debug>::fmt
Unexecuted instantiation: <uuid::Uuid as core::fmt::Debug>::fmt
29
}
30
31
impl fmt::Display for Uuid {
32
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33
0
        fmt::LowerHex::fmt(self, f)
34
0
    }
35
}
36
37
#[cfg(feature = "std")]
38
impl From<Uuid> for String {
39
0
    fn from(uuid: Uuid) -> Self {
40
0
        uuid.to_string()
41
0
    }
42
}
43
44
impl fmt::Display for Variant {
45
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46
0
        match *self {
47
0
            Variant::NCS => write!(f, "NCS"),
48
0
            Variant::RFC4122 => write!(f, "RFC4122"),
49
0
            Variant::Microsoft => write!(f, "Microsoft"),
50
0
            Variant::Future => write!(f, "Future"),
51
        }
52
0
    }
53
}
54
55
impl fmt::LowerHex for Uuid {
56
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57
0
        fmt::LowerHex::fmt(self.as_hyphenated(), f)
58
0
    }
59
}
60
61
impl fmt::UpperHex for Uuid {
62
    #[inline]
63
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64
0
        fmt::UpperHex::fmt(self.as_hyphenated(), f)
65
0
    }
66
}
67
68
/// Format a [`Uuid`] as a hyphenated string, like
69
/// `67e55044-10b1-426f-9247-bb680e5fe0c8`.
70
#[derive(
71
    Clone,
72
    Copy,
73
    Debug,
74
    Default,
75
    Eq,
76
    Hash,
77
    Ord,
78
    PartialEq,
79
    PartialOrd,
80
)]
81
#[cfg_attr(
82
    all(uuid_unstable, feature = "zerocopy"),
83
    derive(
84
        zerocopy::IntoBytes,
85
        zerocopy::FromBytes,
86
        zerocopy::KnownLayout,
87
        zerocopy::Immutable,
88
        zerocopy::Unaligned
89
    )
90
)]
91
#[repr(transparent)]
92
pub struct Hyphenated(Uuid);
93
94
/// Format a [`Uuid`] as a simple string, like
95
/// `67e5504410b1426f9247bb680e5fe0c8`.
96
#[derive(
97
    Clone,
98
    Copy,
99
    Debug,
100
    Default,
101
    Eq,
102
    Hash,
103
    Ord,
104
    PartialEq,
105
    PartialOrd,
106
)]
107
#[cfg_attr(
108
    all(uuid_unstable, feature = "zerocopy"),
109
    derive(
110
        zerocopy::IntoBytes,
111
        zerocopy::FromBytes,
112
        zerocopy::KnownLayout,
113
        zerocopy::Immutable,
114
        zerocopy::Unaligned
115
    )
116
)]
117
#[repr(transparent)]
118
pub struct Simple(Uuid);
119
120
/// Format a [`Uuid`] as a URN string, like
121
/// `urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8`.
122
#[derive(
123
    Clone,
124
    Copy,
125
    Debug,
126
    Default,
127
    Eq,
128
    Hash,
129
    Ord,
130
    PartialEq,
131
    PartialOrd,
132
)]
133
#[cfg_attr(
134
    all(uuid_unstable, feature = "zerocopy"),
135
    derive(
136
        zerocopy::IntoBytes,
137
        zerocopy::FromBytes,
138
        zerocopy::KnownLayout,
139
        zerocopy::Immutable,
140
        zerocopy::Unaligned
141
    )
142
)]
143
#[repr(transparent)]
144
pub struct Urn(Uuid);
145
146
/// Format a [`Uuid`] as a braced hyphenated string, like
147
/// `{67e55044-10b1-426f-9247-bb680e5fe0c8}`.
148
#[derive(
149
    Clone,
150
    Copy,
151
    Debug,
152
    Default,
153
    Eq,
154
    Hash,
155
    Ord,
156
    PartialEq,
157
    PartialOrd,
158
)]
159
#[cfg_attr(
160
    all(uuid_unstable, feature = "zerocopy"),
161
    derive(
162
        zerocopy::IntoBytes,
163
        zerocopy::FromBytes,
164
        zerocopy::KnownLayout,
165
        zerocopy::Immutable,
166
        zerocopy::Unaligned
167
    )
168
)]
169
#[repr(transparent)]
170
pub struct Braced(Uuid);
171
172
impl Uuid {
173
    /// Get a [`Hyphenated`] formatter.
174
    #[inline]
175
0
    pub const fn hyphenated(self) -> Hyphenated {
176
0
        Hyphenated(self)
177
0
    }
178
179
    /// Get a borrowed [`Hyphenated`] formatter.
180
    #[inline]
181
0
    pub fn as_hyphenated(&self) -> &Hyphenated {
182
0
        unsafe_transmute_ref!(self)
183
0
    }
184
185
    /// Get a [`Simple`] formatter.
186
    #[inline]
187
0
    pub const fn simple(self) -> Simple {
188
0
        Simple(self)
189
0
    }
190
191
    /// Get a borrowed [`Simple`] formatter.
192
    #[inline]
193
0
    pub fn as_simple(&self) -> &Simple {
194
0
        unsafe_transmute_ref!(self)
195
0
    }
196
197
    /// Get a [`Urn`] formatter.
198
    #[inline]
199
0
    pub const fn urn(self) -> Urn {
200
0
        Urn(self)
201
0
    }
202
203
    /// Get a borrowed [`Urn`] formatter.
204
    #[inline]
205
0
    pub fn as_urn(&self) -> &Urn {
206
0
        unsafe_transmute_ref!(self)
207
0
    }
208
209
    /// Get a [`Braced`] formatter.
210
    #[inline]
211
0
    pub const fn braced(self) -> Braced {
212
0
        Braced(self)
213
0
    }
214
215
    /// Get a borrowed [`Braced`] formatter.
216
    #[inline]
217
0
    pub fn as_braced(&self) -> &Braced {
218
0
        unsafe_transmute_ref!(self)
219
0
    }
220
}
221
222
const UPPER: [u8; 16] = [
223
    b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'A', b'B', b'C', b'D', b'E', b'F',
224
];
225
const LOWER: [u8; 16] = [
226
    b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b', b'c', b'd', b'e', b'f',
227
];
228
229
#[inline]
230
0
const fn format_simple(src: &[u8; 16], upper: bool) -> [u8; 32] {
231
0
    let lut = if upper { &UPPER } else { &LOWER };
232
0
    let mut dst = [0; 32];
233
0
    let mut i = 0;
234
0
    while i < 16 {
235
0
        let x = src[i];
236
0
        dst[i * 2] = lut[(x >> 4) as usize];
237
0
        dst[i * 2 + 1] = lut[(x & 0x0f) as usize];
238
0
        i += 1;
239
0
    }
240
0
    dst
241
0
}
242
243
#[inline]
244
0
const fn format_hyphenated(src: &[u8; 16], upper: bool) -> [u8; 36] {
245
0
    let lut = if upper { &UPPER } else { &LOWER };
246
0
    let groups = [(0, 8), (9, 13), (14, 18), (19, 23), (24, 36)];
247
0
    let mut dst = [0; 36];
248
249
0
    let mut group_idx = 0;
250
0
    let mut i = 0;
251
0
    while group_idx < 5 {
252
0
        let (start, end) = groups[group_idx];
253
0
        let mut j = start;
254
0
        while j < end {
255
0
            let x = src[i];
256
0
            i += 1;
257
0
258
0
            dst[j] = lut[(x >> 4) as usize];
259
0
            dst[j + 1] = lut[(x & 0x0f) as usize];
260
0
            j += 2;
261
0
        }
262
0
        if group_idx < 4 {
263
0
            dst[end] = b'-';
264
0
        }
265
0
        group_idx += 1;
266
    }
267
0
    dst
268
0
}
269
270
#[inline]
271
0
fn encode_simple<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str {
272
0
    let buf = &mut buffer[..Simple::LENGTH];
273
0
    let buf: &mut [u8; Simple::LENGTH] = buf.try_into().unwrap();
274
0
    *buf = format_simple(src, upper);
275
276
    // SAFETY: The encoded buffer is ASCII encoded
277
0
    unsafe { str::from_utf8_unchecked_mut(buf) }
278
0
}
279
280
#[inline]
281
0
fn encode_hyphenated<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str {
282
0
    let buf = &mut buffer[..Hyphenated::LENGTH];
283
0
    let buf: &mut [u8; Hyphenated::LENGTH] = buf.try_into().unwrap();
284
0
    *buf = format_hyphenated(src, upper);
285
286
    // SAFETY: The encoded buffer is ASCII encoded
287
0
    unsafe { str::from_utf8_unchecked_mut(buf) }
288
0
}
289
290
#[inline]
291
0
fn encode_braced<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str {
292
0
    let buf = &mut buffer[..Hyphenated::LENGTH + 2];
293
0
    let buf: &mut [u8; Hyphenated::LENGTH + 2] = buf.try_into().unwrap();
294
295
    #[cfg_attr(
296
        all(uuid_unstable, feature = "zerocopy"),
297
        derive(zerocopy::IntoBytes)
298
    )]
299
    #[repr(C)]
300
    struct Braced {
301
        open_curly: u8,
302
        hyphenated: [u8; Hyphenated::LENGTH],
303
        close_curly: u8,
304
    }
305
306
0
    let braced = Braced {
307
0
        open_curly: b'{',
308
0
        hyphenated: format_hyphenated(src, upper),
309
0
        close_curly: b'}',
310
0
    };
311
312
0
    *buf = unsafe_transmute!(braced);
313
314
    // SAFETY: The encoded buffer is ASCII encoded
315
0
    unsafe { str::from_utf8_unchecked_mut(buf) }
316
0
}
317
318
#[inline]
319
0
fn encode_urn<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str {
320
0
    let buf = &mut buffer[..Urn::LENGTH];
321
0
    buf[..9].copy_from_slice(b"urn:uuid:");
322
323
0
    let dst = &mut buf[9..(9 + Hyphenated::LENGTH)];
324
0
    let dst: &mut [u8; Hyphenated::LENGTH] = dst.try_into().unwrap();
325
0
    *dst = format_hyphenated(src, upper);
326
327
    // SAFETY: The encoded buffer is ASCII encoded
328
0
    unsafe { str::from_utf8_unchecked_mut(buf) }
329
0
}
330
331
impl Hyphenated {
332
    /// The length of a hyphenated [`Uuid`] string.
333
    ///
334
    /// [`Uuid`]: ../struct.Uuid.html
335
    pub const LENGTH: usize = 36;
336
337
    /// Creates a [`Hyphenated`] from a [`Uuid`].
338
    ///
339
    /// [`Uuid`]: ../struct.Uuid.html
340
    /// [`Hyphenated`]: struct.Hyphenated.html
341
0
    pub const fn from_uuid(uuid: Uuid) -> Self {
342
0
        Hyphenated(uuid)
343
0
    }
344
345
    /// Writes the [`Uuid`] as a lower-case hyphenated string to
346
    /// `buffer`, and returns the subslice of the buffer that contains the
347
    /// encoded UUID.
348
    ///
349
    /// This is slightly more efficient than using the formatting
350
    /// infrastructure as it avoids virtual calls, and may avoid
351
    /// double buffering.
352
    ///
353
    /// [`Uuid`]: ../struct.Uuid.html
354
    ///
355
    /// # Panics
356
    ///
357
    /// Panics if the buffer is not large enough: it must have length at least
358
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
359
    /// sufficiently-large temporary buffer.
360
    ///
361
    /// [`LENGTH`]: #associatedconstant.LENGTH
362
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
363
    ///
364
    /// # Examples
365
    ///
366
    /// ```rust
367
    /// use uuid::Uuid;
368
    ///
369
    /// fn main() -> Result<(), uuid::Error> {
370
    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;
371
    ///
372
    ///     // the encoded portion is returned
373
    ///     assert_eq!(
374
    ///         uuid.hyphenated()
375
    ///             .encode_lower(&mut Uuid::encode_buffer()),
376
    ///         "936da01f-9abd-4d9d-80c7-02af85c822a8"
377
    ///     );
378
    ///
379
    ///     // the buffer is mutated directly, and trailing contents remains
380
    ///     let mut buf = [b'!'; 40];
381
    ///     uuid.hyphenated().encode_lower(&mut buf);
382
    ///     assert_eq!(
383
    ///         &buf as &[_],
384
    ///         b"936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_]
385
    ///     );
386
    ///
387
    ///     Ok(())
388
    /// }
389
    /// ```
390
    /// */
391
    #[inline]
392
0
    pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
393
0
        encode_hyphenated(self.0.as_bytes(), buffer, false)
394
0
    }
395
396
    /// Writes the [`Uuid`] as an upper-case hyphenated string to
397
    /// `buffer`, and returns the subslice of the buffer that contains the
398
    /// encoded UUID.
399
    ///
400
    /// This is slightly more efficient than using the formatting
401
    /// infrastructure as it avoids virtual calls, and may avoid
402
    /// double buffering.
403
    ///
404
    /// [`Uuid`]: ../struct.Uuid.html
405
    ///
406
    /// # Panics
407
    ///
408
    /// Panics if the buffer is not large enough: it must have length at least
409
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
410
    /// sufficiently-large temporary buffer.
411
    ///
412
    /// [`LENGTH`]: #associatedconstant.LENGTH
413
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
414
    ///
415
    /// # Examples
416
    ///
417
    /// ```rust
418
    /// use uuid::Uuid;
419
    ///
420
    /// fn main() -> Result<(), uuid::Error> {
421
    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;
422
    ///
423
    ///     // the encoded portion is returned
424
    ///     assert_eq!(
425
    ///         uuid.hyphenated()
426
    ///             .encode_upper(&mut Uuid::encode_buffer()),
427
    ///         "936DA01F-9ABD-4D9D-80C7-02AF85C822A8"
428
    ///     );
429
    ///
430
    ///     // the buffer is mutated directly, and trailing contents remains
431
    ///     let mut buf = [b'!'; 40];
432
    ///     uuid.hyphenated().encode_upper(&mut buf);
433
    ///     assert_eq!(
434
    ///         &buf as &[_],
435
    ///         b"936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_]
436
    ///     );
437
    ///
438
    ///     Ok(())
439
    /// }
440
    /// ```
441
    /// */
442
    #[inline]
443
0
    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
444
0
        encode_hyphenated(self.0.as_bytes(), buffer, true)
445
0
    }
446
447
    /// Get a reference to the underlying [`Uuid`].
448
    ///
449
    /// # Examples
450
    ///
451
    /// ```rust
452
    /// use uuid::Uuid;
453
    ///
454
    /// let hyphenated = Uuid::nil().hyphenated();
455
    /// assert_eq!(*hyphenated.as_uuid(), Uuid::nil());
456
    /// ```
457
0
    pub const fn as_uuid(&self) -> &Uuid {
458
0
        &self.0
459
0
    }
460
461
    /// Consumes the [`Hyphenated`], returning the underlying [`Uuid`].
462
    ///
463
    /// # Examples
464
    ///
465
    /// ```rust
466
    /// use uuid::Uuid;
467
    ///
468
    /// let hyphenated = Uuid::nil().hyphenated();
469
    /// assert_eq!(hyphenated.into_uuid(), Uuid::nil());
470
    /// ```
471
0
    pub const fn into_uuid(self) -> Uuid {
472
0
        self.0
473
0
    }
474
}
475
476
impl Braced {
477
    /// The length of a braced [`Uuid`] string.
478
    ///
479
    /// [`Uuid`]: ../struct.Uuid.html
480
    pub const LENGTH: usize = 38;
481
482
    /// Creates a [`Braced`] from a [`Uuid`].
483
    ///
484
    /// [`Uuid`]: ../struct.Uuid.html
485
    /// [`Braced`]: struct.Braced.html
486
0
    pub const fn from_uuid(uuid: Uuid) -> Self {
487
0
        Braced(uuid)
488
0
    }
489
490
    /// Writes the [`Uuid`] as a lower-case hyphenated string surrounded by
491
    /// braces to `buffer`, and returns the subslice of the buffer that contains
492
    /// the encoded UUID.
493
    ///
494
    /// This is slightly more efficient than using the formatting
495
    /// infrastructure as it avoids virtual calls, and may avoid
496
    /// double buffering.
497
    ///
498
    /// [`Uuid`]: ../struct.Uuid.html
499
    ///
500
    /// # Panics
501
    ///
502
    /// Panics if the buffer is not large enough: it must have length at least
503
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
504
    /// sufficiently-large temporary buffer.
505
    ///
506
    /// [`LENGTH`]: #associatedconstant.LENGTH
507
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
508
    ///
509
    /// # Examples
510
    ///
511
    /// ```rust
512
    /// use uuid::Uuid;
513
    ///
514
    /// fn main() -> Result<(), uuid::Error> {
515
    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;
516
    ///
517
    ///     // the encoded portion is returned
518
    ///     assert_eq!(
519
    ///         uuid.braced()
520
    ///             .encode_lower(&mut Uuid::encode_buffer()),
521
    ///         "{936da01f-9abd-4d9d-80c7-02af85c822a8}"
522
    ///     );
523
    ///
524
    ///     // the buffer is mutated directly, and trailing contents remains
525
    ///     let mut buf = [b'!'; 40];
526
    ///     uuid.braced().encode_lower(&mut buf);
527
    ///     assert_eq!(
528
    ///         &buf as &[_],
529
    ///         b"{936da01f-9abd-4d9d-80c7-02af85c822a8}!!" as &[_]
530
    ///     );
531
    ///
532
    ///     Ok(())
533
    /// }
534
    /// ```
535
    /// */
536
    #[inline]
537
0
    pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
538
0
        encode_braced(self.0.as_bytes(), buffer, false)
539
0
    }
540
541
    /// Writes the [`Uuid`] as an upper-case hyphenated string surrounded by
542
    /// braces to `buffer`, and returns the subslice of the buffer that contains
543
    /// the encoded UUID.
544
    ///
545
    /// This is slightly more efficient than using the formatting
546
    /// infrastructure as it avoids virtual calls, and may avoid
547
    /// double buffering.
548
    ///
549
    /// [`Uuid`]: ../struct.Uuid.html
550
    ///
551
    /// # Panics
552
    ///
553
    /// Panics if the buffer is not large enough: it must have length at least
554
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
555
    /// sufficiently-large temporary buffer.
556
    ///
557
    /// [`LENGTH`]: #associatedconstant.LENGTH
558
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
559
    ///
560
    /// # Examples
561
    ///
562
    /// ```rust
563
    /// use uuid::Uuid;
564
    ///
565
    /// fn main() -> Result<(), uuid::Error> {
566
    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;
567
    ///
568
    ///     // the encoded portion is returned
569
    ///     assert_eq!(
570
    ///         uuid.braced()
571
    ///             .encode_upper(&mut Uuid::encode_buffer()),
572
    ///         "{936DA01F-9ABD-4D9D-80C7-02AF85C822A8}"
573
    ///     );
574
    ///
575
    ///     // the buffer is mutated directly, and trailing contents remains
576
    ///     let mut buf = [b'!'; 40];
577
    ///     uuid.braced().encode_upper(&mut buf);
578
    ///     assert_eq!(
579
    ///         &buf as &[_],
580
    ///         b"{936DA01F-9ABD-4D9D-80C7-02AF85C822A8}!!" as &[_]
581
    ///     );
582
    ///
583
    ///     Ok(())
584
    /// }
585
    /// ```
586
    /// */
587
    #[inline]
588
0
    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
589
0
        encode_braced(self.0.as_bytes(), buffer, true)
590
0
    }
591
592
    /// Get a reference to the underlying [`Uuid`].
593
    ///
594
    /// # Examples
595
    ///
596
    /// ```rust
597
    /// use uuid::Uuid;
598
    ///
599
    /// let braced = Uuid::nil().braced();
600
    /// assert_eq!(*braced.as_uuid(), Uuid::nil());
601
    /// ```
602
0
    pub const fn as_uuid(&self) -> &Uuid {
603
0
        &self.0
604
0
    }
605
606
    /// Consumes the [`Braced`], returning the underlying [`Uuid`].
607
    ///
608
    /// # Examples
609
    ///
610
    /// ```rust
611
    /// use uuid::Uuid;
612
    ///
613
    /// let braced = Uuid::nil().braced();
614
    /// assert_eq!(braced.into_uuid(), Uuid::nil());
615
    /// ```
616
0
    pub const fn into_uuid(self) -> Uuid {
617
0
        self.0
618
0
    }
619
}
620
621
impl Simple {
622
    /// The length of a simple [`Uuid`] string.
623
    ///
624
    /// [`Uuid`]: ../struct.Uuid.html
625
    pub const LENGTH: usize = 32;
626
627
    /// Creates a [`Simple`] from a [`Uuid`].
628
    ///
629
    /// [`Uuid`]: ../struct.Uuid.html
630
    /// [`Simple`]: struct.Simple.html
631
0
    pub const fn from_uuid(uuid: Uuid) -> Self {
632
0
        Simple(uuid)
633
0
    }
634
635
    /// Writes the [`Uuid`] as a lower-case simple string to `buffer`,
636
    /// and returns the subslice of the buffer that contains the encoded UUID.
637
    ///
638
    /// This is slightly more efficient than using the formatting
639
    /// infrastructure as it avoids virtual calls, and may avoid
640
    /// double buffering.
641
    ///
642
    /// [`Uuid`]: ../struct.Uuid.html
643
    ///
644
    /// # Panics
645
    ///
646
    /// Panics if the buffer is not large enough: it must have length at least
647
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
648
    /// sufficiently-large temporary buffer.
649
    ///
650
    /// [`LENGTH`]: #associatedconstant.LENGTH
651
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
652
    ///
653
    /// # Examples
654
    ///
655
    /// ```rust
656
    /// use uuid::Uuid;
657
    ///
658
    /// fn main() -> Result<(), uuid::Error> {
659
    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;
660
    ///
661
    ///     // the encoded portion is returned
662
    ///     assert_eq!(
663
    ///         uuid.simple().encode_lower(&mut Uuid::encode_buffer()),
664
    ///         "936da01f9abd4d9d80c702af85c822a8"
665
    ///     );
666
    ///
667
    ///     // the buffer is mutated directly, and trailing contents remains
668
    ///     let mut buf = [b'!'; 36];
669
    ///     assert_eq!(
670
    ///         uuid.simple().encode_lower(&mut buf),
671
    ///         "936da01f9abd4d9d80c702af85c822a8"
672
    ///     );
673
    ///     assert_eq!(
674
    ///         &buf as &[_],
675
    ///         b"936da01f9abd4d9d80c702af85c822a8!!!!" as &[_]
676
    ///     );
677
    ///
678
    ///     Ok(())
679
    /// }
680
    /// ```
681
    /// */
682
    #[inline]
683
0
    pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
684
0
        encode_simple(self.0.as_bytes(), buffer, false)
685
0
    }
686
687
    /// Writes the [`Uuid`] as an upper-case simple string to `buffer`,
688
    /// and returns the subslice of the buffer that contains the encoded UUID.
689
    ///
690
    /// [`Uuid`]: ../struct.Uuid.html
691
    ///
692
    /// # Panics
693
    ///
694
    /// Panics if the buffer is not large enough: it must have length at least
695
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
696
    /// sufficiently-large temporary buffer.
697
    ///
698
    /// [`LENGTH`]: #associatedconstant.LENGTH
699
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
700
    ///
701
    /// # Examples
702
    ///
703
    /// ```rust
704
    /// use uuid::Uuid;
705
    ///
706
    /// fn main() -> Result<(), uuid::Error> {
707
    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;
708
    ///
709
    ///     // the encoded portion is returned
710
    ///     assert_eq!(
711
    ///         uuid.simple().encode_upper(&mut Uuid::encode_buffer()),
712
    ///         "936DA01F9ABD4D9D80C702AF85C822A8"
713
    ///     );
714
    ///
715
    ///     // the buffer is mutated directly, and trailing contents remains
716
    ///     let mut buf = [b'!'; 36];
717
    ///     assert_eq!(
718
    ///         uuid.simple().encode_upper(&mut buf),
719
    ///         "936DA01F9ABD4D9D80C702AF85C822A8"
720
    ///     );
721
    ///     assert_eq!(
722
    ///         &buf as &[_],
723
    ///         b"936DA01F9ABD4D9D80C702AF85C822A8!!!!" as &[_]
724
    ///     );
725
    ///
726
    ///     Ok(())
727
    /// }
728
    /// ```
729
    /// */
730
    #[inline]
731
0
    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
732
0
        encode_simple(self.0.as_bytes(), buffer, true)
733
0
    }
734
735
    /// Get a reference to the underlying [`Uuid`].
736
    ///
737
    /// # Examples
738
    ///
739
    /// ```rust
740
    /// use uuid::Uuid;
741
    ///
742
    /// let simple = Uuid::nil().simple();
743
    /// assert_eq!(*simple.as_uuid(), Uuid::nil());
744
    /// ```
745
0
    pub const fn as_uuid(&self) -> &Uuid {
746
0
        &self.0
747
0
    }
748
749
    /// Consumes the [`Simple`], returning the underlying [`Uuid`].
750
    ///
751
    /// # Examples
752
    ///
753
    /// ```rust
754
    /// use uuid::Uuid;
755
    ///
756
    /// let simple = Uuid::nil().simple();
757
    /// assert_eq!(simple.into_uuid(), Uuid::nil());
758
    /// ```
759
0
    pub const fn into_uuid(self) -> Uuid {
760
0
        self.0
761
0
    }
762
}
763
764
impl Urn {
765
    /// The length of a URN [`Uuid`] string.
766
    ///
767
    /// [`Uuid`]: ../struct.Uuid.html
768
    pub const LENGTH: usize = 45;
769
770
    /// Creates a [`Urn`] from a [`Uuid`].
771
    ///
772
    /// [`Uuid`]: ../struct.Uuid.html
773
    /// [`Urn`]: struct.Urn.html
774
0
    pub const fn from_uuid(uuid: Uuid) -> Self {
775
0
        Urn(uuid)
776
0
    }
777
778
    /// Writes the [`Uuid`] as a lower-case URN string to
779
    /// `buffer`, and returns the subslice of the buffer that contains the
780
    /// encoded UUID.
781
    ///
782
    /// This is slightly more efficient than using the formatting
783
    /// infrastructure as it avoids virtual calls, and may avoid
784
    /// double buffering.
785
    ///
786
    /// [`Uuid`]: ../struct.Uuid.html
787
    ///
788
    /// # Panics
789
    ///
790
    /// Panics if the buffer is not large enough: it must have length at least
791
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
792
    /// sufficiently-large temporary buffer.
793
    ///
794
    /// [`LENGTH`]: #associatedconstant.LENGTH
795
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
796
    ///
797
    /// # Examples
798
    ///
799
    /// ```rust
800
    /// use uuid::Uuid;
801
    ///
802
    /// fn main() -> Result<(), uuid::Error> {
803
    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;
804
    ///
805
    ///     // the encoded portion is returned
806
    ///     assert_eq!(
807
    ///         uuid.urn().encode_lower(&mut Uuid::encode_buffer()),
808
    ///         "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8"
809
    ///     );
810
    ///
811
    ///     // the buffer is mutated directly, and trailing contents remains
812
    ///     let mut buf = [b'!'; 49];
813
    ///     uuid.urn().encode_lower(&mut buf);
814
    ///     assert_eq!(
815
    ///         uuid.urn().encode_lower(&mut buf),
816
    ///         "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8"
817
    ///     );
818
    ///     assert_eq!(
819
    ///         &buf as &[_],
820
    ///         b"urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_]
821
    ///     );
822
    ///     
823
    ///     Ok(())
824
    /// }
825
    /// ```
826
    /// */
827
    #[inline]
828
0
    pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
829
0
        encode_urn(self.0.as_bytes(), buffer, false)
830
0
    }
831
832
    /// Writes the [`Uuid`] as an upper-case URN string to
833
    /// `buffer`, and returns the subslice of the buffer that contains the
834
    /// encoded UUID.
835
    ///
836
    /// This is slightly more efficient than using the formatting
837
    /// infrastructure as it avoids virtual calls, and may avoid
838
    /// double buffering.
839
    ///
840
    /// [`Uuid`]: ../struct.Uuid.html
841
    ///
842
    /// # Panics
843
    ///
844
    /// Panics if the buffer is not large enough: it must have length at least
845
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
846
    /// sufficiently-large temporary buffer.
847
    ///
848
    /// [`LENGTH`]: #associatedconstant.LENGTH
849
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
850
    ///
851
    /// # Examples
852
    ///
853
    /// ```rust
854
    /// use uuid::Uuid;
855
    ///
856
    /// fn main() -> Result<(), uuid::Error> {
857
    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;
858
    ///
859
    ///     // the encoded portion is returned
860
    ///     assert_eq!(
861
    ///         uuid.urn().encode_upper(&mut Uuid::encode_buffer()),
862
    ///         "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8"
863
    ///     );
864
    ///
865
    ///     // the buffer is mutated directly, and trailing contents remains
866
    ///     let mut buf = [b'!'; 49];
867
    ///     assert_eq!(
868
    ///         uuid.urn().encode_upper(&mut buf),
869
    ///         "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8"
870
    ///     );
871
    ///     assert_eq!(
872
    ///         &buf as &[_],
873
    ///         b"urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_]
874
    ///     );
875
    ///
876
    ///     Ok(())
877
    /// }
878
    /// ```
879
    /// */
880
    #[inline]
881
0
    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
882
0
        encode_urn(self.0.as_bytes(), buffer, true)
883
0
    }
884
885
    /// Get a reference to the underlying [`Uuid`].
886
    ///
887
    /// # Examples
888
    ///
889
    /// ```rust
890
    /// use uuid::Uuid;
891
    ///
892
    /// let urn = Uuid::nil().urn();
893
    /// assert_eq!(*urn.as_uuid(), Uuid::nil());
894
    /// ```
895
0
    pub const fn as_uuid(&self) -> &Uuid {
896
0
        &self.0
897
0
    }
898
899
    /// Consumes the [`Urn`], returning the underlying [`Uuid`].
900
    ///
901
    /// # Examples
902
    ///
903
    /// ```rust
904
    /// use uuid::Uuid;
905
    ///
906
    /// let urn = Uuid::nil().urn();
907
    /// assert_eq!(urn.into_uuid(), Uuid::nil());
908
    /// ```
909
0
    pub const fn into_uuid(self) -> Uuid {
910
0
        self.0
911
0
    }
912
}
913
914
impl FromStr for Hyphenated {
915
    type Err = Error;
916
917
0
    fn from_str(s: &str) -> Result<Self, Self::Err> {
918
0
        crate::parser::parse_hyphenated(s.as_bytes())
919
0
            .map(|b| Hyphenated(Uuid(b)))
920
0
            .map_err(|invalid| invalid.into_err())
921
0
    }
922
}
923
924
impl FromStr for Simple {
925
    type Err = Error;
926
927
0
    fn from_str(s: &str) -> Result<Self, Self::Err> {
928
0
        crate::parser::parse_simple(s.as_bytes())
929
0
            .map(|b| Simple(Uuid(b)))
930
0
            .map_err(|invalid| invalid.into_err())
931
0
    }
932
}
933
934
impl FromStr for Urn {
935
    type Err = Error;
936
937
0
    fn from_str(s: &str) -> Result<Self, Self::Err> {
938
0
        crate::parser::parse_urn(s.as_bytes())
939
0
            .map(|b| Urn(Uuid(b)))
940
0
            .map_err(|invalid| invalid.into_err())
941
0
    }
942
}
943
944
impl FromStr for Braced {
945
    type Err = Error;
946
947
0
    fn from_str(s: &str) -> Result<Self, Self::Err> {
948
0
        crate::parser::parse_braced(s.as_bytes())
949
0
            .map(|b| Braced(Uuid(b)))
950
0
            .map_err(|invalid| invalid.into_err())
951
0
    }
952
}
953
954
macro_rules! impl_fmt_traits {
955
    ($($T:ident<$($a:lifetime),*>),+) => {$(
956
        impl<$($a),*> fmt::Display for $T<$($a),*> {
957
            #[inline]
958
0
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
959
0
                fmt::LowerHex::fmt(self, f)
960
0
            }
Unexecuted instantiation: <uuid::fmt::Braced as core::fmt::Display>::fmt
Unexecuted instantiation: <uuid::fmt::Hyphenated as core::fmt::Display>::fmt
Unexecuted instantiation: <uuid::fmt::Simple as core::fmt::Display>::fmt
Unexecuted instantiation: <uuid::fmt::Urn as core::fmt::Display>::fmt
961
        }
962
963
        impl<$($a),*> fmt::LowerHex for $T<$($a),*> {
964
0
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
965
0
                f.write_str(self.encode_lower(&mut [0; Self::LENGTH]))
966
0
            }
Unexecuted instantiation: <uuid::fmt::Braced as core::fmt::LowerHex>::fmt
Unexecuted instantiation: <uuid::fmt::Hyphenated as core::fmt::LowerHex>::fmt
Unexecuted instantiation: <uuid::fmt::Simple as core::fmt::LowerHex>::fmt
Unexecuted instantiation: <uuid::fmt::Urn as core::fmt::LowerHex>::fmt
967
        }
968
969
        impl<$($a),*> fmt::UpperHex for $T<$($a),*> {
970
0
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
971
0
                f.write_str(self.encode_upper(&mut [0; Self::LENGTH]))
972
0
            }
Unexecuted instantiation: <uuid::fmt::Braced as core::fmt::UpperHex>::fmt
Unexecuted instantiation: <uuid::fmt::Hyphenated as core::fmt::UpperHex>::fmt
Unexecuted instantiation: <uuid::fmt::Simple as core::fmt::UpperHex>::fmt
Unexecuted instantiation: <uuid::fmt::Urn as core::fmt::UpperHex>::fmt
973
        }
974
975
        impl_fmt_from!($T<$($a),*>);
976
    )+}
977
}
978
979
macro_rules! impl_fmt_from {
980
    ($T:ident<>) => {
981
        impl From<Uuid> for $T {
982
            #[inline]
983
0
            fn from(f: Uuid) -> Self {
984
0
                $T(f)
985
0
            }
Unexecuted instantiation: <uuid::fmt::Hyphenated as core::convert::From<uuid::Uuid>>::from
Unexecuted instantiation: <uuid::fmt::Simple as core::convert::From<uuid::Uuid>>::from
Unexecuted instantiation: <uuid::fmt::Urn as core::convert::From<uuid::Uuid>>::from
Unexecuted instantiation: <uuid::fmt::Braced as core::convert::From<uuid::Uuid>>::from
986
        }
987
988
        impl From<$T> for Uuid {
989
            #[inline]
990
0
            fn from(f: $T) -> Self {
991
0
                f.into_uuid()
992
0
            }
Unexecuted instantiation: <uuid::Uuid as core::convert::From<uuid::fmt::Hyphenated>>::from
Unexecuted instantiation: <uuid::Uuid as core::convert::From<uuid::fmt::Simple>>::from
Unexecuted instantiation: <uuid::Uuid as core::convert::From<uuid::fmt::Urn>>::from
Unexecuted instantiation: <uuid::Uuid as core::convert::From<uuid::fmt::Braced>>::from
993
        }
994
995
        impl AsRef<Uuid> for $T {
996
            #[inline]
997
0
            fn as_ref(&self) -> &Uuid {
998
0
                &self.0
999
0
            }
Unexecuted instantiation: <uuid::fmt::Hyphenated as core::convert::AsRef<uuid::Uuid>>::as_ref
Unexecuted instantiation: <uuid::fmt::Simple as core::convert::AsRef<uuid::Uuid>>::as_ref
Unexecuted instantiation: <uuid::fmt::Urn as core::convert::AsRef<uuid::Uuid>>::as_ref
Unexecuted instantiation: <uuid::fmt::Braced as core::convert::AsRef<uuid::Uuid>>::as_ref
1000
        }
1001
1002
        impl Borrow<Uuid> for $T {
1003
            #[inline]
1004
0
            fn borrow(&self) -> &Uuid {
1005
0
                &self.0
1006
0
            }
Unexecuted instantiation: <uuid::fmt::Hyphenated as core::borrow::Borrow<uuid::Uuid>>::borrow
Unexecuted instantiation: <uuid::fmt::Simple as core::borrow::Borrow<uuid::Uuid>>::borrow
Unexecuted instantiation: <uuid::fmt::Urn as core::borrow::Borrow<uuid::Uuid>>::borrow
Unexecuted instantiation: <uuid::fmt::Braced as core::borrow::Borrow<uuid::Uuid>>::borrow
1007
        }
1008
    };
1009
    ($T:ident<$a:lifetime>) => {
1010
        impl<$a> From<&$a Uuid> for $T<$a> {
1011
            #[inline]
1012
            fn from(f: &$a Uuid) -> Self {
1013
                $T::from_uuid_ref(f)
1014
            }
1015
        }
1016
1017
        impl<$a> From<$T<$a>> for &$a Uuid {
1018
            #[inline]
1019
            fn from(f: $T<$a>) -> &$a Uuid {
1020
                f.0
1021
            }
1022
        }
1023
1024
        impl<$a> AsRef<Uuid> for $T<$a> {
1025
            #[inline]
1026
            fn as_ref(&self) -> &Uuid {
1027
                self.0
1028
            }
1029
        }
1030
1031
        impl<$a> Borrow<Uuid> for $T<$a> {
1032
            #[inline]
1033
            fn borrow(&self) -> &Uuid {
1034
                self.0
1035
            }
1036
        }
1037
    };
1038
}
1039
1040
impl_fmt_traits! {
1041
    Hyphenated<>,
1042
    Simple<>,
1043
    Urn<>,
1044
    Braced<>
1045
}
1046
1047
#[cfg(test)]
1048
mod tests {
1049
    use super::*;
1050
1051
    #[test]
1052
    fn hyphenated_trailing() {
1053
        let mut buf = [b'x'; 100];
1054
        let len = Uuid::nil().hyphenated().encode_lower(&mut buf).len();
1055
        assert_eq!(len, super::Hyphenated::LENGTH);
1056
        assert!(buf[len..].iter().all(|x| *x == b'x'));
1057
    }
1058
1059
    #[test]
1060
    fn hyphenated_ref_trailing() {
1061
        let mut buf = [b'x'; 100];
1062
        let len = Uuid::nil().as_hyphenated().encode_lower(&mut buf).len();
1063
        assert_eq!(len, super::Hyphenated::LENGTH);
1064
        assert!(buf[len..].iter().all(|x| *x == b'x'));
1065
    }
1066
1067
    #[test]
1068
    fn simple_trailing() {
1069
        let mut buf = [b'x'; 100];
1070
        let len = Uuid::nil().simple().encode_lower(&mut buf).len();
1071
        assert_eq!(len, super::Simple::LENGTH);
1072
        assert!(buf[len..].iter().all(|x| *x == b'x'));
1073
    }
1074
1075
    #[test]
1076
    fn simple_ref_trailing() {
1077
        let mut buf = [b'x'; 100];
1078
        let len = Uuid::nil().as_simple().encode_lower(&mut buf).len();
1079
        assert_eq!(len, super::Simple::LENGTH);
1080
        assert!(buf[len..].iter().all(|x| *x == b'x'));
1081
    }
1082
1083
    #[test]
1084
    fn urn_trailing() {
1085
        let mut buf = [b'x'; 100];
1086
        let len = Uuid::nil().urn().encode_lower(&mut buf).len();
1087
        assert_eq!(len, super::Urn::LENGTH);
1088
        assert!(buf[len..].iter().all(|x| *x == b'x'));
1089
    }
1090
1091
    #[test]
1092
    fn urn_ref_trailing() {
1093
        let mut buf = [b'x'; 100];
1094
        let len = Uuid::nil().as_urn().encode_lower(&mut buf).len();
1095
        assert_eq!(len, super::Urn::LENGTH);
1096
        assert!(buf[len..].iter().all(|x| *x == b'x'));
1097
    }
1098
1099
    #[test]
1100
    fn braced_trailing() {
1101
        let mut buf = [b'x'; 100];
1102
        let len = Uuid::nil().braced().encode_lower(&mut buf).len();
1103
        assert_eq!(len, super::Braced::LENGTH);
1104
        assert!(buf[len..].iter().all(|x| *x == b'x'));
1105
    }
1106
1107
    #[test]
1108
    fn braced_ref_trailing() {
1109
        let mut buf = [b'x'; 100];
1110
        let len = Uuid::nil().as_braced().encode_lower(&mut buf).len();
1111
        assert_eq!(len, super::Braced::LENGTH);
1112
        assert!(buf[len..].iter().all(|x| *x == b'x'));
1113
    }
1114
1115
    #[test]
1116
    #[should_panic]
1117
    fn hyphenated_too_small() {
1118
        Uuid::nil().hyphenated().encode_lower(&mut [0; 35]);
1119
    }
1120
1121
    #[test]
1122
    #[should_panic]
1123
    fn simple_too_small() {
1124
        Uuid::nil().simple().encode_lower(&mut [0; 31]);
1125
    }
1126
1127
    #[test]
1128
    #[should_panic]
1129
    fn urn_too_small() {
1130
        Uuid::nil().urn().encode_lower(&mut [0; 44]);
1131
    }
1132
1133
    #[test]
1134
    #[should_panic]
1135
    fn braced_too_small() {
1136
        Uuid::nil().braced().encode_lower(&mut [0; 37]);
1137
    }
1138
1139
    #[test]
1140
    fn hyphenated_to_inner() {
1141
        let hyphenated = Uuid::nil().hyphenated();
1142
        assert_eq!(Uuid::from(hyphenated), Uuid::nil());
1143
    }
1144
1145
    #[test]
1146
    fn simple_to_inner() {
1147
        let simple = Uuid::nil().simple();
1148
        assert_eq!(Uuid::from(simple), Uuid::nil());
1149
    }
1150
1151
    #[test]
1152
    fn urn_to_inner() {
1153
        let urn = Uuid::nil().urn();
1154
        assert_eq!(Uuid::from(urn), Uuid::nil());
1155
    }
1156
1157
    #[test]
1158
    fn braced_to_inner() {
1159
        let braced = Uuid::nil().braced();
1160
        assert_eq!(Uuid::from(braced), Uuid::nil());
1161
    }
1162
}