Coverage Report

Created: 2021-11-03 07:11

/rust/registry/src/github.com-1ecc6299db9ec823/uuid-0.8.2/src/builder/mod.rs
Line
Count
Source (jump to first uncovered line)
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
mod error;
17
pub(crate) use self::error::Error;
18
19
use crate::prelude::*;
20
21
impl Uuid {
22
    /// The 'nil UUID'.
23
    ///
24
    /// The nil UUID is special form of UUID that is specified to have all
25
    /// 128 bits set to zero, as defined in [IETF RFC 4122 Section 4.1.7][RFC].
26
    ///
27
    /// [RFC]: https://tools.ietf.org/html/rfc4122.html#section-4.1.7
28
    ///
29
    /// # Examples
30
    ///
31
    /// Basic usage:
32
    ///
33
    /// ```
34
    /// use uuid::Uuid;
35
    ///
36
    /// let uuid = Uuid::nil();
37
    ///
38
    /// assert_eq!(
39
    ///     uuid.to_hyphenated().to_string(),
40
    ///     "00000000-0000-0000-0000-000000000000"
41
    /// );
42
    /// ```
43
0
    pub const fn nil() -> Self {
44
0
        Uuid::from_bytes([0; 16])
45
0
    }
46
47
    /// Creates a UUID from four field values in big-endian order.
48
    ///
49
    /// # Errors
50
    ///
51
    /// This function will return an error if `d4`'s length is not 8 bytes.
52
    ///
53
    /// # Examples
54
    ///
55
    /// Basic usage:
56
    ///
57
    /// ```
58
    /// use uuid::Uuid;
59
    ///
60
    /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9];
61
    ///
62
    /// let uuid = Uuid::from_fields(42, 12, 5, &d4);
63
    /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string());
64
    ///
65
    /// let expected_uuid =
66
    ///     Ok(String::from("0000002a-000c-0005-0c03-0938362b0809"));
67
    ///
68
    /// assert_eq!(expected_uuid, uuid);
69
    /// ```
70
0
    pub fn from_fields(
71
0
        d1: u32,
72
0
        d2: u16,
73
0
        d3: u16,
74
0
        d4: &[u8],
75
0
    ) -> Result<Uuid, crate::Error> {
76
0
        const D4_LEN: usize = 8;
77
0
78
0
        let len = d4.len();
79
0
80
0
        if len != D4_LEN {
81
0
            Err(Error::new(D4_LEN, len))?;
82
0
        }
83
84
0
        Ok(Uuid::from_bytes([
85
0
            (d1 >> 24) as u8,
86
0
            (d1 >> 16) as u8,
87
0
            (d1 >> 8) as u8,
88
0
            d1 as u8,
89
0
            (d2 >> 8) as u8,
90
0
            d2 as u8,
91
0
            (d3 >> 8) as u8,
92
0
            d3 as u8,
93
0
            d4[0],
94
0
            d4[1],
95
0
            d4[2],
96
0
            d4[3],
97
0
            d4[4],
98
0
            d4[5],
99
0
            d4[6],
100
0
            d4[7],
101
0
        ]))
102
0
    }
103
104
    /// Creates a UUID from four field values in little-endian order.
105
    ///
106
    /// The bytes in the `d1`, `d2` and `d3` fields will
107
    /// be converted into big-endian order.
108
    ///
109
    /// # Examples
110
    ///
111
    /// ```
112
    /// use uuid::Uuid;
113
    ///
114
    /// let d1 = 0xAB3F1097u32;
115
    /// let d2 = 0x501Eu16;
116
    /// let d3 = 0xB736u16;
117
    /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9];
118
    ///
119
    /// let uuid = Uuid::from_fields_le(d1, d2, d3, &d4);
120
    /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string());
121
    ///
122
    /// let expected_uuid =
123
    ///     Ok(String::from("97103fab-1e50-36b7-0c03-0938362b0809"));
124
    ///
125
    /// assert_eq!(expected_uuid, uuid);
126
    /// ```
127
0
    pub fn from_fields_le(
128
0
        d1: u32,
129
0
        d2: u16,
130
0
        d3: u16,
131
0
        d4: &[u8],
132
0
    ) -> Result<Uuid, crate::Error> {
133
0
        const D4_LEN: usize = 8;
134
0
135
0
        let len = d4.len();
136
0
137
0
        if len != D4_LEN {
138
0
            Err(Error::new(D4_LEN, len))?;
139
0
        }
140
141
0
        Ok(Uuid::from_bytes([
142
0
            d1 as u8,
143
0
            (d1 >> 8) as u8,
144
0
            (d1 >> 16) as u8,
145
0
            (d1 >> 24) as u8,
146
0
            (d2) as u8,
147
0
            (d2 >> 8) as u8,
148
0
            d3 as u8,
149
0
            (d3 >> 8) as u8,
150
0
            d4[0],
151
0
            d4[1],
152
0
            d4[2],
153
0
            d4[3],
154
0
            d4[4],
155
0
            d4[5],
156
0
            d4[6],
157
0
            d4[7],
158
0
        ]))
159
0
    }
160
161
    /// Creates a UUID from a 128bit value in big-endian order.
162
0
    pub const fn from_u128(v: u128) -> Self {
163
0
        Uuid::from_bytes([
164
0
            (v >> 120) as u8,
165
0
            (v >> 112) as u8,
166
0
            (v >> 104) as u8,
167
0
            (v >> 96) as u8,
168
0
            (v >> 88) as u8,
169
0
            (v >> 80) as u8,
170
0
            (v >> 72) as u8,
171
0
            (v >> 64) as u8,
172
0
            (v >> 56) as u8,
173
0
            (v >> 48) as u8,
174
0
            (v >> 40) as u8,
175
0
            (v >> 32) as u8,
176
0
            (v >> 24) as u8,
177
0
            (v >> 16) as u8,
178
0
            (v >> 8) as u8,
179
0
            v as u8,
180
0
        ])
181
0
    }
182
183
    /// Creates a UUID from a 128bit value in little-endian order.
184
0
    pub const fn from_u128_le(v: u128) -> Self {
185
0
        Uuid::from_bytes([
186
0
            v as u8,
187
0
            (v >> 8) as u8,
188
0
            (v >> 16) as u8,
189
0
            (v >> 24) as u8,
190
0
            (v >> 32) as u8,
191
0
            (v >> 40) as u8,
192
0
            (v >> 48) as u8,
193
0
            (v >> 56) as u8,
194
0
            (v >> 64) as u8,
195
0
            (v >> 72) as u8,
196
0
            (v >> 80) as u8,
197
0
            (v >> 88) as u8,
198
0
            (v >> 96) as u8,
199
0
            (v >> 104) as u8,
200
0
            (v >> 112) as u8,
201
0
            (v >> 120) as u8,
202
0
        ])
203
0
    }
204
205
    /// Creates a UUID using the supplied big-endian bytes.
206
    ///
207
    /// # Errors
208
    ///
209
    /// This function will return an error if `b` has any length other than 16.
210
    ///
211
    /// # Examples
212
    ///
213
    /// Basic usage:
214
    ///
215
    /// ```
216
    /// use uuid::Uuid;
217
    ///
218
    /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87];
219
    ///
220
    /// let uuid = Uuid::from_slice(&bytes);
221
    /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string());
222
    ///
223
    /// let expected_uuid =
224
    ///     Ok(String::from("0436430c-2b02-624c-2032-570501212b57"));
225
    ///
226
    /// assert_eq!(expected_uuid, uuid);
227
    /// ```
228
    ///
229
    /// An incorrect number of bytes:
230
    ///
231
    /// ```
232
    /// use uuid::Uuid;
233
    ///
234
    /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76];
235
    ///
236
    /// let uuid = Uuid::from_slice(&bytes);
237
    ///
238
    /// assert!(uuid.is_err());
239
    /// ```
240
46.6k
    pub fn from_slice(b: &[u8]) -> Result<Uuid, crate::Error> {
241
46.6k
        const BYTES_LEN: usize = 16;
242
46.6k
243
46.6k
        let len = b.len();
244
46.6k
245
46.6k
        if len != BYTES_LEN {
246
0
            Err(Error::new(BYTES_LEN, len))?;
247
46.6k
        }
248
249
46.6k
        let mut bytes: Bytes = [0; 16];
250
46.6k
        bytes.copy_from_slice(b);
251
46.6k
        Ok(Uuid::from_bytes(bytes))
252
46.6k
    }
253
254
    /// Creates a UUID using the supplied big-endian bytes.
255
48.5k
    pub const fn from_bytes(bytes: Bytes) -> Uuid {
256
48.5k
        Uuid(bytes)
257
48.5k
    }
258
}
259
260
/// A builder struct for creating a UUID.
261
///
262
/// # Examples
263
///
264
/// Creating a v4 UUID from externally generated bytes:
265
///
266
/// ```
267
/// use uuid::{Builder, Variant, Version};
268
///
269
/// # let rng = || [
270
/// #     70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90,
271
/// # 145, 63, 62,
272
/// # ];
273
/// let random_bytes = rng();
274
/// let uuid = Builder::from_bytes(random_bytes)
275
///     .set_variant(Variant::RFC4122)
276
///     .set_version(Version::Random)
277
///     .build();
278
/// ```
279
// TODO: remove in 1.0.0
280
#[allow(dead_code)]
281
#[deprecated]
282
pub type Builder = crate::Builder;
283
284
impl crate::Builder {
285
    /// Creates a `Builder` using the supplied big-endian bytes.
286
    ///
287
    /// # Examples
288
    ///
289
    /// Basic usage:
290
    ///
291
    /// ```
292
    /// let bytes: uuid::Bytes = [
293
    ///     70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, 145, 63, 62,
294
    /// ];
295
    ///
296
    /// let mut builder = uuid::Builder::from_bytes(bytes);
297
    /// let uuid = builder.build().to_hyphenated().to_string();
298
    ///
299
    /// let expected_uuid = String::from("46ebd0ee-0e6d-43c9-b90d-ccc35a913f3e");
300
    ///
301
    /// assert_eq!(expected_uuid, uuid);
302
    /// ```
303
    ///
304
    /// An incorrect number of bytes:
305
    ///
306
    /// ```compile_fail
307
    /// let bytes: uuid::Bytes = [4, 54, 67, 12, 43, 2, 98, 76]; // doesn't compile
308
    ///
309
    /// let uuid = uuid::Builder::from_bytes(bytes);
310
    /// ```
311
0
    pub const fn from_bytes(b: Bytes) -> Self {
312
0
        Builder(b)
313
0
    }
314
315
    /// Creates a `Builder` using the supplied big-endian bytes.
316
    ///
317
    /// # Errors
318
    ///
319
    /// This function will return an error if `b` has any length other than 16.
320
    ///
321
    /// # Examples
322
    ///
323
    /// Basic usage:
324
    ///
325
    /// ```
326
    /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87];
327
    ///
328
    /// let builder = uuid::Builder::from_slice(&bytes);
329
    /// let uuid =
330
    ///     builder.map(|mut builder| builder.build().to_hyphenated().to_string());
331
    ///
332
    /// let expected_uuid =
333
    ///     Ok(String::from("0436430c-2b02-624c-2032-570501212b57"));
334
    ///
335
    /// assert_eq!(expected_uuid, uuid);
336
    /// ```
337
    ///
338
    /// An incorrect number of bytes:
339
    ///
340
    /// ```
341
    /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76];
342
    ///
343
    /// let builder = uuid::Builder::from_slice(&bytes);
344
    ///
345
    /// assert!(builder.is_err());
346
    /// ```
347
0
    pub fn from_slice(b: &[u8]) -> Result<Self, crate::Error> {
348
0
        const BYTES_LEN: usize = 16;
349
0
350
0
        let len = b.len();
351
0
352
0
        if len != BYTES_LEN {
353
0
            Err(Error::new(BYTES_LEN, len))?;
354
0
        }
355
356
0
        let mut bytes: crate::Bytes = [0; 16];
357
0
        bytes.copy_from_slice(b);
358
0
        Ok(Self::from_bytes(bytes))
359
0
    }
360
361
    /// Creates a `Builder` from four big-endian field values.
362
    ///
363
    /// # Errors
364
    ///
365
    /// This function will return an error if `d4`'s length is not 8 bytes.
366
    ///
367
    /// # Examples
368
    ///
369
    /// Basic usage:
370
    ///
371
    /// ```
372
    /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9];
373
    ///
374
    /// let builder = uuid::Builder::from_fields(42, 12, 5, &d4);
375
    /// let uuid =
376
    ///     builder.map(|mut builder| builder.build().to_hyphenated().to_string());
377
    ///
378
    /// let expected_uuid =
379
    ///     Ok(String::from("0000002a-000c-0005-0c03-0938362b0809"));
380
    ///
381
    /// assert_eq!(expected_uuid, uuid);
382
    /// ```
383
    ///
384
    /// An invalid length:
385
    ///
386
    /// ```
387
    /// let d4 = [12];
388
    ///
389
    /// let builder = uuid::Builder::from_fields(42, 12, 5, &d4);
390
    ///
391
    /// assert!(builder.is_err());
392
    /// ```
393
0
    pub fn from_fields(
394
0
        d1: u32,
395
0
        d2: u16,
396
0
        d3: u16,
397
0
        d4: &[u8],
398
0
    ) -> Result<Self, crate::Error> {
399
0
        Uuid::from_fields(d1, d2, d3, d4).map(|uuid| {
400
0
            let bytes = *uuid.as_bytes();
401
0
402
0
            crate::Builder::from_bytes(bytes)
403
0
        })
404
0
    }
405
406
    /// Creates a `Builder` from a big-endian 128bit value.
407
0
    pub fn from_u128(v: u128) -> Self {
408
0
        crate::Builder::from_bytes(*Uuid::from_u128(v).as_bytes())
409
0
    }
410
411
    /// Creates a `Builder` with an initial [`Uuid::nil`].
412
    ///
413
    /// # Examples
414
    ///
415
    /// Basic usage:
416
    ///
417
    /// ```
418
    /// use uuid::Builder;
419
    ///
420
    /// let mut builder = Builder::nil();
421
    ///
422
    /// assert_eq!(
423
    ///     builder.build().to_hyphenated().to_string(),
424
    ///     "00000000-0000-0000-0000-000000000000"
425
    /// );
426
    /// ```
427
0
    pub const fn nil() -> Self {
428
0
        Builder([0; 16])
429
0
    }
430
431
    /// Specifies the variant of the UUID.
432
0
    pub fn set_variant(&mut self, v: crate::Variant) -> &mut Self {
433
0
        let byte = self.0[8];
434
435
0
        self.0[8] = match v {
436
0
            crate::Variant::NCS => byte & 0x7f,
437
0
            crate::Variant::RFC4122 => (byte & 0x3f) | 0x80,
438
0
            crate::Variant::Microsoft => (byte & 0x1f) | 0xc0,
439
0
            crate::Variant::Future => (byte & 0x1f) | 0xe0,
440
        };
441
442
0
        self
443
0
    }
444
445
    /// Specifies the version number of the UUID.
446
0
    pub fn set_version(&mut self, v: crate::Version) -> &mut Self {
447
0
        self.0[6] = (self.0[6] & 0x0f) | ((v as u8) << 4);
448
0
449
0
        self
450
0
    }
451
452
    /// Hands over the internal constructed [`Uuid`].
453
    ///
454
    /// # Examples
455
    ///
456
    /// Basic usage:
457
    ///
458
    /// ```
459
    /// use uuid::Builder;
460
    ///
461
    /// let uuid = Builder::nil().build();
462
    ///
463
    /// assert_eq!(
464
    ///     uuid.to_hyphenated().to_string(),
465
    ///     "00000000-0000-0000-0000-000000000000"
466
    /// );
467
    /// ```
468
    ///
469
    /// [`Uuid`]: struct.Uuid.html
470
0
    pub fn build(&mut self) -> Uuid {
471
0
        Uuid::from_bytes(self.0)
472
0
    }
473
}