Coverage Report

Created: 2026-06-10 06:52

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