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