1 // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
12 Generate and parse UUIDs
14 Provides support for Universally Unique Identifiers (UUIDs). A UUID is a
15 unique 128-bit number, stored as 16 octets. UUIDs are used to assign unique
16 identifiers to entities without requiring a central allocating authority.
18 They are particularly useful in distributed systems, though can be used in
19 disparate areas, such as databases and network protocols. Typically a UUID is
20 displayed in a readable string form as a sequence of hexadecimal digits,
21 separated into groups by hyphens.
23 The uniqueness property is not strictly guaranteed, however for all practical
24 purposes, it can be assumed that an unintentional collision would be extremely
29 To create a new random (V4) UUID and print it out in hexadecimal form:
35 let uuid1 = Uuid::new_v4();
36 println!("{}", uuid1.to_str());
42 Examples of string representations:
44 * simple: `936DA01F9ABD4d9d80C702AF85C822A8`
45 * hyphenated: `550e8400-e29b-41d4-a716-446655440000`
46 * urn: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4`
50 * [Wikipedia: Universally Unique Identifier](
51 http://en.wikipedia.org/wiki/Universally_unique_identifier)
52 * [RFC4122: A Universally Unique IDentifier (UUID) URN Namespace](
53 http://tools.ietf.org/html/rfc4122)
57 #![crate_id = "uuid#0.11.0-pre"]
59 #![crate_type = "rlib"]
60 #![crate_type = "dylib"]
61 #![license = "MIT/ASL2"]
62 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
63 html_favicon_url = "http://www.rust-lang.org/favicon.ico",
64 html_root_url = "http://doc.rust-lang.org/",
65 html_playground_url = "http://play.rust-lang.org/")]
67 #![feature(default_type_params)]
69 // test harness access
72 extern crate serialize;
75 use std::default::Default;
77 use std::from_str::FromStr;
79 use std::mem::{transmute,transmute_copy};
80 use std::num::FromStrRadix;
86 use serialize::{Encoder, Encodable, Decoder, Decodable};
88 /// A 128-bit (16 byte) buffer containing the ID
89 pub type UuidBytes = [u8, ..16];
91 /// The version of the UUID, denoting the generating algorithm
92 #[deriving(PartialEq)]
93 pub enum UuidVersion {
94 /// Version 1: MAC address
96 /// Version 2: DCE Security
98 /// Version 3: MD5 hash
100 /// Version 4: Random
102 /// Version 5: SHA-1 hash
106 /// The reserved variants of UUIDs
107 #[deriving(PartialEq)]
108 pub enum UuidVariant {
109 /// Reserved by the NCS for backward compatibility
111 /// As described in the RFC4122 Specification (default)
113 /// Reserved by Microsoft for backward compatibility
115 /// Reserved for future expansion
119 /// A Universally Unique Identifier (UUID)
121 /// The 128-bit number stored in 16 bytes
125 impl<S: hash::Writer> hash::Hash<S> for Uuid {
126 fn hash(&self, state: &mut S) {
127 self.bytes.hash(state)
131 /// A UUID stored as fields (identical to UUID, used only for conversions)
133 /// First field, 32-bit word
135 /// Second field, 16-bit short
137 /// Third field, 16-bit short
139 /// Fourth field, 8 bytes
143 /// Error details for string parsing failures
144 #[allow(missing_doc)]
145 pub enum ParseError {
146 ErrorInvalidLength(uint),
147 ErrorInvalidCharacter(char, uint),
148 ErrorInvalidGroups(uint),
149 ErrorInvalidGroupLength(uint, uint, uint),
152 /// Converts a ParseError to a string
153 impl fmt::Show for ParseError {
154 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
156 ErrorInvalidLength(found) =>
157 write!(f, "Invalid length; expecting 32, 36 or 45 chars, \
159 ErrorInvalidCharacter(found, pos) =>
160 write!(f, "Invalid character; found `{}` (0x{:02x}) at \
161 offset {}", found, found as uint, pos),
162 ErrorInvalidGroups(found) =>
163 write!(f, "Malformed; wrong number of groups: expected 1 \
164 or 5, found {}", found),
165 ErrorInvalidGroupLength(group, found, expecting) =>
166 write!(f, "Malformed; length of group {} was {}, \
167 expecting {}", group, found, expecting),
172 // Length of each hyphenated group in hex digits
173 static UuidGroupLens: [uint, ..5] = [8u, 4u, 4u, 4u, 12u];
177 /// Returns a nil or empty UUID (containing all zeroes)
178 pub fn nil() -> Uuid {
179 let uuid = Uuid{ bytes: [0, .. 16] };
183 /// Create a new UUID of the specified version
184 pub fn new(v: UuidVersion) -> Option<Uuid> {
186 Version4Random => Some(Uuid::new_v4()),
191 /// Creates a new random UUID
193 /// Uses the `rand` module's default RNG task as the source
194 /// of random numbers. Use the rand::Rand trait to supply
195 /// a custom generator if required.
196 pub fn new_v4() -> Uuid {
197 let ub = rand::task_rng().gen_iter::<u8>().take(16).collect::<Vec<_>>();
198 let mut uuid = Uuid{ bytes: [0, .. 16] };
199 slice::bytes::copy_memory(uuid.bytes, ub.as_slice());
200 uuid.set_variant(VariantRFC4122);
201 uuid.set_version(Version4Random);
205 /// Creates a UUID using the supplied field values
208 /// * `d1` A 32-bit word
209 /// * `d2` A 16-bit word
210 /// * `d3` A 16-bit word
211 /// * `d4` Array of 8 octets
212 pub fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8]) -> Uuid {
213 // First construct a temporary field-based struct
214 let mut fields = UuidFields {
221 fields.data1 = d1.to_be();
222 fields.data2 = d2.to_be();
223 fields.data3 = d3.to_be();
224 slice::bytes::copy_memory(fields.data4, d4);
231 /// Creates a UUID using the supplied bytes
234 /// * `b` An array or slice of 16 bytes
235 pub fn from_bytes(b: &[u8]) -> Option<Uuid> {
240 let mut uuid = Uuid{ bytes: [0, .. 16] };
241 slice::bytes::copy_memory(uuid.bytes, b);
245 /// Specifies the variant of the UUID structure
246 fn set_variant(&mut self, v: UuidVariant) {
247 // Octet 8 contains the variant in the most significant 3 bits
249 VariantNCS => // b0xx...
250 self.bytes[8] = self.bytes[8] & 0x7f,
251 VariantRFC4122 => // b10x...
252 self.bytes[8] = (self.bytes[8] & 0x3f) | 0x80,
253 VariantMicrosoft => // b110...
254 self.bytes[8] = (self.bytes[8] & 0x1f) | 0xc0,
255 VariantFuture => // b111...
256 self.bytes[8] = (self.bytes[8] & 0x1f) | 0xe0,
260 /// Returns the variant of the UUID structure
262 /// This determines the interpretation of the structure of the UUID.
263 /// Currently only the RFC4122 variant is generated by this module.
265 /// * [Variant Reference](http://tools.ietf.org/html/rfc4122#section-4.1.1)
266 pub fn get_variant(&self) -> Option<UuidVariant> {
267 if self.bytes[8] & 0x80 == 0x00 {
269 } else if self.bytes[8] & 0xc0 == 0x80 {
271 } else if self.bytes[8] & 0xe0 == 0xc0 {
272 Some(VariantMicrosoft)
273 } else if self.bytes[8] & 0xe0 == 0xe0 {
280 /// Specifies the version number of the UUID
281 fn set_version(&mut self, v: UuidVersion) {
282 self.bytes[6] = (self.bytes[6] & 0xF) | ((v as u8) << 4);
285 /// Returns the version number of the UUID
287 /// This represents the algorithm used to generate the contents.
289 /// Currently only the Random (V4) algorithm is supported by this
290 /// module. There are security and privacy implications for using
291 /// older versions - see [Wikipedia: Universally Unique Identifier](
292 /// http://en.wikipedia.org/wiki/Universally_unique_identifier) for
295 /// * [Version Reference](http://tools.ietf.org/html/rfc4122#section-4.1.3)
296 pub fn get_version_num(&self) -> uint {
297 (self.bytes[6] >> 4) as uint
300 /// Returns the version of the UUID
302 /// This represents the algorithm used to generate the contents
303 pub fn get_version(&self) -> Option<UuidVersion> {
304 let v = self.bytes[6] >> 4;
306 1 => Some(Version1Mac),
307 2 => Some(Version2Dce),
308 3 => Some(Version3Md5),
309 4 => Some(Version4Random),
310 5 => Some(Version5Sha1),
315 /// Return an array of 16 octets containing the UUID data
316 pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
317 self.bytes.as_slice()
320 /// Returns the UUID as a string of 16 hexadecimal digits
322 /// Example: `936DA01F9ABD4d9d80C702AF85C822A8`
323 pub fn to_simple_str(&self) -> String {
324 let mut s: Vec<u8> = Vec::from_elem(32, 0u8);
325 for i in range(0u, 16u) {
326 let digit = format!("{:02x}", self.bytes[i] as uint);
327 *s.get_mut(i*2+0) = digit.as_bytes()[0];
328 *s.get_mut(i*2+1) = digit.as_bytes()[1];
330 str::from_utf8(s.as_slice()).unwrap().to_string()
333 /// Returns a string of hexadecimal digits, separated into groups with a hyphen.
335 /// Example: `550e8400-e29b-41d4-a716-446655440000`
336 pub fn to_hyphenated_str(&self) -> String {
337 // Convert to field-based struct as it matches groups in output.
338 // Ensure fields are in network byte order, as per RFC.
339 let mut uf: UuidFields;
341 uf = transmute_copy(&self.bytes);
343 uf.data1 = uf.data1.to_be();
344 uf.data2 = uf.data2.to_be();
345 uf.data3 = uf.data3.to_be();
346 let s = format!("{:08x}-{:04x}-{:04x}-{:02x}{:02x}-\
347 {:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
350 uf.data4[0], uf.data4[1],
351 uf.data4[2], uf.data4[3], uf.data4[4],
352 uf.data4[5], uf.data4[6], uf.data4[7]);
356 /// Returns the UUID formatted as a full URN string
358 /// This is the same as the hyphenated format, but with the "urn:uuid:" prefix.
360 /// Example: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4`
361 pub fn to_urn_str(&self) -> String {
362 format!("urn:uuid:{}", self.to_hyphenated_str())
365 /// Parses a UUID from a string of hexadecimal digits with optional hyphens
367 /// Any of the formats generated by this module (simple, hyphenated, urn) are
368 /// supported by this parsing function.
369 pub fn parse_string(us: &str) -> Result<Uuid, ParseError> {
371 let mut us = us.clone();
372 let orig_len = us.len();
374 // Ensure length is valid for any of the supported formats
375 if orig_len != 32 && orig_len != 36 && orig_len != 45 {
376 return Err(ErrorInvalidLength(orig_len));
379 // Strip off URN prefix if present
380 if us.starts_with("urn:uuid:") {
381 us = us.slice(9, orig_len);
384 // Make sure all chars are either hex digits or hyphen
385 for (i, c) in us.chars().enumerate() {
387 '0'..'9' | 'A'..'F' | 'a'..'f' | '-' => {},
388 _ => return Err(ErrorInvalidCharacter(c, i)),
392 // Split string up by hyphens into groups
393 let hex_groups: Vec<&str> = us.split_str("-").collect();
395 // Get the length of each group
396 let group_lens: Vec<uint> = hex_groups.iter().map(|&v| v.len()).collect();
398 // Ensure the group lengths are valid
399 match group_lens.len() {
400 // Single group, no hyphens
402 if *group_lens.get(0) != 32 {
403 return Err(ErrorInvalidLength(*group_lens.get(0)));
406 // Five groups, hyphens in between each
408 // Ensure each group length matches the expected
409 for (i, (&gl, &expected)) in
410 group_lens.iter().zip(UuidGroupLens.iter()).enumerate() {
412 return Err(ErrorInvalidGroupLength(i, gl, expected))
417 return Err(ErrorInvalidGroups(group_lens.len()));
421 // Normalise into one long hex string
422 let vs = hex_groups.concat();
424 // At this point, we know we have a valid hex string, without hyphens
425 assert!(vs.len() == 32);
426 assert!(vs.as_slice().chars().all(|c| c.is_digit_radix(16)));
428 // Allocate output UUID buffer
429 let mut ub = [0u8, ..16];
431 // Extract each hex digit from the string
432 for i in range(0u, 16u) {
433 ub[i] = FromStrRadix::from_str_radix(vs.as_slice()
434 .slice(i*2, (i+1)*2),
438 Ok(Uuid::from_bytes(ub).unwrap())
441 /// Tests if the UUID is nil
442 pub fn is_nil(&self) -> bool {
443 return self.bytes.iter().all(|&b| b == 0);
447 impl Default for Uuid {
448 /// Returns the nil UUID, which is all zeroes
449 fn default() -> Uuid {
454 impl Clone for Uuid {
455 /// Returns a copy of the UUID
456 fn clone(&self) -> Uuid { *self }
459 impl FromStr for Uuid {
460 /// Parse a hex string and interpret as a UUID
462 /// Accepted formats are a sequence of 32 hexadecimal characters,
463 /// with or without hyphens (grouped as 8, 4, 4, 4, 12).
464 fn from_str(us: &str) -> Option<Uuid> {
465 let result = Uuid::parse_string(us);
473 /// Convert the UUID to a hexadecimal-based string representation
474 impl fmt::Show for Uuid {
475 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
476 write!(f, "{}", self.to_simple_str())
480 /// Test two UUIDs for equality
482 /// UUIDs are equal only when they are byte-for-byte identical
483 impl PartialEq for Uuid {
484 fn eq(&self, other: &Uuid) -> bool {
485 self.bytes == other.bytes
491 // FIXME #9845: Test these more thoroughly
492 impl<T: Encoder<E>, E> Encodable<T, E> for Uuid {
493 /// Encode a UUID as a hyphenated string
494 fn encode(&self, e: &mut T) -> Result<(), E> {
495 e.emit_str(self.to_hyphenated_str().as_slice())
499 impl<T: Decoder<E>, E> Decodable<T, E> for Uuid {
500 /// Decode a UUID from a string
501 fn decode(d: &mut T) -> Result<Uuid, E> {
502 Ok(from_str(try!(d.read_str()).as_slice()).unwrap())
506 /// Generates a random instance of UUID (V4 conformant)
507 impl rand::Rand for Uuid {
509 fn rand<R: rand::Rng>(rng: &mut R) -> Uuid {
510 let ub = rng.gen_iter::<u8>().take(16).collect::<Vec<_>>();
511 let mut uuid = Uuid{ bytes: [0, .. 16] };
512 slice::bytes::copy_memory(uuid.bytes, ub.as_slice());
513 uuid.set_variant(VariantRFC4122);
514 uuid.set_version(Version4Random);
521 use super::{Uuid, VariantMicrosoft, VariantNCS, VariantRFC4122,
522 Version1Mac, Version2Dce, Version3Md5, Version4Random,
525 use std::io::MemWriter;
530 let nil = Uuid::nil();
531 let not_nil = Uuid::new_v4();
533 assert!(nil.is_nil());
534 assert!(!not_nil.is_nil());
540 let uuid1 = Uuid::new(Version4Random).unwrap();
541 let s = uuid1.to_simple_str();
543 assert!(s.len() == 32);
544 assert!(uuid1.get_version().unwrap() == Version4Random);
546 // Test unsupported versions
547 assert!(Uuid::new(Version1Mac) == None);
548 assert!(Uuid::new(Version2Dce) == None);
549 assert!(Uuid::new(Version3Md5) == None);
550 assert!(Uuid::new(Version5Sha1) == None);
555 let uuid1 = Uuid::new_v4();
557 assert!(uuid1.get_version().unwrap() == Version4Random);
558 assert!(uuid1.get_variant().unwrap() == VariantRFC4122);
562 fn test_get_version() {
563 let uuid1 = Uuid::new_v4();
565 assert!(uuid1.get_version().unwrap() == Version4Random);
566 assert!(uuid1.get_version_num() == 4);
570 fn test_get_variant() {
571 let uuid1 = Uuid::new_v4();
572 let uuid2 = Uuid::parse_string("550e8400-e29b-41d4-a716-446655440000").unwrap();
573 let uuid3 = Uuid::parse_string("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap();
574 let uuid4 = Uuid::parse_string("936DA01F9ABD4d9dC0C702AF85C822A8").unwrap();
575 let uuid5 = Uuid::parse_string("F9168C5E-CEB2-4faa-D6BF-329BF39FA1E4").unwrap();
576 let uuid6 = Uuid::parse_string("f81d4fae-7dec-11d0-7765-00a0c91e6bf6").unwrap();
578 assert!(uuid1.get_variant().unwrap() == VariantRFC4122);
579 assert!(uuid2.get_variant().unwrap() == VariantRFC4122);
580 assert!(uuid3.get_variant().unwrap() == VariantRFC4122);
581 assert!(uuid4.get_variant().unwrap() == VariantMicrosoft);
582 assert!(uuid5.get_variant().unwrap() == VariantMicrosoft);
583 assert!(uuid6.get_variant().unwrap() == VariantNCS);
587 fn test_parse_uuid_v4() {
588 use super::{ErrorInvalidCharacter, ErrorInvalidGroups,
589 ErrorInvalidGroupLength, ErrorInvalidLength};
592 assert!(Uuid::parse_string("").is_err());
593 assert!(Uuid::parse_string("!").is_err());
594 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45").is_err());
595 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4").is_err());
596 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4").is_err());
597 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4").is_err());
598 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa").is_err());
599 assert!(Uuid::parse_string("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4").is_err());
600 assert!(Uuid::parse_string("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4").is_err());
601 assert!(Uuid::parse_string("01020304-1112-2122-3132-41424344").is_err());
602 assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c").is_err());
603 assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c88").is_err());
604 assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0cg8").is_err());
605 assert!(Uuid::parse_string("67e5504410b1426%9247bb680e5fe0c8").is_err());
608 assert!(Uuid::parse_string("00000000000000000000000000000000").is_ok());
609 assert!(Uuid::parse_string("67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok());
610 assert!(Uuid::parse_string("67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok());
611 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").is_ok());
612 assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c8").is_ok());
613 assert!(Uuid::parse_string("01020304-1112-2122-3132-414243444546").is_ok());
614 assert!(Uuid::parse_string("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok());
617 let nil = Uuid::nil();
618 assert!(Uuid::parse_string("00000000000000000000000000000000").unwrap() == nil);
619 assert!(Uuid::parse_string("00000000-0000-0000-0000-000000000000").unwrap() == nil);
622 let uuid_orig = Uuid::new_v4();
623 let orig_str = uuid_orig.to_str();
624 let uuid_out = Uuid::parse_string(orig_str.as_slice()).unwrap();
625 assert!(uuid_orig == uuid_out);
627 // Test error reporting
628 let e = Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c").unwrap_err();
629 assert!(match e { ErrorInvalidLength(n) => n==31, _ => false });
631 let e = Uuid::parse_string("67e550X410b1426f9247bb680e5fe0cd").unwrap_err();
632 assert!(match e { ErrorInvalidCharacter(c, n) => c=='X' && n==6, _ => false });
634 let e = Uuid::parse_string("67e550-4105b1426f9247bb680e5fe0c").unwrap_err();
635 assert!(match e { ErrorInvalidGroups(n) => n==2, _ => false });
637 let e = Uuid::parse_string("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4").unwrap_err();
638 assert!(match e { ErrorInvalidGroupLength(g, n, e) => g==3 && n==5 && e==4, _ => false });
642 fn test_to_simple_str() {
643 let uuid1 = Uuid::new_v4();
644 let s = uuid1.to_simple_str();
646 assert!(s.len() == 32);
647 assert!(s.as_slice().chars().all(|c| c.is_digit_radix(16)));
652 let uuid1 = Uuid::new_v4();
653 let s = uuid1.to_str();
655 assert!(s.len() == 32);
656 assert!(s.as_slice().chars().all(|c| c.is_digit_radix(16)));
660 fn test_to_hyphenated_str() {
661 let uuid1 = Uuid::new_v4();
662 let s = uuid1.to_hyphenated_str();
664 assert!(s.len() == 36);
665 assert!(s.as_slice().chars().all(|c| c.is_digit_radix(16) || c == '-'));
669 fn test_to_urn_str() {
670 let uuid1 = Uuid::new_v4();
671 let ss = uuid1.to_urn_str();
672 let s = ss.as_slice().slice(9, ss.len());
674 assert!(ss.as_slice().starts_with("urn:uuid:"));
675 assert!(s.len() == 36);
678 .all(|c| c.is_digit_radix(16) || c == '-'));
682 fn test_to_str_matching() {
683 let uuid1 = Uuid::new_v4();
685 let hs = uuid1.to_hyphenated_str();
686 let ss = uuid1.to_str();
688 let hsn = str::from_chars(hs.as_slice()
690 .filter(|&c| c != '-')
691 .collect::<Vec<char>>()
698 fn test_string_roundtrip() {
699 let uuid = Uuid::new_v4();
701 let hs = uuid.to_hyphenated_str();
702 let uuid_hs = Uuid::parse_string(hs.as_slice()).unwrap();
703 assert!(uuid_hs == uuid);
705 let ss = uuid.to_str();
706 let uuid_ss = Uuid::parse_string(ss.as_slice()).unwrap();
707 assert!(uuid_ss == uuid);
712 let uuid1 = Uuid::new_v4();
713 let uuid2 = Uuid::new_v4();
715 assert!(uuid1 == uuid1);
716 assert!(uuid2 == uuid2);
717 assert!(uuid1 != uuid2);
718 assert!(uuid2 != uuid1);
722 fn test_from_fields() {
723 let d1: u32 = 0xa1a2a3a4;
724 let d2: u16 = 0xb1b2;
725 let d3: u16 = 0xc1c2;
726 let d4: Vec<u8> = vec!(0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8);
728 let u = Uuid::from_fields(d1, d2, d3, d4.as_slice());
730 let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8".to_string();
731 let result = u.to_simple_str();
732 assert!(result == expected);
736 fn test_from_bytes() {
737 let b = vec!( 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2,
738 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8 );
740 let u = Uuid::from_bytes(b.as_slice()).unwrap();
741 let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8".to_string();
743 assert!(u.to_simple_str() == expected);
748 let u = Uuid::new_v4();
749 let ub = u.as_bytes();
751 assert!(ub.len() == 16);
752 assert!(! ub.iter().all(|&b| b == 0));
756 fn test_bytes_roundtrip() {
757 let b_in: [u8, ..16] = [ 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2,
758 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8 ];
760 let u = Uuid::from_bytes(b_in.clone()).unwrap();
762 let b_out = u.as_bytes();
764 assert!(b_in == b_out);
768 fn test_operator_eq() {
769 let u1 = Uuid::new_v4();
771 let u3 = Uuid::new_v4();
784 fn test_rand_rand() {
785 let mut rng = rand::task_rng();
786 let u: Uuid = rand::Rand::rand(&mut rng);
787 let ub = u.as_bytes();
789 assert!(ub.len() == 16);
790 assert!(! ub.iter().all(|&b| b == 0));
794 fn test_serialize_round_trip() {
795 use serialize::ebml::Doc;
796 use serialize::ebml::writer::Encoder;
797 use serialize::ebml::reader::Decoder;
798 use serialize::{Encodable, Decodable};
800 let u = Uuid::new_v4();
801 let mut wr = MemWriter::new();
802 let _ = u.encode(&mut Encoder::new(&mut wr));
803 let doc = Doc::new(wr.get_ref());
804 let u2 = Decodable::decode(&mut Decoder::new(doc)).unwrap();
809 fn test_iterbytes_impl_for_uuid() {
810 use std::collections::HashSet;
811 let mut set = HashSet::new();
812 let id1 = Uuid::new_v4();
813 let id2 = Uuid::new_v4();
815 assert!(set.contains(&id1));
816 assert!(!set.contains(&id2));
823 use self::test::Bencher;
827 pub fn create_uuids(b: &mut Bencher) {
834 pub fn uuid_to_str(b: &mut Bencher) {
835 let u = Uuid::new_v4();
842 pub fn parse_str(b: &mut Bencher) {
843 let s = "urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4";
845 Uuid::parse_string(s).unwrap();