// Copyright 2013-2014 The Rust Project Developers. // Copyright 2018 The Uuid Project Developers. // // See the COPYRIGHT file at the top-level directory of this distribution. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. //! A Builder type for [`Uuid`]s. //! //! [`Uuid`]: ../struct.Uuid.html mod error; pub(crate) use self::error::Error; use crate::prelude::*; impl Uuid { /// The 'nil UUID'. /// /// The nil UUID is special form of UUID that is specified to have all /// 128 bits set to zero, as defined in [IETF RFC 4122 Section 4.1.7][RFC]. /// /// [RFC]: https://tools.ietf.org/html/rfc4122.html#section-4.1.7 /// /// # Examples /// /// Basic usage: /// /// ``` /// use uuid::Uuid; /// /// let uuid = Uuid::nil(); /// /// assert_eq!( /// uuid.to_hyphenated().to_string(), /// "00000000-0000-0000-0000-000000000000" /// ); /// ``` pub const fn nil() -> Self { Uuid::from_bytes([0; 16]) } /// Creates a UUID from four field values in big-endian order. /// /// # Errors /// /// This function will return an error if `d4`'s length is not 8 bytes. /// /// # Examples /// /// Basic usage: /// /// ``` /// use uuid::Uuid; /// /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; /// /// let uuid = Uuid::from_fields(42, 12, 5, &d4); /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string()); /// /// let expected_uuid = /// Ok(String::from("0000002a-000c-0005-0c03-0938362b0809")); /// /// assert_eq!(expected_uuid, uuid); /// ``` pub fn from_fields( d1: u32, d2: u16, d3: u16, d4: &[u8], ) -> Result { const D4_LEN: usize = 8; let len = d4.len(); if len != D4_LEN { Err(Error::new(D4_LEN, len))?; } Ok(Uuid::from_bytes([ (d1 >> 24) as u8, (d1 >> 16) as u8, (d1 >> 8) as u8, d1 as u8, (d2 >> 8) as u8, d2 as u8, (d3 >> 8) as u8, d3 as u8, d4[0], d4[1], d4[2], d4[3], d4[4], d4[5], d4[6], d4[7], ])) } /// Creates a UUID from four field values in little-endian order. /// /// The bytes in the `d1`, `d2` and `d3` fields will /// be converted into big-endian order. /// /// # Examples /// /// ``` /// use uuid::Uuid; /// /// let d1 = 0xAB3F1097u32; /// let d2 = 0x501Eu16; /// let d3 = 0xB736u16; /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; /// /// let uuid = Uuid::from_fields_le(d1, d2, d3, &d4); /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string()); /// /// let expected_uuid = /// Ok(String::from("97103fab-1e50-36b7-0c03-0938362b0809")); /// /// assert_eq!(expected_uuid, uuid); /// ``` pub fn from_fields_le( d1: u32, d2: u16, d3: u16, d4: &[u8], ) -> Result { const D4_LEN: usize = 8; let len = d4.len(); if len != D4_LEN { Err(Error::new(D4_LEN, len))?; } Ok(Uuid::from_bytes([ d1 as u8, (d1 >> 8) as u8, (d1 >> 16) as u8, (d1 >> 24) as u8, (d2) as u8, (d2 >> 8) as u8, d3 as u8, (d3 >> 8) as u8, d4[0], d4[1], d4[2], d4[3], d4[4], d4[5], d4[6], d4[7], ])) } /// Creates a UUID from a 128bit value in big-endian order. pub const fn from_u128(v: u128) -> Self { Uuid::from_bytes([ (v >> 120) as u8, (v >> 112) as u8, (v >> 104) as u8, (v >> 96) as u8, (v >> 88) as u8, (v >> 80) as u8, (v >> 72) as u8, (v >> 64) as u8, (v >> 56) as u8, (v >> 48) as u8, (v >> 40) as u8, (v >> 32) as u8, (v >> 24) as u8, (v >> 16) as u8, (v >> 8) as u8, v as u8, ]) } /// Creates a UUID from a 128bit value in little-endian order. pub const fn from_u128_le(v: u128) -> Self { Uuid::from_bytes([ v as u8, (v >> 8) as u8, (v >> 16) as u8, (v >> 24) as u8, (v >> 32) as u8, (v >> 40) as u8, (v >> 48) as u8, (v >> 56) as u8, (v >> 64) as u8, (v >> 72) as u8, (v >> 80) as u8, (v >> 88) as u8, (v >> 96) as u8, (v >> 104) as u8, (v >> 112) as u8, (v >> 120) as u8, ]) } /// Creates a UUID using the supplied big-endian bytes. /// /// # Errors /// /// This function will return an error if `b` has any length other than 16. /// /// # Examples /// /// Basic usage: /// /// ``` /// use uuid::Uuid; /// /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87]; /// /// let uuid = Uuid::from_slice(&bytes); /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string()); /// /// let expected_uuid = /// Ok(String::from("0436430c-2b02-624c-2032-570501212b57")); /// /// assert_eq!(expected_uuid, uuid); /// ``` /// /// An incorrect number of bytes: /// /// ``` /// use uuid::Uuid; /// /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76]; /// /// let uuid = Uuid::from_slice(&bytes); /// /// assert!(uuid.is_err()); /// ``` pub fn from_slice(b: &[u8]) -> Result { const BYTES_LEN: usize = 16; let len = b.len(); if len != BYTES_LEN { Err(Error::new(BYTES_LEN, len))?; } let mut bytes: Bytes = [0; 16]; bytes.copy_from_slice(b); Ok(Uuid::from_bytes(bytes)) } /// Creates a UUID using the supplied big-endian bytes. pub const fn from_bytes(bytes: Bytes) -> Uuid { Uuid(bytes) } } /// A builder struct for creating a UUID. /// /// # Examples /// /// Creating a v4 UUID from externally generated bytes: /// /// ``` /// use uuid::{Builder, Variant, Version}; /// /// # let rng = || [ /// # 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, /// # 145, 63, 62, /// # ]; /// let random_bytes = rng(); /// let uuid = Builder::from_bytes(random_bytes) /// .set_variant(Variant::RFC4122) /// .set_version(Version::Random) /// .build(); /// ``` // TODO: remove in 1.0.0 #[allow(dead_code)] #[deprecated] pub type Builder = crate::Builder; impl crate::Builder { /// Creates a `Builder` using the supplied big-endian bytes. /// /// # Examples /// /// Basic usage: /// /// ``` /// let bytes: uuid::Bytes = [ /// 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, 145, 63, 62, /// ]; /// /// let mut builder = uuid::Builder::from_bytes(bytes); /// let uuid = builder.build().to_hyphenated().to_string(); /// /// let expected_uuid = String::from("46ebd0ee-0e6d-43c9-b90d-ccc35a913f3e"); /// /// assert_eq!(expected_uuid, uuid); /// ``` /// /// An incorrect number of bytes: /// /// ```compile_fail /// let bytes: uuid::Bytes = [4, 54, 67, 12, 43, 2, 98, 76]; // doesn't compile /// /// let uuid = uuid::Builder::from_bytes(bytes); /// ``` pub const fn from_bytes(b: Bytes) -> Self { Builder(b) } /// Creates a `Builder` using the supplied big-endian bytes. /// /// # Errors /// /// This function will return an error if `b` has any length other than 16. /// /// # Examples /// /// Basic usage: /// /// ``` /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87]; /// /// let builder = uuid::Builder::from_slice(&bytes); /// let uuid = /// builder.map(|mut builder| builder.build().to_hyphenated().to_string()); /// /// let expected_uuid = /// Ok(String::from("0436430c-2b02-624c-2032-570501212b57")); /// /// assert_eq!(expected_uuid, uuid); /// ``` /// /// An incorrect number of bytes: /// /// ``` /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76]; /// /// let builder = uuid::Builder::from_slice(&bytes); /// /// assert!(builder.is_err()); /// ``` pub fn from_slice(b: &[u8]) -> Result { const BYTES_LEN: usize = 16; let len = b.len(); if len != BYTES_LEN { Err(Error::new(BYTES_LEN, len))?; } let mut bytes: crate::Bytes = [0; 16]; bytes.copy_from_slice(b); Ok(Self::from_bytes(bytes)) } /// Creates a `Builder` from four big-endian field values. /// /// # Errors /// /// This function will return an error if `d4`'s length is not 8 bytes. /// /// # Examples /// /// Basic usage: /// /// ``` /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; /// /// let builder = uuid::Builder::from_fields(42, 12, 5, &d4); /// let uuid = /// builder.map(|mut builder| builder.build().to_hyphenated().to_string()); /// /// let expected_uuid = /// Ok(String::from("0000002a-000c-0005-0c03-0938362b0809")); /// /// assert_eq!(expected_uuid, uuid); /// ``` /// /// An invalid length: /// /// ``` /// let d4 = [12]; /// /// let builder = uuid::Builder::from_fields(42, 12, 5, &d4); /// /// assert!(builder.is_err()); /// ``` pub fn from_fields( d1: u32, d2: u16, d3: u16, d4: &[u8], ) -> Result { Uuid::from_fields(d1, d2, d3, d4).map(|uuid| { let bytes = *uuid.as_bytes(); crate::Builder::from_bytes(bytes) }) } /// Creates a `Builder` from a big-endian 128bit value. pub fn from_u128(v: u128) -> Self { crate::Builder::from_bytes(*Uuid::from_u128(v).as_bytes()) } /// Creates a `Builder` with an initial [`Uuid::nil`]. /// /// # Examples /// /// Basic usage: /// /// ``` /// use uuid::Builder; /// /// let mut builder = Builder::nil(); /// /// assert_eq!( /// builder.build().to_hyphenated().to_string(), /// "00000000-0000-0000-0000-000000000000" /// ); /// ``` pub const fn nil() -> Self { Builder([0; 16]) } /// Specifies the variant of the UUID. pub fn set_variant(&mut self, v: crate::Variant) -> &mut Self { let byte = self.0[8]; self.0[8] = match v { crate::Variant::NCS => byte & 0x7f, crate::Variant::RFC4122 => (byte & 0x3f) | 0x80, crate::Variant::Microsoft => (byte & 0x1f) | 0xc0, crate::Variant::Future => (byte & 0x1f) | 0xe0, }; self } /// Specifies the version number of the UUID. pub fn set_version(&mut self, v: crate::Version) -> &mut Self { self.0[6] = (self.0[6] & 0x0f) | ((v as u8) << 4); self } /// Hands over the internal constructed [`Uuid`]. /// /// # Examples /// /// Basic usage: /// /// ``` /// use uuid::Builder; /// /// let uuid = Builder::nil().build(); /// /// assert_eq!( /// uuid.to_hyphenated().to_string(), /// "00000000-0000-0000-0000-000000000000" /// ); /// ``` /// /// [`Uuid`]: struct.Uuid.html pub fn build(&mut self) -> Uuid { Uuid::from_bytes(self.0) } }