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 | |
16 | use 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)] |
47 | pub struct Builder(Uuid); |
48 | |
49 | impl 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 | |
493 | impl 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 | |