// 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. //! Adapters for alternative string formats. use crate::{ std::{borrow::Borrow, fmt, ptr, str}, Uuid, Variant, }; impl std::fmt::Debug for Uuid { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::LowerHex::fmt(self, f) } } impl fmt::Display for Uuid { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::LowerHex::fmt(self, f) } } impl fmt::Display for Variant { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { Variant::NCS => write!(f, "NCS"), Variant::RFC4122 => write!(f, "RFC4122"), Variant::Microsoft => write!(f, "Microsoft"), Variant::Future => write!(f, "Future"), } } } impl fmt::LowerHex for Uuid { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::LowerHex::fmt(self.as_hyphenated(), f) } } impl fmt::UpperHex for Uuid { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::UpperHex::fmt(self.as_hyphenated(), f) } } /// Format a [`Uuid`] as a hyphenated string, like /// `67e55044-10b1-426f-9247-bb680e5fe0c8`. #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] #[repr(transparent)] pub struct Hyphenated(Uuid); /// Format a [`Uuid`] as a simple string, like /// `67e5504410b1426f9247bb680e5fe0c8`. #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] #[repr(transparent)] pub struct Simple(Uuid); /// Format a [`Uuid`] as a URN string, like /// `urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8`. #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] #[repr(transparent)] pub struct Urn(Uuid); /// Format a [`Uuid`] as a braced hyphenated string, like /// `{67e55044-10b1-426f-9247-bb680e5fe0c8}`. #[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)] #[repr(transparent)] pub struct Braced(Uuid); impl Uuid { /// Get a [`Hyphenated`] formatter. #[inline] pub const fn hyphenated(self) -> Hyphenated { Hyphenated(self) } /// Get a borrowed [`Hyphenated`] formatter. #[inline] pub fn as_hyphenated(&self) -> &Hyphenated { // SAFETY: `Uuid` and `Hyphenated` have the same ABI unsafe { &*(self as *const Uuid as *const Hyphenated) } } /// Get a [`Simple`] formatter. #[inline] pub const fn simple(self) -> Simple { Simple(self) } /// Get a borrowed [`Simple`] formatter. #[inline] pub fn as_simple(&self) -> &Simple { // SAFETY: `Uuid` and `Simple` have the same ABI unsafe { &*(self as *const Uuid as *const Simple) } } /// Get a [`Urn`] formatter. #[inline] pub const fn urn(self) -> Urn { Urn(self) } /// Get a borrowed [`Urn`] formatter. #[inline] pub fn as_urn(&self) -> &Urn { // SAFETY: `Uuid` and `Urn` have the same ABI unsafe { &*(self as *const Uuid as *const Urn) } } /// Get a [`Braced`] formatter. #[inline] pub const fn braced(self) -> Braced { Braced(self) } /// Get a borrowed [`Braced`] formatter. #[inline] pub fn as_braced(&self) -> &Braced { // SAFETY: `Uuid` and `Braced` have the same ABI unsafe { &*(self as *const Uuid as *const Braced) } } } const UPPER: [u8; 16] = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'A', b'B', b'C', b'D', b'E', b'F', ]; const LOWER: [u8; 16] = [ b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b', b'c', b'd', b'e', b'f', ]; #[inline] const fn format_simple(src: &[u8; 16], upper: bool) -> [u8; 32] { let lut = if upper { &UPPER } else { &LOWER }; let mut dst = [0; 32]; let mut i = 0; while i < 16 { let x = src[i]; dst[i * 2] = lut[(x >> 4) as usize]; dst[i * 2 + 1] = lut[(x & 0x0f) as usize]; i += 1; } dst } #[inline] const fn format_hyphenated(src: &[u8; 16], upper: bool) -> [u8; 36] { let lut = if upper { &UPPER } else { &LOWER }; let groups = [(0, 8), (9, 13), (14, 18), (19, 23), (24, 36)]; let mut dst = [0; 36]; let mut group_idx = 0; let mut i = 0; while group_idx < 5 { let (start, end) = groups[group_idx]; let mut j = start; while j < end { let x = src[i]; i += 1; dst[j] = lut[(x >> 4) as usize]; dst[j + 1] = lut[(x & 0x0f) as usize]; j += 2; } if group_idx < 4 { dst[end] = b'-'; } group_idx += 1; } dst } #[inline] fn encode_simple<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str { let buf = &mut buffer[..Simple::LENGTH]; let dst = buf.as_mut_ptr(); // SAFETY: `buf` is guaranteed to be at least `LEN` bytes // SAFETY: The encoded buffer is ASCII encoded unsafe { ptr::write(dst.cast(), format_simple(src, upper)); str::from_utf8_unchecked_mut(buf) } } #[inline] fn encode_hyphenated<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str { let buf = &mut buffer[..Hyphenated::LENGTH]; let dst = buf.as_mut_ptr(); // SAFETY: `buf` is guaranteed to be at least `LEN` bytes // SAFETY: The encoded buffer is ASCII encoded unsafe { ptr::write(dst.cast(), format_hyphenated(src, upper)); str::from_utf8_unchecked_mut(buf) } } #[inline] fn encode_braced<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str { let buf = &mut buffer[..Braced::LENGTH]; buf[0] = b'{'; buf[Braced::LENGTH - 1] = b'}'; // SAFETY: `buf` is guaranteed to be at least `LEN` bytes // SAFETY: The encoded buffer is ASCII encoded unsafe { let dst = buf.as_mut_ptr().add(1); ptr::write(dst.cast(), format_hyphenated(src, upper)); str::from_utf8_unchecked_mut(buf) } } #[inline] fn encode_urn<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str { let buf = &mut buffer[..Urn::LENGTH]; buf[..9].copy_from_slice(b"urn:uuid:"); // SAFETY: `buf` is guaranteed to be at least `LEN` bytes // SAFETY: The encoded buffer is ASCII encoded unsafe { let dst = buf.as_mut_ptr().add(9); ptr::write(dst.cast(), format_hyphenated(src, upper)); str::from_utf8_unchecked_mut(buf) } } impl Hyphenated { /// The length of a hyphenated [`Uuid`] string. /// /// [`Uuid`]: ../struct.Uuid.html pub const LENGTH: usize = 36; /// Creates a [`Hyphenated`] from a [`Uuid`]. /// /// [`Uuid`]: ../struct.Uuid.html /// [`Hyphenated`]: struct.Hyphenated.html pub const fn from_uuid(uuid: Uuid) -> Self { Hyphenated(uuid) } /// Writes the [`Uuid`] as a lower-case hyphenated string to /// `buffer`, and returns the subslice of the buffer that contains the /// encoded UUID. /// /// This is slightly more efficient than using the formatting /// infrastructure as it avoids virtual calls, and may avoid /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html /// /// # Panics /// /// Panics if the buffer is not large enough: it must have length at least /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a /// sufficiently-large temporary buffer. /// /// [`LENGTH`]: #associatedconstant.LENGTH /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// fn main() -> Result<(), uuid::Error> { /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?; /// /// // the encoded portion is returned /// assert_eq!( /// uuid.hyphenated() /// .encode_lower(&mut Uuid::encode_buffer()), /// "936da01f-9abd-4d9d-80c7-02af85c822a8" /// ); /// /// // the buffer is mutated directly, and trailing contents remains /// let mut buf = [b'!'; 40]; /// uuid.hyphenated().encode_lower(&mut buf); /// assert_eq!( /// &buf as &[_], /// b"936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] /// ); /// /// Ok(()) /// } /// ``` /// */ #[inline] pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode_hyphenated(self.0.as_bytes(), buffer, false) } /// Writes the [`Uuid`] as an upper-case hyphenated string to /// `buffer`, and returns the subslice of the buffer that contains the /// encoded UUID. /// /// This is slightly more efficient than using the formatting /// infrastructure as it avoids virtual calls, and may avoid /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html /// /// # Panics /// /// Panics if the buffer is not large enough: it must have length at least /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a /// sufficiently-large temporary buffer. /// /// [`LENGTH`]: #associatedconstant.LENGTH /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// fn main() -> Result<(), uuid::Error> { /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?; /// /// // the encoded portion is returned /// assert_eq!( /// uuid.hyphenated() /// .encode_upper(&mut Uuid::encode_buffer()), /// "936DA01F-9ABD-4D9D-80C7-02AF85C822A8" /// ); /// /// // the buffer is mutated directly, and trailing contents remains /// let mut buf = [b'!'; 40]; /// uuid.hyphenated().encode_upper(&mut buf); /// assert_eq!( /// &buf as &[_], /// b"936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] /// ); /// /// Ok(()) /// } /// ``` /// */ #[inline] pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode_hyphenated(self.0.as_bytes(), buffer, true) } /// Get a reference to the underlying [`Uuid`]. /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// let hyphenated = Uuid::nil().hyphenated(); /// assert_eq!(*hyphenated.as_uuid(), Uuid::nil()); /// ``` pub const fn as_uuid(&self) -> &Uuid { &self.0 } /// Consumes the [`Hyphenated`], returning the underlying [`Uuid`]. /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// let hyphenated = Uuid::nil().hyphenated(); /// assert_eq!(hyphenated.into_uuid(), Uuid::nil()); /// ``` pub const fn into_uuid(self) -> Uuid { self.0 } } impl Braced { /// The length of a braced [`Uuid`] string. /// /// [`Uuid`]: ../struct.Uuid.html pub const LENGTH: usize = 38; /// Creates a [`Braced`] from a [`Uuid`]. /// /// [`Uuid`]: ../struct.Uuid.html /// [`Braced`]: struct.Braced.html pub const fn from_uuid(uuid: Uuid) -> Self { Braced(uuid) } /// Writes the [`Uuid`] as a lower-case hyphenated string surrounded by /// braces to `buffer`, and returns the subslice of the buffer that contains /// the encoded UUID. /// /// This is slightly more efficient than using the formatting /// infrastructure as it avoids virtual calls, and may avoid /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html /// /// # Panics /// /// Panics if the buffer is not large enough: it must have length at least /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a /// sufficiently-large temporary buffer. /// /// [`LENGTH`]: #associatedconstant.LENGTH /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// fn main() -> Result<(), uuid::Error> { /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?; /// /// // the encoded portion is returned /// assert_eq!( /// uuid.braced() /// .encode_lower(&mut Uuid::encode_buffer()), /// "{936da01f-9abd-4d9d-80c7-02af85c822a8}" /// ); /// /// // the buffer is mutated directly, and trailing contents remains /// let mut buf = [b'!'; 40]; /// uuid.braced().encode_lower(&mut buf); /// assert_eq!( /// &buf as &[_], /// b"{936da01f-9abd-4d9d-80c7-02af85c822a8}!!" as &[_] /// ); /// /// Ok(()) /// } /// ``` /// */ #[inline] pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode_braced(self.0.as_bytes(), buffer, false) } /// Writes the [`Uuid`] as an upper-case hyphenated string surrounded by /// braces to `buffer`, and returns the subslice of the buffer that contains /// the encoded UUID. /// /// This is slightly more efficient than using the formatting /// infrastructure as it avoids virtual calls, and may avoid /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html /// /// # Panics /// /// Panics if the buffer is not large enough: it must have length at least /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a /// sufficiently-large temporary buffer. /// /// [`LENGTH`]: #associatedconstant.LENGTH /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// fn main() -> Result<(), uuid::Error> { /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?; /// /// // the encoded portion is returned /// assert_eq!( /// uuid.braced() /// .encode_upper(&mut Uuid::encode_buffer()), /// "{936DA01F-9ABD-4D9D-80C7-02AF85C822A8}" /// ); /// /// // the buffer is mutated directly, and trailing contents remains /// let mut buf = [b'!'; 40]; /// uuid.braced().encode_upper(&mut buf); /// assert_eq!( /// &buf as &[_], /// b"{936DA01F-9ABD-4D9D-80C7-02AF85C822A8}!!" as &[_] /// ); /// /// Ok(()) /// } /// ``` /// */ #[inline] pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode_braced(self.0.as_bytes(), buffer, true) } /// Get a reference to the underlying [`Uuid`]. /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// let braced = Uuid::nil().braced(); /// assert_eq!(*braced.as_uuid(), Uuid::nil()); /// ``` pub const fn as_uuid(&self) -> &Uuid { &self.0 } /// Consumes the [`Braced`], returning the underlying [`Uuid`]. /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// let braced = Uuid::nil().braced(); /// assert_eq!(braced.into_uuid(), Uuid::nil()); /// ``` pub const fn into_uuid(self) -> Uuid { self.0 } } impl Simple { /// The length of a simple [`Uuid`] string. /// /// [`Uuid`]: ../struct.Uuid.html pub const LENGTH: usize = 32; /// Creates a [`Simple`] from a [`Uuid`]. /// /// [`Uuid`]: ../struct.Uuid.html /// [`Simple`]: struct.Simple.html pub const fn from_uuid(uuid: Uuid) -> Self { Simple(uuid) } /// Writes the [`Uuid`] as a lower-case simple string to `buffer`, /// and returns the subslice of the buffer that contains the encoded UUID. /// /// This is slightly more efficient than using the formatting /// infrastructure as it avoids virtual calls, and may avoid /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html /// /// # Panics /// /// Panics if the buffer is not large enough: it must have length at least /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a /// sufficiently-large temporary buffer. /// /// [`LENGTH`]: #associatedconstant.LENGTH /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// fn main() -> Result<(), uuid::Error> { /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?; /// /// // the encoded portion is returned /// assert_eq!( /// uuid.simple().encode_lower(&mut Uuid::encode_buffer()), /// "936da01f9abd4d9d80c702af85c822a8" /// ); /// /// // the buffer is mutated directly, and trailing contents remains /// let mut buf = [b'!'; 36]; /// assert_eq!( /// uuid.simple().encode_lower(&mut buf), /// "936da01f9abd4d9d80c702af85c822a8" /// ); /// assert_eq!( /// &buf as &[_], /// b"936da01f9abd4d9d80c702af85c822a8!!!!" as &[_] /// ); /// /// Ok(()) /// } /// ``` /// */ #[inline] pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode_simple(self.0.as_bytes(), buffer, false) } /// Writes the [`Uuid`] as an upper-case simple string to `buffer`, /// and returns the subslice of the buffer that contains the encoded UUID. /// /// [`Uuid`]: ../struct.Uuid.html /// /// # Panics /// /// Panics if the buffer is not large enough: it must have length at least /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a /// sufficiently-large temporary buffer. /// /// [`LENGTH`]: #associatedconstant.LENGTH /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// fn main() -> Result<(), uuid::Error> { /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?; /// /// // the encoded portion is returned /// assert_eq!( /// uuid.simple().encode_upper(&mut Uuid::encode_buffer()), /// "936DA01F9ABD4D9D80C702AF85C822A8" /// ); /// /// // the buffer is mutated directly, and trailing contents remains /// let mut buf = [b'!'; 36]; /// assert_eq!( /// uuid.simple().encode_upper(&mut buf), /// "936DA01F9ABD4D9D80C702AF85C822A8" /// ); /// assert_eq!( /// &buf as &[_], /// b"936DA01F9ABD4D9D80C702AF85C822A8!!!!" as &[_] /// ); /// /// Ok(()) /// } /// ``` /// */ #[inline] pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode_simple(self.0.as_bytes(), buffer, true) } /// Get a reference to the underlying [`Uuid`]. /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// let simple = Uuid::nil().simple(); /// assert_eq!(*simple.as_uuid(), Uuid::nil()); /// ``` pub const fn as_uuid(&self) -> &Uuid { &self.0 } /// Consumes the [`Simple`], returning the underlying [`Uuid`]. /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// let simple = Uuid::nil().simple(); /// assert_eq!(simple.into_uuid(), Uuid::nil()); /// ``` pub const fn into_uuid(self) -> Uuid { self.0 } } impl Urn { /// The length of a URN [`Uuid`] string. /// /// [`Uuid`]: ../struct.Uuid.html pub const LENGTH: usize = 45; /// Creates a [`Urn`] from a [`Uuid`]. /// /// [`Uuid`]: ../struct.Uuid.html /// [`Urn`]: struct.Urn.html pub const fn from_uuid(uuid: Uuid) -> Self { Urn(uuid) } /// Writes the [`Uuid`] as a lower-case URN string to /// `buffer`, and returns the subslice of the buffer that contains the /// encoded UUID. /// /// This is slightly more efficient than using the formatting /// infrastructure as it avoids virtual calls, and may avoid /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html /// /// # Panics /// /// Panics if the buffer is not large enough: it must have length at least /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a /// sufficiently-large temporary buffer. /// /// [`LENGTH`]: #associatedconstant.LENGTH /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// fn main() -> Result<(), uuid::Error> { /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?; /// /// // the encoded portion is returned /// assert_eq!( /// uuid.urn().encode_lower(&mut Uuid::encode_buffer()), /// "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" /// ); /// /// // the buffer is mutated directly, and trailing contents remains /// let mut buf = [b'!'; 49]; /// uuid.urn().encode_lower(&mut buf); /// assert_eq!( /// uuid.urn().encode_lower(&mut buf), /// "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" /// ); /// assert_eq!( /// &buf as &[_], /// b"urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] /// ); /// /// Ok(()) /// } /// ``` /// */ #[inline] pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode_urn(self.0.as_bytes(), buffer, false) } /// Writes the [`Uuid`] as an upper-case URN string to /// `buffer`, and returns the subslice of the buffer that contains the /// encoded UUID. /// /// This is slightly more efficient than using the formatting /// infrastructure as it avoids virtual calls, and may avoid /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html /// /// # Panics /// /// Panics if the buffer is not large enough: it must have length at least /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a /// sufficiently-large temporary buffer. /// /// [`LENGTH`]: #associatedconstant.LENGTH /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// fn main() -> Result<(), uuid::Error> { /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?; /// /// // the encoded portion is returned /// assert_eq!( /// uuid.urn().encode_upper(&mut Uuid::encode_buffer()), /// "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" /// ); /// /// // the buffer is mutated directly, and trailing contents remains /// let mut buf = [b'!'; 49]; /// assert_eq!( /// uuid.urn().encode_upper(&mut buf), /// "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" /// ); /// assert_eq!( /// &buf as &[_], /// b"urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] /// ); /// /// Ok(()) /// } /// ``` /// */ #[inline] pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode_urn(self.0.as_bytes(), buffer, true) } /// Get a reference to the underlying [`Uuid`]. /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// let urn = Uuid::nil().urn(); /// assert_eq!(*urn.as_uuid(), Uuid::nil()); /// ``` pub const fn as_uuid(&self) -> &Uuid { &self.0 } /// Consumes the [`Urn`], returning the underlying [`Uuid`]. /// /// # Examples /// /// ```rust /// use uuid::Uuid; /// /// let urn = Uuid::nil().urn(); /// assert_eq!(urn.into_uuid(), Uuid::nil()); /// ``` pub const fn into_uuid(self) -> Uuid { self.0 } } macro_rules! impl_fmt_traits { ($($T:ident<$($a:lifetime),*>),+) => {$( impl<$($a),*> fmt::Display for $T<$($a),*> { #[inline] fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fmt::LowerHex::fmt(self, f) } } impl<$($a),*> fmt::LowerHex for $T<$($a),*> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.encode_lower(&mut [0; Self::LENGTH])) } } impl<$($a),*> fmt::UpperHex for $T<$($a),*> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(self.encode_upper(&mut [0; Self::LENGTH])) } } impl_fmt_from!($T<$($a),*>); )+} } macro_rules! impl_fmt_from { ($T:ident<>) => { impl From for $T { #[inline] fn from(f: Uuid) -> Self { $T(f) } } impl From<$T> for Uuid { #[inline] fn from(f: $T) -> Self { f.into_uuid() } } impl AsRef for $T { #[inline] fn as_ref(&self) -> &Uuid { &self.0 } } impl Borrow for $T { #[inline] fn borrow(&self) -> &Uuid { &self.0 } } }; ($T:ident<$a:lifetime>) => { impl<$a> From<&$a Uuid> for $T<$a> { #[inline] fn from(f: &$a Uuid) -> Self { $T::from_uuid_ref(f) } } impl<$a> From<$T<$a>> for &$a Uuid { #[inline] fn from(f: $T<$a>) -> &$a Uuid { f.0 } } impl<$a> AsRef for $T<$a> { #[inline] fn as_ref(&self) -> &Uuid { self.0 } } impl<$a> Borrow for $T<$a> { #[inline] fn borrow(&self) -> &Uuid { self.0 } } }; } impl_fmt_traits! { Hyphenated<>, Simple<>, Urn<>, Braced<> } #[cfg(test)] mod tests { use super::*; #[test] fn hyphenated_trailing() { let mut buf = [b'x'; 100]; let len = Uuid::nil().hyphenated().encode_lower(&mut buf).len(); assert_eq!(len, super::Hyphenated::LENGTH); assert!(buf[len..].iter().all(|x| *x == b'x')); } #[test] fn hyphenated_ref_trailing() { let mut buf = [b'x'; 100]; let len = Uuid::nil().as_hyphenated().encode_lower(&mut buf).len(); assert_eq!(len, super::Hyphenated::LENGTH); assert!(buf[len..].iter().all(|x| *x == b'x')); } #[test] fn simple_trailing() { let mut buf = [b'x'; 100]; let len = Uuid::nil().simple().encode_lower(&mut buf).len(); assert_eq!(len, super::Simple::LENGTH); assert!(buf[len..].iter().all(|x| *x == b'x')); } #[test] fn simple_ref_trailing() { let mut buf = [b'x'; 100]; let len = Uuid::nil().as_simple().encode_lower(&mut buf).len(); assert_eq!(len, super::Simple::LENGTH); assert!(buf[len..].iter().all(|x| *x == b'x')); } #[test] fn urn_trailing() { let mut buf = [b'x'; 100]; let len = Uuid::nil().urn().encode_lower(&mut buf).len(); assert_eq!(len, super::Urn::LENGTH); assert!(buf[len..].iter().all(|x| *x == b'x')); } #[test] fn urn_ref_trailing() { let mut buf = [b'x'; 100]; let len = Uuid::nil().as_urn().encode_lower(&mut buf).len(); assert_eq!(len, super::Urn::LENGTH); assert!(buf[len..].iter().all(|x| *x == b'x')); } #[test] fn braced_trailing() { let mut buf = [b'x'; 100]; let len = Uuid::nil().braced().encode_lower(&mut buf).len(); assert_eq!(len, super::Braced::LENGTH); assert!(buf[len..].iter().all(|x| *x == b'x')); } #[test] fn braced_ref_trailing() { let mut buf = [b'x'; 100]; let len = Uuid::nil().as_braced().encode_lower(&mut buf).len(); assert_eq!(len, super::Braced::LENGTH); assert!(buf[len..].iter().all(|x| *x == b'x')); } #[test] #[should_panic] fn hyphenated_too_small() { Uuid::nil().hyphenated().encode_lower(&mut [0; 35]); } #[test] #[should_panic] fn simple_too_small() { Uuid::nil().simple().encode_lower(&mut [0; 31]); } #[test] #[should_panic] fn urn_too_small() { Uuid::nil().urn().encode_lower(&mut [0; 44]); } #[test] #[should_panic] fn braced_too_small() { Uuid::nil().braced().encode_lower(&mut [0; 37]); } #[test] fn hyphenated_to_inner() { let hyphenated = Uuid::nil().hyphenated(); assert_eq!(Uuid::from(hyphenated), Uuid::nil()); } #[test] fn simple_to_inner() { let simple = Uuid::nil().simple(); assert_eq!(Uuid::from(simple), Uuid::nil()); } #[test] fn urn_to_inner() { let urn = Uuid::nil().urn(); assert_eq!(Uuid::from(urn), Uuid::nil()); } #[test] fn braced_to_inner() { let braced = Uuid::nil().braced(); assert_eq!(Uuid::from(braced), Uuid::nil()); } }