1#![no_std]
209#![deny(missing_debug_implementations, missing_docs)]
210#![allow(clippy::mixed_attributes_style)]
211#![doc(
212 html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
213 html_favicon_url = "https://www.rust-lang.org/favicon.ico",
214 html_root_url = "https://docs.rs/uuid/1.20.0"
215)]
216
217#[cfg(any(feature = "std", test))]
218#[macro_use]
219extern crate std;
220
221#[cfg(all(not(feature = "std"), not(test)))]
222#[macro_use]
223extern crate core as std;
224
225#[macro_use]
226mod macros;
227
228mod builder;
229mod error;
230mod non_nil;
231mod parser;
232
233pub mod fmt;
234pub mod timestamp;
235
236use core::hash::{Hash, Hasher};
237pub use timestamp::{context::NoContext, ClockSequence, Timestamp};
238
239#[cfg(any(feature = "v1", feature = "v6"))]
240pub use timestamp::context::Context;
241
242#[cfg(feature = "v7")]
243pub use timestamp::context::ContextV7;
244
245#[cfg(feature = "v1")]
246#[doc(hidden)]
247pub mod v1;
250#[cfg(feature = "v3")]
251mod v3;
252#[cfg(feature = "v4")]
253mod v4;
254#[cfg(feature = "v5")]
255mod v5;
256#[cfg(feature = "v6")]
257mod v6;
258#[cfg(feature = "v7")]
259mod v7;
260#[cfg(feature = "v8")]
261mod v8;
262
263#[cfg(feature = "md5")]
264mod md5;
265#[cfg(feature = "rng")]
266mod rng;
267#[cfg(feature = "sha1")]
268mod sha1;
269
270mod external;
271
272#[doc(hidden)]
273pub mod __macro_support {
274 pub use crate::std::result::Result::{Err, Ok};
275}
276
277pub use crate::{builder::Builder, error::Error, non_nil::NonNilUuid};
278
279pub type Bytes = [u8; 16];
285
286#[derive(#[automatically_derived]
impl ::core::clone::Clone for Version {
#[inline]
fn clone(&self) -> Version { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Version { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Version {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Version::Nil => "Nil",
Version::Mac => "Mac",
Version::Dce => "Dce",
Version::Md5 => "Md5",
Version::Random => "Random",
Version::Sha1 => "Sha1",
Version::SortMac => "SortMac",
Version::SortRand => "SortRand",
Version::Custom => "Custom",
Version::Max => "Max",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Version {
#[inline]
fn eq(&self, other: &Version) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq)]
292#[non_exhaustive]
293#[repr(u8)]
294pub enum Version {
295 Nil = 0u8,
297 Mac = 1,
299 Dce = 2,
301 Md5 = 3,
303 Random = 4,
305 Sha1 = 5,
307 SortMac = 6,
309 SortRand = 7,
311 Custom = 8,
313 Max = 0xff,
315}
316
317#[derive(#[automatically_derived]
impl ::core::clone::Clone for Variant {
#[inline]
fn clone(&self) -> Variant { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Variant { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for Variant {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::write_str(f,
match self {
Variant::NCS => "NCS",
Variant::RFC4122 => "RFC4122",
Variant::Microsoft => "Microsoft",
Variant::Future => "Future",
})
}
}Debug, #[automatically_derived]
impl ::core::cmp::PartialEq for Variant {
#[inline]
fn eq(&self, other: &Variant) -> bool {
let __self_discr = ::core::intrinsics::discriminant_value(self);
let __arg1_discr = ::core::intrinsics::discriminant_value(other);
__self_discr == __arg1_discr
}
}PartialEq)]
323#[non_exhaustive]
324#[repr(u8)]
325pub enum Variant {
326 NCS = 0u8,
328 RFC4122,
331 Microsoft,
333 Future,
335}
336
337#[derive(#[automatically_derived]
impl ::core::clone::Clone for Uuid {
#[inline]
fn clone(&self) -> Uuid {
let _: ::core::clone::AssertParamIsClone<Bytes>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Uuid { }Copy, #[automatically_derived]
impl ::core::cmp::Eq for Uuid {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) {
let _: ::core::cmp::AssertParamIsEq<Bytes>;
}
}Eq, #[automatically_derived]
impl ::core::cmp::Ord for Uuid {
#[inline]
fn cmp(&self, other: &Uuid) -> ::core::cmp::Ordering {
::core::cmp::Ord::cmp(&self.0, &other.0)
}
}Ord, #[automatically_derived]
impl ::core::cmp::PartialEq for Uuid {
#[inline]
fn eq(&self, other: &Uuid) -> bool { self.0 == other.0 }
}PartialEq, #[automatically_derived]
impl ::core::cmp::PartialOrd for Uuid {
#[inline]
fn partial_cmp(&self, other: &Uuid)
-> ::core::option::Option<::core::cmp::Ordering> {
::core::cmp::PartialOrd::partial_cmp(&self.0, &other.0)
}
}PartialOrd)]
432#[repr(transparent)]
433#[cfg_attr(
435 feature = "borsh",
436 derive(borsh_derive::BorshDeserialize, borsh_derive::BorshSerialize)
437)]
438#[cfg_attr(
439 feature = "bytemuck",
440 derive(bytemuck::Zeroable, bytemuck::Pod, bytemuck::TransparentWrapper)
441)]
442#[cfg_attr(
443 all(uuid_unstable, feature = "zerocopy"),
444 derive(
445 zerocopy::IntoBytes,
446 zerocopy::FromBytes,
447 zerocopy::KnownLayout,
448 zerocopy::Immutable,
449 zerocopy::Unaligned
450 )
451)]
452pub struct Uuid(Bytes);
453
454impl Uuid {
455 pub const NAMESPACE_DNS: Self = Uuid([
457 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
458 0xc8,
459 ]);
460
461 pub const NAMESPACE_OID: Self = Uuid([
463 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
464 0xc8,
465 ]);
466
467 pub const NAMESPACE_URL: Self = Uuid([
469 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
470 0xc8,
471 ]);
472
473 pub const NAMESPACE_X500: Self = Uuid([
475 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30,
476 0xc8,
477 ]);
478
479 pub const fn get_variant(&self) -> Variant {
503 match self.as_bytes()[8] {
504 x if x & 0x80 == 0x00 => Variant::NCS,
505 x if x & 0xc0 == 0x80 => Variant::RFC4122,
506 x if x & 0xe0 == 0xc0 => Variant::Microsoft,
507 x if x & 0xe0 == 0xe0 => Variant::Future,
508 _ => Variant::Future,
512 }
513 }
514
515 pub const fn get_version_num(&self) -> usize {
538 (self.as_bytes()[6] >> 4) as usize
539 }
540
541 pub const fn get_version(&self) -> Option<Version> {
568 match self.get_version_num() {
569 0 if self.is_nil() => Some(Version::Nil),
570 1 => Some(Version::Mac),
571 2 => Some(Version::Dce),
572 3 => Some(Version::Md5),
573 4 => Some(Version::Random),
574 5 => Some(Version::Sha1),
575 6 => Some(Version::SortMac),
576 7 => Some(Version::SortRand),
577 8 => Some(Version::Custom),
578 0xf => Some(Version::Max),
579 _ => None,
580 }
581 }
582
583 pub fn as_fields(&self) -> (u32, u16, u16, &[u8; 8]) {
627 let bytes = self.as_bytes();
628
629 let d1 = (bytes[0] as u32) << 24
630 | (bytes[1] as u32) << 16
631 | (bytes[2] as u32) << 8
632 | (bytes[3] as u32);
633
634 let d2 = (bytes[4] as u16) << 8 | (bytes[5] as u16);
635
636 let d3 = (bytes[6] as u16) << 8 | (bytes[7] as u16);
637
638 let d4: &[u8; 8] = bytes[8..16].try_into().unwrap();
639 (d1, d2, d3, d4)
640 }
641
642 pub fn to_fields_le(&self) -> (u32, u16, u16, &[u8; 8]) {
670 let d1 = (self.as_bytes()[0] as u32)
671 | (self.as_bytes()[1] as u32) << 8
672 | (self.as_bytes()[2] as u32) << 16
673 | (self.as_bytes()[3] as u32) << 24;
674
675 let d2 = (self.as_bytes()[4] as u16) | (self.as_bytes()[5] as u16) << 8;
676
677 let d3 = (self.as_bytes()[6] as u16) | (self.as_bytes()[7] as u16) << 8;
678
679 let d4: &[u8; 8] = self.as_bytes()[8..16].try_into().unwrap();
680 (d1, d2, d3, d4)
681 }
682
683 pub const fn as_u128(&self) -> u128 {
702 u128::from_be_bytes(*self.as_bytes())
703 }
704
705 pub const fn to_u128_le(&self) -> u128 {
731 u128::from_le_bytes(*self.as_bytes())
732 }
733
734 pub const fn as_u64_pair(&self) -> (u64, u64) {
754 let value = self.as_u128();
755 ((value >> 64) as u64, value as u64)
756 }
757
758 #[inline]
785 pub const fn as_bytes(&self) -> &Bytes {
786 &self.0
787 }
788
789 #[inline]
805 pub const fn into_bytes(self) -> Bytes {
806 self.0
807 }
808
809 pub const fn to_bytes_le(&self) -> Bytes {
837 [
838 self.0[3], self.0[2], self.0[1], self.0[0], self.0[5], self.0[4], self.0[7], self.0[6],
839 self.0[8], self.0[9], self.0[10], self.0[11], self.0[12], self.0[13], self.0[14],
840 self.0[15],
841 ]
842 }
843
844 pub const fn is_nil(&self) -> bool {
846 self.as_u128() == u128::MIN
847 }
848
849 pub const fn is_max(&self) -> bool {
851 self.as_u128() == u128::MAX
852 }
853
854 pub const fn encode_buffer() -> [u8; fmt::Urn::LENGTH] {
880 [0; fmt::Urn::LENGTH]
881 }
882
883 pub const fn get_timestamp(&self) -> Option<Timestamp> {
893 match self.get_version() {
894 Some(Version::Mac) => {
895 let (ticks, counter) = timestamp::decode_gregorian_timestamp(self);
896
897 Some(Timestamp::from_gregorian(ticks, counter))
898 }
899 Some(Version::SortMac) => {
900 let (ticks, counter) = timestamp::decode_sorted_gregorian_timestamp(self);
901
902 Some(Timestamp::from_gregorian(ticks, counter))
903 }
904 Some(Version::SortRand) => {
905 let millis = timestamp::decode_unix_timestamp_millis(self);
906
907 let seconds = millis / 1000;
908 let nanos = ((millis % 1000) * 1_000_000) as u32;
909
910 Some(Timestamp::from_unix_time(seconds, nanos, 0, 0))
911 }
912 _ => None,
913 }
914 }
915
916 pub const fn get_node_id(&self) -> Option<[u8; 6]> {
919 match self.get_version() {
920 Some(Version::Mac) | Some(Version::SortMac) => {
921 let mut node_id = [0; 6];
922
923 node_id[0] = self.0[10];
924 node_id[1] = self.0[11];
925 node_id[2] = self.0[12];
926 node_id[3] = self.0[13];
927 node_id[4] = self.0[14];
928 node_id[5] = self.0[15];
929
930 Some(node_id)
931 }
932 _ => None,
933 }
934 }
935}
936
937impl Hash for Uuid {
938 fn hash<H: Hasher>(&self, state: &mut H) {
939 state.write(&self.0);
940 }
941}
942
943impl Default for Uuid {
944 #[inline]
945 fn default() -> Self {
946 Uuid::nil()
947 }
948}
949
950impl AsRef<Uuid> for Uuid {
951 #[inline]
952 fn as_ref(&self) -> &Uuid {
953 self
954 }
955}
956
957impl AsRef<[u8]> for Uuid {
958 #[inline]
959 fn as_ref(&self) -> &[u8] {
960 &self.0
961 }
962}
963
964#[cfg(feature = "std")]
965impl From<Uuid> for std::vec::Vec<u8> {
966 fn from(value: Uuid) -> Self {
967 value.0.to_vec()
968 }
969}
970
971#[cfg(feature = "std")]
972impl TryFrom<std::vec::Vec<u8>> for Uuid {
973 type Error = Error;
974
975 fn try_from(value: std::vec::Vec<u8>) -> Result<Self, Self::Error> {
976 Uuid::from_slice(&value)
977 }
978}
979
980#[cfg(feature = "serde")]
981pub mod serde {
982 pub use crate::external::serde_support::{braced, compact, simple, urn};
989}
990
991#[cfg(test)]
992mod tests {
993 use super::*;
994
995 use crate::std::string::{String, ToString};
996
997 #[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
998 use wasm_bindgen_test::*;
999
1000 macro_rules! check {
1001 ($buf:ident, $format:expr, $target:expr, $len:expr, $cond:expr) => {
1002 $buf.clear();
1003 write!($buf, $format, $target).unwrap();
1004 assert!($buf.len() == $len);
1005 assert!($buf.chars().all($cond), "{}", $buf);
1006 };
1007 }
1008
1009 pub const fn new() -> Uuid {
1010 Uuid::from_bytes([
1011 0xF9, 0x16, 0x8C, 0x5E, 0xCE, 0xB2, 0x4F, 0xAA, 0xB6, 0xBF, 0x32, 0x9B, 0xF3, 0x9F,
1012 0xA1, 0xE4,
1013 ])
1014 }
1015
1016 pub const fn new2() -> Uuid {
1017 Uuid::from_bytes([
1018 0xF9, 0x16, 0x8C, 0x5E, 0xCE, 0xB2, 0x4F, 0xAB, 0xB6, 0xBF, 0x32, 0x9B, 0xF3, 0x9F,
1019 0xA1, 0xE4,
1020 ])
1021 }
1022
1023 #[test]
1024 #[cfg_attr(
1025 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1026 wasm_bindgen_test
1027 )]
1028 fn test_uuid_compare() {
1029 let uuid1 = new();
1030 let uuid2 = new2();
1031
1032 assert_eq!(uuid1, uuid1);
1033 assert_eq!(uuid2, uuid2);
1034
1035 assert_ne!(uuid1, uuid2);
1036 assert_ne!(uuid2, uuid1);
1037 }
1038
1039 #[test]
1040 #[cfg_attr(
1041 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1042 wasm_bindgen_test
1043 )]
1044 fn test_uuid_default() {
1045 let default_uuid = Uuid::default();
1046 let nil_uuid = Uuid::nil();
1047
1048 assert_eq!(default_uuid, nil_uuid);
1049 }
1050
1051 #[test]
1052 #[cfg_attr(
1053 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1054 wasm_bindgen_test
1055 )]
1056 fn test_uuid_display() {
1057 use crate::std::fmt::Write;
1058
1059 let uuid = new();
1060 let s = uuid.to_string();
1061 let mut buffer = String::new();
1062
1063 assert_eq!(s, uuid.hyphenated().to_string());
1064
1065 check!(buffer, "{}", uuid, 36, |c| c.is_lowercase()
1066 || c.is_ascii_digit()
1067 || c == '-');
1068 }
1069
1070 #[test]
1071 #[cfg_attr(
1072 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1073 wasm_bindgen_test
1074 )]
1075 fn test_uuid_lowerhex() {
1076 use crate::std::fmt::Write;
1077
1078 let mut buffer = String::new();
1079 let uuid = new();
1080
1081 check!(buffer, "{:x}", uuid, 36, |c| c.is_lowercase()
1082 || c.is_ascii_digit()
1083 || c == '-');
1084 }
1085
1086 #[test]
1088 #[cfg_attr(
1089 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1090 wasm_bindgen_test
1091 )]
1092 fn test_uuid_operator_eq() {
1093 let uuid1 = new();
1094 let uuid1_dup = uuid1;
1095 let uuid2 = new2();
1096
1097 assert!(uuid1 == uuid1);
1098 assert!(uuid1 == uuid1_dup);
1099 assert!(uuid1_dup == uuid1);
1100
1101 assert!(uuid1 != uuid2);
1102 assert!(uuid2 != uuid1);
1103 assert!(uuid1_dup != uuid2);
1104 assert!(uuid2 != uuid1_dup);
1105 }
1106
1107 #[test]
1108 #[cfg_attr(
1109 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1110 wasm_bindgen_test
1111 )]
1112 fn test_uuid_to_string() {
1113 use crate::std::fmt::Write;
1114
1115 let uuid = new();
1116 let s = uuid.to_string();
1117 let mut buffer = String::new();
1118
1119 assert_eq!(s.len(), 36);
1120
1121 check!(buffer, "{}", s, 36, |c| c.is_lowercase()
1122 || c.is_ascii_digit()
1123 || c == '-');
1124 }
1125
1126 #[test]
1127 #[cfg_attr(
1128 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1129 wasm_bindgen_test
1130 )]
1131 fn test_non_conforming() {
1132 let from_bytes =
1133 Uuid::from_bytes([4, 54, 67, 12, 43, 2, 2, 76, 32, 50, 87, 5, 1, 33, 43, 87]);
1134
1135 assert_eq!(from_bytes.get_version(), None);
1136 }
1137
1138 #[test]
1139 #[cfg_attr(
1140 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1141 wasm_bindgen_test
1142 )]
1143 fn test_nil() {
1144 let nil = Uuid::nil();
1145 let not_nil = new();
1146
1147 assert!(nil.is_nil());
1148 assert!(!not_nil.is_nil());
1149
1150 assert_eq!(nil.get_version(), Some(Version::Nil));
1151 assert_eq!(not_nil.get_version(), Some(Version::Random));
1152
1153 assert_eq!(
1154 nil,
1155 Builder::from_bytes([0; 16])
1156 .with_version(Version::Nil)
1157 .into_uuid()
1158 );
1159 }
1160
1161 #[test]
1162 #[cfg_attr(
1163 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1164 wasm_bindgen_test
1165 )]
1166 fn test_max() {
1167 let max = Uuid::max();
1168 let not_max = new();
1169
1170 assert!(max.is_max());
1171 assert!(!not_max.is_max());
1172
1173 assert_eq!(max.get_version(), Some(Version::Max));
1174 assert_eq!(not_max.get_version(), Some(Version::Random));
1175
1176 assert_eq!(
1177 max,
1178 Builder::from_bytes([0xff; 16])
1179 .with_version(Version::Max)
1180 .into_uuid()
1181 );
1182 }
1183
1184 #[test]
1185 #[cfg_attr(
1186 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1187 wasm_bindgen_test
1188 )]
1189 fn test_predefined_namespaces() {
1190 assert_eq!(
1191 Uuid::NAMESPACE_DNS.hyphenated().to_string(),
1192 "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
1193 );
1194 assert_eq!(
1195 Uuid::NAMESPACE_URL.hyphenated().to_string(),
1196 "6ba7b811-9dad-11d1-80b4-00c04fd430c8"
1197 );
1198 assert_eq!(
1199 Uuid::NAMESPACE_OID.hyphenated().to_string(),
1200 "6ba7b812-9dad-11d1-80b4-00c04fd430c8"
1201 );
1202 assert_eq!(
1203 Uuid::NAMESPACE_X500.hyphenated().to_string(),
1204 "6ba7b814-9dad-11d1-80b4-00c04fd430c8"
1205 );
1206 }
1207
1208 #[cfg(feature = "v3")]
1209 #[test]
1210 #[cfg_attr(
1211 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1212 wasm_bindgen_test
1213 )]
1214 fn test_get_version_v3() {
1215 let uuid = Uuid::new_v3(&Uuid::NAMESPACE_DNS, "rust-lang.org".as_bytes());
1216
1217 assert_eq!(uuid.get_version().unwrap(), Version::Md5);
1218 assert_eq!(uuid.get_version_num(), 3);
1219 }
1220
1221 #[test]
1222 #[cfg_attr(
1223 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1224 wasm_bindgen_test
1225 )]
1226 fn test_get_timestamp_unsupported_version() {
1227 let uuid = new();
1228
1229 assert_ne!(Version::Mac, uuid.get_version().unwrap());
1230 assert_ne!(Version::SortMac, uuid.get_version().unwrap());
1231 assert_ne!(Version::SortRand, uuid.get_version().unwrap());
1232
1233 assert!(uuid.get_timestamp().is_none());
1234 }
1235
1236 #[test]
1237 #[cfg_attr(
1238 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1239 wasm_bindgen_test
1240 )]
1241 fn test_get_node_id_unsupported_version() {
1242 let uuid = new();
1243
1244 assert_ne!(Version::Mac, uuid.get_version().unwrap());
1245 assert_ne!(Version::SortMac, uuid.get_version().unwrap());
1246
1247 assert!(uuid.get_node_id().is_none());
1248 }
1249
1250 #[test]
1251 #[cfg_attr(
1252 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1253 wasm_bindgen_test
1254 )]
1255 fn test_get_variant() {
1256 let uuid1 = new();
1257 let uuid2 = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();
1258 let uuid3 = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap();
1259 let uuid4 = Uuid::parse_str("936DA01F9ABD4d9dC0C702AF85C822A8").unwrap();
1260 let uuid5 = Uuid::parse_str("F9168C5E-CEB2-4faa-D6BF-329BF39FA1E4").unwrap();
1261 let uuid6 = Uuid::parse_str("f81d4fae-7dec-11d0-7765-00a0c91e6bf6").unwrap();
1262
1263 assert_eq!(uuid1.get_variant(), Variant::RFC4122);
1264 assert_eq!(uuid2.get_variant(), Variant::RFC4122);
1265 assert_eq!(uuid3.get_variant(), Variant::RFC4122);
1266 assert_eq!(uuid4.get_variant(), Variant::Microsoft);
1267 assert_eq!(uuid5.get_variant(), Variant::Microsoft);
1268 assert_eq!(uuid6.get_variant(), Variant::NCS);
1269 }
1270
1271 #[test]
1272 #[cfg_attr(
1273 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1274 wasm_bindgen_test
1275 )]
1276 fn test_to_simple_string() {
1277 let uuid1 = new();
1278 let s = uuid1.simple().to_string();
1279
1280 assert_eq!(s.len(), 32);
1281 assert!(s.chars().all(|c| c.is_ascii_hexdigit()));
1282 }
1283
1284 #[test]
1285 #[cfg_attr(
1286 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1287 wasm_bindgen_test
1288 )]
1289 fn test_hyphenated_string() {
1290 let uuid1 = new();
1291 let s = uuid1.hyphenated().to_string();
1292
1293 assert_eq!(36, s.len());
1294 assert!(s.chars().all(|c| c.is_ascii_hexdigit() || c == '-'));
1295 }
1296
1297 #[test]
1298 #[cfg_attr(
1299 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1300 wasm_bindgen_test
1301 )]
1302 fn test_upper_lower_hex() {
1303 use std::fmt::Write;
1304
1305 let mut buf = String::new();
1306 let u = new();
1307
1308 macro_rules! check {
1309 ($buf:ident, $format:expr, $target:expr, $len:expr, $cond:expr) => {
1310 $buf.clear();
1311 write!($buf, $format, $target).unwrap();
1312 assert_eq!($len, buf.len());
1313 assert!($buf.chars().all($cond), "{}", $buf);
1314 };
1315 }
1316
1317 check!(buf, "{:x}", u, 36, |c| c.is_lowercase()
1318 || c.is_ascii_digit()
1319 || c == '-');
1320 check!(buf, "{:X}", u, 36, |c| c.is_uppercase()
1321 || c.is_ascii_digit()
1322 || c == '-');
1323 check!(buf, "{:#x}", u, 36, |c| c.is_lowercase()
1324 || c.is_ascii_digit()
1325 || c == '-');
1326 check!(buf, "{:#X}", u, 36, |c| c.is_uppercase()
1327 || c.is_ascii_digit()
1328 || c == '-');
1329
1330 check!(buf, "{:X}", u.hyphenated(), 36, |c| c.is_uppercase()
1331 || c.is_ascii_digit()
1332 || c == '-');
1333 check!(buf, "{:X}", u.simple(), 32, |c| c.is_uppercase()
1334 || c.is_ascii_digit());
1335 check!(buf, "{:#X}", u.hyphenated(), 36, |c| c.is_uppercase()
1336 || c.is_ascii_digit()
1337 || c == '-');
1338 check!(buf, "{:#X}", u.simple(), 32, |c| c.is_uppercase()
1339 || c.is_ascii_digit());
1340
1341 check!(buf, "{:x}", u.hyphenated(), 36, |c| c.is_lowercase()
1342 || c.is_ascii_digit()
1343 || c == '-');
1344 check!(buf, "{:x}", u.simple(), 32, |c| c.is_lowercase()
1345 || c.is_ascii_digit());
1346 check!(buf, "{:#x}", u.hyphenated(), 36, |c| c.is_lowercase()
1347 || c.is_ascii_digit()
1348 || c == '-');
1349 check!(buf, "{:#x}", u.simple(), 32, |c| c.is_lowercase()
1350 || c.is_ascii_digit());
1351 }
1352
1353 #[test]
1354 #[cfg_attr(
1355 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1356 wasm_bindgen_test
1357 )]
1358 fn test_to_urn_string() {
1359 let uuid1 = new();
1360 let ss = uuid1.urn().to_string();
1361 let s = &ss[9..];
1362
1363 assert!(ss.starts_with("urn:uuid:"));
1364 assert_eq!(s.len(), 36);
1365 assert!(s.chars().all(|c| c.is_ascii_hexdigit() || c == '-'));
1366 }
1367
1368 #[test]
1369 #[cfg_attr(
1370 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1371 wasm_bindgen_test
1372 )]
1373 fn test_to_simple_string_matching() {
1374 let uuid1 = new();
1375
1376 let hs = uuid1.hyphenated().to_string();
1377 let ss = uuid1.simple().to_string();
1378
1379 let hsn = hs.chars().filter(|&c| c != '-').collect::<String>();
1380
1381 assert_eq!(hsn, ss);
1382 }
1383
1384 #[test]
1385 #[cfg_attr(
1386 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1387 wasm_bindgen_test
1388 )]
1389 fn test_string_roundtrip() {
1390 let uuid = new();
1391
1392 let hs = uuid.hyphenated().to_string();
1393 let uuid_hs = Uuid::parse_str(&hs).unwrap();
1394 assert_eq!(uuid_hs, uuid);
1395
1396 let ss = uuid.to_string();
1397 let uuid_ss = Uuid::parse_str(&ss).unwrap();
1398 assert_eq!(uuid_ss, uuid);
1399 }
1400
1401 #[test]
1402 #[cfg_attr(
1403 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1404 wasm_bindgen_test
1405 )]
1406 fn test_from_fields() {
1407 let d1: u32 = 0xa1a2a3a4;
1408 let d2: u16 = 0xb1b2;
1409 let d3: u16 = 0xc1c2;
1410 let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
1411
1412 let u = Uuid::from_fields(d1, d2, d3, &d4);
1413
1414 let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1415 let result = u.simple().to_string();
1416 assert_eq!(result, expected);
1417 }
1418
1419 #[test]
1420 #[cfg_attr(
1421 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1422 wasm_bindgen_test
1423 )]
1424 fn test_from_fields_le() {
1425 let d1: u32 = 0xa4a3a2a1;
1426 let d2: u16 = 0xb2b1;
1427 let d3: u16 = 0xc2c1;
1428 let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
1429
1430 let u = Uuid::from_fields_le(d1, d2, d3, &d4);
1431
1432 let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1433 let result = u.simple().to_string();
1434 assert_eq!(result, expected);
1435 }
1436
1437 #[test]
1438 #[cfg_attr(
1439 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1440 wasm_bindgen_test
1441 )]
1442 fn test_as_fields() {
1443 let u = new();
1444 let (d1, d2, d3, d4) = u.as_fields();
1445
1446 assert_ne!(d1, 0);
1447 assert_ne!(d2, 0);
1448 assert_ne!(d3, 0);
1449 assert_eq!(d4.len(), 8);
1450 assert!(!d4.iter().all(|&b| b == 0));
1451 }
1452
1453 #[test]
1454 #[cfg_attr(
1455 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1456 wasm_bindgen_test
1457 )]
1458 fn test_fields_roundtrip() {
1459 let d1_in: u32 = 0xa1a2a3a4;
1460 let d2_in: u16 = 0xb1b2;
1461 let d3_in: u16 = 0xc1c2;
1462 let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
1463
1464 let u = Uuid::from_fields(d1_in, d2_in, d3_in, d4_in);
1465 let (d1_out, d2_out, d3_out, d4_out) = u.as_fields();
1466
1467 assert_eq!(d1_in, d1_out);
1468 assert_eq!(d2_in, d2_out);
1469 assert_eq!(d3_in, d3_out);
1470 assert_eq!(d4_in, d4_out);
1471 }
1472
1473 #[test]
1474 #[cfg_attr(
1475 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1476 wasm_bindgen_test
1477 )]
1478 fn test_fields_le_roundtrip() {
1479 let d1_in: u32 = 0xa4a3a2a1;
1480 let d2_in: u16 = 0xb2b1;
1481 let d3_in: u16 = 0xc2c1;
1482 let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
1483
1484 let u = Uuid::from_fields_le(d1_in, d2_in, d3_in, d4_in);
1485 let (d1_out, d2_out, d3_out, d4_out) = u.to_fields_le();
1486
1487 assert_eq!(d1_in, d1_out);
1488 assert_eq!(d2_in, d2_out);
1489 assert_eq!(d3_in, d3_out);
1490 assert_eq!(d4_in, d4_out);
1491 }
1492
1493 #[test]
1494 #[cfg_attr(
1495 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1496 wasm_bindgen_test
1497 )]
1498 fn test_fields_le_are_actually_le() {
1499 let d1_in: u32 = 0xa1a2a3a4;
1500 let d2_in: u16 = 0xb1b2;
1501 let d3_in: u16 = 0xc1c2;
1502 let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
1503
1504 let u = Uuid::from_fields(d1_in, d2_in, d3_in, d4_in);
1505 let (d1_out, d2_out, d3_out, d4_out) = u.to_fields_le();
1506
1507 assert_eq!(d1_in, d1_out.swap_bytes());
1508 assert_eq!(d2_in, d2_out.swap_bytes());
1509 assert_eq!(d3_in, d3_out.swap_bytes());
1510 assert_eq!(d4_in, d4_out);
1511 }
1512
1513 #[test]
1514 #[cfg_attr(
1515 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1516 wasm_bindgen_test
1517 )]
1518 fn test_from_u128() {
1519 let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8;
1520
1521 let u = Uuid::from_u128(v_in);
1522
1523 let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1524 let result = u.simple().to_string();
1525 assert_eq!(result, expected);
1526 }
1527
1528 #[test]
1529 #[cfg_attr(
1530 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1531 wasm_bindgen_test
1532 )]
1533 fn test_from_u128_le() {
1534 let v_in: u128 = 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1;
1535
1536 let u = Uuid::from_u128_le(v_in);
1537
1538 let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1539 let result = u.simple().to_string();
1540 assert_eq!(result, expected);
1541 }
1542
1543 #[test]
1544 #[cfg_attr(
1545 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1546 wasm_bindgen_test
1547 )]
1548 fn test_from_u64_pair() {
1549 let high_in: u64 = 0xa1a2a3a4b1b2c1c2;
1550 let low_in: u64 = 0xd1d2d3d4d5d6d7d8;
1551
1552 let u = Uuid::from_u64_pair(high_in, low_in);
1553
1554 let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1555 let result = u.simple().to_string();
1556 assert_eq!(result, expected);
1557 }
1558
1559 #[test]
1560 #[cfg_attr(
1561 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1562 wasm_bindgen_test
1563 )]
1564 fn test_u128_roundtrip() {
1565 let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8;
1566
1567 let u = Uuid::from_u128(v_in);
1568 let v_out = u.as_u128();
1569
1570 assert_eq!(v_in, v_out);
1571 }
1572
1573 #[test]
1574 #[cfg_attr(
1575 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1576 wasm_bindgen_test
1577 )]
1578 fn test_u128_le_roundtrip() {
1579 let v_in: u128 = 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1;
1580
1581 let u = Uuid::from_u128_le(v_in);
1582 let v_out = u.to_u128_le();
1583
1584 assert_eq!(v_in, v_out);
1585 }
1586
1587 #[test]
1588 #[cfg_attr(
1589 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1590 wasm_bindgen_test
1591 )]
1592 fn test_u64_pair_roundtrip() {
1593 let high_in: u64 = 0xa1a2a3a4b1b2c1c2;
1594 let low_in: u64 = 0xd1d2d3d4d5d6d7d8;
1595
1596 let u = Uuid::from_u64_pair(high_in, low_in);
1597 let (high_out, low_out) = u.as_u64_pair();
1598
1599 assert_eq!(high_in, high_out);
1600 assert_eq!(low_in, low_out);
1601 }
1602
1603 #[test]
1604 #[cfg_attr(
1605 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1606 wasm_bindgen_test
1607 )]
1608 fn test_u128_le_is_actually_le() {
1609 let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8;
1610
1611 let u = Uuid::from_u128(v_in);
1612 let v_out = u.to_u128_le();
1613
1614 assert_eq!(v_in, v_out.swap_bytes());
1615 }
1616
1617 #[test]
1618 #[cfg_attr(
1619 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1620 wasm_bindgen_test
1621 )]
1622 fn test_from_slice() {
1623 let b = [
1624 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
1625 0xd7, 0xd8,
1626 ];
1627
1628 let u = Uuid::from_slice(&b).unwrap();
1629 let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1630
1631 assert_eq!(u.simple().to_string(), expected);
1632 }
1633
1634 #[test]
1635 #[cfg_attr(
1636 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1637 wasm_bindgen_test
1638 )]
1639 fn test_from_bytes() {
1640 let b = [
1641 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
1642 0xd7, 0xd8,
1643 ];
1644
1645 let u = Uuid::from_bytes(b);
1646 let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";
1647
1648 assert_eq!(u.simple().to_string(), expected);
1649 }
1650
1651 #[test]
1652 #[cfg_attr(
1653 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1654 wasm_bindgen_test
1655 )]
1656 fn test_as_bytes() {
1657 let u = new();
1658 let ub = u.as_bytes();
1659 let ur: &[u8] = u.as_ref();
1660
1661 assert_eq!(ub.len(), 16);
1662 assert_eq!(ur.len(), 16);
1663 assert!(!ub.iter().all(|&b| b == 0));
1664 assert!(!ur.iter().all(|&b| b == 0));
1665 }
1666
1667 #[test]
1668 #[cfg(feature = "std")]
1669 #[cfg_attr(
1670 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1671 wasm_bindgen_test
1672 )]
1673 fn test_convert_vec() {
1674 let u = new();
1675 let ub: &[u8] = u.as_ref();
1676
1677 let v: std::vec::Vec<u8> = u.into();
1678
1679 assert_eq!(&v, ub);
1680
1681 let uv: Uuid = v.try_into().unwrap();
1682
1683 assert_eq!(uv, u);
1684 }
1685
1686 #[test]
1687 #[cfg_attr(
1688 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1689 wasm_bindgen_test
1690 )]
1691 fn test_bytes_roundtrip() {
1692 let b_in: crate::Bytes = [
1693 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
1694 0xd7, 0xd8,
1695 ];
1696
1697 let u = Uuid::from_slice(&b_in).unwrap();
1698
1699 let b_out = u.as_bytes();
1700
1701 assert_eq!(&b_in, b_out);
1702 }
1703
1704 #[test]
1705 #[cfg_attr(
1706 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1707 wasm_bindgen_test
1708 )]
1709 fn test_bytes_le_roundtrip() {
1710 let b = [
1711 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
1712 0xd7, 0xd8,
1713 ];
1714
1715 let u1 = Uuid::from_bytes(b);
1716
1717 let b_le = u1.to_bytes_le();
1718
1719 let u2 = Uuid::from_bytes_le(b_le);
1720
1721 assert_eq!(u1, u2);
1722 }
1723
1724 #[test]
1725 #[cfg_attr(
1726 all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
1727 wasm_bindgen_test
1728 )]
1729 fn test_iterbytes_impl_for_uuid() {
1730 let mut set = std::collections::HashSet::new();
1731 let id1 = new();
1732 let id2 = new2();
1733 set.insert(id1);
1734
1735 assert!(set.contains(&id1));
1736 assert!(!set.contains(&id2));
1737 }
1738}