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