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 /// ``` nil() -> Self43 pub const fn nil() -> Self { 44 Uuid::from_bytes([0; 16]) 45 } 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 /// ``` from_fields( d1: u32, d2: u16, d3: u16, d4: &[u8], ) -> Result<Uuid, crate::Error>70 pub fn from_fields( 71 d1: u32, 72 d2: u16, 73 d3: u16, 74 d4: &[u8], 75 ) -> Result<Uuid, crate::Error> { 76 const D4_LEN: usize = 8; 77 78 let len = d4.len(); 79 80 if len != D4_LEN { 81 Err(Error::new(D4_LEN, len))?; 82 } 83 84 Ok(Uuid::from_bytes([ 85 (d1 >> 24) as u8, 86 (d1 >> 16) as u8, 87 (d1 >> 8) as u8, 88 d1 as u8, 89 (d2 >> 8) as u8, 90 d2 as u8, 91 (d3 >> 8) as u8, 92 d3 as u8, 93 d4[0], 94 d4[1], 95 d4[2], 96 d4[3], 97 d4[4], 98 d4[5], 99 d4[6], 100 d4[7], 101 ])) 102 } 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 /// ``` from_fields_le( d1: u32, d2: u16, d3: u16, d4: &[u8], ) -> Result<Uuid, crate::Error>127 pub fn from_fields_le( 128 d1: u32, 129 d2: u16, 130 d3: u16, 131 d4: &[u8], 132 ) -> Result<Uuid, crate::Error> { 133 const D4_LEN: usize = 8; 134 135 let len = d4.len(); 136 137 if len != D4_LEN { 138 Err(Error::new(D4_LEN, len))?; 139 } 140 141 Ok(Uuid::from_bytes([ 142 d1 as u8, 143 (d1 >> 8) as u8, 144 (d1 >> 16) as u8, 145 (d1 >> 24) as u8, 146 (d2) as u8, 147 (d2 >> 8) as u8, 148 d3 as u8, 149 (d3 >> 8) as u8, 150 d4[0], 151 d4[1], 152 d4[2], 153 d4[3], 154 d4[4], 155 d4[5], 156 d4[6], 157 d4[7], 158 ])) 159 } 160 161 /// Creates a UUID from a 128bit value in big-endian order. from_u128(v: u128) -> Self162 pub const fn from_u128(v: u128) -> Self { 163 Uuid::from_bytes([ 164 (v >> 120) as u8, 165 (v >> 112) as u8, 166 (v >> 104) as u8, 167 (v >> 96) as u8, 168 (v >> 88) as u8, 169 (v >> 80) as u8, 170 (v >> 72) as u8, 171 (v >> 64) as u8, 172 (v >> 56) as u8, 173 (v >> 48) as u8, 174 (v >> 40) as u8, 175 (v >> 32) as u8, 176 (v >> 24) as u8, 177 (v >> 16) as u8, 178 (v >> 8) as u8, 179 v as u8, 180 ]) 181 } 182 183 /// Creates a UUID from a 128bit value in little-endian order. from_u128_le(v: u128) -> Self184 pub const fn from_u128_le(v: u128) -> Self { 185 Uuid::from_bytes([ 186 v as u8, 187 (v >> 8) as u8, 188 (v >> 16) as u8, 189 (v >> 24) as u8, 190 (v >> 32) as u8, 191 (v >> 40) as u8, 192 (v >> 48) as u8, 193 (v >> 56) as u8, 194 (v >> 64) as u8, 195 (v >> 72) as u8, 196 (v >> 80) as u8, 197 (v >> 88) as u8, 198 (v >> 96) as u8, 199 (v >> 104) as u8, 200 (v >> 112) as u8, 201 (v >> 120) as u8, 202 ]) 203 } 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 /// ``` from_slice(b: &[u8]) -> Result<Uuid, crate::Error>240 pub fn from_slice(b: &[u8]) -> Result<Uuid, crate::Error> { 241 const BYTES_LEN: usize = 16; 242 243 let len = b.len(); 244 245 if len != BYTES_LEN { 246 Err(Error::new(BYTES_LEN, len))?; 247 } 248 249 let mut bytes: Bytes = [0; 16]; 250 bytes.copy_from_slice(b); 251 Ok(Uuid::from_bytes(bytes)) 252 } 253 254 /// Creates a UUID using the supplied big-endian bytes. from_bytes(bytes: Bytes) -> Uuid255 pub const fn from_bytes(bytes: Bytes) -> Uuid { 256 Uuid(bytes) 257 } 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 /// ``` from_bytes(b: Bytes) -> Self311 pub const fn from_bytes(b: Bytes) -> Self { 312 Builder(b) 313 } 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 /// ``` from_slice(b: &[u8]) -> Result<Self, crate::Error>347 pub fn from_slice(b: &[u8]) -> Result<Self, crate::Error> { 348 const BYTES_LEN: usize = 16; 349 350 let len = b.len(); 351 352 if len != BYTES_LEN { 353 Err(Error::new(BYTES_LEN, len))?; 354 } 355 356 let mut bytes: crate::Bytes = [0; 16]; 357 bytes.copy_from_slice(b); 358 Ok(Self::from_bytes(bytes)) 359 } 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 /// ``` from_fields( d1: u32, d2: u16, d3: u16, d4: &[u8], ) -> Result<Self, crate::Error>393 pub fn from_fields( 394 d1: u32, 395 d2: u16, 396 d3: u16, 397 d4: &[u8], 398 ) -> Result<Self, crate::Error> { 399 Uuid::from_fields(d1, d2, d3, d4).map(|uuid| { 400 let bytes = *uuid.as_bytes(); 401 402 crate::Builder::from_bytes(bytes) 403 }) 404 } 405 406 /// Creates a `Builder` from a big-endian 128bit value. from_u128(v: u128) -> Self407 pub fn from_u128(v: u128) -> Self { 408 crate::Builder::from_bytes(*Uuid::from_u128(v).as_bytes()) 409 } 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 /// ``` nil() -> Self427 pub const fn nil() -> Self { 428 Builder([0; 16]) 429 } 430 431 /// Specifies the variant of the UUID. set_variant(&mut self, v: crate::Variant) -> &mut Self432 pub fn set_variant(&mut self, v: crate::Variant) -> &mut Self { 433 let byte = self.0[8]; 434 435 self.0[8] = match v { 436 crate::Variant::NCS => byte & 0x7f, 437 crate::Variant::RFC4122 => (byte & 0x3f) | 0x80, 438 crate::Variant::Microsoft => (byte & 0x1f) | 0xc0, 439 crate::Variant::Future => (byte & 0x1f) | 0xe0, 440 }; 441 442 self 443 } 444 445 /// Specifies the version number of the UUID. set_version(&mut self, v: crate::Version) -> &mut Self446 pub fn set_version(&mut self, v: crate::Version) -> &mut Self { 447 self.0[6] = (self.0[6] & 0x0f) | ((v as u8) << 4); 448 449 self 450 } 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 build(&mut self) -> Uuid470 pub fn build(&mut self) -> Uuid { 471 Uuid::from_bytes(self.0) 472 } 473 } 474