Coverage Report

Created: 2025-11-16 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/uuid-0.8.2/src/adapter/mod.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 various formats for UUIDs
13
14
use crate::prelude::*;
15
use crate::std::{fmt, str};
16
17
#[cfg(feature = "serde")]
18
pub mod compact;
19
20
/// An adaptor for formatting an [`Uuid`] as a hyphenated string.
21
///
22
/// Takes an owned instance of the [`Uuid`].
23
///
24
/// [`Uuid`]: ../struct.Uuid.html
25
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
26
pub struct Hyphenated(Uuid);
27
28
/// An adaptor for formatting an [`Uuid`] as a hyphenated string.
29
///
30
/// Takes a reference of the [`Uuid`].
31
///
32
/// [`Uuid`]: ../struct.Uuid.html
33
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
34
pub struct HyphenatedRef<'a>(&'a Uuid);
35
36
/// An adaptor for formatting an [`Uuid`] as a simple string.
37
///
38
/// Takes an owned instance of the [`Uuid`].
39
///
40
/// [`Uuid`]: ../struct.Uuid.html
41
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
42
pub struct Simple(Uuid);
43
44
/// An adaptor for formatting an [`Uuid`] as a simple string.
45
///
46
/// Takes a reference of the [`Uuid`].
47
///
48
/// [`Uuid`]: ../struct.Uuid.html
49
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
50
pub struct SimpleRef<'a>(&'a Uuid);
51
52
/// An adaptor for formatting an [`Uuid`] as a URN string.
53
///
54
/// Takes an owned instance of the [`Uuid`].
55
///
56
/// [`Uuid`]: ../struct.Uuid.html
57
#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
58
pub struct Urn(Uuid);
59
60
/// An adaptor for formatting an [`Uuid`] as a URN string.
61
///
62
/// Takes a reference of the [`Uuid`].
63
///
64
/// [`Uuid`]: ../struct.Uuid.html
65
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
66
pub struct UrnRef<'a>(&'a Uuid);
67
68
impl Uuid {
69
    /// Get a [`Hyphenated`] formatter.
70
    ///
71
    /// [`Hyphenated`]: adapter/struct.Hyphenated.html
72
    #[inline]
73
53.1k
    pub const fn to_hyphenated(self) -> Hyphenated {
74
53.1k
        Hyphenated::from_uuid(self)
75
53.1k
    }
76
77
    /// Get a borrowed [`HyphenatedRef`] formatter.
78
    ///
79
    /// [`HyphenatedRef`]: adapter/struct.HyphenatedRef.html
80
    #[inline]
81
0
    pub const fn to_hyphenated_ref(&self) -> HyphenatedRef<'_> {
82
0
        HyphenatedRef::from_uuid_ref(self)
83
0
    }
84
85
    /// Get a [`Simple`] formatter.
86
    ///
87
    /// [`Simple`]: adapter/struct.Simple.html
88
    #[inline]
89
0
    pub const fn to_simple(self) -> Simple {
90
0
        Simple::from_uuid(self)
91
0
    }
92
93
    /// Get a borrowed [`SimpleRef`] formatter.
94
    ///
95
    /// [`SimpleRef`]: adapter/struct.SimpleRef.html
96
    #[inline]
97
0
    pub const fn to_simple_ref(&self) -> SimpleRef<'_> {
98
0
        SimpleRef::from_uuid_ref(self)
99
0
    }
100
101
    /// Get a [`Urn`] formatter.
102
    ///
103
    /// [`Uuid`]: ../struct.Uuid.html
104
    /// [`Urn`]: adapter/struct.Urn.html
105
    #[inline]
106
0
    pub const fn to_urn(self) -> Urn {
107
0
        Urn::from_uuid(self)
108
0
    }
109
110
    /// Get a borrowed [`UrnRef`] formatter.
111
    ///
112
    /// [`Uuid`]: ../struct.Uuid.html
113
    /// [`UrnRef`]: adapter/struct.UrnRef.html
114
    #[inline]
115
0
    pub const fn to_urn_ref(&self) -> UrnRef<'_> {
116
0
        UrnRef::from_uuid_ref(self)
117
0
    }
118
}
119
120
const UPPER: [u8; 16] = [
121
    b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'A', b'B',
122
    b'C', b'D', b'E', b'F',
123
];
124
const LOWER: [u8; 16] = [
125
    b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b',
126
    b'c', b'd', b'e', b'f',
127
];
128
/// The segments of a UUID's [u8; 16] corresponding to each group.
129
const BYTE_POSITIONS: [usize; 6] = [0, 4, 6, 8, 10, 16];
130
/// The locations that hyphens are written into the buffer, after each
131
/// group.
132
const HYPHEN_POSITIONS: [usize; 4] = [8, 13, 18, 23];
133
134
/// Encodes the `uuid` possibly with hyphens, and possibly in upper
135
/// case, to full_buffer[start..] and returns the str sliced from
136
/// full_buffer[..start + encoded_length].
137
///
138
/// The `start` parameter allows writing a prefix (such as
139
/// "urn:uuid:") to the buffer that's included in the final encoded
140
/// UUID.
141
#[allow(clippy::needless_range_loop)]
142
53.1k
fn encode<'a>(
143
53.1k
    full_buffer: &'a mut [u8],
144
53.1k
    start: usize,
145
53.1k
    uuid: &Uuid,
146
53.1k
    hyphens: bool,
147
53.1k
    upper: bool,
148
53.1k
) -> &'a mut str {
149
53.1k
    let len = if hyphens { 36 } else { 32 };
150
151
    {
152
53.1k
        let buffer = &mut full_buffer[start..start + len];
153
53.1k
        let bytes = uuid.as_bytes();
154
155
53.1k
        let hex = if upper { &UPPER } else { &LOWER };
156
157
318k
        for group in 0..5 {
158
            // If we're writing hyphens, we need to shift the output
159
            // location along by how many of them have been written
160
            // before this point. That's exactly the (0-indexed) group
161
            // number.
162
265k
            let hyphens_before = if hyphens { group } else { 0 };
163
849k
            for idx in BYTE_POSITIONS[group]..BYTE_POSITIONS[group + 1] {
164
849k
                let b = bytes[idx];
165
849k
                let out_idx = hyphens_before + 2 * idx;
166
849k
167
849k
                buffer[out_idx] = hex[(b >> 4) as usize];
168
849k
                buffer[out_idx + 1] = hex[(b & 0b1111) as usize];
169
849k
            }
170
171
265k
            if group != 4 && hyphens {
172
212k
                buffer[HYPHEN_POSITIONS[group]] = b'-';
173
212k
            }
174
        }
175
    }
176
177
53.1k
    str::from_utf8_mut(&mut full_buffer[..start + len])
178
53.1k
        .expect("found non-ASCII output characters while encoding a UUID")
179
53.1k
}
180
181
impl Hyphenated {
182
    /// The length of a hyphenated [`Uuid`] string.
183
    ///
184
    /// [`Uuid`]: ../struct.Uuid.html
185
    pub const LENGTH: usize = 36;
186
187
    /// Creates a [`Hyphenated`] from a [`Uuid`].
188
    ///
189
    /// [`Uuid`]: ../struct.Uuid.html
190
    /// [`Hyphenated`]: struct.Hyphenated.html
191
53.1k
    pub const fn from_uuid(uuid: Uuid) -> Self {
192
53.1k
        Hyphenated(uuid)
193
53.1k
    }
194
195
    /// Writes the [`Uuid`] as a lower-case hyphenated string to
196
    /// `buffer`, and returns the subslice of the buffer that contains the
197
    /// encoded UUID.
198
    ///
199
    /// This is slightly more efficient than using the formatting
200
    /// infrastructure as it avoids virtual calls, and may avoid
201
    /// double buffering.
202
    ///
203
    /// [`Uuid`]: ../struct.Uuid.html
204
    ///
205
    /// # Panics
206
    ///
207
    /// Panics if the buffer is not large enough: it must have length at least
208
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
209
    /// sufficiently-large temporary buffer.
210
    ///
211
    /// [`LENGTH`]: #associatedconstant.LENGTH
212
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
213
    ///
214
    /// # Examples
215
    ///
216
    /// ```rust
217
    /// use uuid::Uuid;
218
    ///
219
    /// fn main() -> Result<(), uuid::Error> {
220
    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;
221
    ///
222
    ///     // the encoded portion is returned
223
    ///     assert_eq!(
224
    ///         uuid.to_hyphenated()
225
    ///             .encode_lower(&mut Uuid::encode_buffer()),
226
    ///         "936da01f-9abd-4d9d-80c7-02af85c822a8"
227
    ///     );
228
    ///
229
    ///     // the buffer is mutated directly, and trailing contents remains
230
    ///     let mut buf = [b'!'; 40];
231
    ///     uuid.to_hyphenated().encode_lower(&mut buf);
232
    ///     assert_eq!(
233
    ///         &buf as &[_],
234
    ///         b"936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_]
235
    ///     );
236
    ///
237
    ///     Ok(())
238
    /// }
239
    /// ```
240
    /// */
241
53.1k
    pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
242
53.1k
        encode(buffer, 0, &self.0, true, false)
243
53.1k
    }
244
245
    /// Writes the [`Uuid`] as an upper-case hyphenated string to
246
    /// `buffer`, and returns the subslice of the buffer that contains the
247
    /// encoded UUID.
248
    ///
249
    /// This is slightly more efficient than using the formatting
250
    /// infrastructure as it avoids virtual calls, and may avoid
251
    /// double buffering.
252
    ///
253
    /// [`Uuid`]: ../struct.Uuid.html
254
    ///
255
    /// # Panics
256
    ///
257
    /// Panics if the buffer is not large enough: it must have length at least
258
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
259
    /// sufficiently-large temporary buffer.
260
    ///
261
    /// [`LENGTH`]: #associatedconstant.LENGTH
262
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
263
    ///
264
    /// # Examples
265
    ///
266
    /// ```rust
267
    /// use uuid::Uuid;
268
    ///
269
    /// fn main() -> Result<(), uuid::Error> {
270
    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;
271
    ///
272
    ///     // the encoded portion is returned
273
    ///     assert_eq!(
274
    ///         uuid.to_hyphenated()
275
    ///             .encode_upper(&mut Uuid::encode_buffer()),
276
    ///         "936DA01F-9ABD-4D9D-80C7-02AF85C822A8"
277
    ///     );
278
    ///
279
    ///     // the buffer is mutated directly, and trailing contents remains
280
    ///     let mut buf = [b'!'; 40];
281
    ///     uuid.to_hyphenated().encode_upper(&mut buf);
282
    ///     assert_eq!(
283
    ///         &buf as &[_],
284
    ///         b"936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_]
285
    ///     );
286
    ///
287
    ///     Ok(())
288
    /// }
289
    /// ```
290
    /// */
291
0
    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
292
0
        encode(buffer, 0, &self.0, true, true)
293
0
    }
294
}
295
296
impl<'a> HyphenatedRef<'a> {
297
    /// The length of a hyphenated [`Uuid`] string.
298
    ///
299
    /// [`Uuid`]: ../struct.Uuid.html
300
    pub const LENGTH: usize = 36;
301
302
    /// Creates a [`HyphenatedRef`] from a [`Uuid`] reference.
303
    ///
304
    /// [`Uuid`]: ../struct.Uuid.html
305
    /// [`HyphenatedRef`]: struct.HyphenatedRef.html
306
0
    pub const fn from_uuid_ref(uuid: &'a Uuid) -> Self {
307
0
        HyphenatedRef(uuid)
308
0
    }
309
310
    /// Writes the [`Uuid`] as a lower-case hyphenated string to
311
    /// `buffer`, and returns the subslice of the buffer that contains the
312
    /// encoded UUID.
313
    ///
314
    /// This is slightly more efficient than using the formatting
315
    /// infrastructure as it avoids virtual calls, and may avoid
316
    /// double buffering.
317
    ///
318
    /// [`Uuid`]: ../struct.Uuid.html
319
    ///
320
    /// # Panics
321
    ///
322
    /// Panics if the buffer is not large enough: it must have length at least
323
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
324
    /// sufficiently-large temporary buffer.
325
    ///
326
    /// [`LENGTH`]: #associatedconstant.LENGTH
327
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
328
    ///
329
    /// # Examples
330
    ///
331
    /// ```rust
332
    /// use uuid::Uuid;
333
    ///
334
    /// fn main() -> Result<(), uuid::Error> {
335
    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;
336
    ///
337
    ///     // the encoded portion is returned
338
    ///     assert_eq!(
339
    ///         uuid.to_hyphenated()
340
    ///             .encode_lower(&mut Uuid::encode_buffer()),
341
    ///         "936da01f-9abd-4d9d-80c7-02af85c822a8"
342
    ///     );
343
    ///     
344
    ///     // the buffer is mutated directly, and trailing contents remains
345
    ///     let mut buf = [b'!'; 40];
346
    ///     uuid.to_hyphenated().encode_lower(&mut buf);
347
    ///     assert_eq!(
348
    ///         uuid.to_hyphenated().encode_lower(&mut buf),
349
    ///         "936da01f-9abd-4d9d-80c7-02af85c822a8"
350
    ///     );
351
    ///     assert_eq!(
352
    ///         &buf as &[_],
353
    ///         b"936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_]
354
    ///     );
355
    ///
356
    ///     Ok(())
357
    /// }
358
    /// ```
359
    /// */
360
0
    pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
361
0
        encode(buffer, 0, self.0, true, false)
362
0
    }
363
364
    /// Writes the [`Uuid`] as an upper-case hyphenated string to
365
    /// `buffer`, and returns the subslice of the buffer that contains the
366
    /// encoded UUID.
367
    ///
368
    /// This is slightly more efficient than using the formatting
369
    /// infrastructure as it avoids virtual calls, and may avoid
370
    /// double buffering.
371
    ///
372
    /// [`Uuid`]: ../struct.Uuid.html
373
    ///
374
    /// # Panics
375
    ///
376
    /// Panics if the buffer is not large enough: it must have length at least
377
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
378
    /// sufficiently-large temporary buffer.
379
    ///
380
    /// [`LENGTH`]: #associatedconstant.LENGTH
381
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
382
    ///
383
    /// # Examples
384
    ///
385
    /// ```rust
386
    /// use uuid::Uuid;
387
    ///
388
    /// fn main() -> Result<(), uuid::Error> {
389
    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;
390
    ///
391
    ///     // the encoded portion is returned
392
    ///     assert_eq!(
393
    ///         uuid.to_hyphenated()
394
    ///             .encode_upper(&mut Uuid::encode_buffer()),
395
    ///         "936DA01F-9ABD-4D9D-80C7-02AF85C822A8"
396
    ///     );
397
    ///
398
    ///     // the buffer is mutated directly, and trailing contents remains
399
    ///     let mut buf = [b'!'; 40];
400
    ///     assert_eq!(
401
    ///         uuid.to_hyphenated().encode_upper(&mut buf),
402
    ///         "936DA01F-9ABD-4D9D-80C7-02AF85C822A8"
403
    ///     );
404
    ///     assert_eq!(
405
    ///         &buf as &[_],
406
    ///         b"936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_]
407
    ///     );
408
    ///
409
    ///     Ok(())
410
    /// }
411
    /// ```
412
    /// */
413
0
    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
414
0
        encode(buffer, 0, self.0, true, true)
415
0
    }
416
}
417
418
impl Simple {
419
    /// The length of a simple [`Uuid`] string.
420
    ///
421
    /// [`Uuid`]: ../struct.Uuid.html
422
    pub const LENGTH: usize = 32;
423
424
    /// Creates a [`Simple`] from a [`Uuid`].
425
    ///
426
    /// [`Uuid`]: ../struct.Uuid.html
427
    /// [`Simple`]: struct.Simple.html
428
0
    pub const fn from_uuid(uuid: Uuid) -> Self {
429
0
        Simple(uuid)
430
0
    }
431
432
    /// Writes the [`Uuid`] as a lower-case simple string to `buffer`,
433
    /// and returns the subslice of the buffer that contains the encoded UUID.
434
    ///
435
    /// This is slightly more efficient than using the formatting
436
    /// infrastructure as it avoids virtual calls, and may avoid
437
    /// double buffering.
438
    ///
439
    /// [`Uuid`]: ../struct.Uuid.html
440
    ///
441
    /// # Panics
442
    ///
443
    /// Panics if the buffer is not large enough: it must have length at least
444
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
445
    /// sufficiently-large temporary buffer.
446
    ///
447
    /// [`LENGTH`]: #associatedconstant.LENGTH
448
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
449
    ///
450
    /// # Examples
451
    ///
452
    /// ```rust
453
    /// use uuid::Uuid;
454
    ///
455
    /// fn main() -> Result<(), uuid::Error> {
456
    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;
457
    ///
458
    ///     // the encoded portion is returned
459
    ///     assert_eq!(
460
    ///         uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()),
461
    ///         "936da01f9abd4d9d80c702af85c822a8"
462
    ///     );
463
    ///
464
    ///     // the buffer is mutated directly, and trailing contents remains
465
    ///     let mut buf = [b'!'; 36];
466
    ///     assert_eq!(
467
    ///         uuid.to_simple().encode_lower(&mut buf),
468
    ///         "936da01f9abd4d9d80c702af85c822a8"
469
    ///     );
470
    ///     assert_eq!(
471
    ///         &buf as &[_],
472
    ///         b"936da01f9abd4d9d80c702af85c822a8!!!!" as &[_]
473
    ///     );
474
    ///
475
    ///     Ok(())
476
    /// }
477
    /// ```
478
    /// */
479
0
    pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
480
0
        encode(buffer, 0, &self.0, false, false)
481
0
    }
482
483
    /// Writes the [`Uuid`] as an upper-case simple string to `buffer`,
484
    /// and returns the subslice of the buffer that contains the encoded UUID.
485
    ///
486
    /// [`Uuid`]: ../struct.Uuid.html
487
    ///
488
    /// # Panics
489
    ///
490
    /// Panics if the buffer is not large enough: it must have length at least
491
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
492
    /// sufficiently-large temporary buffer.
493
    ///
494
    /// [`LENGTH`]: #associatedconstant.LENGTH
495
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
496
    ///
497
    /// # Examples
498
    ///
499
    /// ```rust
500
    /// use uuid::Uuid;
501
    ///
502
    /// fn main() -> Result<(), uuid::Error> {
503
    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;
504
    ///
505
    ///     // the encoded portion is returned
506
    ///     assert_eq!(
507
    ///         uuid.to_simple().encode_upper(&mut Uuid::encode_buffer()),
508
    ///         "936DA01F9ABD4D9D80C702AF85C822A8"
509
    ///     );
510
    ///
511
    ///     // the buffer is mutated directly, and trailing contents remains
512
    ///     let mut buf = [b'!'; 36];
513
    ///     assert_eq!(
514
    ///         uuid.to_simple().encode_upper(&mut buf),
515
    ///         "936DA01F9ABD4D9D80C702AF85C822A8"
516
    ///     );
517
    ///     assert_eq!(
518
    ///         &buf as &[_],
519
    ///         b"936DA01F9ABD4D9D80C702AF85C822A8!!!!" as &[_]
520
    ///     );
521
    ///
522
    ///     Ok(())
523
    /// }
524
    /// ```
525
    /// */
526
0
    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
527
0
        encode(buffer, 0, &self.0, false, true)
528
0
    }
529
}
530
531
impl<'a> SimpleRef<'a> {
532
    /// The length of a simple [`Uuid`] string.
533
    ///
534
    /// [`Uuid`]: ../struct.Uuid.html
535
    pub const LENGTH: usize = 32;
536
537
    /// Creates a [`SimpleRef`] from a [`Uuid`] reference.
538
    ///
539
    /// [`Uuid`]: ../struct.Uuid.html
540
    /// [`SimpleRef`]: struct.SimpleRef.html
541
0
    pub const fn from_uuid_ref(uuid: &'a Uuid) -> Self {
542
0
        SimpleRef(uuid)
543
0
    }
544
545
    /// Writes the [`Uuid`] as a lower-case simple string to `buffer`,
546
    /// and returns the subslice of the buffer that contains the encoded UUID.
547
    ///
548
    /// This is slightly more efficient than using the formatting
549
    /// infrastructure as it avoids virtual calls, and may avoid
550
    /// double buffering.
551
    ///
552
    /// [`Uuid`]: ../struct.Uuid.html
553
    ///
554
    /// # Panics
555
    ///
556
    /// Panics if the buffer is not large enough: it must have length at least
557
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
558
    /// sufficiently-large temporary buffer.
559
    ///
560
    /// [`LENGTH`]: #associatedconstant.LENGTH
561
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
562
    ///
563
    /// # Examples
564
    ///
565
    /// ```rust
566
    /// use uuid::Uuid;
567
    ///
568
    /// fn main() -> Result<(), uuid::Error> {
569
    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;
570
    ///
571
    ///     // the encoded portion is returned
572
    ///     assert_eq!(
573
    ///         uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()),
574
    ///         "936da01f9abd4d9d80c702af85c822a8"
575
    ///     );
576
    ///
577
    ///     // the buffer is mutated directly, and trailing contents remains
578
    ///     let mut buf = [b'!'; 36];
579
    ///     assert_eq!(
580
    ///         uuid.to_simple().encode_lower(&mut buf),
581
    ///         "936da01f9abd4d9d80c702af85c822a8"
582
    ///     );
583
    ///     assert_eq!(
584
    ///         &buf as &[_],
585
    ///         b"936da01f9abd4d9d80c702af85c822a8!!!!" as &[_]
586
    ///     );
587
    ///
588
    ///     Ok(())
589
    /// }
590
    /// ```
591
    /// */
592
0
    pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
593
0
        encode(buffer, 0, self.0, false, false)
594
0
    }
595
596
    /// Writes the [`Uuid`] as an upper-case simple string to `buffer`,
597
    /// and returns the subslice of the buffer that contains the encoded UUID.
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.to_simple().encode_upper(&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.to_simple().encode_upper(&mut buf),
628
    ///         "936DA01F9ABD4D9D80C702AF85C822A8"
629
    ///     );
630
    ///     assert_eq!(
631
    ///         &buf as &[_],
632
    ///         b"936DA01F9ABD4D9D80C702AF85C822A8!!!!" as &[_]
633
    ///     );
634
    ///
635
    ///     Ok(())
636
    /// }
637
    /// ```
638
    /// */
639
0
    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
640
0
        encode(buffer, 0, self.0, false, true)
641
0
    }
642
}
643
644
impl Urn {
645
    /// The length of a URN [`Uuid`] string.
646
    ///
647
    /// [`Uuid`]: ../struct.Uuid.html
648
    pub const LENGTH: usize = 45;
649
650
    /// Creates a [`Urn`] from a [`Uuid`].
651
    ///
652
    /// [`Uuid`]: ../struct.Uuid.html
653
    /// [`Urn`]: struct.Urn.html
654
0
    pub const fn from_uuid(uuid: Uuid) -> Self {
655
0
        Urn(uuid)
656
0
    }
657
658
    /// Writes the [`Uuid`] as a lower-case URN string to
659
    /// `buffer`, and returns the subslice of the buffer that contains the
660
    /// encoded UUID.
661
    ///
662
    /// This is slightly more efficient than using the formatting
663
    /// infrastructure as it avoids virtual calls, and may avoid
664
    /// double buffering.
665
    ///
666
    /// [`Uuid`]: ../struct.Uuid.html
667
    ///
668
    /// # Panics
669
    ///
670
    /// Panics if the buffer is not large enough: it must have length at least
671
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
672
    /// sufficiently-large temporary buffer.
673
    ///
674
    /// [`LENGTH`]: #associatedconstant.LENGTH
675
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
676
    ///
677
    /// # Examples
678
    ///
679
    /// ```rust
680
    /// use uuid::Uuid;
681
    ///
682
    /// fn main() -> Result<(), uuid::Error> {
683
    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;
684
    ///
685
    ///     // the encoded portion is returned
686
    ///     assert_eq!(
687
    ///         uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()),
688
    ///         "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8"
689
    ///     );
690
    ///
691
    ///     // the buffer is mutated directly, and trailing contents remains
692
    ///     let mut buf = [b'!'; 49];
693
    ///     uuid.to_urn().encode_lower(&mut buf);
694
    ///     assert_eq!(
695
    ///         uuid.to_urn().encode_lower(&mut buf),
696
    ///         "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8"
697
    ///     );
698
    ///     assert_eq!(
699
    ///         &buf as &[_],
700
    ///         b"urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_]
701
    ///     );
702
    ///     
703
    ///     Ok(())
704
    /// }
705
    /// ```
706
    /// */
707
0
    pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
708
0
        buffer[..9].copy_from_slice(b"urn:uuid:");
709
0
        encode(buffer, 9, &self.0, true, false)
710
0
    }
711
712
    /// Writes the [`Uuid`] as an upper-case URN string to
713
    /// `buffer`, and returns the subslice of the buffer that contains the
714
    /// encoded UUID.
715
    ///
716
    /// This is slightly more efficient than using the formatting
717
    /// infrastructure as it avoids virtual calls, and may avoid
718
    /// double buffering.
719
    ///
720
    /// [`Uuid`]: ../struct.Uuid.html
721
    ///
722
    /// # Panics
723
    ///
724
    /// Panics if the buffer is not large enough: it must have length at least
725
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
726
    /// sufficiently-large temporary buffer.
727
    ///
728
    /// [`LENGTH`]: #associatedconstant.LENGTH
729
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
730
    ///
731
    /// # Examples
732
    ///
733
    /// ```rust
734
    /// use uuid::Uuid;
735
    ///
736
    /// fn main() -> Result<(), uuid::Error> {
737
    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;
738
    ///
739
    ///     // the encoded portion is returned
740
    ///     assert_eq!(
741
    ///         uuid.to_urn().encode_upper(&mut Uuid::encode_buffer()),
742
    ///         "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8"
743
    ///     );
744
    ///
745
    ///     // the buffer is mutated directly, and trailing contents remains
746
    ///     let mut buf = [b'!'; 49];
747
    ///     assert_eq!(
748
    ///         uuid.to_urn().encode_upper(&mut buf),
749
    ///         "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8"
750
    ///     );
751
    ///     assert_eq!(
752
    ///         &buf as &[_],
753
    ///         b"urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_]
754
    ///     );
755
    ///
756
    ///     Ok(())
757
    /// }
758
    /// ```
759
    /// */
760
0
    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
761
0
        buffer[..9].copy_from_slice(b"urn:uuid:");
762
0
        encode(buffer, 9, &self.0, true, true)
763
0
    }
764
}
765
766
impl<'a> UrnRef<'a> {
767
    /// The length of a URN [`Uuid`] string.
768
    ///
769
    /// [`Uuid`]: ../struct.Uuid.html
770
    pub const LENGTH: usize = 45;
771
772
    /// Creates a [`UrnRef`] from a [`Uuid`] reference.
773
    ///
774
    /// [`Uuid`]: ../struct.Uuid.html
775
    /// [`UrnRef`]: struct.UrnRef.html
776
0
    pub const fn from_uuid_ref(uuid: &'a Uuid) -> Self {
777
0
        UrnRef(&uuid)
778
0
    }
779
780
    /// Writes the [`Uuid`] as a lower-case URN string to
781
    /// `buffer`, and returns the subslice of the buffer that contains the
782
    /// encoded UUID.
783
    ///
784
    /// This is slightly more efficient than using the formatting
785
    /// infrastructure as it avoids virtual calls, and may avoid
786
    /// double buffering.
787
    ///
788
    /// [`Uuid`]: ../struct.Uuid.html
789
    ///
790
    /// # Panics
791
    ///
792
    /// Panics if the buffer is not large enough: it must have length at least
793
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
794
    /// sufficiently-large temporary buffer.
795
    ///
796
    /// [`LENGTH`]: #associatedconstant.LENGTH
797
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
798
    ///
799
    /// # Examples
800
    ///
801
    /// ```rust
802
    /// use uuid::Uuid;
803
    ///
804
    /// fn main() -> Result<(), uuid::Error> {
805
    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;
806
    ///
807
    ///     // the encoded portion is returned
808
    ///     assert_eq!(
809
    ///         uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()),
810
    ///         "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8"
811
    ///     );
812
    ///
813
    ///     // the buffer is mutated directly, and trailing contents remains
814
    ///     let mut buf = [b'!'; 49];
815
    ///     uuid.to_urn().encode_lower(&mut buf);
816
    ///     assert_eq!(
817
    ///         uuid.to_urn().encode_lower(&mut buf),
818
    ///         "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8"
819
    ///     );
820
    ///     assert_eq!(
821
    ///         &buf as &[_],
822
    ///         b"urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_]
823
    ///     );
824
    ///
825
    ///     Ok(())
826
    /// }
827
    /// ```
828
    /// */
829
0
    pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
830
0
        buffer[..9].copy_from_slice(b"urn:uuid:");
831
0
        encode(buffer, 9, self.0, true, false)
832
0
    }
833
834
    /// Writes the [`Uuid`] as an upper-case URN string to
835
    /// `buffer`, and returns the subslice of the buffer that contains the
836
    /// encoded UUID.
837
    ///
838
    /// This is slightly more efficient than using the formatting
839
    /// infrastructure as it avoids virtual calls, and may avoid
840
    /// double buffering.
841
    ///
842
    /// [`Uuid`]: ../struct.Uuid.html
843
    ///
844
    /// # Panics
845
    ///
846
    /// Panics if the buffer is not large enough: it must have length at least
847
    /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a
848
    /// sufficiently-large temporary buffer.
849
    ///
850
    /// [`LENGTH`]: #associatedconstant.LENGTH
851
    /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer
852
    ///
853
    /// # Examples
854
    ///
855
    /// ```rust
856
    /// use uuid::Uuid;
857
    ///
858
    /// fn main() -> Result<(), uuid::Error> {
859
    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;
860
    ///
861
    ///     // the encoded portion is returned
862
    ///     assert_eq!(
863
    ///         uuid.to_urn().encode_upper(&mut Uuid::encode_buffer()),
864
    ///         "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8"
865
    ///     );
866
    ///
867
    ///     // the buffer is mutated directly, and trailing contents remains
868
    ///     let mut buf = [b'!'; 49];
869
    ///     assert_eq!(
870
    ///         uuid.to_urn().encode_upper(&mut buf),
871
    ///         "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8"
872
    ///     );
873
    ///     assert_eq!(
874
    ///         &buf as &[_],
875
    ///         b"urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_]
876
    ///     );
877
    ///
878
    ///     Ok(())
879
    /// }
880
    /// ```
881
    /// */
882
0
    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
883
0
        buffer[..9].copy_from_slice(b"urn:uuid:");
884
0
        encode(buffer, 9, self.0, true, true)
885
0
    }
886
}
887
888
macro_rules! impl_adapter_traits {
889
    ($($T:ident<$($a:lifetime),*>),+) => {$(
890
        impl<$($a),*> fmt::Display for $T<$($a),*> {
891
            #[inline]
892
53.1k
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
893
53.1k
                fmt::LowerHex::fmt(self, f)
894
53.1k
            }
<uuid::adapter::Hyphenated as core::fmt::Display>::fmt
Line
Count
Source
892
53.1k
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
893
53.1k
                fmt::LowerHex::fmt(self, f)
894
53.1k
            }
Unexecuted instantiation: <uuid::adapter::HyphenatedRef as core::fmt::Display>::fmt
Unexecuted instantiation: <uuid::adapter::Simple as core::fmt::Display>::fmt
Unexecuted instantiation: <uuid::adapter::SimpleRef as core::fmt::Display>::fmt
Unexecuted instantiation: <uuid::adapter::Urn as core::fmt::Display>::fmt
Unexecuted instantiation: <uuid::adapter::UrnRef as core::fmt::Display>::fmt
895
        }
896
897
        impl<$($a),*> fmt::LowerHex for $T<$($a),*> {
898
53.1k
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
899
                // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808
900
53.1k
                f.write_str(self.encode_lower(&mut [0; $T::LENGTH]))
901
53.1k
            }
<uuid::adapter::Hyphenated as core::fmt::LowerHex>::fmt
Line
Count
Source
898
53.1k
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
899
                // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808
900
53.1k
                f.write_str(self.encode_lower(&mut [0; $T::LENGTH]))
901
53.1k
            }
Unexecuted instantiation: <uuid::adapter::HyphenatedRef as core::fmt::LowerHex>::fmt
Unexecuted instantiation: <uuid::adapter::Simple as core::fmt::LowerHex>::fmt
Unexecuted instantiation: <uuid::adapter::SimpleRef as core::fmt::LowerHex>::fmt
Unexecuted instantiation: <uuid::adapter::Urn as core::fmt::LowerHex>::fmt
Unexecuted instantiation: <uuid::adapter::UrnRef as core::fmt::LowerHex>::fmt
902
        }
903
904
        impl<$($a),*> fmt::UpperHex for $T<$($a),*> {
905
0
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
906
                // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808
907
0
                f.write_str(self.encode_upper(&mut [0; $T::LENGTH]))
908
0
            }
Unexecuted instantiation: <uuid::adapter::Hyphenated as core::fmt::UpperHex>::fmt
Unexecuted instantiation: <uuid::adapter::HyphenatedRef as core::fmt::UpperHex>::fmt
Unexecuted instantiation: <uuid::adapter::Simple as core::fmt::UpperHex>::fmt
Unexecuted instantiation: <uuid::adapter::SimpleRef as core::fmt::UpperHex>::fmt
Unexecuted instantiation: <uuid::adapter::Urn as core::fmt::UpperHex>::fmt
Unexecuted instantiation: <uuid::adapter::UrnRef as core::fmt::UpperHex>::fmt
909
        }
910
911
        impl_adapter_from!($T<$($a),*>);
912
    )+}
913
}
914
915
macro_rules! impl_adapter_from {
916
    ($T:ident<>) => {
917
        impl From<Uuid> for $T {
918
            #[inline]
919
0
            fn from(f: Uuid) -> Self {
920
0
                $T::from_uuid(f)
921
0
            }
Unexecuted instantiation: <uuid::adapter::Hyphenated as core::convert::From<uuid::Uuid>>::from
Unexecuted instantiation: <uuid::adapter::Simple as core::convert::From<uuid::Uuid>>::from
Unexecuted instantiation: <uuid::adapter::Urn as core::convert::From<uuid::Uuid>>::from
922
        }
923
    };
924
    ($T:ident<$a:lifetime>) => {
925
        impl<$a> From<&$a Uuid> for $T<$a> {
926
            #[inline]
927
0
            fn from(f: &$a Uuid) -> Self {
928
0
                $T::from_uuid_ref(f)
929
0
            }
Unexecuted instantiation: <uuid::adapter::HyphenatedRef as core::convert::From<&uuid::Uuid>>::from
Unexecuted instantiation: <uuid::adapter::SimpleRef as core::convert::From<&uuid::Uuid>>::from
Unexecuted instantiation: <uuid::adapter::UrnRef as core::convert::From<&uuid::Uuid>>::from
930
        }
931
    };
932
}
933
934
impl_adapter_traits! {
935
    Hyphenated<>,
936
    HyphenatedRef<'a>,
937
    Simple<>,
938
    SimpleRef<'a>,
939
    Urn<>,
940
    UrnRef<'a>
941
}
942
943
#[cfg(test)]
944
mod tests {
945
    use crate::prelude::*;
946
947
    #[test]
948
    fn hyphenated_trailing() {
949
        let mut buf = [b'x'; 100];
950
        let len = Uuid::nil().to_hyphenated().encode_lower(&mut buf).len();
951
        assert_eq!(len, super::Hyphenated::LENGTH);
952
        assert!(buf[len..].iter().all(|x| *x == b'x'));
953
    }
954
955
    #[test]
956
    fn hyphenated_ref_trailing() {
957
        let mut buf = [b'x'; 100];
958
        let len = Uuid::nil().to_hyphenated().encode_lower(&mut buf).len();
959
        assert_eq!(len, super::HyphenatedRef::LENGTH);
960
        assert!(buf[len..].iter().all(|x| *x == b'x'));
961
    }
962
963
    #[test]
964
    fn simple_trailing() {
965
        let mut buf = [b'x'; 100];
966
        let len = Uuid::nil().to_simple().encode_lower(&mut buf).len();
967
        assert_eq!(len, super::Simple::LENGTH);
968
        assert!(buf[len..].iter().all(|x| *x == b'x'));
969
    }
970
971
    #[test]
972
    fn simple_ref_trailing() {
973
        let mut buf = [b'x'; 100];
974
        let len = Uuid::nil().to_simple().encode_lower(&mut buf).len();
975
        assert_eq!(len, super::SimpleRef::LENGTH);
976
        assert!(buf[len..].iter().all(|x| *x == b'x'));
977
    }
978
979
    #[test]
980
    fn urn_trailing() {
981
        let mut buf = [b'x'; 100];
982
        let len = Uuid::nil().to_urn().encode_lower(&mut buf).len();
983
        assert_eq!(len, super::Urn::LENGTH);
984
        assert!(buf[len..].iter().all(|x| *x == b'x'));
985
    }
986
987
    #[test]
988
    fn urn_ref_trailing() {
989
        let mut buf = [b'x'; 100];
990
        let len = Uuid::nil().to_urn().encode_lower(&mut buf).len();
991
        assert_eq!(len, super::UrnRef::LENGTH);
992
        assert!(buf[len..].iter().all(|x| *x == b'x'));
993
    }
994
995
    #[test]
996
    #[should_panic]
997
    fn hyphenated_too_small() {
998
        Uuid::nil().to_hyphenated().encode_lower(&mut [0; 35]);
999
    }
1000
1001
    #[test]
1002
    #[should_panic]
1003
    fn hyphenated_ref_too_small() {
1004
        Uuid::nil().to_hyphenated_ref().encode_lower(&mut [0; 35]);
1005
    }
1006
1007
    #[test]
1008
    #[should_panic]
1009
    fn simple_too_small() {
1010
        Uuid::nil().to_simple().encode_lower(&mut [0; 31]);
1011
    }
1012
    #[test]
1013
    #[should_panic]
1014
    fn simple_ref_too_small() {
1015
        Uuid::nil().to_simple_ref().encode_lower(&mut [0; 31]);
1016
    }
1017
    #[test]
1018
    #[should_panic]
1019
    fn urn_too_small() {
1020
        Uuid::nil().to_urn().encode_lower(&mut [0; 44]);
1021
    }
1022
    #[test]
1023
    #[should_panic]
1024
    fn urn_ref_too_small() {
1025
        Uuid::nil().to_urn_ref().encode_lower(&mut [0; 44]);
1026
    }
1027
}