1use core::{mem::MaybeUninit, ptr, slice, str::FromStr};
15
16use crate::{
17 std::{borrow::Borrow, fmt, str},
18 Error, Uuid, Variant,
19};
20
21#[cfg(feature = "std")]
22use crate::std::string::{String, ToString};
23
24impl std::fmt::Debug for Uuid {
25 #[inline]
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 fmt::LowerHex::fmt(self, f)
28 }
29}
30
31impl fmt::Display for Uuid {
32 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
33 fmt::LowerHex::fmt(self, f)
34 }
35}
36
37#[cfg(feature = "std")]
38impl From<Uuid> for String {
39 fn from(uuid: Uuid) -> Self {
40 uuid.to_string()
41 }
42}
43
44impl fmt::Display for Variant {
45 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
46 match *self {
47 Variant::NCS => f.write_fmt(format_args!("NCS"))write!(f, "NCS"),
48 Variant::RFC4122 => f.write_fmt(format_args!("RFC4122"))write!(f, "RFC4122"),
49 Variant::Microsoft => f.write_fmt(format_args!("Microsoft"))write!(f, "Microsoft"),
50 Variant::Future => f.write_fmt(format_args!("Future"))write!(f, "Future"),
51 }
52 }
53}
54
55impl fmt::LowerHex for Uuid {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 fmt::LowerHex::fmt(self.as_hyphenated(), f)
58 }
59}
60
61impl fmt::UpperHex for Uuid {
62 #[inline]
63 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
64 fmt::UpperHex::fmt(self.as_hyphenated(), f)
65 }
66}
67
68#[derive(#[automatically_derived]
impl ::core::clone::Clone for Hyphenated {
#[inline]
fn clone(&self) -> Hyphenated {
let _: ::core::clone::AssertParamIsClone<Uuid>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Hyphenated { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Hyphenated {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Hyphenated",
&&self.0)
}
}Debug, #[automatically_derived]
impl ::core::default::Default for Hyphenated {
#[inline]
fn default() -> Hyphenated {
Hyphenated(::core::default::Default::default())
}
}Default, #[automatically_derived]
impl ::core::cmp::Eq for Hyphenated {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Uuid>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Hyphenated {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::Ord for Hyphenated {
#[inline]
fn cmp(&self, other: &Hyphenated) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialEq for Hyphenated {
#[inline]
fn eq(&self, other: &Hyphenated) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Hyphenated {
#[inline]
fn partial_cmp(&self, other: &Hyphenated)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd)]
71#[cfg_attr(
72 all(uuid_unstable, feature = "zerocopy"),
73 derive(
74 zerocopy::IntoBytes,
75 zerocopy::FromBytes,
76 zerocopy::KnownLayout,
77 zerocopy::Immutable,
78 zerocopy::Unaligned
79 )
80)]
81#[repr(transparent)]
82pub struct Hyphenated(Uuid);
83
84#[derive(#[automatically_derived]
impl ::core::clone::Clone for Simple {
#[inline]
fn clone(&self) -> Simple {
let _: ::core::clone::AssertParamIsClone<Uuid>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Simple { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Simple {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Simple",
&&self.0)
}
}Debug, #[automatically_derived]
impl ::core::default::Default for Simple {
#[inline]
fn default() -> Simple { Simple(::core::default::Default::default()) }
}Default, #[automatically_derived]
impl ::core::cmp::Eq for Simple {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Uuid>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Simple {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::Ord for Simple {
#[inline]
fn cmp(&self, other: &Simple) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialEq for Simple {
#[inline]
fn eq(&self, other: &Simple) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Simple {
#[inline]
fn partial_cmp(&self, other: &Simple)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd)]
87#[cfg_attr(
88 all(uuid_unstable, feature = "zerocopy"),
89 derive(
90 zerocopy::IntoBytes,
91 zerocopy::FromBytes,
92 zerocopy::KnownLayout,
93 zerocopy::Immutable,
94 zerocopy::Unaligned
95 )
96)]
97#[repr(transparent)]
98pub struct Simple(Uuid);
99
100#[derive(#[automatically_derived]
impl ::core::clone::Clone for Urn {
#[inline]
fn clone(&self) -> Urn {
let _: ::core::clone::AssertParamIsClone<Uuid>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Urn { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Urn {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Urn", &&self.0)
}
}Debug, #[automatically_derived]
impl ::core::default::Default for Urn {
#[inline]
fn default() -> Urn { Urn(::core::default::Default::default()) }
}Default, #[automatically_derived]
impl ::core::cmp::Eq for Urn {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Uuid>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Urn {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::Ord for Urn {
#[inline]
fn cmp(&self, other: &Urn) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialEq for Urn {
#[inline]
fn eq(&self, other: &Urn) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Urn {
#[inline]
fn partial_cmp(&self, other: &Urn)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd)]
103#[cfg_attr(
104 all(uuid_unstable, feature = "zerocopy"),
105 derive(
106 zerocopy::IntoBytes,
107 zerocopy::FromBytes,
108 zerocopy::KnownLayout,
109 zerocopy::Immutable,
110 zerocopy::Unaligned
111 )
112)]
113#[repr(transparent)]
114pub struct Urn(Uuid);
115
116#[derive(#[automatically_derived]
impl ::core::clone::Clone for Braced {
#[inline]
fn clone(&self) -> Braced {
let _: ::core::clone::AssertParamIsClone<Uuid>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Braced { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Braced {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "Braced",
&&self.0)
}
}Debug, #[automatically_derived]
impl ::core::default::Default for Braced {
#[inline]
fn default() -> Braced { Braced(::core::default::Default::default()) }
}Default, #[automatically_derived]
impl ::core::cmp::Eq for Braced {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_fields_are_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Uuid>;
}
}Eq, #[automatically_derived]
impl ::core::hash::Hash for Braced {
#[inline]
fn hash<__H: ::core::hash::Hasher>(&self, state: &mut __H) {
::core::hash::Hash::hash(&self.0, state)
}
}Hash, #[automatically_derived]
impl ::core::cmp::Ord for Braced {
#[inline]
fn cmp(&self, other: &Braced) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialEq for Braced {
#[inline]
fn eq(&self, other: &Braced) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Braced {
#[inline]
fn partial_cmp(&self, other: &Braced)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::option::Option::Some(::core::cmp::Ord::cmp(self, other))
}
}PartialOrd)]
119#[cfg_attr(
120 all(uuid_unstable, feature = "zerocopy"),
121 derive(
122 zerocopy::IntoBytes,
123 zerocopy::FromBytes,
124 zerocopy::KnownLayout,
125 zerocopy::Immutable,
126 zerocopy::Unaligned
127 )
128)]
129#[repr(transparent)]
130pub struct Braced(Uuid);
131
132impl Uuid {
133 #[inline]
135 pub const fn hyphenated(self) -> Hyphenated {
136 Hyphenated(self)
137 }
138
139 #[inline]
141 pub fn as_hyphenated(&self) -> &Hyphenated {
142 unsafe { core::mem::transmute::<&_, &_>(self) }unsafe_transmute_ref!(self)
143 }
144
145 #[inline]
147 pub const fn simple(self) -> Simple {
148 Simple(self)
149 }
150
151 #[inline]
153 pub fn as_simple(&self) -> &Simple {
154 unsafe { core::mem::transmute::<&_, &_>(self) }unsafe_transmute_ref!(self)
155 }
156
157 #[inline]
159 pub const fn urn(self) -> Urn {
160 Urn(self)
161 }
162
163 #[inline]
165 pub fn as_urn(&self) -> &Urn {
166 unsafe { core::mem::transmute::<&_, &_>(self) }unsafe_transmute_ref!(self)
167 }
168
169 #[inline]
171 pub const fn braced(self) -> Braced {
172 Braced(self)
173 }
174
175 #[inline]
177 pub fn as_braced(&self) -> &Braced {
178 unsafe { core::mem::transmute::<&_, &_>(self) }unsafe_transmute_ref!(self)
179 }
180}
181
182#[inline]
185const fn nibble_to_hex(nibble: u8, alpha_offset: u8) -> u8 {
186 nibble + b'0' + if nibble > 9 { alpha_offset } else { 0 }
187}
188
189#[inline]
190const fn format_simple(src: &[u8; 16], upper: bool) -> [u8; 32] {
191 let alpha_offset = if upper { 0x07 } else { 0x27 };
192 let mut dst = [0; 32];
193 let mut i = 0;
194 while i < 16 {
195 let x = src[i];
196 dst[i * 2] = nibble_to_hex(x >> 4, alpha_offset);
197 dst[i * 2 + 1] = nibble_to_hex(x & 0x0f, alpha_offset);
198 i += 1;
199 }
200 dst
201}
202
203#[inline]
204const fn format_hyphenated(src: &[u8; 16], upper: bool) -> [u8; 36] {
205 let simple = format_simple(src, upper);
206 let mut dst = [0; 36];
207
208 let mut i = 0;
209 while i < 8 {
210 dst[i] = simple[i];
211 i += 1;
212 }
213 dst[8] = b'-';
214 while i < 12 {
215 dst[i + 1] = simple[i];
216 i += 1;
217 }
218 dst[13] = b'-';
219 while i < 16 {
220 dst[i + 2] = simple[i];
221 i += 1;
222 }
223 dst[18] = b'-';
224 while i < 20 {
225 dst[i + 3] = simple[i];
226 i += 1;
227 }
228 dst[23] = b'-';
229 while i < 32 {
230 dst[i + 4] = simple[i];
231 i += 1;
232 }
233 dst
234}
235
236#[inline]
237fn encode_simple<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str {
238 let buf = &mut buffer[..Simple::LENGTH];
239
240 encode_simple_uninit(src, slice_as_uninit_mut(buf), upper)
241}
242
243#[inline]
244fn encode_hyphenated<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str {
245 let buf = &mut buffer[..Hyphenated::LENGTH];
246
247 encode_hyphenated_uninit(src, slice_as_uninit_mut(buf), upper)
248}
249
250#[inline]
251fn encode_braced<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str {
252 let buf = &mut buffer[..Hyphenated::LENGTH + 2];
253
254 encode_braced_uninit(src, slice_as_uninit_mut(buf), upper)
255}
256
257#[inline]
258fn encode_urn<'b>(src: &[u8; 16], buffer: &'b mut [u8], upper: bool) -> &'b mut str {
259 let buf = &mut buffer[..Urn::LENGTH];
260
261 encode_urn_uninit(src, slice_as_uninit_mut(buf), upper)
262}
263
264#[inline]
265fn encode_simple_uninit<'b>(
266 src: &[u8; 16],
267 buffer: &'b mut [MaybeUninit<u8>],
268 upper: bool,
269) -> &'b mut str {
270 let buf = &mut buffer[..Simple::LENGTH];
271 write_bytes(buf, &format_simple(src, upper));
272
273 unsafe { assume_init_ascii_mut(buf) }
275}
276
277#[inline]
278fn encode_hyphenated_uninit<'b>(
279 src: &[u8; 16],
280 buffer: &'b mut [MaybeUninit<u8>],
281 upper: bool,
282) -> &'b mut str {
283 let buf = &mut buffer[..Hyphenated::LENGTH];
284 write_bytes(buf, &format_hyphenated(src, upper));
285
286 unsafe { assume_init_ascii_mut(buf) }
288}
289
290#[inline]
291fn encode_braced_uninit<'b>(
292 src: &[u8; 16],
293 buffer: &'b mut [MaybeUninit<u8>],
294 upper: bool,
295) -> &'b mut str {
296 let buf = &mut buffer[..Hyphenated::LENGTH + 2];
297
298 #[cfg_attr(all(uuid_unstable, feature = "zerocopy"), derive(zerocopy::IntoBytes))]
299 #[repr(C)]
300 struct BracedBytes {
301 open_curly: u8,
302 hyphenated: [u8; Hyphenated::LENGTH],
303 close_curly: u8,
304 }
305
306 let braced = BracedBytes {
307 open_curly: b'{',
308 hyphenated: format_hyphenated(src, upper),
309 close_curly: b'}',
310 };
311 let braced: [u8; Hyphenated::LENGTH + 2] = unsafe { core::mem::transmute::<_, _>(braced) }unsafe_transmute!(braced);
312
313 write_bytes(buf, &braced);
314
315 unsafe { assume_init_ascii_mut(buf) }
317}
318
319#[inline]
320fn encode_urn_uninit<'b>(
321 src: &[u8; 16],
322 buffer: &'b mut [MaybeUninit<u8>],
323 upper: bool,
324) -> &'b mut str {
325 let buf = &mut buffer[..Urn::LENGTH];
326 write_bytes(&mut buf[..9], b"urn:uuid:");
327
328 let dst = &mut buf[9..(9 + Hyphenated::LENGTH)];
329 write_bytes(dst, &format_hyphenated(src, upper));
330
331 unsafe { assume_init_ascii_mut(buf) }
333}
334
335#[inline]
336fn write_bytes(dst: &mut [MaybeUninit<u8>], src: &[u8]) {
337 if true {
{
match (&dst.len(), &src.len()) {
(left_val, right_val) => {
if !(*left_val == *right_val) {
let kind = ::core::panicking::AssertKind::Eq;
::core::panicking::assert_failed(kind, &*left_val,
&*right_val, ::core::option::Option::None);
}
}
}
};
};debug_assert_eq!(dst.len(), src.len());
338 let dst = &mut dst[..src.len()];
339
340 unsafe {
343 ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr().cast(), src.len());
344 }
345}
346
347#[inline]
348fn slice_as_uninit_mut(buffer: &mut [u8]) -> &mut [MaybeUninit<u8>] {
349 unsafe { slice::from_raw_parts_mut(buffer.as_mut_ptr().cast(), buffer.len()) }
351}
352
353#[inline]
354unsafe fn assume_init_ascii_mut(buffer: &mut [MaybeUninit<u8>]) -> &mut str {
355 let buffer = unsafe { slice::from_raw_parts_mut(buffer.as_mut_ptr().cast(), buffer.len()) };
357
358 unsafe { str::from_utf8_unchecked_mut(buffer) }
360}
361
362impl Hyphenated {
363 pub const LENGTH: usize = 36;
367
368 pub const fn from_uuid(uuid: Uuid) -> Self {
373 Hyphenated(uuid)
374 }
375
376 #[inline]
423 pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
424 encode_hyphenated(self.0.as_bytes(), buffer, false)
425 }
426
427 #[inline]
443 pub fn encode_lower_uninit<'buf>(&self, buffer: &'buf mut [MaybeUninit<u8>]) -> &'buf mut str {
444 encode_hyphenated_uninit(self.0.as_bytes(), buffer, false)
445 }
446
447 #[inline]
494 pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
495 encode_hyphenated(self.0.as_bytes(), buffer, true)
496 }
497
498 #[inline]
514 pub fn encode_upper_uninit<'buf>(&self, buffer: &'buf mut [MaybeUninit<u8>]) -> &'buf mut str {
515 encode_hyphenated_uninit(self.0.as_bytes(), buffer, true)
516 }
517
518 pub const fn as_uuid(&self) -> &Uuid {
529 &self.0
530 }
531
532 pub const fn into_uuid(self) -> Uuid {
543 self.0
544 }
545}
546
547impl Braced {
548 pub const LENGTH: usize = 38;
552
553 pub const fn from_uuid(uuid: Uuid) -> Self {
558 Braced(uuid)
559 }
560
561 #[inline]
608 pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
609 encode_braced(self.0.as_bytes(), buffer, false)
610 }
611
612 #[inline]
628 pub fn encode_lower_uninit<'buf>(&self, buffer: &'buf mut [MaybeUninit<u8>]) -> &'buf mut str {
629 encode_braced_uninit(self.0.as_bytes(), buffer, false)
630 }
631
632 #[inline]
679 pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
680 encode_braced(self.0.as_bytes(), buffer, true)
681 }
682
683 #[inline]
699 pub fn encode_upper_uninit<'buf>(&self, buffer: &'buf mut [MaybeUninit<u8>]) -> &'buf mut str {
700 encode_braced_uninit(self.0.as_bytes(), buffer, true)
701 }
702
703 pub const fn as_uuid(&self) -> &Uuid {
714 &self.0
715 }
716
717 pub const fn into_uuid(self) -> Uuid {
728 self.0
729 }
730}
731
732impl Simple {
733 pub const LENGTH: usize = 32;
737
738 pub const fn from_uuid(uuid: Uuid) -> Self {
743 Simple(uuid)
744 }
745
746 #[inline]
794 pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
795 encode_simple(self.0.as_bytes(), buffer, false)
796 }
797
798 #[inline]
814 pub fn encode_lower_uninit<'buf>(&self, buffer: &'buf mut [MaybeUninit<u8>]) -> &'buf mut str {
815 encode_simple_uninit(self.0.as_bytes(), buffer, false)
816 }
817
818 #[inline]
862 pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
863 encode_simple(self.0.as_bytes(), buffer, true)
864 }
865
866 #[inline]
882 pub fn encode_upper_uninit<'buf>(&self, buffer: &'buf mut [MaybeUninit<u8>]) -> &'buf mut str {
883 encode_simple_uninit(self.0.as_bytes(), buffer, true)
884 }
885
886 pub const fn as_uuid(&self) -> &Uuid {
897 &self.0
898 }
899
900 pub const fn into_uuid(self) -> Uuid {
911 self.0
912 }
913}
914
915impl Urn {
916 pub const LENGTH: usize = 45;
920
921 pub const fn from_uuid(uuid: Uuid) -> Self {
926 Urn(uuid)
927 }
928
929 #[inline]
979 pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
980 encode_urn(self.0.as_bytes(), buffer, false)
981 }
982
983 #[inline]
999 pub fn encode_lower_uninit<'buf>(&self, buffer: &'buf mut [MaybeUninit<u8>]) -> &'buf mut str {
1000 encode_urn_uninit(self.0.as_bytes(), buffer, false)
1001 }
1002
1003 #[inline]
1052 pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {
1053 encode_urn(self.0.as_bytes(), buffer, true)
1054 }
1055
1056 #[inline]
1072 pub fn encode_upper_uninit<'buf>(&self, buffer: &'buf mut [MaybeUninit<u8>]) -> &'buf mut str {
1073 encode_urn_uninit(self.0.as_bytes(), buffer, true)
1074 }
1075
1076 pub const fn as_uuid(&self) -> &Uuid {
1087 &self.0
1088 }
1089
1090 pub const fn into_uuid(self) -> Uuid {
1101 self.0
1102 }
1103}
1104
1105impl FromStr for Hyphenated {
1106 type Err = Error;
1107
1108 fn from_str(s: &str) -> Result<Self, Self::Err> {
1109 crate::parser::parse_hyphenated(s.as_bytes())
1110 .map(|b| Hyphenated(Uuid(b)))
1111 .map_err(|invalid| invalid.into_err())
1112 }
1113}
1114
1115impl FromStr for Simple {
1116 type Err = Error;
1117
1118 fn from_str(s: &str) -> Result<Self, Self::Err> {
1119 crate::parser::parse_simple(s.as_bytes(), false)
1120 .map(|b| Simple(Uuid(b)))
1121 .map_err(|invalid| invalid.into_err())
1122 }
1123}
1124
1125impl FromStr for Urn {
1126 type Err = Error;
1127
1128 fn from_str(s: &str) -> Result<Self, Self::Err> {
1129 crate::parser::parse_urn(s.as_bytes())
1130 .map(|b| Urn(Uuid(b)))
1131 .map_err(|invalid| invalid.into_err())
1132 }
1133}
1134
1135impl FromStr for Braced {
1136 type Err = Error;
1137
1138 fn from_str(s: &str) -> Result<Self, Self::Err> {
1139 crate::parser::parse_braced(s.as_bytes())
1140 .map(|b| Braced(Uuid(b)))
1141 .map_err(|invalid| invalid.into_err())
1142 }
1143}
1144
1145macro_rules! impl_fmt_traits {
1146 ($($T:ident<$($a:lifetime),*>),+) => {$(
1147 impl<$($a),*> fmt::Display for $T<$($a),*> {
1148 #[inline]
1149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1150 fmt::LowerHex::fmt(self, f)
1151 }
1152 }
1153
1154 impl<$($a),*> fmt::LowerHex for $T<$($a),*> {
1155 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1156 f.write_str(self.encode_lower(&mut [0; Self::LENGTH]))
1157 }
1158 }
1159
1160 impl<$($a),*> fmt::UpperHex for $T<$($a),*> {
1161 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1162 f.write_str(self.encode_upper(&mut [0; Self::LENGTH]))
1163 }
1164 }
1165
1166 impl_fmt_from!($T<$($a),*>);
1167 )+}
1168}
1169
1170macro_rules! impl_fmt_from {
1171 ($T:ident<>) => {
1172 impl From<Uuid> for $T {
1173 #[inline]
1174 fn from(f: Uuid) -> Self {
1175 $T(f)
1176 }
1177 }
1178
1179 impl From<$T> for Uuid {
1180 #[inline]
1181 fn from(f: $T) -> Self {
1182 f.into_uuid()
1183 }
1184 }
1185
1186 impl AsRef<Uuid> for $T {
1187 #[inline]
1188 fn as_ref(&self) -> &Uuid {
1189 &self.0
1190 }
1191 }
1192
1193 impl Borrow<Uuid> for $T {
1194 #[inline]
1195 fn borrow(&self) -> &Uuid {
1196 &self.0
1197 }
1198 }
1199 };
1200 ($T:ident<$a:lifetime>) => {
1201 impl<$a> From<&$a Uuid> for $T<$a> {
1202 #[inline]
1203 fn from(f: &$a Uuid) -> Self {
1204 $T::from_uuid_ref(f)
1205 }
1206 }
1207
1208 impl<$a> From<$T<$a>> for &$a Uuid {
1209 #[inline]
1210 fn from(f: $T<$a>) -> &$a Uuid {
1211 f.0
1212 }
1213 }
1214
1215 impl<$a> AsRef<Uuid> for $T<$a> {
1216 #[inline]
1217 fn as_ref(&self) -> &Uuid {
1218 self.0
1219 }
1220 }
1221
1222 impl<$a> Borrow<Uuid> for $T<$a> {
1223 #[inline]
1224 fn borrow(&self) -> &Uuid {
1225 self.0
1226 }
1227 }
1228 };
1229}
1230
1231impl fmt::Display for Braced<> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::LowerHex::fmt(self, f)
}
}
impl fmt::LowerHex for Braced<> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.encode_lower(&mut [0; Self::LENGTH]))
}
}
impl fmt::UpperHex for Braced<> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.encode_upper(&mut [0; Self::LENGTH]))
}
}
impl From<Uuid> for Braced {
#[inline]
fn from(f: Uuid) -> Self { Braced(f) }
}
impl From<Braced> for Uuid {
#[inline]
fn from(f: Braced) -> Self { f.into_uuid() }
}
impl AsRef<Uuid> for Braced {
#[inline]
fn as_ref(&self) -> &Uuid { &self.0 }
}
impl Borrow<Uuid> for Braced {
#[inline]
fn borrow(&self) -> &Uuid { &self.0 }
}impl_fmt_traits! {
1232 Hyphenated<>,
1233 Simple<>,
1234 Urn<>,
1235 Braced<>
1236}
1237
1238#[cfg(test)]
1239mod tests {
1240 use super::*;
1241
1242 use core::mem::MaybeUninit;
1243
1244 #[test]
1245 fn encode_lower_uninit() {
1246 let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap();
1247
1248 let mut buf = [MaybeUninit::new(b'x'); 100];
1249 let len = {
1250 let encoded = uuid.hyphenated().encode_lower_uninit(&mut buf);
1251 assert_eq!(encoded, "936da01f-9abd-4d9d-80c7-02af85c822a8");
1252 encoded.len()
1253 };
1254 assert_eq!(len, Hyphenated::LENGTH);
1255 assert_uninit_tail_unchanged(&buf, len);
1256
1257 let mut buf = [MaybeUninit::new(b'x'); 100];
1258 let len = {
1259 let encoded = uuid.simple().encode_lower_uninit(&mut buf);
1260 assert_eq!(encoded, "936da01f9abd4d9d80c702af85c822a8");
1261 encoded.len()
1262 };
1263 assert_eq!(len, Simple::LENGTH);
1264 assert_uninit_tail_unchanged(&buf, len);
1265
1266 let mut buf = [MaybeUninit::new(b'x'); 100];
1267 let len = {
1268 let encoded = uuid.urn().encode_lower_uninit(&mut buf);
1269 assert_eq!(encoded, "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8");
1270 encoded.len()
1271 };
1272 assert_eq!(len, Urn::LENGTH);
1273 assert_uninit_tail_unchanged(&buf, len);
1274
1275 let mut buf = [MaybeUninit::new(b'x'); 100];
1276 let len = {
1277 let encoded = uuid.braced().encode_lower_uninit(&mut buf);
1278 assert_eq!(encoded, "{936da01f-9abd-4d9d-80c7-02af85c822a8}");
1279 encoded.len()
1280 };
1281 assert_eq!(len, Braced::LENGTH);
1282 assert_uninit_tail_unchanged(&buf, len);
1283 }
1284
1285 #[test]
1286 fn encode_upper_uninit() {
1287 let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap();
1288
1289 let mut buf = [MaybeUninit::new(b'x'); 100];
1290 let len = {
1291 let encoded = uuid.hyphenated().encode_upper_uninit(&mut buf);
1292 assert_eq!(encoded, "936DA01F-9ABD-4D9D-80C7-02AF85C822A8");
1293 encoded.len()
1294 };
1295 assert_eq!(len, Hyphenated::LENGTH);
1296 assert_uninit_tail_unchanged(&buf, len);
1297
1298 let mut buf = [MaybeUninit::new(b'x'); 100];
1299 let len = {
1300 let encoded = uuid.simple().encode_upper_uninit(&mut buf);
1301 assert_eq!(encoded, "936DA01F9ABD4D9D80C702AF85C822A8");
1302 encoded.len()
1303 };
1304 assert_eq!(len, Simple::LENGTH);
1305 assert_uninit_tail_unchanged(&buf, len);
1306
1307 let mut buf = [MaybeUninit::new(b'x'); 100];
1308 let len = {
1309 let encoded = uuid.urn().encode_upper_uninit(&mut buf);
1310 assert_eq!(encoded, "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8");
1311 encoded.len()
1312 };
1313 assert_eq!(len, Urn::LENGTH);
1314 assert_uninit_tail_unchanged(&buf, len);
1315
1316 let mut buf = [MaybeUninit::new(b'x'); 100];
1317 let len = {
1318 let encoded = uuid.braced().encode_upper_uninit(&mut buf);
1319 assert_eq!(encoded, "{936DA01F-9ABD-4D9D-80C7-02AF85C822A8}");
1320 encoded.len()
1321 };
1322 assert_eq!(len, Braced::LENGTH);
1323 assert_uninit_tail_unchanged(&buf, len);
1324 }
1325
1326 fn assert_uninit_tail_unchanged(buffer: &[MaybeUninit<u8>], initialized: usize) {
1327 let buffer: &[u8] =
1329 unsafe { core::slice::from_raw_parts(buffer.as_ptr().cast(), buffer.len()) };
1330
1331 assert!(buffer[initialized..].iter().all(|b| *b == b'x'));
1332 }
1333
1334 #[test]
1335 fn hyphenated_trailing() {
1336 let mut buf = [b'x'; 100];
1337 let len = Uuid::nil().hyphenated().encode_lower(&mut buf).len();
1338 assert_eq!(len, super::Hyphenated::LENGTH);
1339 assert!(buf[len..].iter().all(|x| *x == b'x'));
1340 }
1341
1342 #[test]
1343 fn hyphenated_ref_trailing() {
1344 let mut buf = [b'x'; 100];
1345 let len = Uuid::nil().as_hyphenated().encode_lower(&mut buf).len();
1346 assert_eq!(len, super::Hyphenated::LENGTH);
1347 assert!(buf[len..].iter().all(|x| *x == b'x'));
1348 }
1349
1350 #[test]
1351 fn simple_trailing() {
1352 let mut buf = [b'x'; 100];
1353 let len = Uuid::nil().simple().encode_lower(&mut buf).len();
1354 assert_eq!(len, super::Simple::LENGTH);
1355 assert!(buf[len..].iter().all(|x| *x == b'x'));
1356 }
1357
1358 #[test]
1359 fn simple_ref_trailing() {
1360 let mut buf = [b'x'; 100];
1361 let len = Uuid::nil().as_simple().encode_lower(&mut buf).len();
1362 assert_eq!(len, super::Simple::LENGTH);
1363 assert!(buf[len..].iter().all(|x| *x == b'x'));
1364 }
1365
1366 #[test]
1367 fn urn_trailing() {
1368 let mut buf = [b'x'; 100];
1369 let len = Uuid::nil().urn().encode_lower(&mut buf).len();
1370 assert_eq!(len, super::Urn::LENGTH);
1371 assert!(buf[len..].iter().all(|x| *x == b'x'));
1372 }
1373
1374 #[test]
1375 fn urn_ref_trailing() {
1376 let mut buf = [b'x'; 100];
1377 let len = Uuid::nil().as_urn().encode_lower(&mut buf).len();
1378 assert_eq!(len, super::Urn::LENGTH);
1379 assert!(buf[len..].iter().all(|x| *x == b'x'));
1380 }
1381
1382 #[test]
1383 fn braced_trailing() {
1384 let mut buf = [b'x'; 100];
1385 let len = Uuid::nil().braced().encode_lower(&mut buf).len();
1386 assert_eq!(len, super::Braced::LENGTH);
1387 assert!(buf[len..].iter().all(|x| *x == b'x'));
1388 }
1389
1390 #[test]
1391 fn braced_ref_trailing() {
1392 let mut buf = [b'x'; 100];
1393 let len = Uuid::nil().as_braced().encode_lower(&mut buf).len();
1394 assert_eq!(len, super::Braced::LENGTH);
1395 assert!(buf[len..].iter().all(|x| *x == b'x'));
1396 }
1397
1398 #[test]
1399 #[should_panic]
1400 fn hyphenated_too_small() {
1401 Uuid::nil().hyphenated().encode_lower(&mut [0; 35]);
1402 }
1403
1404 #[test]
1405 #[should_panic]
1406 fn simple_too_small() {
1407 Uuid::nil().simple().encode_lower(&mut [0; 31]);
1408 }
1409
1410 #[test]
1411 #[should_panic]
1412 fn urn_too_small() {
1413 Uuid::nil().urn().encode_lower(&mut [0; 44]);
1414 }
1415
1416 #[test]
1417 #[should_panic]
1418 fn braced_too_small() {
1419 Uuid::nil().braced().encode_lower(&mut [0; 37]);
1420 }
1421
1422 #[test]
1423 fn hyphenated_to_inner() {
1424 let hyphenated = Uuid::nil().hyphenated();
1425 assert_eq!(Uuid::from(hyphenated), Uuid::nil());
1426 }
1427
1428 #[test]
1429 fn simple_to_inner() {
1430 let simple = Uuid::nil().simple();
1431 assert_eq!(Uuid::from(simple), Uuid::nil());
1432 }
1433
1434 #[test]
1435 fn urn_to_inner() {
1436 let urn = Uuid::nil().urn();
1437 assert_eq!(Uuid::from(urn), Uuid::nil());
1438 }
1439
1440 #[test]
1441 fn braced_to_inner() {
1442 let braced = Uuid::nil().braced();
1443 assert_eq!(Uuid::from(braced), Uuid::nil());
1444 }
1445}