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"]
58 #![crate_type = "rlib"]
59 #![crate_type = "dylib"]
60 #![license = "MIT/ASL2"]
61 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
62 html_favicon_url = "http://www.rust-lang.org/favicon.ico",
63 html_root_url = "http://doc.rust-lang.org/",
64 html_playground_url = "http://play.rust-lang.org/")]
66 #![feature(default_type_params)]
68 // test harness access
71 extern crate serialize;
74 use std::default::Default;
76 use std::from_str::FromStr;
78 use std::mem::{transmute,transmute_copy};
79 use std::num::FromStrRadix;
85 use serialize::{Encoder, Encodable, Decoder, Decodable};
87 /// A 128-bit (16 byte) buffer containing the ID
88 pub type UuidBytes = [u8, ..16];
90 /// The version of the UUID, denoting the generating algorithm
91 #[deriving(PartialEq)]
92 pub enum UuidVersion {
93 /// Version 1: MAC address
95 /// Version 2: DCE Security
97 /// Version 3: MD5 hash
101 /// Version 5: SHA-1 hash
105 /// The reserved variants of UUIDs
106 #[deriving(PartialEq)]
107 pub enum UuidVariant {
108 /// Reserved by the NCS for backward compatibility
110 /// As described in the RFC4122 Specification (default)
112 /// Reserved by Microsoft for backward compatibility
114 /// Reserved for future expansion
118 /// A Universally Unique Identifier (UUID)
120 /// The 128-bit number stored in 16 bytes
124 impl<S: hash::Writer> hash::Hash<S> for Uuid {
125 fn hash(&self, state: &mut S) {
126 self.bytes.hash(state)
130 /// A UUID stored as fields (identical to UUID, used only for conversions)
132 /// First field, 32-bit word
134 /// Second field, 16-bit short
136 /// Third field, 16-bit short
138 /// Fourth field, 8 bytes
142 /// Error details for string parsing failures
143 #[allow(missing_doc)]
144 pub enum ParseError {
145 ErrorInvalidLength(uint),
146 ErrorInvalidCharacter(char, uint),
147 ErrorInvalidGroups(uint),
148 ErrorInvalidGroupLength(uint, uint, uint),
151 /// Converts a ParseError to a string
152 impl fmt::Show for ParseError {
153 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
155 ErrorInvalidLength(found) =>
156 write!(f, "Invalid length; expecting 32, 36 or 45 chars, \
158 ErrorInvalidCharacter(found, pos) =>
159 write!(f, "Invalid character; found `{}` (0x{:02x}) at \
160 offset {}", found, found as uint, pos),
161 ErrorInvalidGroups(found) =>
162 write!(f, "Malformed; wrong number of groups: expected 1 \
163 or 5, found {}", found),
164 ErrorInvalidGroupLength(group, found, expecting) =>
165 write!(f, "Malformed; length of group {} was {}, \
166 expecting {}", group, found, expecting),
171 // Length of each hyphenated group in hex digits
172 static UuidGroupLens: [uint, ..5] = [8u, 4u, 4u, 4u, 12u];
176 /// Returns a nil or empty UUID (containing all zeroes)
177 pub fn nil() -> Uuid {
178 let uuid = Uuid{ bytes: [0, .. 16] };
182 /// Create a new UUID of the specified version
183 pub fn new(v: UuidVersion) -> Option<Uuid> {
185 Version4Random => Some(Uuid::new_v4()),
190 /// Creates a new random UUID
192 /// Uses the `rand` module's default RNG task as the source
193 /// of random numbers. Use the rand::Rand trait to supply
194 /// a custom generator if required.
195 pub fn new_v4() -> Uuid {
196 let ub = rand::task_rng().gen_iter::<u8>().take(16).collect::<Vec<_>>();
197 let mut uuid = Uuid{ bytes: [0, .. 16] };
198 slice::bytes::copy_memory(uuid.bytes, ub.as_slice());
199 uuid.set_variant(VariantRFC4122);
200 uuid.set_version(Version4Random);
204 /// Creates a UUID using the supplied field values
207 /// * `d1` A 32-bit word
208 /// * `d2` A 16-bit word
209 /// * `d3` A 16-bit word
210 /// * `d4` Array of 8 octets
211 pub fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8]) -> Uuid {
212 // First construct a temporary field-based struct
213 let mut fields = UuidFields {
220 fields.data1 = d1.to_be();
221 fields.data2 = d2.to_be();
222 fields.data3 = d3.to_be();
223 slice::bytes::copy_memory(fields.data4, d4);
230 /// Creates a UUID using the supplied bytes
233 /// * `b` An array or slice of 16 bytes
234 pub fn from_bytes(b: &[u8]) -> Option<Uuid> {
239 let mut uuid = Uuid{ bytes: [0, .. 16] };
240 slice::bytes::copy_memory(uuid.bytes, b);
244 /// Specifies the variant of the UUID structure
245 fn set_variant(&mut self, v: UuidVariant) {
246 // Octet 8 contains the variant in the most significant 3 bits
248 VariantNCS => // b0xx...
249 self.bytes[8] = self.bytes[8] & 0x7f,
250 VariantRFC4122 => // b10x...
251 self.bytes[8] = (self.bytes[8] & 0x3f) | 0x80,
252 VariantMicrosoft => // b110...
253 self.bytes[8] = (self.bytes[8] & 0x1f) | 0xc0,
254 VariantFuture => // b111...
255 self.bytes[8] = (self.bytes[8] & 0x1f) | 0xe0,
259 /// Returns the variant of the UUID structure
261 /// This determines the interpretation of the structure of the UUID.
262 /// Currently only the RFC4122 variant is generated by this module.
264 /// * [Variant Reference](http://tools.ietf.org/html/rfc4122#section-4.1.1)
265 pub fn get_variant(&self) -> Option<UuidVariant> {
266 if self.bytes[8] & 0x80 == 0x00 {
268 } else if self.bytes[8] & 0xc0 == 0x80 {
270 } else if self.bytes[8] & 0xe0 == 0xc0 {
271 Some(VariantMicrosoft)
272 } else if self.bytes[8] & 0xe0 == 0xe0 {
279 /// Specifies the version number of the UUID
280 fn set_version(&mut self, v: UuidVersion) {
281 self.bytes[6] = (self.bytes[6] & 0xF) | ((v as u8) << 4);
284 /// Returns the version number of the UUID
286 /// This represents the algorithm used to generate the contents.
288 /// Currently only the Random (V4) algorithm is supported by this
289 /// module. There are security and privacy implications for using
290 /// older versions - see [Wikipedia: Universally Unique Identifier](
291 /// http://en.wikipedia.org/wiki/Universally_unique_identifier) for
294 /// * [Version Reference](http://tools.ietf.org/html/rfc4122#section-4.1.3)
295 pub fn get_version_num(&self) -> uint {
296 (self.bytes[6] >> 4) as uint
299 /// Returns the version of the UUID
301 /// This represents the algorithm used to generate the contents
302 pub fn get_version(&self) -> Option<UuidVersion> {
303 let v = self.bytes[6] >> 4;
305 1 => Some(Version1Mac),
306 2 => Some(Version2Dce),
307 3 => Some(Version3Md5),
308 4 => Some(Version4Random),
309 5 => Some(Version5Sha1),
314 /// Return an array of 16 octets containing the UUID data
315 pub fn as_bytes<'a>(&'a self) -> &'a [u8] {
316 self.bytes.as_slice()
319 /// Returns the UUID as a string of 16 hexadecimal digits
321 /// Example: `936DA01F9ABD4d9d80C702AF85C822A8`
322 pub fn to_simple_str(&self) -> String {
323 let mut s: Vec<u8> = Vec::from_elem(32, 0u8);
324 for i in range(0u, 16u) {
325 let digit = format!("{:02x}", self.bytes[i] as uint);
326 *s.get_mut(i*2+0) = digit.as_slice()[0];
327 *s.get_mut(i*2+1) = digit.as_slice()[1];
329 str::from_utf8(s.as_slice()).unwrap().to_string()
332 /// Returns a string of hexadecimal digits, separated into groups with a hyphen.
334 /// Example: `550e8400-e29b-41d4-a716-446655440000`
335 pub fn to_hyphenated_str(&self) -> String {
336 // Convert to field-based struct as it matches groups in output.
337 // Ensure fields are in network byte order, as per RFC.
338 let mut uf: UuidFields;
340 uf = transmute_copy(&self.bytes);
342 uf.data1 = uf.data1.to_be();
343 uf.data2 = uf.data2.to_be();
344 uf.data3 = uf.data3.to_be();
345 let s = format!("{:08x}-{:04x}-{:04x}-{:02x}{:02x}-\
346 {:02x}{:02x}{:02x}{:02x}{:02x}{:02x}",
349 uf.data4[0], uf.data4[1],
350 uf.data4[2], uf.data4[3], uf.data4[4],
351 uf.data4[5], uf.data4[6], uf.data4[7]);
355 /// Returns the UUID formatted as a full URN string
357 /// This is the same as the hyphenated format, but with the "urn:uuid:" prefix.
359 /// Example: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4`
360 pub fn to_urn_str(&self) -> String {
361 format!("urn:uuid:{}", self.to_hyphenated_str())
364 /// Parses a UUID from a string of hexadecimal digits with optional hyphens
366 /// Any of the formats generated by this module (simple, hyphenated, urn) are
367 /// supported by this parsing function.
368 pub fn parse_string(us: &str) -> Result<Uuid, ParseError> {
370 let mut us = us.clone();
371 let orig_len = us.len();
373 // Ensure length is valid for any of the supported formats
374 if orig_len != 32 && orig_len != 36 && orig_len != 45 {
375 return Err(ErrorInvalidLength(orig_len));
378 // Strip off URN prefix if present
379 if us.starts_with("urn:uuid:") {
380 us = us.slice(9, orig_len);
383 // Make sure all chars are either hex digits or hyphen
384 for (i, c) in us.chars().enumerate() {
386 '0'..'9' | 'A'..'F' | 'a'..'f' | '-' => {},
387 _ => return Err(ErrorInvalidCharacter(c, i)),
391 // Split string up by hyphens into groups
392 let hex_groups: Vec<&str> = us.split_str("-").collect();
394 // Get the length of each group
395 let group_lens: Vec<uint> = hex_groups.iter().map(|&v| v.len()).collect();
397 // Ensure the group lengths are valid
398 match group_lens.len() {
399 // Single group, no hyphens
401 if *group_lens.get(0) != 32 {
402 return Err(ErrorInvalidLength(*group_lens.get(0)));
405 // Five groups, hyphens in between each
407 // Ensure each group length matches the expected
408 for (i, (&gl, &expected)) in
409 group_lens.iter().zip(UuidGroupLens.iter()).enumerate() {
411 return Err(ErrorInvalidGroupLength(i, gl, expected))
416 return Err(ErrorInvalidGroups(group_lens.len()));
420 // Normalise into one long hex string
421 let vs = hex_groups.concat();
423 // At this point, we know we have a valid hex string, without hyphens
424 assert!(vs.len() == 32);
425 assert!(vs.as_slice().chars().all(|c| c.is_digit_radix(16)));
427 // Allocate output UUID buffer
428 let mut ub = [0u8, ..16];
430 // Extract each hex digit from the string
431 for i in range(0u, 16u) {
432 ub[i] = FromStrRadix::from_str_radix(vs.as_slice()
433 .slice(i*2, (i+1)*2),
437 Ok(Uuid::from_bytes(ub).unwrap())
440 /// Tests if the UUID is nil
441 pub fn is_nil(&self) -> bool {
442 return self.bytes.iter().all(|&b| b == 0);
446 impl Default for Uuid {
447 /// Returns the nil UUID, which is all zeroes
448 fn default() -> Uuid {
453 impl Clone for Uuid {
454 /// Returns a copy of the UUID
455 fn clone(&self) -> Uuid { *self }
458 impl FromStr for Uuid {
459 /// Parse a hex string and interpret as a UUID
461 /// Accepted formats are a sequence of 32 hexadecimal characters,
462 /// with or without hyphens (grouped as 8, 4, 4, 4, 12).
463 fn from_str(us: &str) -> Option<Uuid> {
464 let result = Uuid::parse_string(us);
472 /// Convert the UUID to a hexadecimal-based string representation
473 impl fmt::Show for Uuid {
474 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
475 write!(f, "{}", self.to_simple_str())
479 /// Test two UUIDs for equality
481 /// UUIDs are equal only when they are byte-for-byte identical
482 impl PartialEq for Uuid {
483 fn eq(&self, other: &Uuid) -> bool {
484 self.bytes == other.bytes
490 // FIXME #9845: Test these more thoroughly
491 impl<T: Encoder<E>, E> Encodable<T, E> for Uuid {
492 /// Encode a UUID as a hyphenated string
493 fn encode(&self, e: &mut T) -> Result<(), E> {
494 e.emit_str(self.to_hyphenated_str().as_slice())
498 impl<T: Decoder<E>, E> Decodable<T, E> for Uuid {
499 /// Decode a UUID from a string
500 fn decode(d: &mut T) -> Result<Uuid, E> {
501 Ok(from_str(try!(d.read_str()).as_slice()).unwrap())
505 /// Generates a random instance of UUID (V4 conformant)
506 impl rand::Rand for Uuid {
508 fn rand<R: rand::Rng>(rng: &mut R) -> Uuid {
509 let ub = rng.gen_iter::<u8>().take(16).collect::<Vec<_>>();
510 let mut uuid = Uuid{ bytes: [0, .. 16] };
511 slice::bytes::copy_memory(uuid.bytes, ub.as_slice());
512 uuid.set_variant(VariantRFC4122);
513 uuid.set_version(Version4Random);
520 use super::{Uuid, VariantMicrosoft, VariantNCS, VariantRFC4122,
521 Version1Mac, Version2Dce, Version3Md5, Version4Random,
524 use std::io::MemWriter;
529 let nil = Uuid::nil();
530 let not_nil = Uuid::new_v4();
532 assert!(nil.is_nil());
533 assert!(!not_nil.is_nil());
539 let uuid1 = Uuid::new(Version4Random).unwrap();
540 let s = uuid1.to_simple_str();
542 assert!(s.len() == 32);
543 assert!(uuid1.get_version().unwrap() == Version4Random);
545 // Test unsupported versions
546 assert!(Uuid::new(Version1Mac) == None);
547 assert!(Uuid::new(Version2Dce) == None);
548 assert!(Uuid::new(Version3Md5) == None);
549 assert!(Uuid::new(Version5Sha1) == None);
554 let uuid1 = Uuid::new_v4();
556 assert!(uuid1.get_version().unwrap() == Version4Random);
557 assert!(uuid1.get_variant().unwrap() == VariantRFC4122);
561 fn test_get_version() {
562 let uuid1 = Uuid::new_v4();
564 assert!(uuid1.get_version().unwrap() == Version4Random);
565 assert!(uuid1.get_version_num() == 4);
569 fn test_get_variant() {
570 let uuid1 = Uuid::new_v4();
571 let uuid2 = Uuid::parse_string("550e8400-e29b-41d4-a716-446655440000").unwrap();
572 let uuid3 = Uuid::parse_string("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap();
573 let uuid4 = Uuid::parse_string("936DA01F9ABD4d9dC0C702AF85C822A8").unwrap();
574 let uuid5 = Uuid::parse_string("F9168C5E-CEB2-4faa-D6BF-329BF39FA1E4").unwrap();
575 let uuid6 = Uuid::parse_string("f81d4fae-7dec-11d0-7765-00a0c91e6bf6").unwrap();
577 assert!(uuid1.get_variant().unwrap() == VariantRFC4122);
578 assert!(uuid2.get_variant().unwrap() == VariantRFC4122);
579 assert!(uuid3.get_variant().unwrap() == VariantRFC4122);
580 assert!(uuid4.get_variant().unwrap() == VariantMicrosoft);
581 assert!(uuid5.get_variant().unwrap() == VariantMicrosoft);
582 assert!(uuid6.get_variant().unwrap() == VariantNCS);
586 fn test_parse_uuid_v4() {
587 use super::{ErrorInvalidCharacter, ErrorInvalidGroups,
588 ErrorInvalidGroupLength, ErrorInvalidLength};
591 assert!(Uuid::parse_string("").is_err());
592 assert!(Uuid::parse_string("!").is_err());
593 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45").is_err());
594 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4").is_err());
595 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4").is_err());
596 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4").is_err());
597 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa").is_err());
598 assert!(Uuid::parse_string("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4").is_err());
599 assert!(Uuid::parse_string("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4").is_err());
600 assert!(Uuid::parse_string("01020304-1112-2122-3132-41424344").is_err());
601 assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c").is_err());
602 assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c88").is_err());
603 assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0cg8").is_err());
604 assert!(Uuid::parse_string("67e5504410b1426%9247bb680e5fe0c8").is_err());
607 assert!(Uuid::parse_string("00000000000000000000000000000000").is_ok());
608 assert!(Uuid::parse_string("67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok());
609 assert!(Uuid::parse_string("67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok());
610 assert!(Uuid::parse_string("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").is_ok());
611 assert!(Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c8").is_ok());
612 assert!(Uuid::parse_string("01020304-1112-2122-3132-414243444546").is_ok());
613 assert!(Uuid::parse_string("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok());
616 let nil = Uuid::nil();
617 assert!(Uuid::parse_string("00000000000000000000000000000000").unwrap() == nil);
618 assert!(Uuid::parse_string("00000000-0000-0000-0000-000000000000").unwrap() == nil);
621 let uuid_orig = Uuid::new_v4();
622 let orig_str = uuid_orig.to_str();
623 let uuid_out = Uuid::parse_string(orig_str.as_slice()).unwrap();
624 assert!(uuid_orig == uuid_out);
626 // Test error reporting
627 let e = Uuid::parse_string("67e5504410b1426f9247bb680e5fe0c").unwrap_err();
628 assert!(match e { ErrorInvalidLength(n) => n==31, _ => false });
630 let e = Uuid::parse_string("67e550X410b1426f9247bb680e5fe0cd").unwrap_err();
631 assert!(match e { ErrorInvalidCharacter(c, n) => c=='X' && n==6, _ => false });
633 let e = Uuid::parse_string("67e550-4105b1426f9247bb680e5fe0c").unwrap_err();
634 assert!(match e { ErrorInvalidGroups(n) => n==2, _ => false });
636 let e = Uuid::parse_string("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4").unwrap_err();
637 assert!(match e { ErrorInvalidGroupLength(g, n, e) => g==3 && n==5 && e==4, _ => false });
641 fn test_to_simple_str() {
642 let uuid1 = Uuid::new_v4();
643 let s = uuid1.to_simple_str();
645 assert!(s.len() == 32);
646 assert!(s.as_slice().chars().all(|c| c.is_digit_radix(16)));
651 let uuid1 = Uuid::new_v4();
652 let s = uuid1.to_str();
654 assert!(s.len() == 32);
655 assert!(s.as_slice().chars().all(|c| c.is_digit_radix(16)));
659 fn test_to_hyphenated_str() {
660 let uuid1 = Uuid::new_v4();
661 let s = uuid1.to_hyphenated_str();
663 assert!(s.len() == 36);
664 assert!(s.as_slice().chars().all(|c| c.is_digit_radix(16) || c == '-'));
668 fn test_to_urn_str() {
669 let uuid1 = Uuid::new_v4();
670 let ss = uuid1.to_urn_str();
671 let s = ss.as_slice().slice(9, ss.len());
673 assert!(ss.as_slice().starts_with("urn:uuid:"));
674 assert!(s.len() == 36);
677 .all(|c| c.is_digit_radix(16) || c == '-'));
681 fn test_to_str_matching() {
682 let uuid1 = Uuid::new_v4();
684 let hs = uuid1.to_hyphenated_str();
685 let ss = uuid1.to_str();
687 let hsn = str::from_chars(hs.as_slice()
689 .filter(|&c| c != '-')
690 .collect::<Vec<char>>()
697 fn test_string_roundtrip() {
698 let uuid = Uuid::new_v4();
700 let hs = uuid.to_hyphenated_str();
701 let uuid_hs = Uuid::parse_string(hs.as_slice()).unwrap();
702 assert!(uuid_hs == uuid);
704 let ss = uuid.to_str();
705 let uuid_ss = Uuid::parse_string(ss.as_slice()).unwrap();
706 assert!(uuid_ss == uuid);
711 let uuid1 = Uuid::new_v4();
712 let uuid2 = Uuid::new_v4();
714 assert!(uuid1 == uuid1);
715 assert!(uuid2 == uuid2);
716 assert!(uuid1 != uuid2);
717 assert!(uuid2 != uuid1);
721 fn test_from_fields() {
722 let d1: u32 = 0xa1a2a3a4;
723 let d2: u16 = 0xb1b2;
724 let d3: u16 = 0xc1c2;
725 let d4: Vec<u8> = vec!(0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8);
727 let u = Uuid::from_fields(d1, d2, d3, d4.as_slice());
729 let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8".to_string();
730 let result = u.to_simple_str();
731 assert!(result == expected);
735 fn test_from_bytes() {
736 let b = vec!( 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2,
737 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8 );
739 let u = Uuid::from_bytes(b.as_slice()).unwrap();
740 let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8".to_string();
742 assert!(u.to_simple_str() == expected);
747 let u = Uuid::new_v4();
748 let ub = u.as_bytes();
750 assert!(ub.len() == 16);
751 assert!(! ub.iter().all(|&b| b == 0));
755 fn test_bytes_roundtrip() {
756 let b_in: [u8, ..16] = [ 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2,
757 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8 ];
759 let u = Uuid::from_bytes(b_in.clone()).unwrap();
761 let b_out = u.as_bytes();
763 assert!(b_in == b_out);
767 fn test_operator_eq() {
768 let u1 = Uuid::new_v4();
770 let u3 = Uuid::new_v4();
783 fn test_rand_rand() {
784 let mut rng = rand::task_rng();
785 let u: Uuid = rand::Rand::rand(&mut rng);
786 let ub = u.as_bytes();
788 assert!(ub.len() == 16);
789 assert!(! ub.iter().all(|&b| b == 0));
793 fn test_serialize_round_trip() {
794 use serialize::ebml::Doc;
795 use serialize::ebml::writer::Encoder;
796 use serialize::ebml::reader::Decoder;
797 use serialize::{Encodable, Decodable};
799 let u = Uuid::new_v4();
800 let mut wr = MemWriter::new();
801 let _ = u.encode(&mut Encoder::new(&mut wr));
802 let doc = Doc::new(wr.get_ref());
803 let u2 = Decodable::decode(&mut Decoder::new(doc)).unwrap();
808 fn test_iterbytes_impl_for_uuid() {
809 use std::collections::HashSet;
810 let mut set = HashSet::new();
811 let id1 = Uuid::new_v4();
812 let id2 = Uuid::new_v4();
814 assert!(set.contains(&id1));
815 assert!(!set.contains(&id2));
822 use self::test::Bencher;
826 pub fn create_uuids(b: &mut Bencher) {
833 pub fn uuid_to_str(b: &mut Bencher) {
834 let u = Uuid::new_v4();
841 pub fn parse_str(b: &mut Bencher) {
842 let s = "urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4";
844 Uuid::parse_string(s).unwrap();