uuid/
builder.rs

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//! A Builder type for [`Uuid`]s.
13//!
14//! [`Uuid`]: ../struct.Uuid.html
15
16use crate::{error::*, Bytes, Uuid, Variant, Version};
17
18/// A builder struct for creating a UUID.
19///
20/// This type is useful if you need to mutate individual fields of a [`Uuid`]
21/// while constructing it. Since the [`Uuid`] type is `Copy`, it doesn't offer
22/// any methods to mutate in place. They live on the `Builder` instead.
23///
24/// # Examples
25///
26/// Creating a v4 UUID from externally generated bytes:
27///
28/// ```
29/// # use uuid::{Builder, Version, Variant};
30/// # let rng = || [
31/// #     70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90,
32/// # 145, 63, 62,
33/// # ];
34/// let random_bytes = rng();
35///
36/// let uuid = Builder::from_random_bytes(random_bytes).into_uuid();
37///
38/// assert_eq!(Some(Version::Random), uuid.get_version());
39/// assert_eq!(Variant::RFC4122, uuid.get_variant());
40/// ```
41#[allow(missing_copy_implementations)]
42#[derive(Debug)]
43pub struct Builder(Uuid);
44
45impl Uuid {
46    /// The 'nil UUID'.
47    ///
48    /// The nil UUID is a special form of UUID that is specified to have all
49    /// 128 bits set to zero, as defined in [IETF RFC 4122 Section 4.1.7][RFC].
50    ///
51    /// [RFC]: https://tools.ietf.org/html/rfc4122.html#section-4.1.7
52    ///
53    /// # Examples
54    ///
55    /// Basic usage:
56    ///
57    /// ```
58    /// # use uuid::Uuid;
59    /// let uuid = Uuid::nil();
60    ///
61    /// assert_eq!(
62    ///     "00000000-0000-0000-0000-000000000000",
63    ///     uuid.hyphenated().to_string(),
64    /// );
65    /// ```
66    pub const fn nil() -> Self {
67        Uuid::from_bytes([0; 16])
68    }
69
70    /// Creates a UUID from four field values.
71    ///
72    /// # Examples
73    ///
74    /// Basic usage:
75    ///
76    /// ```
77    /// # use uuid::Uuid;
78    /// let d1 = 0xa1a2a3a4;
79    /// let d2 = 0xb1b2;
80    /// let d3 = 0xc1c2;
81    /// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
82    ///
83    /// let uuid = Uuid::from_fields(d1, d2, d3, &d4);
84    ///
85    /// assert_eq!(
86    ///     "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
87    ///     uuid.hyphenated().to_string(),
88    /// );
89    /// ```
90    pub const fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Uuid {
91        Uuid::from_bytes([
92            (d1 >> 24) as u8,
93            (d1 >> 16) as u8,
94            (d1 >> 8) as u8,
95            d1 as u8,
96            (d2 >> 8) as u8,
97            d2 as u8,
98            (d3 >> 8) as u8,
99            d3 as u8,
100            d4[0],
101            d4[1],
102            d4[2],
103            d4[3],
104            d4[4],
105            d4[5],
106            d4[6],
107            d4[7],
108        ])
109    }
110
111    /// Creates a UUID from four field values in little-endian order.
112    ///
113    /// The bytes in the `d1`, `d2` and `d3` fields will be flipped to convert
114    /// into big-endian order. This is based on the endianness of the UUID,
115    /// rather than the target environment so bytes will be flipped on both
116    /// big and little endian machines.
117    ///
118    /// # Examples
119    ///
120    /// ```
121    /// # use uuid::Uuid;
122    /// let d1 = 0xa1a2a3a4;
123    /// let d2 = 0xb1b2;
124    /// let d3 = 0xc1c2;
125    /// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
126    ///
127    /// let uuid = Uuid::from_fields_le(d1, d2, d3, &d4);
128    ///
129    /// assert_eq!(
130    ///     "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
131    ///     uuid.hyphenated().to_string(),
132    /// );
133    /// ```
134    pub const fn from_fields_le(
135        d1: u32,
136        d2: u16,
137        d3: u16,
138        d4: &[u8; 8],
139    ) -> Uuid {
140        Uuid::from_bytes([
141            d1 as u8,
142            (d1 >> 8) as u8,
143            (d1 >> 16) as u8,
144            (d1 >> 24) as u8,
145            (d2) as u8,
146            (d2 >> 8) as u8,
147            d3 as u8,
148            (d3 >> 8) as u8,
149            d4[0],
150            d4[1],
151            d4[2],
152            d4[3],
153            d4[4],
154            d4[5],
155            d4[6],
156            d4[7],
157        ])
158    }
159
160    /// Creates a UUID from a 128bit value.
161    ///
162    /// # Examples
163    ///
164    /// Basic usage:
165    ///
166    /// ```
167    /// # use uuid::Uuid;
168    /// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
169    ///
170    /// let uuid = Uuid::from_u128(v);
171    ///
172    /// assert_eq!(
173    ///     "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
174    ///     uuid.hyphenated().to_string(),
175    /// );
176    /// ```
177    pub const fn from_u128(v: u128) -> Self {
178        Uuid::from_bytes([
179            (v >> 120) as u8,
180            (v >> 112) as u8,
181            (v >> 104) as u8,
182            (v >> 96) as u8,
183            (v >> 88) as u8,
184            (v >> 80) as u8,
185            (v >> 72) as u8,
186            (v >> 64) as u8,
187            (v >> 56) as u8,
188            (v >> 48) as u8,
189            (v >> 40) as u8,
190            (v >> 32) as u8,
191            (v >> 24) as u8,
192            (v >> 16) as u8,
193            (v >> 8) as u8,
194            v as u8,
195        ])
196    }
197
198    /// Creates a UUID from a 128bit value in little-endian order.
199    ///
200    /// The entire value will be flipped to convert into big-endian order.
201    /// This is based on the endianness of the UUID, rather than the target
202    /// environment so bytes will be flipped on both big and little endian
203    /// machines.
204    ///
205    /// # Examples
206    ///
207    /// Basic usage:
208    ///
209    /// ```
210    /// # use uuid::Uuid;
211    /// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
212    ///
213    /// let uuid = Uuid::from_u128_le(v);
214    ///
215    /// assert_eq!(
216    ///     "d8d7d6d5-d4d3-d2d1-c2c1-b2b1a4a3a2a1",
217    ///     uuid.hyphenated().to_string(),
218    /// );
219    /// ```
220    pub const fn from_u128_le(v: u128) -> Self {
221        Uuid::from_bytes([
222            v as u8,
223            (v >> 8) as u8,
224            (v >> 16) as u8,
225            (v >> 24) as u8,
226            (v >> 32) as u8,
227            (v >> 40) as u8,
228            (v >> 48) as u8,
229            (v >> 56) as u8,
230            (v >> 64) as u8,
231            (v >> 72) as u8,
232            (v >> 80) as u8,
233            (v >> 88) as u8,
234            (v >> 96) as u8,
235            (v >> 104) as u8,
236            (v >> 112) as u8,
237            (v >> 120) as u8,
238        ])
239    }
240
241    /// Creates a UUID from two 64bit values.
242    ///
243    /// # Examples
244    ///
245    /// Basic usage:
246    ///
247    /// ```
248    /// # use uuid::Uuid;
249    /// let hi = 0xa1a2a3a4b1b2c1c2u64;
250    /// let lo = 0xd1d2d3d4d5d6d7d8u64;
251    ///
252    /// let uuid = Uuid::from_u64_pair(hi, lo);
253    ///
254    /// assert_eq!(
255    ///     "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
256    ///     uuid.hyphenated().to_string(),
257    /// );
258    /// ```
259    pub const fn from_u64_pair(high_bits: u64, low_bits: u64) -> Self {
260        Uuid::from_bytes([
261            (high_bits >> 56) as u8,
262            (high_bits >> 48) as u8,
263            (high_bits >> 40) as u8,
264            (high_bits >> 32) as u8,
265            (high_bits >> 24) as u8,
266            (high_bits >> 16) as u8,
267            (high_bits >> 8) as u8,
268            high_bits as u8,
269            (low_bits >> 56) as u8,
270            (low_bits >> 48) as u8,
271            (low_bits >> 40) as u8,
272            (low_bits >> 32) as u8,
273            (low_bits >> 24) as u8,
274            (low_bits >> 16) as u8,
275            (low_bits >> 8) as u8,
276            low_bits as u8,
277        ])
278    }
279
280    /// Creates a UUID using the supplied bytes.
281    ///
282    /// # Errors
283    ///
284    /// This function will return an error if `b` has any length other than 16.
285    ///
286    /// # Examples
287    ///
288    /// Basic usage:
289    ///
290    /// ```
291    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
292    /// # use uuid::Uuid;
293    /// let bytes = [
294    ///     0xa1, 0xa2, 0xa3, 0xa4,
295    ///     0xb1, 0xb2,
296    ///     0xc1, 0xc2,
297    ///     0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
298    /// ];
299    ///
300    /// let uuid = Uuid::from_slice(&bytes)?;
301    ///
302    /// assert_eq!(
303    ///     "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
304    ///     uuid.hyphenated().to_string(),
305    /// );
306    /// # Ok(())
307    /// # }
308    /// ```
309    pub fn from_slice(b: &[u8]) -> Result<Uuid, Error> {
310        if b.len() != 16 {
311            return Err(Error(ErrorKind::ByteLength { len: b.len() }));
312        }
313
314        let mut bytes: Bytes = [0; 16];
315        bytes.copy_from_slice(b);
316        Ok(Uuid::from_bytes(bytes))
317    }
318
319    /// Creates a UUID using the supplied bytes in little endian order.
320    ///
321    /// The individual fields encoded in the buffer will be flipped.
322    ///
323    /// # Errors
324    ///
325    /// This function will return an error if `b` has any length other than 16.
326    ///
327    /// # Examples
328    ///
329    /// Basic usage:
330    ///
331    /// ```
332    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
333    /// # use uuid::Uuid;
334    /// let bytes = [
335    ///     0xa1, 0xa2, 0xa3, 0xa4,
336    ///     0xb1, 0xb2,
337    ///     0xc1, 0xc2,
338    ///     0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
339    /// ];
340    ///
341    /// let uuid = Uuid::from_slice_le(&bytes)?;
342    ///
343    /// assert_eq!(
344    ///     uuid.hyphenated().to_string(),
345    ///     "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8"
346    /// );
347    /// # Ok(())
348    /// # }
349    /// ```
350    pub fn from_slice_le(b: &[u8]) -> Result<Uuid, Error> {
351        if b.len() != 16 {
352            return Err(Error(ErrorKind::ByteLength { len: b.len() }));
353        }
354
355        let mut bytes: Bytes = [0; 16];
356        bytes.copy_from_slice(b);
357        Ok(Uuid::from_bytes_le(bytes))
358    }
359
360    /// Creates a UUID using the supplied bytes.
361    ///
362    /// # Examples
363    ///
364    /// Basic usage:
365    ///
366    /// ```
367    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
368    /// # use uuid::Uuid;
369    /// let bytes = [
370    ///     0xa1, 0xa2, 0xa3, 0xa4,
371    ///     0xb1, 0xb2,
372    ///     0xc1, 0xc2,
373    ///     0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
374    /// ];
375    ///
376    /// let uuid = Uuid::from_bytes(bytes);
377    ///
378    /// assert_eq!(
379    ///     uuid.hyphenated().to_string(),
380    ///     "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8"
381    /// );
382    /// # Ok(())
383    /// # }
384    /// ```
385    pub const fn from_bytes(bytes: Bytes) -> Uuid {
386        Uuid(bytes)
387    }
388
389    /// Creates a UUID using the supplied bytes in little endian order.
390    ///
391    /// The individual fields encoded in the buffer will be flipped.
392    ///
393    /// # Examples
394    ///
395    /// Basic usage:
396    ///
397    /// ```
398    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
399    /// # use uuid::Uuid;
400    /// let bytes = [
401    ///     0xa1, 0xa2, 0xa3, 0xa4,
402    ///     0xb1, 0xb2,
403    ///     0xc1, 0xc2,
404    ///     0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
405    /// ];
406    ///
407    /// let uuid = Uuid::from_bytes_le(bytes);
408    ///
409    /// assert_eq!(
410    ///     "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
411    ///     uuid.hyphenated().to_string(),
412    /// );
413    /// # Ok(())
414    /// # }
415    /// ```
416    pub const fn from_bytes_le(b: Bytes) -> Uuid {
417        Uuid([
418            b[3], b[2], b[1], b[0], b[5], b[4], b[7], b[6], b[8], b[9], b[10],
419            b[11], b[12], b[13], b[14], b[15],
420        ])
421    }
422
423    /// Creates a reference to a UUID from a reference to the supplied bytes.
424    ///
425    /// # Examples
426    ///
427    /// Basic usage:
428    ///
429    /// ```
430    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
431    /// # use uuid::Uuid;
432    /// let bytes = [
433    ///     0xa1, 0xa2, 0xa3, 0xa4,
434    ///     0xb1, 0xb2,
435    ///     0xc1, 0xc2,
436    ///     0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
437    /// ];
438    ///
439    /// let uuid = Uuid::from_bytes_ref(&bytes);
440    ///
441    /// assert_eq!(
442    ///     uuid.hyphenated().to_string(),
443    ///     "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8"
444    /// );
445    ///
446    /// assert!(std::ptr::eq(
447    ///     uuid as *const Uuid as *const u8,
448    ///     &bytes as *const [u8; 16] as *const u8,
449    /// ));
450    /// # Ok(())
451    /// # }
452    /// ```
453    pub fn from_bytes_ref(bytes: &Bytes) -> &Uuid {
454        // SAFETY: `Bytes` and `Uuid` have the same ABI
455        unsafe { &*(bytes as *const Bytes as *const Uuid) }
456    }
457
458    // NOTE: There is no `from_u128_ref` because in little-endian
459    // environments the value isn't properly encoded. Callers would
460    // need to use `.to_be()` themselves.
461}
462
463impl Builder {
464    /// Creates a `Builder` using the supplied bytes.
465    ///
466    /// # Examples
467    ///
468    /// Basic usage:
469    ///
470    /// ```
471    /// # use uuid::Builder;
472    /// let bytes = [
473    ///     0xa1, 0xa2, 0xa3, 0xa4,
474    ///     0xb1, 0xb2,
475    ///     0xc1, 0xc2,
476    ///     0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
477    /// ];
478    ///
479    /// let uuid = Builder::from_bytes(bytes).into_uuid();
480    ///
481    /// assert_eq!(
482    ///     "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
483    ///     uuid.hyphenated().to_string(),
484    /// );
485    /// ```
486    pub const fn from_bytes(b: Bytes) -> Self {
487        Builder(Uuid::from_bytes(b))
488    }
489
490    /// Creates a `Builder` using the supplied bytes in little endian order.
491    ///
492    /// The individual fields encoded in the buffer will be flipped.
493    ///
494    /// # Examples
495    ///
496    /// Basic usage:
497    ///
498    /// ```
499    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
500    /// # use uuid::{Builder, Uuid};
501    /// let bytes = [
502    ///     0xa1, 0xa2, 0xa3, 0xa4,
503    ///     0xb1, 0xb2,
504    ///     0xc1, 0xc2,
505    ///     0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
506    /// ];
507    ///
508    /// let uuid = Builder::from_bytes_le(bytes).into_uuid();
509    ///
510    /// assert_eq!(
511    ///     "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
512    ///     uuid.hyphenated().to_string(),
513    /// );
514    /// # Ok(())
515    /// # }
516    /// ```
517    pub const fn from_bytes_le(b: Bytes) -> Self {
518        Builder(Uuid::from_bytes_le(b))
519    }
520
521    /// Creates a `Builder` using the supplied random bytes.
522    ///
523    /// This method can be useful in environments where the `v4` feature isn't
524    /// available. This method will take care of setting the appropriate
525    /// version and variant fields.
526    ///
527    /// # Examples
528    ///
529    /// ```
530    /// # use uuid::{Builder, Variant, Version};
531    /// # let rng = || [
532    /// #     70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90,
533    /// # 145, 63, 62,
534    /// # ];
535    /// let random_bytes = rng();
536    /// let uuid = Builder::from_random_bytes(random_bytes).into_uuid();
537    ///
538    /// assert_eq!(Some(Version::Random), uuid.get_version());
539    /// assert_eq!(Variant::RFC4122, uuid.get_variant());
540    /// ```
541    pub const fn from_random_bytes(b: Bytes) -> Self {
542        Builder(Uuid::from_bytes(b))
543            .with_variant(Variant::RFC4122)
544            .with_version(Version::Random)
545    }
546
547    /// Creates a `Builder` using the supplied MD5 hashed bytes.
548    pub const fn from_md5_bytes(b: Bytes) -> Self {
549        Builder(Uuid::from_bytes(b))
550            .with_variant(Variant::RFC4122)
551            .with_version(Version::Md5)
552    }
553
554    /// Creates a `Builder` using the supplied SHA1 hashed bytes.
555    pub const fn from_sha1_bytes(b: Bytes) -> Self {
556        Builder(Uuid::from_bytes(b))
557            .with_variant(Variant::RFC4122)
558            .with_version(Version::Sha1)
559    }
560
561    /// Creates a `Builder` using the supplied bytes.
562    ///
563    /// # Errors
564    ///
565    /// This function will return an error if `b` has any length other than 16.
566    ///
567    /// # Examples
568    ///
569    /// Basic usage:
570    ///
571    /// ```
572    /// # use uuid::Builder;
573    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
574    /// let bytes = [
575    ///     0xa1, 0xa2, 0xa3, 0xa4,
576    ///     0xb1, 0xb2,
577    ///     0xc1, 0xc2,
578    ///     0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
579    /// ];
580    ///
581    /// let uuid = Builder::from_slice(&bytes)?.into_uuid();
582    ///
583    /// assert_eq!(
584    ///     "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
585    ///     uuid.hyphenated().to_string(),
586    /// );
587    /// # Ok(())
588    /// # }
589    /// ```
590    pub fn from_slice(b: &[u8]) -> Result<Self, Error> {
591        Ok(Builder(Uuid::from_slice(b)?))
592    }
593
594    /// Creates a `Builder` using the supplied bytes in little endian order.
595    ///
596    /// The individual fields encoded in the buffer will be flipped.
597    ///
598    /// # Errors
599    ///
600    /// This function will return an error if `b` has any length other than 16.
601    ///
602    /// # Examples
603    ///
604    /// Basic usage:
605    ///
606    /// ```
607    /// # use uuid::Builder;
608    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
609    /// let bytes = [
610    ///     0xa1, 0xa2, 0xa3, 0xa4,
611    ///     0xb1, 0xb2,
612    ///     0xc1, 0xc2,
613    ///     0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
614    /// ];
615    ///
616    /// let uuid = Builder::from_slice_le(&bytes)?.into_uuid();
617    ///
618    /// assert_eq!(
619    ///     "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
620    ///     uuid.hyphenated().to_string(),
621    /// );
622    /// # Ok(())
623    /// # }
624    /// ```
625    pub fn from_slice_le(b: &[u8]) -> Result<Self, Error> {
626        Ok(Builder(Uuid::from_slice_le(b)?))
627    }
628
629    /// Creates a `Builder` from four field values.
630    ///
631    /// # Examples
632    ///
633    /// Basic usage:
634    ///
635    /// ```
636    /// # use uuid::Builder;
637    /// let d1 = 0xa1a2a3a4;
638    /// let d2 = 0xb1b2;
639    /// let d3 = 0xc1c2;
640    /// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
641    ///
642    /// let uuid = Builder::from_fields(d1, d2, d3, &d4).into_uuid();
643    ///
644    /// assert_eq!(
645    ///     uuid.hyphenated().to_string(),
646    ///     "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8"
647    /// );
648    /// ```
649    pub const fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Self {
650        Builder(Uuid::from_fields(d1, d2, d3, d4))
651    }
652
653    /// Creates a `Builder` from four field values.
654    ///
655    /// # Examples
656    ///
657    /// Basic usage:
658    ///
659    /// ```
660    /// # use uuid::Builder;
661    /// let d1 = 0xa1a2a3a4;
662    /// let d2 = 0xb1b2;
663    /// let d3 = 0xc1c2;
664    /// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
665    ///
666    /// let uuid = Builder::from_fields_le(d1, d2, d3, &d4).into_uuid();
667    ///
668    /// assert_eq!(
669    ///     uuid.hyphenated().to_string(),
670    ///     "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8"
671    /// );
672    /// ```
673    pub const fn from_fields_le(
674        d1: u32,
675        d2: u16,
676        d3: u16,
677        d4: &[u8; 8],
678    ) -> Self {
679        Builder(Uuid::from_fields_le(d1, d2, d3, d4))
680    }
681
682    /// Creates a `Builder` from a 128bit value.
683    ///
684    /// # Examples
685    ///
686    /// Basic usage:
687    ///
688    /// ```
689    /// # use uuid::Builder;
690    /// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
691    ///
692    /// let uuid = Builder::from_u128(v).into_uuid();
693    ///
694    /// assert_eq!(
695    ///     "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
696    ///     uuid.hyphenated().to_string(),
697    /// );
698    /// ```
699    pub const fn from_u128(v: u128) -> Self {
700        Builder(Uuid::from_u128(v))
701    }
702
703    /// Creates a UUID from a 128bit value in little-endian order.
704    ///
705    /// # Examples
706    ///
707    /// Basic usage:
708    ///
709    /// ```
710    /// # use uuid::Builder;
711    /// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
712    ///
713    /// let uuid = Builder::from_u128_le(v).into_uuid();
714    ///
715    /// assert_eq!(
716    ///     "d8d7d6d5-d4d3-d2d1-c2c1-b2b1a4a3a2a1",
717    ///     uuid.hyphenated().to_string(),
718    /// );
719    /// ```
720    pub const fn from_u128_le(v: u128) -> Self {
721        Builder(Uuid::from_u128_le(v))
722    }
723
724    /// Creates a `Builder` with an initial [`Uuid::nil`].
725    ///
726    /// # Examples
727    ///
728    /// Basic usage:
729    ///
730    /// ```
731    /// # use uuid::Builder;
732    /// let uuid = Builder::nil().into_uuid();
733    ///
734    /// assert_eq!(
735    ///     "00000000-0000-0000-0000-000000000000",
736    ///     uuid.hyphenated().to_string(),
737    /// );
738    /// ```
739    pub const fn nil() -> Self {
740        Builder(Uuid::nil())
741    }
742
743    /// Specifies the variant of the UUID.
744    pub fn set_variant(&mut self, v: Variant) -> &mut Self {
745        *self = Builder(self.0).with_variant(v);
746        self
747    }
748
749    /// Specifies the variant of the UUID.
750    pub const fn with_variant(mut self, v: Variant) -> Self {
751        let byte = (self.0).0[8];
752
753        (self.0).0[8] = match v {
754            Variant::NCS => byte & 0x7f,
755            Variant::RFC4122 => (byte & 0x3f) | 0x80,
756            Variant::Microsoft => (byte & 0x1f) | 0xc0,
757            Variant::Future => byte | 0xe0,
758        };
759
760        self
761    }
762
763    /// Specifies the version number of the UUID.
764    pub fn set_version(&mut self, v: Version) -> &mut Self {
765        *self = Builder(self.0).with_version(v);
766        self
767    }
768
769    /// Specifies the version number of the UUID.
770    pub const fn with_version(mut self, v: Version) -> Self {
771        (self.0).0[6] = ((self.0).0[6] & 0x0f) | ((v as u8) << 4);
772
773        self
774    }
775
776    /// Get a reference to the underlying [`Uuid`].
777    ///
778    /// # Examples
779    ///
780    /// Basic usage:
781    ///
782    /// ```
783    /// # use uuid::Builder;
784    /// let builder = Builder::nil();
785    ///
786    /// let uuid1 = builder.as_uuid();
787    /// let uuid2 = builder.as_uuid();
788    ///
789    /// assert_eq!(uuid1, uuid2);
790    /// ```
791    pub const fn as_uuid(&self) -> &Uuid {
792        &self.0
793    }
794
795    /// Convert the builder into a [`Uuid`].
796    ///
797    /// # Examples
798    ///
799    /// Basic usage:
800    ///
801    /// ```
802    /// # use uuid::Builder;
803    /// let uuid = Builder::nil().into_uuid();
804    ///
805    /// assert_eq!(
806    ///     uuid.hyphenated().to_string(),
807    ///     "00000000-0000-0000-0000-000000000000"
808    /// );
809    /// ```
810    pub const fn into_uuid(self) -> Uuid {
811        self.0
812    }
813}