From 69b9014747a3fd16dd9446256cb32b35aa5462c6 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Mon, 1 Nov 2021 07:13:46 +1000 Subject: [PATCH 1/9] focus benches on formatting and parsing --- benches/format_str.rs | 24 +++++------ benches/invalid_parse_str.rs | 58 -------------------------- benches/mod.rs | 4 -- benches/parse_str.rs | 68 +++++++++++++++++++++++++++++++ benches/serde_support.rs | 48 ---------------------- benches/slog_support/mod.rs | 1 - benches/slog_support/parse_str.rs | 15 ------- benches/valid_parse_str.rs | 39 ------------------ 8 files changed, 80 insertions(+), 177 deletions(-) delete mode 100644 benches/invalid_parse_str.rs delete mode 100644 benches/mod.rs create mode 100644 benches/parse_str.rs delete mode 100644 benches/serde_support.rs delete mode 100644 benches/slog_support/mod.rs delete mode 100644 benches/slog_support/parse_str.rs delete mode 100644 benches/valid_parse_str.rs diff --git a/benches/format_str.rs b/benches/format_str.rs index f029cf03d..818d4185e 100644 --- a/benches/format_str.rs +++ b/benches/format_str.rs @@ -6,61 +6,61 @@ use test::Bencher; use uuid::Uuid; #[bench] -fn bench_hyphen(b: &mut Bencher) { +fn hyphenated(b: &mut Bencher) { let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap(); b.iter(|| { let mut buffer = [0_u8; 36]; write!(&mut buffer as &mut [_], "{:x}", uuid.to_hyphenated()).unwrap(); - test::black_box(buffer); + buffer }); } #[bench] -fn bench_simple(b: &mut Bencher) { +fn simple(b: &mut Bencher) { let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap(); b.iter(|| { let mut buffer = [0_u8; 32]; write!(&mut buffer as &mut [_], "{:x}", uuid.to_simple()).unwrap(); - test::black_box(buffer); + buffer }) } #[bench] -fn bench_urn(b: &mut Bencher) { +fn urn(b: &mut Bencher) { let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap(); b.iter(|| { let mut buffer = [0_u8; 36 + 9]; write!(&mut buffer as &mut [_], "{:x}", uuid.to_urn()).unwrap(); - test::black_box(buffer); + buffer }) } #[bench] -fn bench_encode_hyphen(b: &mut Bencher) { +fn encode_hyphen(b: &mut Bencher) { let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap(); b.iter(|| { let mut buffer = [0_u8; 36]; uuid.to_hyphenated().encode_lower(&mut buffer); - test::black_box(buffer); + buffer }); } #[bench] -fn bench_encode_simple(b: &mut Bencher) { +fn encode_simple(b: &mut Bencher) { let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap(); b.iter(|| { let mut buffer = [0_u8; 32]; uuid.to_simple().encode_lower(&mut buffer); - test::black_box(buffer); + buffer }) } #[bench] -fn bench_encode_urn(b: &mut Bencher) { +fn encode_urn(b: &mut Bencher) { let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap(); b.iter(|| { let mut buffer = [0_u8; 36 + 9]; uuid.to_urn().encode_lower(&mut buffer); - test::black_box(buffer); + buffer }) } diff --git a/benches/invalid_parse_str.rs b/benches/invalid_parse_str.rs deleted file mode 100644 index 7fde28b3b..000000000 --- a/benches/invalid_parse_str.rs +++ /dev/null @@ -1,58 +0,0 @@ -#![feature(test)] -extern crate test; - -use test::Bencher; -use uuid::Uuid; - -#[bench] -fn bench_parse_invalid_strings(b: &mut Bencher) { - b.iter(|| { - let _ = Uuid::parse_str(""); - let _ = Uuid::parse_str("!"); - let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45"); - let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4"); - let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4"); - let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4"); - let _ = Uuid::parse_str("F9168C5E-CEB2-4faa"); - let _ = Uuid::parse_str("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4"); - let _ = Uuid::parse_str("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4"); - let _ = Uuid::parse_str("01020304-1112-2122-3132-41424344"); - let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c88"); - let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0cg8"); - let _ = Uuid::parse_str("67e5504410b1426%9247bb680e5fe0c8"); - - // Test error reporting - let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c"); - let _ = Uuid::parse_str("67e550X410b1426f9247bb680e5fe0cd"); - let _ = Uuid::parse_str("67e550-4105b1426f9247bb680e5fe0c"); - let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4"); - }); -} - -#[bench] -fn bench_parse_invalid_len(b: &mut Bencher) { - b.iter(|| { - let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4"); - }) -} - -#[bench] -fn bench_parse_invalid_character(b: &mut Bencher) { - b.iter(|| { - let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4"); - }) -} - -#[bench] -fn bench_parse_invalid_group_len(b: &mut Bencher) { - b.iter(|| { - let _ = Uuid::parse_str("01020304-1112-2122-3132-41424344"); - }); -} - -#[bench] -fn bench_parse_invalid_groups(b: &mut Bencher) { - b.iter(|| { - let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4"); - }); -} diff --git a/benches/mod.rs b/benches/mod.rs deleted file mode 100644 index 2ef574f01..000000000 --- a/benches/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -#![feature(test)] - -#[cfg(feature = "slog")] -pub mod slog_support; diff --git a/benches/parse_str.rs b/benches/parse_str.rs new file mode 100644 index 000000000..3cfca60c2 --- /dev/null +++ b/benches/parse_str.rs @@ -0,0 +1,68 @@ +#![feature(test)] +extern crate test; + +use test::Bencher; +use uuid::Uuid; + +#[bench] +fn parse_nil(b: &mut Bencher) { + b.iter(|| { + Uuid::parse_str("00000000000000000000000000000000") + }); +} + +#[bench] +fn parse_nil_hyphenated(b: &mut Bencher) { + b.iter(|| { + Uuid::parse_str("00000000-0000-0000-0000-000000000000") + }); +} + +#[bench] +fn parse_random(b: &mut Bencher) { + b.iter(|| { + Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8") + }); +} + +#[bench] +fn parse_random_hyphenated(b: &mut Bencher) { + b.iter(|| { + Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8") + }); +} + +#[bench] +fn parse_urn(b: &mut Bencher) { + b.iter(|| { + Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8") + }); +} + +#[bench] +fn parse_invalid_len(b: &mut Bencher) { + b.iter(|| { + Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4") + }) +} + +#[bench] +fn parse_invalid_character(b: &mut Bencher) { + b.iter(|| { + Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4") + }) +} + +#[bench] +fn parse_invalid_group_len(b: &mut Bencher) { + b.iter(|| { + Uuid::parse_str("01020304-1112-2122-3132-41424344") + }); +} + +#[bench] +fn parse_invalid_groups(b: &mut Bencher) { + b.iter(|| { + Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4") + }); +} diff --git a/benches/serde_support.rs b/benches/serde_support.rs deleted file mode 100644 index a7ce64f82..000000000 --- a/benches/serde_support.rs +++ /dev/null @@ -1,48 +0,0 @@ -#![cfg(feature = "serde")] -#![feature(test)] - -use bincode; -use serde_json; -extern crate test; - -use test::Bencher; -use uuid::Uuid; - -#[bench] -fn bench_json_encode(b: &mut Bencher) { - let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap(); - let mut buffer = [0_u8; 38]; - b.iter(|| { - serde_json::to_writer(&mut buffer as &mut [u8], &uuid).unwrap(); - test::black_box(buffer); - }); - b.bytes = buffer.len() as u64; -} - -#[bench] -fn bench_json_decode(b: &mut Bencher) { - let s = "\"F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4\""; - b.iter(|| serde_json::from_str::(s).unwrap()); - b.bytes = s.len() as u64; -} - -#[bench] -fn bench_bincode_encode(b: &mut Bencher) { - let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap(); - let mut buffer = [0_u8; 24]; - b.iter(|| { - bincode::serialize_into(&mut buffer as &mut [u8], &uuid).unwrap(); - test::black_box(buffer); - }); - b.bytes = buffer.len() as u64; -} - -#[bench] -fn bench_bincode_decode(b: &mut Bencher) { - let bytes = [ - 16, 0, 0, 0, 0, 0, 0, 0, 249, 22, 140, 94, 206, 178, 79, 170, 182, 191, - 50, 155, 243, 159, 161, 228, - ]; - b.iter(|| bincode::deserialize::(&bytes).unwrap()); - b.bytes = bytes.len() as u64; -} diff --git a/benches/slog_support/mod.rs b/benches/slog_support/mod.rs deleted file mode 100644 index cdc37a735..000000000 --- a/benches/slog_support/mod.rs +++ /dev/null @@ -1 +0,0 @@ -pub mod parse_str; diff --git a/benches/slog_support/parse_str.rs b/benches/slog_support/parse_str.rs deleted file mode 100644 index fa0e5f702..000000000 --- a/benches/slog_support/parse_str.rs +++ /dev/null @@ -1,15 +0,0 @@ -extern crate test; - -#[bench] -#[cfg(feature = "slog")] -pub fn bench_log_discard_kv(b: &mut test::Bencher) { - let u1 = - uuid::Uuid::parse_str("F9168C5E-CEB2-4FAB-B6BF-329BF39FA1E4").unwrap(); - let root = - slog::Logger::root(::slog::Drain::fuse(::slog::Discard), slog::o!()); - - b.iter(|| { - #[cfg(feature = "slog")] - slog::crit!(root, "test"; "u1" => u1); - }); -} diff --git a/benches/valid_parse_str.rs b/benches/valid_parse_str.rs deleted file mode 100644 index f20d6e320..000000000 --- a/benches/valid_parse_str.rs +++ /dev/null @@ -1,39 +0,0 @@ -#![feature(test)] - -extern crate test; - -use test::Bencher; -use uuid::Uuid; - -#[bench] -fn bench_parse_valid_strings(b: &mut Bencher) { - b.iter(|| { - // Valid - let _ = Uuid::parse_str("00000000000000000000000000000000"); - let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8"); - let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8"); - let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4"); - let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8"); - let _ = Uuid::parse_str("01020304-1112-2122-3132-414243444546"); - let _ = - Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8"); - - // Nil - let _ = Uuid::parse_str("00000000000000000000000000000000"); - let _ = Uuid::parse_str("00000000-0000-0000-0000-000000000000"); - }); -} - -#[bench] -fn bench_valid_hyphenated(b: &mut Bencher) { - b.iter(|| { - let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8"); - }); -} - -#[bench] -fn bench_valid_short(b: &mut Bencher) { - b.iter(|| { - let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8"); - }); -} From 128befda46edd6e037cce9ad1a7a8be3db64c09c Mon Sep 17 00:00:00 2001 From: KodrAus Date: Mon, 1 Nov 2021 08:15:44 +1000 Subject: [PATCH 2/9] split up v1 tests --- src/v1.rs | 73 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/src/v1.rs b/src/v1.rs index 3153d9e56..04dcebb18 100644 --- a/src/v1.rs +++ b/src/v1.rs @@ -286,36 +286,47 @@ mod tests { let node = [1, 2, 3, 4, 5, 6]; let context = Context::new(0); - { - let uuid = Uuid::new_v1( - Timestamp::from_unix(&context, time, time_fraction), - &node, - ); - - assert_eq!(uuid.get_version(), Some(Version::Mac)); - assert_eq!(uuid.get_variant(), Variant::RFC4122); - assert_eq!( - uuid.to_hyphenated().to_string(), - "20616934-4ba2-11e7-8000-010203040506" - ); - - let ts = uuid.get_timestamp().unwrap().to_rfc4122(); - - assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460); - assert_eq!(ts.1, 0); - }; - - { - let uuid2 = Uuid::new_v1( - Timestamp::from_unix(&context, time, time_fraction), - &node, - ); - - assert_eq!( - uuid2.to_hyphenated().to_string(), - "20616934-4ba2-11e7-8001-010203040506" - ); - assert_eq!(uuid2.get_timestamp().unwrap().to_rfc4122().1, 1) - }; + let uuid = Uuid::new_v1( + Timestamp::from_unix(&context, time, time_fraction), + &node, + ); + + assert_eq!(uuid.get_version(), Some(Version::Mac)); + assert_eq!(uuid.get_variant(), Variant::RFC4122); + assert_eq!( + uuid.to_hyphenated().to_string(), + "20616934-4ba2-11e7-8000-010203040506" + ); + + let ts = uuid.get_timestamp().unwrap().to_rfc4122(); + + assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460); + + // Ensure parsing the same UUID produces the same timestamp + let parsed = Uuid::parse_str("20616934-4ba2-11e7-8000-010203040506").unwrap(); + + assert_eq!(uuid.get_timestamp().unwrap(), parsed.get_timestamp().unwrap()); + } + + #[test] + #[cfg_attr(target_arch = "wasm32", wasm_bindgen_test)] + fn test_new_v1_context() { + let time: u64 = 1_496_854_535; + let time_fraction: u32 = 812_946_000; + let node = [1, 2, 3, 4, 5, 6]; + let context = Context::new(0); + + let uuid1 = Uuid::new_v1( + Timestamp::from_unix(&context, time, time_fraction), + &node, + ); + + let uuid2 = Uuid::new_v1( + Timestamp::from_unix(&context, time, time_fraction), + &node, + ); + + assert_eq!(uuid1.get_timestamp().unwrap().to_rfc4122().1, 0); + assert_eq!(uuid2.get_timestamp().unwrap().to_rfc4122().1, 1); } } From 5c1d3853ddb4a379b716978c9b485deb6116fd28 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Mon, 1 Nov 2021 08:24:56 +1000 Subject: [PATCH 3/9] make version and variant non_exhaustive --- src/lib.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ff41f7181..63cf7c9a8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -245,6 +245,7 @@ pub type Bytes = [u8; 16]; /// The version of the UUID, denoting the generating algorithm. #[derive(Clone, Copy, Debug, PartialEq)] +#[non_exhaustive] pub enum Version { /// Special case for `nil` UUID. Nil = 0, @@ -262,6 +263,7 @@ pub enum Version { /// The reserved variants of UUIDs. #[derive(Clone, Copy, Debug, PartialEq)] +#[non_exhaustive] pub enum Variant { /// Reserved by the NCS for backward compatibility. NCS = 0, @@ -274,6 +276,8 @@ pub enum Variant { } /// A Universally Unique Identifier (UUID). +/// +/// This type is always guaranteed to be have the same ABI as a `[u8; 16]`. #[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] #[cfg_attr(feature = "zerocopy-unstable", derive(AsBytes, FromBytes, Unaligned))] #[repr(transparent)] @@ -328,24 +332,19 @@ impl Uuid { /// Returns the version number of the UUID. /// /// This represents the algorithm used to generate the contents. - /// - /// Currently only the Random (V4) algorithm is supported by this - /// module. There are security and privacy implications for using - /// older versions - see [Wikipedia: Universally Unique Identifier]( - /// http://en.wikipedia.org/wiki/Universally_unique_identifier) for - /// details. - /// - /// * [Version Reference](http://tools.ietf.org/html/rfc4122#section-4.1.3) + /// This method is the future-proof alternative to [`get_version`]. pub const fn get_version_num(&self) -> usize { (self.as_bytes()[6] >> 4) as usize } /// Returns the version of the UUID. /// - /// This represents the algorithm used to generate the contents + /// This represents the algorithm used to generate the contents. + /// If the version field doesn't contain a recognized version then `None` + /// is returned. If you're trying to read the version for a future extension + /// you can also use [`get_version_num`] to unconditionally return a number. pub const fn get_version(&self) -> Option { - let v = self.as_bytes()[6] >> 4; - match v { + match self.get_version_num() { 0 if self.is_nil() => Some(Version::Nil), 1 => Some(Version::Mac), 2 => Some(Version::Dce), @@ -576,7 +575,7 @@ impl Uuid { } /// A buffer that can be used for `encode_...` calls, that is - /// guaranteed to be long enough for any of the format format adapters. + /// guaranteed to be long enough for any of the format adapters. /// /// # Examples /// From afa89e6e50979efc20ee250a3f93cb325fd5361b Mon Sep 17 00:00:00 2001 From: KodrAus Date: Mon, 1 Nov 2021 10:49:31 +1000 Subject: [PATCH 4/9] work on doc examples --- benches/parse_str.rs | 36 +--- shared/parser.rs | 19 +-- src/builder.rs | 370 +++++++++++++++++++++++++++++++----------- src/lib.rs | 296 ++++++++++++++++++++------------- src/v1.rs | 12 +- src/v3.rs | 11 ++ src/v4.rs | 9 +- src/v5.rs | 11 ++ src/winapi_support.rs | 9 +- 9 files changed, 509 insertions(+), 264 deletions(-) diff --git a/benches/parse_str.rs b/benches/parse_str.rs index 3cfca60c2..e53ba242d 100644 --- a/benches/parse_str.rs +++ b/benches/parse_str.rs @@ -6,63 +6,45 @@ use uuid::Uuid; #[bench] fn parse_nil(b: &mut Bencher) { - b.iter(|| { - Uuid::parse_str("00000000000000000000000000000000") - }); + b.iter(|| Uuid::parse_str("00000000000000000000000000000000")); } #[bench] fn parse_nil_hyphenated(b: &mut Bencher) { - b.iter(|| { - Uuid::parse_str("00000000-0000-0000-0000-000000000000") - }); + b.iter(|| Uuid::parse_str("00000000-0000-0000-0000-000000000000")); } #[bench] fn parse_random(b: &mut Bencher) { - b.iter(|| { - Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8") - }); + b.iter(|| Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8")); } #[bench] fn parse_random_hyphenated(b: &mut Bencher) { - b.iter(|| { - Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8") - }); + b.iter(|| Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8")); } #[bench] fn parse_urn(b: &mut Bencher) { - b.iter(|| { - Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8") - }); + b.iter(|| Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8")); } #[bench] fn parse_invalid_len(b: &mut Bencher) { - b.iter(|| { - Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4") - }) + b.iter(|| Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4")) } #[bench] fn parse_invalid_character(b: &mut Bencher) { - b.iter(|| { - Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4") - }) + b.iter(|| Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4")) } #[bench] fn parse_invalid_group_len(b: &mut Bencher) { - b.iter(|| { - Uuid::parse_str("01020304-1112-2122-3132-41424344") - }); + b.iter(|| Uuid::parse_str("01020304-1112-2122-3132-41424344")); } #[bench] fn parse_invalid_groups(b: &mut Bencher) { - b.iter(|| { - Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4") - }); + b.iter(|| Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4")); } diff --git a/shared/parser.rs b/shared/parser.rs index 0eb270175..49342eaf6 100644 --- a/shared/parser.rs +++ b/shared/parser.rs @@ -34,15 +34,9 @@ pub fn parse_str(mut input: &str) -> Result<[u8; 16], Error> { if len == 45 && input.starts_with("urn:uuid:") { input = &input[9..]; - } else if !len_matches_any( - len, - &[36, 32], - ) { + } else if !len_matches_any(len, &[36, 32]) { return Err(ErrorKind::InvalidLength { - expected: ExpectedLength::Any(&[ - 36, - 32, - ]), + expected: ExpectedLength::Any(&[36, 32]), found: len, } .into()); @@ -58,10 +52,7 @@ pub fn parse_str(mut input: &str) -> Result<[u8; 16], Error> { if digit as usize >= 32 && group != 4 { if group == 0 { return Err(ErrorKind::InvalidLength { - expected: ExpectedLength::Any(&[ - 36, - 32, - ]), + expected: ExpectedLength::Any(&[36, 32]), found: len, } .into()); @@ -93,9 +84,7 @@ pub fn parse_str(mut input: &str) -> Result<[u8; 16], Error> { }; return Err(ErrorKind::InvalidGroupLength { - expected: ExpectedLength::Exact( - GROUP_LENS[group], - ), + expected: ExpectedLength::Exact(GROUP_LENS[group]), found: found as usize, group, } diff --git a/src/builder.rs b/src/builder.rs index 74e0ed0cb..c2ed72d50 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -22,17 +22,17 @@ use crate::{error::*, Bytes, Uuid, Variant, Version}; /// Creating a v4 UUID from externally generated bytes: /// /// ``` -/// use uuid::{Builder, Variant, Version}; -/// +/// # use uuid::{Builder, Version, Variant}; /// # let rng = || [ /// # 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, /// # 145, 63, 62, /// # ]; /// let random_bytes = rng(); -/// let uuid = Builder::from_bytes(random_bytes) -/// .set_variant(Variant::RFC4122) -/// .set_version(Version::Random) -/// .build(); +/// +/// let uuid = Builder::from_random_bytes(random_bytes).build(); +/// +/// assert_eq!(Some(Version::Random), uuid.get_version()); +/// assert_eq!(Variant::RFC4122, uuid.get_variant()); /// ``` #[allow(missing_copy_implementations)] #[derive(Debug)] @@ -51,13 +51,12 @@ impl Uuid { /// Basic usage: /// /// ``` - /// use uuid::Uuid; - /// + /// # use uuid::Uuid; /// let uuid = Uuid::nil(); /// /// assert_eq!( + /// "00000000-0000-0000-0000-000000000000", /// uuid.to_hyphenated().to_string(), - /// "00000000-0000-0000-0000-000000000000" /// ); /// ``` pub const fn nil() -> Self { @@ -71,18 +70,17 @@ impl Uuid { /// Basic usage: /// /// ``` - /// use uuid::Uuid; - /// - /// let d1 = 0xAB3F1097u32; - /// let d2 = 0x501Eu16; - /// let d3 = 0xB736u16; - /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; + /// # use uuid::Uuid; + /// let d1 = 0xa1a2a3a4; + /// let d2 = 0xb1b2; + /// let d3 = 0xc1c2; + /// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; /// /// let uuid = Uuid::from_fields(d1, d2, d3, &d4); /// /// assert_eq!( + /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", /// uuid.to_hyphenated().to_string(), - /// "ab3f1097-501e-b736-0c03-0938362b0809" /// ); /// ``` pub const fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Uuid { @@ -116,18 +114,17 @@ impl Uuid { /// # Examples /// /// ``` - /// use uuid::Uuid; - /// - /// let d1 = 0xAB3F1097u32; - /// let d2 = 0x501Eu16; - /// let d3 = 0xB736u16; - /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; + /// # use uuid::Uuid; + /// let d1 = 0xa1a2a3a4; + /// let d2 = 0xb1b2; + /// let d3 = 0xc1c2; + /// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; /// /// let uuid = Uuid::from_fields_le(d1, d2, d3, &d4); /// /// assert_eq!( + /// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8", /// uuid.to_hyphenated().to_string(), - /// "97103fab-1e50-36b7-0c03-0938362b0809" /// ); /// ``` pub const fn from_fields_le(d1: u32, d2: u16, d3: u16, d4: &[u8]) -> Uuid { @@ -158,15 +155,14 @@ impl Uuid { /// Basic usage: /// /// ``` - /// use uuid::Uuid; - /// + /// # use uuid::Uuid; /// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128; /// /// let uuid = Uuid::from_u128(v); /// /// assert_eq!( + /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", /// uuid.to_hyphenated().to_string(), - /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8" /// ); /// ``` pub const fn from_u128(v: u128) -> Self { @@ -202,15 +198,14 @@ impl Uuid { /// Basic usage: /// /// ``` - /// use uuid::Uuid; - /// + /// # use uuid::Uuid; /// let v = 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1u128; /// /// let uuid = Uuid::from_u128_le(v); /// /// assert_eq!( + /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", /// uuid.to_hyphenated().to_string(), - /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8" /// ); /// ``` pub const fn from_u128_le(v: u128) -> Self { @@ -241,16 +236,15 @@ impl Uuid { /// Basic usage: /// /// ``` - /// use uuid::Uuid; - /// + /// # use uuid::Uuid; /// let hi = 0xa1a2a3a4b1b2c1c2u64; /// let lo = 0xd1d2d3d4d5d6d7d8u64; /// /// let uuid = Uuid::from_u64_pair(hi, lo); /// /// assert_eq!( + /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", /// uuid.to_hyphenated().to_string(), - /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8" /// ); /// ``` pub const fn from_u64_pair(high_bits: u64, low_bits: u64) -> Self { @@ -286,35 +280,69 @@ impl Uuid { /// /// ``` /// # fn main() -> Result<(), Box> { - /// use uuid::Uuid; - /// - /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87]; + /// # use uuid::Uuid; + /// let bytes = [ + /// 0xa1, 0xa2, 0xa3, 0xa4, + /// 0xb1, 0xb2, + /// 0xc1, 0xc2, + /// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + /// ]; /// /// let uuid = Uuid::from_slice(&bytes)?; /// /// assert_eq!( + /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", /// uuid.to_hyphenated().to_string(), - /// "0436430c-2b02-624c-2032-570501212b57" /// ); /// # Ok(()) /// # } /// ``` + pub fn from_slice(b: &[u8]) -> Result { + if b.len() != 16 { + return Err(ErrorKind::InvalidLength { + expected: ExpectedLength::Exact(16), + found: b.len(), + } + .into()); + } + + let mut bytes: Bytes = [0; 16]; + bytes.copy_from_slice(b); + Ok(Uuid::from_bytes(bytes)) + } + + /// Creates a UUID using the supplied bytes in little endian order. /// - /// An incorrect number of bytes: + /// The individual fields encoded in the buffer will be flipped. + /// + /// # Errors + /// + /// This function will return an error if `b` has any length other than 16. + /// + /// # Examples + /// + /// Basic usage: /// /// ``` /// # fn main() -> Result<(), Box> { - /// use uuid::Uuid; - /// - /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76]; + /// # use uuid::Uuid; + /// let bytes = [ + /// 0xa1, 0xa2, 0xa3, 0xa4, + /// 0xb1, 0xb2, + /// 0xc1, 0xc2, + /// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + /// ]; /// - /// let uuid = Uuid::from_slice(&bytes); + /// let uuid = Uuid::from_slice_le(&bytes)?; /// - /// assert!(uuid.is_err()); + /// assert_eq!( + /// uuid.to_hyphenated().to_string(), + /// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8" + /// ); /// # Ok(()) /// # } /// ``` - pub fn from_slice(b: &[u8]) -> Result { + pub fn from_slice_le(b: &[u8]) -> Result { if b.len() != 16 { return Err(ErrorKind::InvalidLength { expected: ExpectedLength::Exact(16), @@ -325,7 +353,7 @@ impl Uuid { let mut bytes: Bytes = [0; 16]; bytes.copy_from_slice(b); - Ok(Uuid::from_bytes(bytes)) + Ok(Uuid::from_bytes_le(bytes)) } /// Creates a UUID using the supplied bytes. @@ -336,15 +364,19 @@ impl Uuid { /// /// ``` /// # fn main() -> Result<(), Box> { - /// use uuid::Uuid; - /// - /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87]; + /// # use uuid::Uuid; + /// let bytes = [ + /// 0xa1, 0xa2, 0xa3, 0xa4, + /// 0xb1, 0xb2, + /// 0xc1, 0xc2, + /// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + /// ]; /// /// let uuid = Uuid::from_bytes(bytes); /// /// assert_eq!( /// uuid.to_hyphenated().to_string(), - /// "0436430c-2b02-624c-2032-570501212b57" + /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8" /// ); /// # Ok(()) /// # } @@ -352,6 +384,40 @@ impl Uuid { pub const fn from_bytes(bytes: Bytes) -> Uuid { Uuid(bytes) } + + /// Creates a UUID using the supplied bytes in little endian order. + /// + /// The individual fields encoded in the buffer will be flipped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # fn main() -> Result<(), Box> { + /// # use uuid::Uuid; + /// let bytes = [ + /// 0xa1, 0xa2, 0xa3, 0xa4, + /// 0xb1, 0xb2, + /// 0xc1, 0xc2, + /// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + /// ]; + /// + /// let uuid = Uuid::from_bytes_le(bytes); + /// + /// assert_eq!( + /// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8", + /// uuid.to_hyphenated().to_string(), + /// ); + /// # Ok(()) + /// # } + /// ``` + pub const fn from_bytes_le(b: Bytes) -> Uuid { + Uuid([ + b[3], b[2], b[1], b[0], b[5], b[4], b[7], b[6], b[8], b[9], b[10], + b[11], b[12], b[13], b[14], b[15], + ]) + } } impl Builder { @@ -362,27 +428,80 @@ impl Builder { /// Basic usage: /// /// ``` - /// let bytes: uuid::Bytes = [ - /// 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, 145, 63, 62, + /// # use uuid::Builder; + /// let bytes = [ + /// 0xa1, 0xa2, 0xa3, 0xa4, + /// 0xb1, 0xb2, + /// 0xc1, 0xc2, + /// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, /// ]; /// - /// let mut builder = uuid::Builder::from_bytes(bytes); - /// let uuid = builder.build().to_hyphenated().to_string(); + /// let uuid = Builder::from_bytes(bytes).into_uuid(); /// - /// let expected_uuid = String::from("46ebd0ee-0e6d-43c9-b90d-ccc35a913f3e"); + /// assert_eq!( + /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", + /// uuid.to_hyphenated().to_string(), + /// ); + /// ``` + pub const fn from_bytes(b: Bytes) -> Self { + Builder(Uuid::from_bytes(b).0) + } + + /// Creates a `Builder` using the supplied bytes in little endian order. /// - /// assert_eq!(expected_uuid, uuid); + /// The individual fields encoded in the buffer will be flipped. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # fn main() -> Result<(), Box> { + /// # use uuid::{Builder, Uuid}; + /// let bytes = [ + /// 0xa1, 0xa2, 0xa3, 0xa4, + /// 0xb1, 0xb2, + /// 0xc1, 0xc2, + /// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + /// ]; + /// + /// let uuid = Builder::from_bytes_le(bytes).into_uuid(); + /// + /// assert_eq!( + /// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8", + /// uuid.to_hyphenated().to_string(), + /// ); + /// # Ok(()) + /// # } /// ``` + pub const fn from_bytes_le(b: Bytes) -> Self { + Builder(Uuid::from_bytes_le(b).0) + } + + /// Creates a `Builder` using the supplied random bytes. /// - /// An incorrect number of bytes: + /// This method can be useful in environments where the `v4` feature isn't + /// available. This method will take care of setting the appropriate + /// version and variant fields. /// - /// ```compile_fail - /// let bytes: uuid::Bytes = [4, 54, 67, 12, 43, 2, 98, 76]; // doesn't compile + /// # Examples /// - /// let uuid = uuid::Builder::from_bytes(bytes); /// ``` - pub const fn from_bytes(b: Bytes) -> Self { + /// # use uuid::{Builder, Variant, Version}; + /// # let rng = || [ + /// # 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, + /// # 145, 63, 62, + /// # ]; + /// let random_bytes = rng(); + /// let uuid = Builder::from_random_bytes(random_bytes).build(); + /// + /// assert_eq!(Some(Version::Random), uuid.get_version()); + /// assert_eq!(Variant::RFC4122, uuid.get_variant()); + /// ``` + pub const fn from_random_bytes(b: Bytes) -> Self { Builder(b) + .with_variant(Variant::RFC4122) + .with_version(Version::Random) } /// Creates a `Builder` using the supplied bytes. @@ -396,29 +515,61 @@ impl Builder { /// Basic usage: /// /// ``` - /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87]; - /// - /// let builder = uuid::Builder::from_slice(&bytes); - /// let uuid = - /// builder.map(|mut builder| builder.build().to_hyphenated().to_string()); + /// # use uuid::Builder; + /// # fn main() -> Result<(), Box> { + /// let bytes = [ + /// 0xa1, 0xa2, 0xa3, 0xa4, + /// 0xb1, 0xb2, + /// 0xc1, 0xc2, + /// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + /// ]; /// - /// let expected_uuid = - /// Ok(String::from("0436430c-2b02-624c-2032-570501212b57")); + /// let uuid = Builder::from_slice(&bytes)?.into_uuid(); /// - /// assert_eq!(expected_uuid, uuid); + /// assert_eq!( + /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", + /// uuid.to_hyphenated().to_string(), + /// ); + /// # Ok(()) + /// # } /// ``` + pub fn from_slice(b: &[u8]) -> Result { + Ok(Builder(*Uuid::from_slice(b)?.as_bytes())) + } + + /// Creates a `Builder` using the supplied bytes in little endian order. /// - /// An incorrect number of bytes: + /// The individual fields encoded in the buffer will be flipped. + /// + /// # Errors + /// + /// This function will return an error if `b` has any length other than 16. + /// + /// # Examples + /// + /// Basic usage: /// /// ``` - /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76]; + /// # use uuid::Builder; + /// # fn main() -> Result<(), Box> { + /// let bytes = [ + /// 0xa1, 0xa2, 0xa3, 0xa4, + /// 0xb1, 0xb2, + /// 0xc1, 0xc2, + /// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, + /// ]; /// - /// let builder = uuid::Builder::from_slice(&bytes); + /// let uuid = Builder::from_slice_le(&bytes)?.into_uuid(); /// - /// assert!(builder.is_err()); + /// assert_eq!( + /// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8", + /// uuid.to_hyphenated().to_string(), + /// ); + /// # Ok(()) + /// # } /// ``` - pub fn from_slice(b: &[u8]) -> Result { - Ok(Builder(*Uuid::from_slice(b)?.as_bytes())) + pub fn from_slice_le(b: &[u8]) -> Result { + Ok(Builder(*Uuid::from_slice_le(b)?.as_bytes())) } /// Creates a `Builder` from four field values. @@ -428,16 +579,17 @@ impl Builder { /// Basic usage: /// /// ``` - /// let d1 = 0xAB3F1097u32; - /// let d2 = 0x501Eu16; - /// let d3 = 0xB736u16; - /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; + /// # use uuid::Builder; + /// let d1 = 0xa1a2a3a4; + /// let d2 = 0xb1b2; + /// let d3 = 0xc1c2; + /// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; /// - /// let uuid = uuid::Builder::from_fields(d1, d2, d3, &d4).into_uuid(); + /// let uuid = Builder::from_fields(d1, d2, d3, &d4).into_uuid(); /// /// assert_eq!( /// uuid.to_hyphenated().to_string(), - /// "ab3f1097-501e-b736-0c03-0938362b0809" + /// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8" /// ); /// ``` pub const fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Self { @@ -451,16 +603,17 @@ impl Builder { /// Basic usage: /// /// ``` - /// let d1 = 0xAB3F1097u32; - /// let d2 = 0x501Eu16; - /// let d3 = 0xB736u16; - /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; + /// # use uuid::Builder; + /// let d1 = 0xa1a2a3a4; + /// let d2 = 0xb1b2; + /// let d3 = 0xc1c2; + /// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; /// - /// let uuid = uuid::Builder::from_fields_le(d1, d2, d3, &d4).into_uuid(); + /// let uuid = Builder::from_fields_le(d1, d2, d3, &d4).into_uuid(); /// /// assert_eq!( /// uuid.to_hyphenated().to_string(), - /// "97103fab-1e50-36b7-0c03-0938362b0809" + /// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8" /// ); /// ``` pub const fn from_fields_le( @@ -484,13 +637,12 @@ impl Builder { /// Basic usage: /// /// ``` - /// use uuid::Builder; - /// - /// let mut builder = Builder::nil(); + /// # use uuid::Builder; + /// let uuid = Builder::nil().into_uuid(); /// /// assert_eq!( - /// builder.build().to_hyphenated().to_string(), - /// "00000000-0000-0000-0000-000000000000" + /// "00000000-0000-0000-0000-000000000000", + /// uuid.to_hyphenated().to_string(), /// ); /// ``` pub const fn nil() -> Self { @@ -537,8 +689,7 @@ impl Builder { /// Basic usage: /// /// ``` - /// use uuid::Builder; - /// + /// # use uuid::Builder; /// let uuid = Builder::nil().build(); /// /// assert_eq!( @@ -546,13 +697,44 @@ impl Builder { /// "00000000-0000-0000-0000-000000000000" /// ); /// ``` - /// - /// [`Uuid`]: struct.Uuid.html pub fn build(&mut self) -> Uuid { Uuid::from_bytes(self.0) } /// Convert the builder into a [`Uuid`]. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # use uuid::Builder; + /// let builder = Builder::nil(); + /// + /// let uuid1 = builder.to_uuid(); + /// let uuid2 = builder.to_uuid(); + /// + /// assert_eq!(uuid1, uuid2); + /// ``` + pub const fn to_uuid(&self) -> Uuid { + Uuid::from_bytes(self.0) + } + + /// Convert the builder into a [`Uuid`]. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// # use uuid::Builder; + /// let uuid = Builder::nil().into_uuid(); + /// + /// assert_eq!( + /// uuid.to_hyphenated().to_string(), + /// "00000000-0000-0000-0000-000000000000" + /// ); + /// ``` pub const fn into_uuid(self) -> Uuid { Uuid::from_bytes(self.0) } diff --git a/src/lib.rs b/src/lib.rs index 63cf7c9a8..4849f668d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -66,15 +66,17 @@ //! //! ## Unstable features //! -//! Some features are unstable. They may be incomplete or depend on other unstable libraries. -//! These include: +//! Some features are unstable. They may be incomplete or depend on other +//! unstable libraries. These include: //! -//! * `zerocopy-unstable` - adds support for zero-copy deserialization using the `zerocopy` library. +//! * `zerocopy-unstable` - adds support for zero-copy deserialization using the +//! `zerocopy` library. //! //! Unstable features may break between minor releases. //! -//! To allow unstable features, you'll need to enable the Cargo feature as normal, but also pass an additional -//! flag through your environment to opt-in to unstable `uuid` features: +//! To allow unstable features, you'll need to enable the Cargo feature as +//! normal, but also pass an additional flag through your environment to opt-in +//! to unstable `uuid` features: //! //! ```text //! RUSTFLAGS="--cfg uuid_unstable" @@ -118,60 +120,30 @@ //! //! To parse a UUID given in the simple format and print it as a urn: //! -//! ```rust -//! use uuid::Uuid; +//! ``` +//! # use uuid::Uuid; +//! # fn main() -> Result<(), Box> { +//! let my_uuid = Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8")?; //! -//! fn main() -> Result<(), uuid::Error> { -//! let my_uuid = -//! Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8")?; -//! println!("{}", my_uuid.to_urn()); -//! Ok(()) -//! } +//! println!("{}", my_uuid.to_urn()); +//! # Ok(()) +//! # } //! ``` //! //! To create a new random (V4) UUID and print it out in hexadecimal form: //! -//! ```rust +//! ``` //! // Note that this requires the `v4` feature enabled in the uuid crate. +//! # use uuid::Uuid; +//! # fn main() { +//! # #[cfg(feature = "v4")] { +//! let my_uuid = Uuid::new_v4(); //! -//! use uuid::Uuid; -//! -//! fn main() { -//! # #[cfg(feature = "v4")] { -//! let my_uuid = Uuid::new_v4(); -//! println!("{}", my_uuid) -//! # } -//! } +//! println!("{}", my_uuid) +//! # } +//! # } //! ``` //! -//! # Strings -//! -//! Examples of string representations: -//! -//! * simple: `936DA01F9ABD4d9d80C702AF85C822A8` -//! * hyphenated: `550e8400-e29b-41d4-a716-446655440000` -//! * urn: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4` -//! -//! # Endianness -//! -//! The specification for UUIDs encodes the integer fields that make up the -//! value in big-endian order. This crate assumes integer inputs are already in -//! the correct order by default, regardless of the endianness of the -//! environment. Most methods that accept integers have a `_le` variant (such as -//! `from_fields_le`) that assumes any integer values will need to have their -//! bytes flipped, regardless of the endianness of the environment. -//! -//! Most users won't need to worry about endianness unless they need to operate -//! on individual fields (such as when converting between Microsoft GUIDs). The -//! important things to remember are: -//! -//! - The endianness is in terms of the fields of the UUID, not the environment. -//! - The endianness is assumed to be big-endian when there's no `_le` suffix -//! somewhere. -//! - Byte-flipping in `_le` methods applies to each integer. -//! - Endianness roundtrips, so if you create a UUID with `from_fields_le` -//! you'll get the same values back out with `to_fields_le`. -//! //! # References //! //! * [Wikipedia: Universally Unique Identifier](http://en.wikipedia.org/wiki/Universally_unique_identifier) @@ -277,9 +249,103 @@ pub enum Variant { /// A Universally Unique Identifier (UUID). /// -/// This type is always guaranteed to be have the same ABI as a `[u8; 16]`. +/// # Examples +/// +/// To parse a UUID given in the simple format and print it as a urn: +/// +/// ``` +/// # use uuid::Uuid; +/// # fn main() -> Result<(), Box> { +/// let my_uuid = Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8")?; +/// +/// println!("{}", my_uuid.to_urn()); +/// # Ok(()) +/// # } +/// ``` +/// +/// To create a new random (V4) UUID and print it out in hexadecimal form: +/// +/// ``` +/// // Note that this requires the `v4` feature enabled in the uuid crate. +/// # use uuid::Uuid; +/// # fn main() { +/// # #[cfg(feature = "v4")] { +/// let my_uuid = Uuid::new_v4(); +/// +/// println!("{}", my_uuid) +/// # } +/// # } +/// ``` +/// +/// # Formatting +/// +/// A UUID can be formatted in one of a few ways: +/// +/// * [`simple`](#method.to_simple): `a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8`. +/// * [`hyphenated`](#method.to_hyphenated): +/// `a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8`. +/// * [`urn`](#method.to_urn): `urn:uuid:A1A2A3A4-B1B2-C1C2-D1D2-D3D4D5D6D7D8`. +/// +/// The default representation when formatting a UUID with `Display` is +/// hyphenated: +/// +/// ``` +/// # use uuid::Uuid; +/// # fn main() -> Result<(), Box> { +/// let my_uuid = Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8")?; +/// +/// assert_eq!( +/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", +/// my_uuid.to_string(), +/// ); +/// # Ok(()) +/// # } +/// ``` +/// +/// Other formats can be specified using adapter methods on the UUID: +/// +/// ``` +/// # use uuid::Uuid; +/// # fn main() -> Result<(), Box> { +/// let my_uuid = Uuid::parse_str("a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8")?; +/// +/// assert_eq!( +/// "urn:uuid:a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8", +/// my_uuid.to_urn().to_string(), +/// ); +/// # Ok(()) +/// # } +/// ``` +/// +/// # Endianness +/// +/// The specification for UUIDs encodes the integer fields that make up the +/// value in big-endian order. This crate assumes integer inputs are already in +/// the correct order by default, regardless of the endianness of the +/// environment. Most methods that accept integers have a `_le` variant (such as +/// `from_fields_le`) that assumes any integer values will need to have their +/// bytes flipped, regardless of the endianness of the environment. +/// +/// Most users won't need to worry about endianness unless they need to operate +/// on individual fields (such as when converting between Microsoft GUIDs). The +/// important things to remember are: +/// +/// - The endianness is in terms of the fields of the UUID, not the environment. +/// - The endianness is assumed to be big-endian when there's no `_le` suffix +/// somewhere. +/// - Byte-flipping in `_le` methods applies to each integer. +/// - Endianness roundtrips, so if you create a UUID with `from_fields_le` +/// you'll get the same values back out with `to_fields_le`. +/// +/// # ABI +/// +/// The `Uuid` type is always guaranteed to be have the same ABI as a `[u8; +/// 16]`. #[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] -#[cfg_attr(feature = "zerocopy-unstable", derive(AsBytes, FromBytes, Unaligned))] +#[cfg_attr( + feature = "zerocopy-unstable", + derive(AsBytes, FromBytes, Unaligned) +)] #[repr(transparent)] pub struct Uuid(Bytes); @@ -332,7 +398,7 @@ impl Uuid { /// Returns the version number of the UUID. /// /// This represents the algorithm used to generate the contents. - /// This method is the future-proof alternative to [`get_version`]. + /// This method is the future-proof alternative to [`Uuid::get_version`]. pub const fn get_version_num(&self) -> usize { (self.as_bytes()[6] >> 4) as usize } @@ -342,7 +408,8 @@ impl Uuid { /// This represents the algorithm used to generate the contents. /// If the version field doesn't contain a recognized version then `None` /// is returned. If you're trying to read the version for a future extension - /// you can also use [`get_version_num`] to unconditionally return a number. + /// you can also use [`Uuid::get_version_num`] to unconditionally return a + /// number. pub const fn get_version(&self) -> Option { match self.get_version_num() { 0 if self.is_nil() => Some(Version::Nil), @@ -378,25 +445,25 @@ impl Uuid { /// # Examples /// /// ``` - /// use uuid::Uuid; + /// # use uuid::Uuid; + /// # fn main() -> Result<(), Box> { + /// let uuid = Uuid::nil(); /// - /// fn main() -> Result<(), uuid::Error> { - /// let uuid = Uuid::nil(); - /// assert_eq!(uuid.as_fields(), (0, 0, 0, &[0u8; 8])); + /// assert_eq!(uuid.as_fields(), (0, 0, 0, &[0u8; 8])); /// - /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?; - /// assert_eq!( - /// uuid.as_fields(), - /// ( - /// 0x936DA01F, - /// 0x9ABD, - /// 0x4D9D, - /// b"\x80\xC7\x02\xAF\x85\xC8\x22\xA8" - /// ) - /// ); + /// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?; /// - /// Ok(()) - /// } + /// assert_eq!( + /// uuid.as_fields(), + /// ( + /// 0xa1a2a3a4, + /// 0xb1b2, + /// 0xc1c2, + /// &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8], + /// ) + /// ); + /// # Ok(()) + /// # } /// ``` pub fn as_fields(&self) -> (u32, u16, u16, &[u8; 8]) { let bytes = self.as_bytes(); @@ -426,19 +493,20 @@ impl Uuid { /// ``` /// use uuid::Uuid; /// - /// fn main() -> Result<(), uuid::Error> { - /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?; - /// assert_eq!( - /// uuid.to_fields_le(), - /// ( - /// 0x1FA06D93, - /// 0xBD9A, - /// 0x9D4D, - /// b"\x80\xC7\x02\xAF\x85\xC8\x22\xA8" - /// ) - /// ); - /// Ok(()) - /// } + /// # fn main() -> Result<(), Box> { + /// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?; + /// + /// assert_eq!( + /// uuid.to_fields_le(), + /// ( + /// 0xa4a3a2a1, + /// 0xb2b1, + /// 0xc2c1, + /// &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8], + /// ) + /// ); + /// # Ok(()) + /// # } /// ``` pub fn to_fields_le(&self) -> (u32, u16, u16, &[u8; 8]) { let d1 = (self.as_bytes()[0] as u32) @@ -463,16 +531,16 @@ impl Uuid { /// # Examples /// /// ``` - /// use uuid::Uuid; + /// # use uuid::Uuid; + /// # fn main() -> Result<(), Box> { + /// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?; /// - /// fn main() -> Result<(), uuid::Error> { - /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?; - /// assert_eq!( - /// uuid.as_u128(), - /// 0x936DA01F9ABD4D9D80C702AF85C822A8, - /// ); - /// Ok(()) - /// } + /// assert_eq!( + /// uuid.as_u128(), + /// 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8, + /// ); + /// # Ok(()) + /// # } /// ``` pub const fn as_u128(&self) -> u128 { (self.as_bytes()[0] as u128) << 120 @@ -507,17 +575,16 @@ impl Uuid { /// # Examples /// /// ``` - /// use uuid::Uuid; - /// - /// fn main() -> Result<(), uuid::Error> { - /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?; + /// # use uuid::Uuid; + /// # fn main() -> Result<(), Box> { + /// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?; /// - /// assert_eq!( - /// uuid.to_u128_le(), - /// 0xA822C885AF02C7809D4DBD9A1FA06D93, - /// ); - /// Ok(()) - /// } + /// assert_eq!( + /// uuid.to_u128_le(), + /// 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1, + /// ); + /// # Ok(()) + /// # } /// ``` pub const fn to_u128_le(&self) -> u128 { (self.as_bytes()[0] as u128) @@ -547,17 +614,15 @@ impl Uuid { /// # Examples /// /// ``` - /// use uuid::Uuid; - /// - /// fn main() -> Result<(), uuid::Error> { - /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?; - /// assert_eq!( - /// uuid.as_u64_pair(), - /// (0x936DA01F9ABD4D9D, - /// 0x80C702AF85C822A8), - /// ); - /// Ok(()) - /// } + /// # use uuid::Uuid; + /// # fn main() -> Result<(), Box> { + /// let uuid = Uuid::parse_str("a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8")?; + /// assert_eq!( + /// uuid.as_u64_pair(), + /// (0xa1a2a3a4b1b2c1c2, 0xd1d2d3d4d5d6d7d8), + /// ); + /// # Ok(()) + /// # } /// ``` pub const fn as_u64_pair(&self) -> (u64, u64) { let value = self.as_u128(); @@ -579,9 +644,8 @@ impl Uuid { /// /// # Examples /// - /// ```rust - /// use uuid::Uuid; - /// + /// ``` + /// # use uuid::Uuid; /// let uuid = Uuid::nil(); /// /// assert_eq!( diff --git a/src/v1.rs b/src/v1.rs index 04dcebb18..7f0b1bff7 100644 --- a/src/v1.rs +++ b/src/v1.rs @@ -161,7 +161,7 @@ impl Uuid { /// /// ```rust /// use uuid::v1::{Timestamp, Context}; - /// use uuid::Uuid; + /// # use uuid::Uuid; /// /// let context = Context::new(42); /// let ts = Timestamp::from_unix(&context, 1497624119, 1234); @@ -177,7 +177,7 @@ impl Uuid { /// /// ``` /// use uuid::v1::{Timestamp, Context}; - /// use uuid::Uuid; + /// # use uuid::Uuid; /// /// let context = Context::new(42); /// let ts = Timestamp::from_rfc4122(1497624119, 0); @@ -303,9 +303,13 @@ mod tests { assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460); // Ensure parsing the same UUID produces the same timestamp - let parsed = Uuid::parse_str("20616934-4ba2-11e7-8000-010203040506").unwrap(); + let parsed = + Uuid::parse_str("20616934-4ba2-11e7-8000-010203040506").unwrap(); - assert_eq!(uuid.get_timestamp().unwrap(), parsed.get_timestamp().unwrap()); + assert_eq!( + uuid.get_timestamp().unwrap(), + parsed.get_timestamp().unwrap() + ); } #[test] diff --git a/src/v3.rs b/src/v3.rs index c6f7c7554..d9fcf1d8c 100644 --- a/src/v3.rs +++ b/src/v3.rs @@ -16,6 +16,17 @@ impl Uuid { /// Note that usage of this method requires the `v3` feature of this crate /// to be enabled. /// + /// # Examples + /// + /// Generating a MD5 DNS UUID for `rust-lang.ord`: + /// + /// ``` + /// # use uuid::{Uuid, Version}; + /// let uuid = Uuid::new_v3(&Uuid::NAMESPACE_DNS, b"rust-lang.org"); + /// + /// assert_eq!(Some(Version::Md5), uuid.get_version()); + /// ``` + /// /// [`NAMESPACE_DNS`]: #associatedconstant.NAMESPACE_DNS /// [`NAMESPACE_OID`]: #associatedconstant.NAMESPACE_OID /// [`NAMESPACE_URL`]: #associatedconstant.NAMESPACE_URL diff --git a/src/v4.rs b/src/v4.rs index a4f2bdf95..20e89b4ec 100644 --- a/src/v4.rs +++ b/src/v4.rs @@ -7,7 +7,7 @@ impl Uuid { /// as the source of random numbers. If you'd like to use a custom /// generator, don't use this method: generate random bytes using your /// custom generator and pass them to the - /// [`uuid::Builder::from_bytes`][from_bytes] function instead. + /// [`uuid::Builder::from_random_bytes`][from_random_bytes] function instead. /// /// Note that usage of this method requires the `v4` feature of this crate /// to be enabled. @@ -17,13 +17,14 @@ impl Uuid { /// Basic usage: /// /// ``` - /// use uuid::Uuid; - /// + /// # use uuid::{Uuid, Version}; /// let uuid = Uuid::new_v4(); + /// + /// assert_eq!(Some(Version::Random), uuid.get_version()); /// ``` /// /// [`getrandom`]: https://crates.io/crates/getrandom - /// [from_bytes]: struct.Builder.html#method.from_bytes + /// [from_random_bytes]: struct.Builder.html#method.from_random_bytes pub fn new_v4() -> Uuid { let mut bytes = [0u8; 16]; getrandom::getrandom(&mut bytes).unwrap_or_else(|err| { diff --git a/src/v5.rs b/src/v5.rs index 146aa27f3..116eba9c0 100644 --- a/src/v5.rs +++ b/src/v5.rs @@ -15,6 +15,17 @@ impl Uuid { /// Note that usage of this method requires the `v5` feature of this crate /// to be enabled. /// + /// # Examples + /// + /// Generating a SHA1 DNS UUID for `rust-lang.ord`: + /// + /// ``` + /// # use uuid::{Uuid, Version}; + /// let uuid = Uuid::new_v5(&Uuid::NAMESPACE_DNS, b"rust-lang.org"); + /// + /// assert_eq!(Some(Version::Sha1), uuid.get_version()); + /// ``` + /// /// [`NAMESPACE_DNS`]: struct.Uuid.html#associatedconst.NAMESPACE_DNS /// [`NAMESPACE_OID`]: struct.Uuid.html#associatedconst.NAMESPACE_OID /// [`NAMESPACE_URL`]: struct.Uuid.html#associatedconst.NAMESPACE_URL diff --git a/src/winapi_support.rs b/src/winapi_support.rs index d6c3a83ed..a6e7c8afa 100644 --- a/src/winapi_support.rs +++ b/src/winapi_support.rs @@ -48,7 +48,8 @@ mod tests { #[test] fn test_parse_guid() { // This example GUID is directly from https://docs.microsoft.com/en-us/windows/win32/api/guiddef/ns-guiddef-guid - let uuid = Uuid::parse_str("6B29FC40-CA47-1067-B31D-00DD010662DA").unwrap(); + let uuid = + Uuid::parse_str("6B29FC40-CA47-1067-B31D-00DD010662DA").unwrap(); assert_eq!(Variant::RFC4122, uuid.get_variant()); assert_eq!(Some(Version::Mac), uuid.get_version()); @@ -62,13 +63,13 @@ mod tests { Data3: Default::default(), Data4: Default::default(), }; - + unsafe { CoCreateGuid(&mut guid as *mut _); } - + let uuid = Uuid::from_guid(guid); - + assert_eq!(Variant::RFC4122, uuid.get_variant()); assert_eq!(Some(Version::Random), uuid.get_version()); } From 1960f9faf4bd3b484c9344f01542830a32eb7239 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Mon, 1 Nov 2021 11:02:37 +1000 Subject: [PATCH 5/9] fix up signature of Uuid::from_fields_le --- src/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/builder.rs b/src/builder.rs index c2ed72d50..5359f9985 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -127,7 +127,7 @@ impl Uuid { /// uuid.to_hyphenated().to_string(), /// ); /// ``` - pub const fn from_fields_le(d1: u32, d2: u16, d3: u16, d4: &[u8]) -> Uuid { + pub const fn from_fields_le(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Uuid { Uuid::from_bytes([ d1 as u8, (d1 >> 8) as u8, From fd0fb6e3387790d0eebb9c63cc6a10da5584cac6 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Mon, 1 Nov 2021 11:03:02 +1000 Subject: [PATCH 6/9] more work on docs --- src/lib.rs | 12 +++++++++++- src/parser.rs | 15 +++++++++++++++ src/v1.rs | 8 +++++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 4849f668d..50b9a247a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -381,7 +381,9 @@ impl Uuid { /// Callers should only trust the value returned by this method if they /// trust the UUID itself. /// - /// * [Variant Reference](http://tools.ietf.org/html/rfc4122#section-4.1.1) + /// # References + /// + /// * [Variant in RFC4122](http://tools.ietf.org/html/rfc4122#section-4.1.1) pub const fn get_variant(&self) -> Variant { match self.as_bytes()[8] { x if x & 0x80 == 0x00 => Variant::NCS, @@ -399,6 +401,10 @@ impl Uuid { /// /// This represents the algorithm used to generate the contents. /// This method is the future-proof alternative to [`Uuid::get_version`]. + /// + /// # References + /// + /// * [Version in RFC4122](https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.3) pub const fn get_version_num(&self) -> usize { (self.as_bytes()[6] >> 4) as usize } @@ -410,6 +416,10 @@ impl Uuid { /// is returned. If you're trying to read the version for a future extension /// you can also use [`Uuid::get_version_num`] to unconditionally return a /// number. + /// + /// # References + /// + /// * [Version in RFC4122](https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.3) pub const fn get_version(&self) -> Option { match self.get_version_num() { 0 if self.is_nil() => Some(Version::Nil), diff --git a/src/parser.rs b/src/parser.rs index 04ebd3f8a..44f3e88de 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -32,6 +32,21 @@ impl Uuid { /// /// Any of the formats generated by this module (simple, hyphenated, urn) /// are supported by this parsing function. + /// + /// # Examples + /// + /// Parse a hyphenated UUID: + /// + /// ``` + /// # use uuid::{Uuid, Version, Variant}; + /// # fn main() -> Result<(), Box> { + /// let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")?; + /// + /// assert_eq!(Some(Version::Random), uuid.get_version()); + /// assert_eq!(Variant::RFC4122, uuid.get_variant()); + /// # Ok(()) + /// # } + /// ``` pub fn parse_str(input: &str) -> Result { Ok(Uuid::from_bytes(imp::parse_str(input)?)) } diff --git a/src/v1.rs b/src/v1.rs index 7f0b1bff7..bcca31433 100644 --- a/src/v1.rs +++ b/src/v1.rs @@ -120,6 +120,10 @@ impl Timestamp { } /// A trait that abstracts over generation of UUID v1 "Clock Sequence" values. +/// +/// # References +/// +/// * [Clock Sequence in RFC4122](https://datatracker.ietf.org/doc/html/rfc4122#section-4.1.5) pub trait ClockSequence { /// Return a 16-bit number that will be used as the "clock sequence" in /// the UUID. The number must be different if the time has changed since @@ -165,6 +169,7 @@ impl Uuid { /// /// let context = Context::new(42); /// let ts = Timestamp::from_unix(&context, 1497624119, 1234); + /// /// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]); /// /// assert_eq!( @@ -181,6 +186,7 @@ impl Uuid { /// /// let context = Context::new(42); /// let ts = Timestamp::from_rfc4122(1497624119, 0); + /// /// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]); /// /// assert_eq!( @@ -190,7 +196,7 @@ impl Uuid { /// ``` /// /// [`Timestamp`]: v1/struct.Timestamp.html - /// [`ClockSequence`]: v1/struct.ClockSequence.html + /// [`ClockSequence`]: v1/trait.ClockSequence.html /// [`Context`]: v1/struct.Context.html pub const fn new_v1(ts: Timestamp, node_id: &[u8; 6]) -> Self { let time_low = (ts.ticks & 0xFFFF_FFFF) as u32; From 94cf3fb3bb1560e86b05221503895333a0b171c8 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Mon, 1 Nov 2021 11:06:38 +1000 Subject: [PATCH 7/9] reword the v1 module docs a little --- src/v1.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/v1.rs b/src/v1.rs index bcca31433..8f308caca 100644 --- a/src/v1.rs +++ b/src/v1.rs @@ -1,6 +1,7 @@ //! The implementation for Version 1 UUIDs. //! -//! Note that you need feature `v1` in order to use these features. +//! Note that you need to enable the `v1` Cargo feature +//! in order to use this module. use crate::{Uuid, Version}; From be01b14747680f681ab237853a085b51ddff4466 Mon Sep 17 00:00:00 2001 From: KodrAus Date: Mon, 1 Nov 2021 11:08:21 +1000 Subject: [PATCH 8/9] update some old links --- .github/workflows/ci.yml | 2 +- CONTRIBUTING.md | 8 +++----- README.md | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 418e0ee80..dd6138f72 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,7 +4,7 @@ on: pull_request: push: branches: - - master + - main schedule: - cron: '0 0 * * *' diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2bd9f87b3..89fabc538 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -80,15 +80,13 @@ source repository. Unless the changes are fairly minor (like documentation changes or tiny patches), we require PRs to relevant issues. -Please open PRs against branch: -* `master` when making non-breaking changes -* `breaking` when your changes alter the public API in a breaking manner +Please open PRs against the `main` branch. If the pull request is still a work in progress, prepend`[WIP] ` in your title. `WIP bot` will make sure that the PR doesn't accidentally get merged. > Uuid Project has a minimum rust version policy. Currently `uuid` should -compile with atleast `1.22.0`, and is enforced on our CI builds. +compile with at least `1.22.0`, and is enforced on our CI builds. When you feel that the PR is ready, please ping one of the maintainers so they can review your changes. @@ -105,7 +103,7 @@ improvements to documentation are always welcome. We follow the documentation style guidelines as given by [RFC 1574]. -[RFC 1574]: https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text +[RFC 1574]: https://github.com/rust-lang/rfcs/blob/main/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text # Issue Triage [Issue Triage]: #issue-triage diff --git a/README.md b/README.md index 0e9359ff6..888e52605 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ uuid [![Latest Version](https://img.shields.io/crates/v/uuid.svg)](https://crates.io/crates/uuid) [![Join the chat at https://gitter.im/uuid-rs/Lobby](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/uuid-rs/Lobby?utm_source=badge&utm_medium=badge&utm_content=badge) ![Minimum rustc version](https://img.shields.io/badge/rustc-1.46.0+-yellow.svg) -[![Build Status](https://ci.appveyor.com/api/projects/status/github/uuid-rs/uuid?branch=master&svg=true)](https://ci.appveyor.com/project/uuid-rs/uuid/branch/master) -[![Build Status](https://travis-ci.org/uuid-rs/uuid.svg?branch=master)](https://travis-ci.org/uuid-rs/uuid) +[![Build Status](https://ci.appveyor.com/api/projects/status/github/uuid-rs/uuid?branch=main&svg=true)](https://ci.appveyor.com/project/uuid-rs/uuid/branch/main) +[![Build Status](https://travis-ci.org/uuid-rs/uuid.svg?branch=main)](https://travis-ci.org/uuid-rs/uuid) [![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/uuid-rs/uuid.svg)](https://isitmaintained.com/project/uuid-rs/uuid "Average time to resolve an issue") [![Percentage of issues still open](https://isitmaintained.com/badge/open/uuid-rs/uuid.svg)](https://isitmaintained.com/project/uuid-rs/uuid "Percentage of issues still open") [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fuuid-rs%2Fuuid.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fuuid-rs%2Fuuid?ref=badge_shield) From c84f5b8fe7b1c96bc77217d487f04363d6cf8ebc Mon Sep 17 00:00:00 2001 From: KodrAus Date: Mon, 1 Nov 2021 11:12:15 +1000 Subject: [PATCH 9/9] update docs for random on embedded --- src/builder.rs | 7 ++++++- src/lib.rs | 4 +++- src/v4.rs | 3 ++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/builder.rs b/src/builder.rs index 5359f9985..6fc399095 100644 --- a/src/builder.rs +++ b/src/builder.rs @@ -127,7 +127,12 @@ impl Uuid { /// uuid.to_hyphenated().to_string(), /// ); /// ``` - pub const fn from_fields_le(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Uuid { + pub const fn from_fields_le( + d1: u32, + d2: u16, + d3: u16, + d4: &[u8; 8], + ) -> Uuid { Uuid::from_bytes([ d1 as u8, (d1 >> 8) as u8, diff --git a/src/lib.rs b/src/lib.rs index 50b9a247a..45e3978eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -114,7 +114,9 @@ //! //! If you need to use `v4` in a no-std environment, you'll need to //! follow [`getrandom`'s docs] on configuring a source of randomness -//! on currently unsupported targets. +//! on currently unsupported targets. Alternatively, you can produce +//! random bytes yourself and then pass them to [`Builder::from_random_bytes`] +//! without enabling the `v4` feature. //! //! # Examples //! diff --git a/src/v4.rs b/src/v4.rs index 20e89b4ec..0e6930647 100644 --- a/src/v4.rs +++ b/src/v4.rs @@ -7,7 +7,8 @@ impl Uuid { /// as the source of random numbers. If you'd like to use a custom /// generator, don't use this method: generate random bytes using your /// custom generator and pass them to the - /// [`uuid::Builder::from_random_bytes`][from_random_bytes] function instead. + /// [`uuid::Builder::from_random_bytes`][from_random_bytes] function + /// instead. /// /// Note that usage of this method requires the `v4` feature of this crate /// to be enabled.