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