diff -Nru rust-uuid-0.7.1/benches/format_str.rs rust-uuid-0.8.1/benches/format_str.rs --- rust-uuid-0.7.1/benches/format_str.rs 2018-09-14 20:25:43.000000000 +0000 +++ rust-uuid-0.8.1/benches/format_str.rs 2019-10-17 04:22:56.000000000 +0000 @@ -1,10 +1,9 @@ #![feature(test)] extern crate test; -extern crate uuid; use std::io::Write; use test::Bencher; -use uuid::prelude::*; +use uuid::Uuid; #[bench] fn bench_hyphen(b: &mut Bencher) { @@ -41,7 +40,7 @@ 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); + uuid.to_hyphenated().encode_lower(&mut buffer); test::black_box(buffer); }); } @@ -51,7 +50,7 @@ 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); + uuid.to_simple().encode_lower(&mut buffer); test::black_box(buffer); }) } @@ -61,7 +60,7 @@ 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); + uuid.to_urn().encode_lower(&mut buffer); test::black_box(buffer); }) } diff -Nru rust-uuid-0.7.1/benches/invalid_parse_str.rs rust-uuid-0.8.1/benches/invalid_parse_str.rs --- rust-uuid-0.7.1/benches/invalid_parse_str.rs 2018-09-14 20:25:04.000000000 +0000 +++ rust-uuid-0.8.1/benches/invalid_parse_str.rs 2019-10-17 04:22:56.000000000 +0000 @@ -1,14 +1,8 @@ #![feature(test)] -#[cfg(feature = "slog")] -#[macro_use] -extern crate slog; extern crate test; -extern crate uuid; -#[cfg(feature = "slog")] -use slog::Drain; use test::Bencher; -use uuid::prelude::*; +use uuid::Uuid; #[bench] fn bench_parse_invalid_strings(b: &mut Bencher) { diff -Nru rust-uuid-0.7.1/benches/mod.rs rust-uuid-0.8.1/benches/mod.rs --- rust-uuid-0.7.1/benches/mod.rs 2018-09-14 20:25:04.000000000 +0000 +++ rust-uuid-0.8.1/benches/mod.rs 2019-04-09 03:51:03.000000000 +0000 @@ -1,8 +1,4 @@ #![feature(test)] -#[cfg(feature = "slog")] -#[macro_use] -extern crate slog; -extern crate test; -extern crate uuid; +#[cfg(feature = "slog")] pub mod slog_support; diff -Nru rust-uuid-0.7.1/benches/serde_support.rs rust-uuid-0.8.1/benches/serde_support.rs --- rust-uuid-0.7.1/benches/serde_support.rs 2018-09-14 20:25:04.000000000 +0000 +++ rust-uuid-0.8.1/benches/serde_support.rs 2019-10-17 04:22:56.000000000 +0000 @@ -1,13 +1,12 @@ #![cfg(feature = "serde")] #![feature(test)] -extern crate bincode; -extern crate serde_json; +use bincode; +use serde_json; extern crate test; -extern crate uuid; use test::Bencher; -use uuid::prelude::*; +use uuid::Uuid; #[bench] fn bench_json_encode(b: &mut Bencher) { diff -Nru rust-uuid-0.7.1/benches/slog_support/mod.rs rust-uuid-0.8.1/benches/slog_support/mod.rs --- rust-uuid-0.7.1/benches/slog_support/mod.rs 2018-09-14 20:25:43.000000000 +0000 +++ rust-uuid-0.8.1/benches/slog_support/mod.rs 2019-04-09 03:51:03.000000000 +0000 @@ -1,7 +1 @@ -#[cfg(feature = "slog")] -// #[macro_use] -// extern crate slog; -// extern crate test; -extern crate uuid; - pub mod parse_str; diff -Nru rust-uuid-0.7.1/benches/slog_support/parse_str.rs rust-uuid-0.8.1/benches/slog_support/parse_str.rs --- rust-uuid-0.7.1/benches/slog_support/parse_str.rs 2018-09-14 20:25:43.000000000 +0000 +++ rust-uuid-0.8.1/benches/slog_support/parse_str.rs 2019-04-09 03:51:03.000000000 +0000 @@ -1,15 +1,15 @@ -use test::Bencher; -use uuid::prelude::*; +extern crate test; #[bench] #[cfg(feature = "slog")] -pub fn bench_log_discard_kv(b: &mut Bencher) { - let u1 = Uuid::parse_str("F9168C5E-CEB2-4FAB-B6BF-329BF39FA1E4").unwrap(); - let root = ::slog::Logger::root(::slog::Drain::fuse(::slog::Discard), o!()); - // let root = ::slog::Logger::root(::slog::Discard.fuse(), o!()); +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")] - crit!(root, "test"; "u1" => u1); + slog::crit!(root, "test"; "u1" => u1); }); } diff -Nru rust-uuid-0.7.1/benches/valid_parse_str.rs rust-uuid-0.8.1/benches/valid_parse_str.rs --- rust-uuid-0.7.1/benches/valid_parse_str.rs 2018-09-14 20:25:04.000000000 +0000 +++ rust-uuid-0.8.1/benches/valid_parse_str.rs 2019-10-17 04:22:56.000000000 +0000 @@ -1,14 +1,9 @@ #![feature(test)] -#[cfg(feature = "slog")] -#[macro_use] -extern crate slog; + extern crate test; -extern crate uuid; -#[cfg(feature = "slog")] -use slog::Drain; use test::Bencher; -use uuid::prelude::*; +use uuid::Uuid; #[bench] fn bench_parse_valid_strings(b: &mut Bencher) { diff -Nru rust-uuid-0.7.1/Cargo.toml rust-uuid-0.8.1/Cargo.toml --- rust-uuid-0.7.1/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/Cargo.toml 1970-01-01 00:00:00.000000000 +0000 @@ -11,37 +11,36 @@ # will likely look very different (and much more reasonable) [package] +edition = "2018" name = "uuid" -version = "0.7.1" +version = "0.8.1" authors = ["Ashley Mannix", "Christopher Armstrong", "Dylan DPC", "Hunar Roop Kahlon"] exclude = [".github/**", ".travis.yml", "appveyor.yml", "bors.toml"] description = "A library to generate and parse UUIDs." homepage = "https://github.com/uuid-rs/uuid" documentation = "https://docs.rs/uuid" readme = "README.md" +keywords = ["guid", "unique", "uuid"] +categories = ["data-structures", "no-std", "parser-implementations", "wasm"] license = "Apache-2.0 OR MIT" repository = "https://github.com/uuid-rs/uuid" [package.metadata.docs.rs] -all-features = true +default-target = "x86_64-pc-windows-msvc" +features = ["guid", "serde", "slog", "v1", "v3", "v4", "v5"] [package.metadata.playground] -features = ["serde", "u128", "v1", "v3", "v4", "v5"] -[dependencies.byteorder] -version = "1" -features = ["i128"] -optional = true -default-features = false - +features = ["serde", "v1", "v3", "v4", "v5"] [dependencies.md5] -version = "0.3" +version = "0.6" optional = true [dependencies.rand] -version = "0.5" +version = "0.7" optional = true [dependencies.serde] version = "1.0.56" +features = ["serde_derive"] optional = true default-features = false @@ -55,6 +54,9 @@ [dev-dependencies.bincode] version = "1.0" +[dev-dependencies.serde_derive] +version = "1.0.79" + [dev-dependencies.serde_json] version = "1.0" @@ -62,12 +64,29 @@ version = "1.0.56" [features] -const_fn = ["nightly"] default = ["std"] -nightly = [] +guid = ["winapi"] std = [] -u128 = ["byteorder"] +stdweb = ["rand/stdweb"] v1 = [] -v3 = ["md5", "rand"] +v3 = ["md5"] v4 = ["rand"] -v5 = ["sha1", "rand"] +v5 = ["sha1"] +wasm-bindgen = ["rand/wasm-bindgen"] +[target."cfg(windows)".dependencies.winapi] +version = "0.3" +optional = true +[badges.appveyor] +repository = "uuid-rs/uuid" + +[badges.is-it-maintained-issue-resolution] +repository = "uuid-rs/uuid" + +[badges.is-it-maintained-open-issues] +repository = "uuid-rs/uuid" + +[badges.maintenance] +status = "actively-developed" + +[badges.travis-ci] +repository = "uuid-rs/uuid" diff -Nru rust-uuid-0.7.1/Cargo.toml.orig rust-uuid-0.8.1/Cargo.toml.orig --- rust-uuid-0.7.1/Cargo.toml.orig 2018-09-14 20:26:39.000000000 +0000 +++ rust-uuid-0.8.1/Cargo.toml.orig 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +1,92 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies +# +# If you believe there's an error in this file please file an +# issue against the rust-lang/cargo repository. If you're +# editing this file be aware that the upstream Cargo.toml +# will likely look very different (and much more reasonable) + [package] -authors = [ - "Ashley Mannix", - "Christopher Armstrong", - "Dylan DPC", - "Hunar Roop Kahlon" -] +edition = "2018" +name = "uuid" +version = "0.8.1" +authors = ["Ashley Mannix", "Christopher Armstrong", "Dylan DPC", "Hunar Roop Kahlon"] +exclude = [".github/**", ".travis.yml", "appveyor.yml", "bors.toml"] description = "A library to generate and parse UUIDs." -documentation = "https://docs.rs/uuid" -exclude = [ - ".github/**", - ".travis.yml", - "appveyor.yml", - "bors.toml" -] -license = "Apache-2.0 OR MIT" homepage = "https://github.com/uuid-rs/uuid" -name = "uuid" +documentation = "https://docs.rs/uuid" readme = "README.md" +keywords = ["guid", "unique", "uuid"] +categories = ["data-structures", "no-std", "parser-implementations", "wasm"] +license = "Apache-2.0 OR MIT" repository = "https://github.com/uuid-rs/uuid" -version = "0.7.1" - [package.metadata.docs.rs] -all-features = true +default-target = "x86_64-pc-windows-msvc" +features = ["guid", "serde", "slog", "v1", "v3", "v4", "v5"] [package.metadata.playground] -features = ["serde", "u128", "v1", "v3", "v4", "v5"] - -[dependencies.byteorder] -default-features = false -features = ["i128"] -optional = true -version = "1" - +features = ["serde", "v1", "v3", "v4", "v5"] [dependencies.md5] +version = "0.6" optional = true -version = "0.3" [dependencies.rand] +version = "0.7" optional = true -version = "0.5" [dependencies.serde] -default-features = false -optional = true version = "1.0.56" +features = ["serde_derive"] +optional = true +default-features = false [dependencies.sha1] -optional = true version = "0.6" +optional = true [dependencies.slog] -optional = true version = "2" +optional = true +[dev-dependencies.bincode] +version = "1.0" -[dev-dependencies.serde_test] -version = "1.0.56" +[dev-dependencies.serde_derive] +version = "1.0.79" [dev-dependencies.serde_json] version = "1.0" -[dev-dependencies.bincode] -version = "1.0" +[dev-dependencies.serde_test] +version = "1.0.56" [features] default = ["std"] +guid = ["winapi"] std = [] +stdweb = ["rand/stdweb"] v1 = [] -v3 = ["md5", "rand"] +v3 = ["md5"] v4 = ["rand"] -v5 = ["sha1", "rand"] +v5 = ["sha1"] +wasm-bindgen = ["rand/wasm-bindgen"] +[target."cfg(windows)".dependencies.winapi] +version = "0.3" +optional = true +[badges.appveyor] +repository = "uuid-rs/uuid" + +[badges.is-it-maintained-issue-resolution] +repository = "uuid-rs/uuid" + +[badges.is-it-maintained-open-issues] +repository = "uuid-rs/uuid" -# since rust 1.26.0 -u128 = ["byteorder"] +[badges.maintenance] +status = "actively-developed" -# nightly rust -#------------------------ -# Allow using `const fn`s -const_fn = ["nightly"] -# Nightly marker feature gate -nightly = [] +[badges.travis-ci] +repository = "uuid-rs/uuid" diff -Nru rust-uuid-0.7.1/.cargo_vcs_info.json rust-uuid-0.8.1/.cargo_vcs_info.json --- rust-uuid-0.7.1/.cargo_vcs_info.json 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/.cargo_vcs_info.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +1,5 @@ { "git": { - "sha1": "7e453d81fb6f1389c135635a1aa0b39e4360f93d" + "sha1": "fb62500eef27e068fa0f86b1e99513f2b959b867" } } diff -Nru rust-uuid-0.7.1/CONTRIBUTING.md rust-uuid-0.8.1/CONTRIBUTING.md --- rust-uuid-0.7.1/CONTRIBUTING.md 2018-09-02 10:45:54.000000000 +0000 +++ rust-uuid-0.8.1/CONTRIBUTING.md 2018-11-05 21:13:31.000000000 +0000 @@ -88,7 +88,7 @@ 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.18.0`, and is enforced on our CI builds. +compile with atleast `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. diff -Nru rust-uuid-0.7.1/debian/cargo-checksum.json rust-uuid-0.8.1/debian/cargo-checksum.json --- rust-uuid-0.7.1/debian/cargo-checksum.json 2018-10-14 10:13:13.000000000 +0000 +++ rust-uuid-0.8.1/debian/cargo-checksum.json 2019-12-29 10:54:22.000000000 +0000 @@ -1 +1 @@ -{"package":"dab5c5526c5caa3d106653401a267fed923e7046f35895ffcb5ca42db64942e6","files":{}} +{"package":"Could not get crate checksum","files":{}} diff -Nru rust-uuid-0.7.1/debian/changelog rust-uuid-0.8.1/debian/changelog --- rust-uuid-0.7.1/debian/changelog 2018-10-14 10:13:13.000000000 +0000 +++ rust-uuid-0.8.1/debian/changelog 2020-01-11 00:07:07.000000000 +0000 @@ -1,3 +1,58 @@ +rust-uuid (0.8.1-2ubuntu1) focal; urgency=medium + + * Merge from Debian unstable; remaining changes: + - Don't build librust-uuid+wasm-bindgen-dev on ppc64el + + -- Steve Langasek Fri, 10 Jan 2020 16:07:07 -0800 + +rust-uuid (0.8.1-2) unstable; urgency=medium + + * Team upload. + * Package uuid 0.8.1 from crates.io using debcargo 2.4.0 + + -- Andrej Shadura Sun, 29 Dec 2019 11:54:22 +0100 + +rust-uuid (0.8.1-1) unstable; urgency=medium + + * Team upload. + * Package uuid 0.8.1 from crates.io using debcargo 2.2.10 + + -- Andrej Shadura Tue, 29 Oct 2019 09:23:10 +0100 + +rust-uuid (0.7.4-1) unstable; urgency=medium + + * Package uuid 0.7.4 from crates.io using debcargo 2.2.10 + + -- Sylvestre Ledru Mon, 14 Oct 2019 10:56:38 +0200 + +rust-uuid (0.7.2-2ubuntu1) eoan; urgency=medium + + * Merge from Debian unstable; remaining changes: + - Don't build librust-uuid+wasm-bindgen-dev on ppc64el + + -- Steve Langasek Tue, 27 Aug 2019 08:55:25 -0700 + +rust-uuid (0.7.2-2) unstable; urgency=medium + + * Package uuid 0.7.2 from crates.io using debcargo 2.2.10 + * Source upload for migration + + -- Sylvestre Ledru Tue, 06 Aug 2019 18:26:42 +0200 + +rust-uuid (0.7.2-1ubuntu1) disco; urgency=medium + + * Don't build librust-uuid+wasm-bindgen-dev on ppc64el, uninstallable + until further notice due to + https://github.com/rust-lang/rust/issues/58516. + + -- Steve Langasek Tue, 26 Feb 2019 22:28:25 -0800 + +rust-uuid (0.7.2-1) unstable; urgency=medium + + * Package uuid 0.7.2 from crates.io using debcargo 2.2.10 + + -- Sylvestre Ledru Sun, 03 Feb 2019 21:26:18 +0100 + rust-uuid (0.7.1-1) unstable; urgency=medium * Package uuid 0.7.1 from crates.io using debcargo 2.2.7 diff -Nru rust-uuid-0.7.1/debian/control rust-uuid-0.8.1/debian/control --- rust-uuid-0.7.1/debian/control 2018-10-14 10:13:13.000000000 +0000 +++ rust-uuid-0.8.1/debian/control 2020-01-11 00:07:07.000000000 +0000 @@ -2,11 +2,12 @@ Section: rust Priority: optional Build-Depends: debhelper (>= 11), - dh-cargo (>= 10), + dh-cargo (>= 18), cargo:native , rustc:native , libstd-rust-dev -Maintainer: Debian Rust Maintainers +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: Debian Rust Maintainers Uploaders: Sylvestre Ledru Standards-Version: 4.2.0 @@ -20,58 +21,54 @@ Depends: ${misc:Depends} Suggests: - librust-uuid+byteorder-dev (= ${binary:Version}), + librust-uuid+guid-dev (= ${binary:Version}), librust-uuid+md5-dev (= ${binary:Version}), librust-uuid+rand-dev (= ${binary:Version}), librust-uuid+serde-dev (= ${binary:Version}), librust-uuid+sha1-dev (= ${binary:Version}), librust-uuid+slog-dev (= ${binary:Version}), - librust-uuid+u128-dev (= ${binary:Version}), - librust-uuid+v3-dev (= ${binary:Version}), - librust-uuid+v4-dev (= ${binary:Version}), - librust-uuid+v5-dev (= ${binary:Version}) + librust-uuid+stdweb-dev (= ${binary:Version}), + librust-uuid+wasm-bindgen-dev (= ${binary:Version}) Provides: - librust-uuid+const-fn-dev (= ${binary:Version}), librust-uuid+default-dev (= ${binary:Version}), - librust-uuid+nightly-dev (= ${binary:Version}), librust-uuid+std-dev (= ${binary:Version}), librust-uuid+v1-dev (= ${binary:Version}), librust-uuid-0-dev (= ${binary:Version}), - librust-uuid-0+const-fn-dev (= ${binary:Version}), librust-uuid-0+default-dev (= ${binary:Version}), - librust-uuid-0+nightly-dev (= ${binary:Version}), librust-uuid-0+std-dev (= ${binary:Version}), librust-uuid-0+v1-dev (= ${binary:Version}), - librust-uuid-0.7-dev (= ${binary:Version}), - librust-uuid-0.7+const-fn-dev (= ${binary:Version}), - librust-uuid-0.7+default-dev (= ${binary:Version}), - librust-uuid-0.7+nightly-dev (= ${binary:Version}), - librust-uuid-0.7+std-dev (= ${binary:Version}), - librust-uuid-0.7+v1-dev (= ${binary:Version}), - librust-uuid-0.7.1-dev (= ${binary:Version}), - librust-uuid-0.7.1+const-fn-dev (= ${binary:Version}), - librust-uuid-0.7.1+default-dev (= ${binary:Version}), - librust-uuid-0.7.1+nightly-dev (= ${binary:Version}), - librust-uuid-0.7.1+std-dev (= ${binary:Version}), - librust-uuid-0.7.1+v1-dev (= ${binary:Version}) + librust-uuid-0.8-dev (= ${binary:Version}), + librust-uuid-0.8+default-dev (= ${binary:Version}), + librust-uuid-0.8+std-dev (= ${binary:Version}), + librust-uuid-0.8+v1-dev (= ${binary:Version}), + librust-uuid-0.8.1-dev (= ${binary:Version}), + librust-uuid-0.8.1+default-dev (= ${binary:Version}), + librust-uuid-0.8.1+std-dev (= ${binary:Version}), + librust-uuid-0.8.1+v1-dev (= ${binary:Version}) Description: Generate and parse UUIDs - Rust source code This package contains the source for the Rust uuid crate, packaged by debcargo for use with cargo and dh-cargo. -Package: librust-uuid+byteorder-dev +Package: librust-uuid+guid-dev Architecture: any Multi-Arch: same Depends: ${misc:Depends}, librust-uuid-dev (= ${binary:Version}), - librust-byteorder-1+i128-dev + librust-winapi-0.3+default-dev Provides: - librust-uuid-0+byteorder-dev (= ${binary:Version}), - librust-uuid-0.7+byteorder-dev (= ${binary:Version}), - librust-uuid-0.7.1+byteorder-dev (= ${binary:Version}) -Description: Generate and parse UUIDs - feature "byteorder" - This metapackage enables feature byteorder for the Rust uuid crate, by pulling - in any additional dependencies needed by that feature. + librust-uuid+winapi-dev (= ${binary:Version}), + librust-uuid-0+guid-dev (= ${binary:Version}), + librust-uuid-0+winapi-dev (= ${binary:Version}), + librust-uuid-0.8+guid-dev (= ${binary:Version}), + librust-uuid-0.8+winapi-dev (= ${binary:Version}), + librust-uuid-0.8.1+guid-dev (= ${binary:Version}), + librust-uuid-0.8.1+winapi-dev (= ${binary:Version}) +Description: Generate and parse UUIDs - feature "guid" and 1 more + This metapackage enables feature "guid" for the Rust uuid crate, by pulling in + any additional dependencies needed by that feature. + . + Additionally, this package also provides the "winapi" feature. Package: librust-uuid+md5-dev Architecture: any @@ -79,14 +76,20 @@ Depends: ${misc:Depends}, librust-uuid-dev (= ${binary:Version}), - librust-md5-0.3+default-dev + librust-md5-0.7+default-dev Provides: + librust-uuid+v3-dev (= ${binary:Version}), librust-uuid-0+md5-dev (= ${binary:Version}), - librust-uuid-0.7+md5-dev (= ${binary:Version}), - librust-uuid-0.7.1+md5-dev (= ${binary:Version}) -Description: Generate and parse UUIDs - feature "md5" - This metapackage enables feature md5 for the Rust uuid crate, by pulling in any - additional dependencies needed by that feature. + librust-uuid-0+v3-dev (= ${binary:Version}), + librust-uuid-0.8+md5-dev (= ${binary:Version}), + librust-uuid-0.8+v3-dev (= ${binary:Version}), + librust-uuid-0.8.1+md5-dev (= ${binary:Version}), + librust-uuid-0.8.1+v3-dev (= ${binary:Version}) +Description: Generate and parse UUIDs - feature "md5" and 1 more + This metapackage enables feature "md5" for the Rust uuid crate, by pulling in + any additional dependencies needed by that feature. + . + Additionally, this package also provides the "v3" feature. Package: librust-uuid+rand-dev Architecture: any @@ -94,14 +97,20 @@ Depends: ${misc:Depends}, librust-uuid-dev (= ${binary:Version}), - librust-rand-0.5+default-dev + librust-rand-0.7+default-dev Provides: + librust-uuid+v4-dev (= ${binary:Version}), librust-uuid-0+rand-dev (= ${binary:Version}), - librust-uuid-0.7+rand-dev (= ${binary:Version}), - librust-uuid-0.7.1+rand-dev (= ${binary:Version}) -Description: Generate and parse UUIDs - feature "rand" - This metapackage enables feature rand for the Rust uuid crate, by pulling in + librust-uuid-0+v4-dev (= ${binary:Version}), + librust-uuid-0.8+rand-dev (= ${binary:Version}), + librust-uuid-0.8+v4-dev (= ${binary:Version}), + librust-uuid-0.8.1+rand-dev (= ${binary:Version}), + librust-uuid-0.8.1+v4-dev (= ${binary:Version}) +Description: Generate and parse UUIDs - feature "rand" and 1 more + This metapackage enables feature "rand" for the Rust uuid crate, by pulling in any additional dependencies needed by that feature. + . + Additionally, this package also provides the "v4" feature. Package: librust-uuid+serde-dev Architecture: any @@ -109,13 +118,13 @@ Depends: ${misc:Depends}, librust-uuid-dev (= ${binary:Version}), - librust-serde-1-dev (>= 1.0.56~~) + librust-serde-1+serde-derive-dev (>= 1.0.56-~~) Provides: librust-uuid-0+serde-dev (= ${binary:Version}), - librust-uuid-0.7+serde-dev (= ${binary:Version}), - librust-uuid-0.7.1+serde-dev (= ${binary:Version}) + librust-uuid-0.8+serde-dev (= ${binary:Version}), + librust-uuid-0.8.1+serde-dev (= ${binary:Version}) Description: Generate and parse UUIDs - feature "serde" - This metapackage enables feature serde for the Rust uuid crate, by pulling in + This metapackage enables feature "serde" for the Rust uuid crate, by pulling in any additional dependencies needed by that feature. Package: librust-uuid+sha1-dev @@ -126,12 +135,18 @@ librust-uuid-dev (= ${binary:Version}), librust-sha1-0.6+default-dev Provides: + librust-uuid+v5-dev (= ${binary:Version}), librust-uuid-0+sha1-dev (= ${binary:Version}), - librust-uuid-0.7+sha1-dev (= ${binary:Version}), - librust-uuid-0.7.1+sha1-dev (= ${binary:Version}) -Description: Generate and parse UUIDs - feature "sha1" - This metapackage enables feature sha1 for the Rust uuid crate, by pulling in + librust-uuid-0+v5-dev (= ${binary:Version}), + librust-uuid-0.8+sha1-dev (= ${binary:Version}), + librust-uuid-0.8+v5-dev (= ${binary:Version}), + librust-uuid-0.8.1+sha1-dev (= ${binary:Version}), + librust-uuid-0.8.1+v5-dev (= ${binary:Version}) +Description: Generate and parse UUIDs - feature "sha1" and 1 more + This metapackage enables feature "sha1" for the Rust uuid crate, by pulling in any additional dependencies needed by that feature. + . + Additionally, this package also provides the "v5" feature. Package: librust-uuid+slog-dev Architecture: any @@ -142,70 +157,38 @@ librust-slog-2+default-dev Provides: librust-uuid-0+slog-dev (= ${binary:Version}), - librust-uuid-0.7+slog-dev (= ${binary:Version}), - librust-uuid-0.7.1+slog-dev (= ${binary:Version}) + librust-uuid-0.8+slog-dev (= ${binary:Version}), + librust-uuid-0.8.1+slog-dev (= ${binary:Version}) Description: Generate and parse UUIDs - feature "slog" - This metapackage enables feature slog for the Rust uuid crate, by pulling in + This metapackage enables feature "slog" for the Rust uuid crate, by pulling in any additional dependencies needed by that feature. -Package: librust-uuid+u128-dev +Package: librust-uuid+stdweb-dev Architecture: any Multi-Arch: same Depends: ${misc:Depends}, librust-uuid-dev (= ${binary:Version}), - librust-byteorder-1+i128-dev + librust-rand-0.7+stdweb-dev Provides: - librust-uuid-0+u128-dev (= ${binary:Version}), - librust-uuid-0.7+u128-dev (= ${binary:Version}), - librust-uuid-0.7.1+u128-dev (= ${binary:Version}) -Description: Generate and parse UUIDs - feature "u128" - This metapackage enables feature u128 for the Rust uuid crate, by pulling in - any additional dependencies needed by that feature. - -Package: librust-uuid+v3-dev -Architecture: any -Multi-Arch: same -Depends: - ${misc:Depends}, - librust-uuid-dev (= ${binary:Version}), - librust-md5-0.3+default-dev, - librust-rand-0.5+default-dev -Provides: - librust-uuid-0+v3-dev (= ${binary:Version}), - librust-uuid-0.7+v3-dev (= ${binary:Version}), - librust-uuid-0.7.1+v3-dev (= ${binary:Version}) -Description: Generate and parse UUIDs - feature "v3" - This metapackage enables feature v3 for the Rust uuid crate, by pulling in any - additional dependencies needed by that feature. - -Package: librust-uuid+v4-dev -Architecture: any -Multi-Arch: same -Depends: - ${misc:Depends}, - librust-uuid-dev (= ${binary:Version}), - librust-rand-0.5+default-dev -Provides: - librust-uuid-0+v4-dev (= ${binary:Version}), - librust-uuid-0.7+v4-dev (= ${binary:Version}), - librust-uuid-0.7.1+v4-dev (= ${binary:Version}) -Description: Generate and parse UUIDs - feature "v4" - This metapackage enables feature v4 for the Rust uuid crate, by pulling in any - additional dependencies needed by that feature. + librust-uuid-0+stdweb-dev (= ${binary:Version}), + librust-uuid-0.8+stdweb-dev (= ${binary:Version}), + librust-uuid-0.8.1+stdweb-dev (= ${binary:Version}) +Description: Generate and parse UUIDs - feature "stdweb" + This metapackage enables feature "stdweb" for the Rust uuid crate, by pulling + in any additional dependencies needed by that feature. -Package: librust-uuid+v5-dev -Architecture: any +Package: librust-uuid+wasm-bindgen-dev +Architecture: amd64 arm64 armhf s390x Multi-Arch: same Depends: ${misc:Depends}, librust-uuid-dev (= ${binary:Version}), - librust-rand-0.5+default-dev, - librust-sha1-0.6+default-dev + librust-rand-0.7+wasm-bindgen-dev Provides: - librust-uuid-0+v5-dev (= ${binary:Version}), - librust-uuid-0.7+v5-dev (= ${binary:Version}), - librust-uuid-0.7.1+v5-dev (= ${binary:Version}) -Description: Generate and parse UUIDs - feature "v5" - This metapackage enables feature v5 for the Rust uuid crate, by pulling in any - additional dependencies needed by that feature. + librust-uuid-0+wasm-bindgen-dev (= ${binary:Version}), + librust-uuid-0.8+wasm-bindgen-dev (= ${binary:Version}), + librust-uuid-0.8.1+wasm-bindgen-dev (= ${binary:Version}) +Description: Generate and parse UUIDs - feature "wasm-bindgen" + This metapackage enables feature "wasm-bindgen" for the Rust uuid crate, by + pulling in any additional dependencies needed by that feature. diff -Nru rust-uuid-0.7.1/debian/copyright.debcargo.hint rust-uuid-0.8.1/debian/copyright.debcargo.hint --- rust-uuid-0.7.1/debian/copyright.debcargo.hint 2018-10-14 10:13:13.000000000 +0000 +++ rust-uuid-0.8.1/debian/copyright.debcargo.hint 2019-12-29 10:54:22.000000000 +0000 @@ -38,15 +38,6 @@ FIXME (overlay): These notices are extracted from files. Please review them before uploading to the archive. -Files: ./src/adapter/core_support/mod.rs -Copyright: - 2013-2014 The Rust Project Developers. - 2018 The Uuid Project Developers. -License: UNKNOWN-LICENSE; FIXME (overlay) -Comment: - FIXME (overlay): These notices are extracted from files. Please review them - before uploading to the archive. - Files: ./src/adapter/mod.rs Copyright: 2013-2014 The Rust Project Developers. @@ -56,7 +47,7 @@ FIXME (overlay): These notices are extracted from files. Please review them before uploading to the archive. -Files: ./src/core_support.rs +Files: ./src/builder/mod.rs Copyright: 2013-2014 The Rust Project Developers. 2018 The Uuid Project Developers. @@ -74,15 +65,6 @@ FIXME (overlay): These notices are extracted from files. Please review them before uploading to the archive. -Files: ./src/parser/core_support.rs -Copyright: - 2013-2014 The Rust Project Developers. - 2018 The Uuid Project Developers. -License: UNKNOWN-LICENSE; FIXME (overlay) -Comment: - FIXME (overlay): These notices are extracted from files. Please review them - before uploading to the archive. - Files: ./src/parser/mod.rs Copyright: 2013-2014 The Rust Project Developers. @@ -92,15 +74,6 @@ FIXME (overlay): These notices are extracted from files. Please review them before uploading to the archive. -Files: ./src/parser/std_support.rs -Copyright: - 2013-2014 The Rust Project Developers. - 2018 The Uuid Project Developers. -License: UNKNOWN-LICENSE; FIXME (overlay) -Comment: - FIXME (overlay): These notices are extracted from files. Please review them - before uploading to the archive. - Files: ./src/prelude.rs Copyright: 2013-2014 The Rust Project Developers. @@ -128,15 +101,6 @@ FIXME (overlay): These notices are extracted from files. Please review them before uploading to the archive. -Files: ./src/std_support.rs -Copyright: - 2013-2014 The Rust Project Developers. - 2018 The Uuid Project Developers. -License: UNKNOWN-LICENSE; FIXME (overlay) -Comment: - FIXME (overlay): These notices are extracted from files. Please review them - before uploading to the archive. - Files: ./src/test_util.rs Copyright: 2013-2014 The Rust Project Developers. @@ -146,19 +110,10 @@ FIXME (overlay): These notices are extracted from files. Please review them before uploading to the archive. -Files: ./src/u128_support.rs -Copyright: - 2013-2014 The Rust Project Developers. - 2018 The Uuid Project Developers. -License: UNKNOWN-LICENSE; FIXME (overlay) -Comment: - FIXME (overlay): These notices are extracted from files. Please review them - before uploading to the archive. - Files: debian/* Copyright: - 2018 Debian Rust Maintainers - 2018 Sylvestre Ledru + 2018-2019 Debian Rust Maintainers + 2018-2019 Sylvestre Ledru License: Apache-2.0 or MIT License: Apache-2.0 diff -Nru rust-uuid-0.7.1/debian/patches/md5-0.7.patch rust-uuid-0.8.1/debian/patches/md5-0.7.patch --- rust-uuid-0.7.1/debian/patches/md5-0.7.patch 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/debian/patches/md5-0.7.patch 2019-12-29 10:54:22.000000000 +0000 @@ -0,0 +1,11 @@ +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -31,7 +31,7 @@ + [package.metadata.playground] + features = ["serde", "v1", "v3", "v4", "v5"] + [dependencies.md5] +-version = "0.6" ++version = "0.7" + optional = true + + [dependencies.rand] diff -Nru rust-uuid-0.7.1/debian/patches/series rust-uuid-0.8.1/debian/patches/series --- rust-uuid-0.7.1/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/debian/patches/series 2019-12-29 10:54:22.000000000 +0000 @@ -0,0 +1 @@ +md5-0.7.patch diff -Nru rust-uuid-0.7.1/debian/tests/control rust-uuid-0.8.1/debian/tests/control --- rust-uuid-0.7.1/debian/tests/control 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/debian/tests/control 2019-12-29 10:54:22.000000000 +0000 @@ -0,0 +1,39 @@ +Test-Command: /usr/share/cargo/bin/cargo-auto-test uuid 0.8.1 --all-targets --all-features +Depends: dh-cargo (>= 18), librust-bincode-1+default-dev, librust-serde-derive-1+default-dev (>= 1.0.79-~~), librust-serde-json-1+default-dev, librust-serde-test-1+default-dev (>= 1.0.56-~~), @ +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test uuid 0.8.1 --all-targets --no-default-features +Depends: dh-cargo (>= 18), librust-bincode-1+default-dev, librust-serde-derive-1+default-dev (>= 1.0.79-~~), librust-serde-json-1+default-dev, librust-serde-test-1+default-dev (>= 1.0.56-~~), librust-uuid-dev +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test uuid 0.8.1 --all-targets --features guid +Depends: dh-cargo (>= 18), librust-bincode-1+default-dev, librust-serde-derive-1+default-dev (>= 1.0.79-~~), librust-serde-json-1+default-dev, librust-serde-test-1+default-dev (>= 1.0.56-~~), librust-uuid+guid-dev +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test uuid 0.8.1 --all-targets --features md5 +Depends: dh-cargo (>= 18), librust-bincode-1+default-dev, librust-serde-derive-1+default-dev (>= 1.0.79-~~), librust-serde-json-1+default-dev, librust-serde-test-1+default-dev (>= 1.0.56-~~), librust-uuid+md5-dev +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test uuid 0.8.1 --all-targets --features rand +Depends: dh-cargo (>= 18), librust-bincode-1+default-dev, librust-serde-derive-1+default-dev (>= 1.0.79-~~), librust-serde-json-1+default-dev, librust-serde-test-1+default-dev (>= 1.0.56-~~), librust-uuid+rand-dev +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test uuid 0.8.1 --all-targets --features serde +Depends: dh-cargo (>= 18), librust-bincode-1+default-dev, librust-serde-derive-1+default-dev (>= 1.0.79-~~), librust-serde-json-1+default-dev, librust-serde-test-1+default-dev (>= 1.0.56-~~), librust-uuid+serde-dev +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test uuid 0.8.1 --all-targets --features sha1 +Depends: dh-cargo (>= 18), librust-bincode-1+default-dev, librust-serde-derive-1+default-dev (>= 1.0.79-~~), librust-serde-json-1+default-dev, librust-serde-test-1+default-dev (>= 1.0.56-~~), librust-uuid+sha1-dev +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test uuid 0.8.1 --all-targets --features slog +Depends: dh-cargo (>= 18), librust-bincode-1+default-dev, librust-serde-derive-1+default-dev (>= 1.0.79-~~), librust-serde-json-1+default-dev, librust-serde-test-1+default-dev (>= 1.0.56-~~), librust-uuid+slog-dev +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test uuid 0.8.1 --all-targets --features stdweb +Depends: dh-cargo (>= 18), librust-bincode-1+default-dev, librust-serde-derive-1+default-dev (>= 1.0.79-~~), librust-serde-json-1+default-dev, librust-serde-test-1+default-dev (>= 1.0.56-~~), librust-uuid+stdweb-dev +Restrictions: allow-stderr, skip-not-installable + +Test-Command: /usr/share/cargo/bin/cargo-auto-test uuid 0.8.1 --all-targets --features wasm-bindgen +Depends: dh-cargo (>= 18), librust-bincode-1+default-dev, librust-serde-derive-1+default-dev (>= 1.0.79-~~), librust-serde-json-1+default-dev, librust-serde-test-1+default-dev (>= 1.0.56-~~), librust-uuid+wasm-bindgen-dev +Restrictions: allow-stderr, skip-not-installable diff -Nru rust-uuid-0.7.1/.gitignore rust-uuid-0.8.1/.gitignore --- rust-uuid-0.7.1/.gitignore 2018-02-05 19:07:18.000000000 +0000 +++ rust-uuid-0.8.1/.gitignore 2019-04-09 03:51:03.000000000 +0000 @@ -1,12 +1,31 @@ +### CLion ### +# CMake +cmake-build-debug/ + ### IntelliJ ### .idea *.iws *.iml *.ipr -### CLion ### -# CMake -cmake-build-debug/ +### Vim ### +# Swap +[._]*.s[a-v][a-z] +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ ### Rust ### /target/ diff -Nru rust-uuid-0.7.1/README.md rust-uuid-0.8.1/README.md --- rust-uuid-0.7.1/README.md 2018-09-14 20:25:04.000000000 +0000 +++ rust-uuid-0.8.1/README.md 2019-10-18 22:08:23.000000000 +0000 @@ -1,81 +1,98 @@ uuid -==== +--------- -[![Build Status](https://travis-ci.org/uuid-rs/uuid.svg?branch=master)](https://travis-ci.org/uuid-rs/uuid) -[![Appveyor Status](https://ci.appveyor.com/api/projects/status/github/uuid-rs/uuid?branch=master&svg=true)](https://ci.appveyor.com/project/KodrAus/uuid) -[![Latest Version](https://img.shields.io/crates/v/uuid.svg)](https://crates.io/crates/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.22.0+-yellow.svg) - -A Rust library to generate and parse UUIDs. - -Provides support for Universally Unique Identifiers (UUIDs). A UUID is a unique -128-bit number, stored as 16 octets. UUIDs are used to assign unique identifiers -to entities without requiring a central allocating authority. +![Minimum rustc version](https://img.shields.io/badge/rustc-1.31.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) +[![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") + +--- + +Generate and parse UUIDs. + +Provides support for Universally Unique Identifiers (UUIDs). A UUID is a +unique 128-bit number, stored as 16 octets. UUIDs are used to assign +unique identifiers to entities without requiring a central allocating +authority. They are particularly useful in distributed systems, though can be used in -disparate areas, such as databases and network protocols. Typically a UUID is -displayed in a readable string form as a sequence of hexadecimal digits, +disparate areas, such as databases and network protocols. Typically a UUID +is displayed in a readable string form as a sequence of hexadecimal digits, separated into groups by hyphens. -The uniqueness property is not strictly guaranteed, however for all practical -purposes, it can be assumed that an unintentional collision would be extremely -unlikely. +The uniqueness property is not strictly guaranteed, however for all +practical purposes, it can be assumed that an unintentional collision would +be extremely unlikely. + +## Dependencies + +By default, this crate depends on nothing but `std` and cannot generate +[`Uuid`]s. You need to enable the following Cargo features to enable +various pieces of functionality: + +* `v1` - adds the `Uuid::new_v1` function and the ability to create a V1 + using an implementation of `uuid::v1::ClockSequence` (usually +`uuid::v1::Context`) and a timestamp from `time::timespec`. +* `v3` - adds the `Uuid::new_v3` function and the ability to create a V3 + UUID based on the MD5 hash of some data. +* `v4` - adds the `Uuid::new_v4` function and the ability to randomly + generate a `Uuid`. +* `v5` - adds the `Uuid::new_v5` function and the ability to create a V5 + UUID based on the SHA1 hash of some data. +* `serde` - adds the ability to serialize and deserialize a `Uuid` using the + `serde` crate. + +You need to enable one of the following Cargo features together with +`v3`, `v4` or `v5` feature if you're targeting `wasm32` architecture: + +* `stdweb` - enables support for `OsRng` on `wasm32-unknown-unknown` via + `stdweb` combined with `cargo-web` +* `wasm-bindgen` - `wasm-bindgen` enables support for `OsRng` on + `wasm32-unknown-unknown` via [`wasm-bindgen`] -[Documentation](https://docs.rs/uuid) +By default, `uuid` can be depended on with: -## Usage +```toml +[dependencies] +uuid = "0.8" +``` -Add this to your `Cargo.toml`: +To activate various features, use syntax like: ```toml [dependencies] -uuid = "0.7" +uuid = { version = "0.8", features = ["serde", "v4"] } ``` -and this to your crate root: +You can disable default features with: -```rust -extern crate uuid; +```toml +[dependencies] +uuid = { version = "0.8", default-features = false } ``` ## Examples -To parse a simple UUID, then print the version and urn string format: +To parse a UUID given in the simple format and print it as a urn: ```rust -extern crate uuid; use uuid::Uuid; fn main() { - let my_uuid = Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap(); - println!("Parsed a version {} UUID.", my_uuid.get_version_num()); - println!("{}", my_uuid); + let my_uuid = + Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap(); + println!("{}", my_uuid.to_urn()); } ``` -The library supports 5 versions of UUID: - -Name | Version ----------|---------- -Mac | Version 1: MAC address -Dce | Version 2: DCE Security -Md5 | Version 3: MD5 hash -Random | Version 4: Random -Sha1 | Version 5: SHA-1 hash - -To create a new random (V4) UUID and print it out in hexadecimal form, first -you'll need to change how you depend on `uuid`: - -```toml -[dependencies] -uuid = { version = "0.7", features = ["v4"] } -``` - -Next, you'll write: +To create a new random (V4) UUID and print it out in hexadecimal form: ```rust -extern crate uuid; +// Note that this requires the `v4` feature enabled in the uuid crate. + use uuid::Uuid; fn main() { @@ -84,26 +101,35 @@ } ``` -To create a new sha1-hash based (V5) UUID and print it out in hexadecimal form, -you'll also need to change how you depend on `uuid`: +## Strings -```toml -[dependencies] -uuid = { version = "0.7", features = ["v5"] } -``` +Examples of string representations: -Next, you'll write: +* simple: `936DA01F9ABD4d9d80C702AF85C822A8` +* hyphenated: `550e8400-e29b-41d4-a716-446655440000` +* urn: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4` -```rust -extern crate uuid; -use uuid::Uuid; +## References -fn main() { - let my_uuid = Uuid::new_v5(&Uuid::NAMESPACE_DNS, "foo".as_bytes()); - println!("{}", my_uuid); -} -``` +* [Wikipedia: Universally Unique Identifier]( http://en.wikipedia.org/wiki/Universally_unique_identifier) +* [RFC4122: A Universally Unique IDentifier (UUID) URN Namespace]( http://tools.ietf.org/html/rfc4122) -## References +[`wasm-bindgen`]: https://github.com/rustwasm/wasm-bindgen + +[`Uuid`]: https://docs.rs/uuid/0.8.1/uuid/struct.Uuid.html + +--- +# License + +Licensed under either of + +* Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0) +* MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT) + +at your option. + +## Contribution -[Wikipedia: Universally Unique Identifier](https://en.wikipedia.org/wiki/Universally_unique_identifier) +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff -Nru rust-uuid-0.7.1/README.tpl rust-uuid-0.8.1/README.tpl --- rust-uuid-0.7.1/README.tpl 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/README.tpl 2019-04-09 03:51:03.000000000 +0000 @@ -0,0 +1,29 @@ +{{crate}} +--------- + +[![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.31.0+-yellow.svg) +{{badges}} + +--- + +{{readme}} + +[`Uuid`]: https://docs.rs/uuid/{{version}}/uuid/struct.Uuid.html + +--- +# License + +Licensed under either of + +* Apache License, Version 2.0, (LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0) +* MIT license (LICENSE-MIT or https://opensource.org/licenses/MIT) + +at your option. + +## Contribution + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall +be dual licensed as above, without any additional terms or conditions. diff -Nru rust-uuid-0.7.1/src/adapter/compact.rs rust-uuid-0.8.1/src/adapter/compact.rs --- rust-uuid-0.7.1/src/adapter/compact.rs 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/src/adapter/compact.rs 2019-10-18 22:08:23.000000000 +0000 @@ -0,0 +1,79 @@ +//! Module for use with `#[serde(with = "...")]` to serialize a [`Uuid`] +//! as a `[u8; 16]`. +//! +//! [`Uuid`]: ../../struct.Uuid.html + +/// Serializer for a [`Uuid`] into a `[u8; 16]` +/// +/// [`Uuid`]: ../../struct.Uuid.html +pub fn serialize(u: &crate::Uuid, serializer: S) -> Result +where + S: serde::Serializer, +{ + serde::Serialize::serialize(u.as_bytes(), serializer) +} + +/// Deserializer from a `[u8; 16]` into a [`Uuid`] +/// +/// [`Uuid`]: ../../struct.Uuid.html +pub fn deserialize<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ + let bytes: [u8; 16] = serde::Deserialize::deserialize(deserializer)?; + + Ok(crate::Uuid::from_bytes(bytes)) +} + +#[cfg(test)] +mod tests { + + use serde_test; + + #[test] + fn test_serialize_compact() { + #[derive(serde::Serialize, Debug, serde::Deserialize, PartialEq)] + struct UuidContainer { + #[serde(with = "super")] + u: crate::Uuid, + } + use serde_test::Configure; + + let uuid_bytes = b"F9168C5E-CEB2-4F"; + let container = UuidContainer { + u: crate::Uuid::from_slice(uuid_bytes).unwrap(), + }; + + // more complex because of the struct wrapping the actual UUID + // serialization + serde_test::assert_tokens( + &container.compact(), + &[ + serde_test::Token::Struct { + name: "UuidContainer", + len: 1, + }, + serde_test::Token::Str("u"), + serde_test::Token::Tuple { len: 16 }, + serde_test::Token::U8(uuid_bytes[0]), + serde_test::Token::U8(uuid_bytes[1]), + serde_test::Token::U8(uuid_bytes[2]), + serde_test::Token::U8(uuid_bytes[3]), + serde_test::Token::U8(uuid_bytes[4]), + serde_test::Token::U8(uuid_bytes[5]), + serde_test::Token::U8(uuid_bytes[6]), + serde_test::Token::U8(uuid_bytes[7]), + serde_test::Token::U8(uuid_bytes[8]), + serde_test::Token::U8(uuid_bytes[9]), + serde_test::Token::U8(uuid_bytes[10]), + serde_test::Token::U8(uuid_bytes[11]), + serde_test::Token::U8(uuid_bytes[12]), + serde_test::Token::U8(uuid_bytes[13]), + serde_test::Token::U8(uuid_bytes[14]), + serde_test::Token::U8(uuid_bytes[15]), + serde_test::Token::TupleEnd, + serde_test::Token::StructEnd, + ], + ) + } +} diff -Nru rust-uuid-0.7.1/src/adapter/core_support/mod.rs rust-uuid-0.8.1/src/adapter/core_support/mod.rs --- rust-uuid-0.7.1/src/adapter/core_support/mod.rs 2018-09-14 20:25:04.000000000 +0000 +++ rust-uuid-0.8.1/src/adapter/core_support/mod.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,175 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. -// Copyright 2018 The Uuid Project Developers. -// -// See the COPYRIGHT file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use core::fmt; -use prelude::*; - -impl fmt::Display for super::Hyphenated { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } -} - -impl<'a> fmt::Display for super::HyphenatedRef<'a> { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } -} - -impl fmt::Display for super::Simple { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } -} - -impl<'a> fmt::Display for super::SimpleRef<'a> { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } -} - -impl fmt::Display for super::Urn { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } -} - -impl<'a> fmt::Display for super::UrnRef<'a> { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } -} - -impl fmt::LowerHex for super::Hyphenated { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(self.encode_lower(&mut [0; Self::LENGTH])) - } -} - -impl<'a> fmt::LowerHex for super::HyphenatedRef<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808 - f.write_str(self.encode_lower(&mut [0; super::HyphenatedRef::LENGTH])) - } -} - -impl fmt::LowerHex for super::Simple { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(self.encode_lower(&mut [0; Self::LENGTH])) - } -} - -impl<'a> fmt::LowerHex for super::SimpleRef<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808 - f.write_str(self.encode_lower(&mut [0; super::SimpleRef::LENGTH])) - } -} - -impl fmt::LowerHex for super::Urn { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(self.encode_lower(&mut [0; Self::LENGTH])) - } -} - -impl<'a> fmt::LowerHex for super::UrnRef<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808 - f.write_str(self.encode_lower(&mut [0; super::UrnRef::LENGTH])) - } -} - -impl fmt::UpperHex for super::Hyphenated { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(self.encode_upper(&mut [0; Self::LENGTH])) - } -} - -impl<'a> fmt::UpperHex for super::HyphenatedRef<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808 - f.write_str(self.encode_upper(&mut [0; super::HyphenatedRef::LENGTH])) - } -} - -impl fmt::UpperHex for super::Simple { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(self.encode_upper(&mut [0; Self::LENGTH])) - } -} - -impl<'a> fmt::UpperHex for super::SimpleRef<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808 - f.write_str(self.encode_upper(&mut [0; super::SimpleRef::LENGTH])) - } -} - -impl fmt::UpperHex for super::Urn { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.write_str(self.encode_upper(&mut [0; Self::LENGTH])) - } -} - -impl<'a> fmt::UpperHex for super::UrnRef<'a> { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808 - f.write_str(self.encode_upper(&mut [0; super::UrnRef::LENGTH])) - } -} - -impl From for super::Hyphenated { - #[inline] - fn from(f: Uuid) -> Self { - super::Hyphenated::from_uuid(f) - } -} - -impl<'a> From<&'a Uuid> for super::HyphenatedRef<'a> { - #[inline] - fn from(f: &'a Uuid) -> Self { - super::HyphenatedRef::from_uuid_ref(f) - } -} - -impl From for super::Simple { - #[inline] - fn from(f: Uuid) -> Self { - super::Simple::from_uuid(f) - } -} - -impl<'a> From<&'a Uuid> for super::SimpleRef<'a> { - #[inline] - fn from(f: &'a Uuid) -> Self { - super::SimpleRef::from_uuid_ref(f) - } -} - -impl From for super::Urn { - #[inline] - fn from(f: Uuid) -> Self { - super::Urn::from_uuid(f) - } -} - -impl<'a> From<&'a Uuid> for super::UrnRef<'a> { - #[inline] - fn from(f: &'a Uuid) -> Self { - super::UrnRef::from_uuid_ref(f) - } -} diff -Nru rust-uuid-0.7.1/src/adapter/mod.rs rust-uuid-0.8.1/src/adapter/mod.rs --- rust-uuid-0.7.1/src/adapter/mod.rs 2018-09-14 20:25:43.000000000 +0000 +++ rust-uuid-0.8.1/src/adapter/mod.rs 2019-10-18 22:08:23.000000000 +0000 @@ -9,14 +9,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -//! Adapters for various formats for [`Uuid`]s -//! -//! [`Uuid`]: ../struct.Uuid.html +//! Adapters for various formats for UUIDs -use core::str; -use prelude::*; +use crate::prelude::*; +use crate::std::{fmt, str}; -mod core_support; +#[cfg(feature = "serde")] +pub mod compact; /// An adaptor for formatting an [`Uuid`] as a hyphenated string. /// @@ -67,123 +66,53 @@ pub struct UrnRef<'a>(&'a Uuid); impl Uuid { - /// Creates a [`Hyphenated`] instance from a [`Uuid`]. + /// Get a [`Hyphenated`] formatter. /// - /// [`Uuid`]: ../struct.Uuid.html - /// [`Hyphenated`]: adapter/struct.Hyphenated.html - #[cfg(not(feature = "const_fn"))] - #[inline] - pub fn to_hyphenated(self) -> Hyphenated { - Hyphenated::from_uuid(self) - } - - /// Creates a [`Hyphenated`] instance from a [`Uuid`]. - /// - /// [`Uuid`]: ../struct.Uuid.html /// [`Hyphenated`]: adapter/struct.Hyphenated.html - #[cfg(feature = "const_fn")] #[inline] pub const fn to_hyphenated(self) -> Hyphenated { Hyphenated::from_uuid(self) } - /// Creates a [`HyphenatedRef`] instance from a [`Uuid`] reference. - /// - /// [`Uuid`]: ../struct.Uuid.html - /// [`HyphenatedRef`]: adapter/struct.HyphenatedRef.html - #[cfg(not(feature = "const_fn"))] - #[inline] - pub fn to_hyphenated_ref(&self) -> HyphenatedRef { - HyphenatedRef::from_uuid_ref(self) - } - - /// Creates a [`HyphenatedRef`] instance from a [`Uuid`] reference. + /// Get a borrowed [`HyphenatedRef`] formatter. /// - /// [`Uuid`]: ../struct.Uuid.html /// [`HyphenatedRef`]: adapter/struct.HyphenatedRef.html - #[cfg(feature = "const_fn")] #[inline] - pub const fn to_hyphenated_ref(&self) -> HyphenatedRef { + pub const fn to_hyphenated_ref(&self) -> HyphenatedRef<'_> { HyphenatedRef::from_uuid_ref(self) } - /// Creates a [`Simple`] instance from a [`Uuid`]. + /// Get a [`Simple`] formatter. /// - /// [`Uuid`]: ../struct.Uuid.html /// [`Simple`]: adapter/struct.Simple.html - #[cfg(not(feature = "const_fn"))] - #[inline] - pub fn to_simple(self) -> Simple { - Simple::from_uuid(self) - } - - /// Creates a [`Simple`] instance from a [`Uuid`]. - /// - /// [`Uuid`]: ../struct.Uuid.html - /// [`Simple`]: adapter/struct.Simple.html - #[cfg(feature = "const_fn")] #[inline] pub const fn to_simple(self) -> Simple { Simple::from_uuid(self) } - /// Creates a [`SimpleRef`] instance from a [`Uuid`] reference. + /// Get a borrowed [`SimpleRef`] formatter. /// - /// [`Uuid`]: ../struct.Uuid.html /// [`SimpleRef`]: adapter/struct.SimpleRef.html - #[cfg(not(feature = "const_fn"))] #[inline] - pub fn to_simple_ref(&self) -> SimpleRef { + pub const fn to_simple_ref(&self) -> SimpleRef<'_> { SimpleRef::from_uuid_ref(self) } - /// Creates a [`SimpleRef`] instance from a [`Uuid`] reference. - /// - /// [`Uuid`]: ../struct.Uuid.html - /// [`SimpleRef`]: adapter/struct.SimpleRef.html - #[cfg(feature = "const_fn")] - #[inline] - pub const fn to_simple_ref(&self) -> SimpleRef { - SimpleRef::from_uuid_ref(self) - } - - /// Creates a [`Urn`] instance from a [`Uuid`]. - /// - /// [`Uuid`]: ../struct.Uuid.html - /// [`Urn`]: adapter/struct.Urn.html - #[cfg(not(feature = "const_fn"))] - #[inline] - pub fn to_urn(self) -> Urn { - Urn::from_uuid(self) - } - - /// Creates a [`Urn`] instance from a [`Uuid`]. + /// Get a [`Urn`] formatter. /// /// [`Uuid`]: ../struct.Uuid.html /// [`Urn`]: adapter/struct.Urn.html - #[cfg(feature = "const_fn")] #[inline] pub const fn to_urn(self) -> Urn { Urn::from_uuid(self) } - /// Creates a [`UrnRef`] instance from a [`Uuid`] reference. + /// Get a borrowed [`UrnRef`] formatter. /// /// [`Uuid`]: ../struct.Uuid.html /// [`UrnRef`]: adapter/struct.UrnRef.html - #[cfg(not(feature = "const_fn"))] #[inline] - pub fn to_urn_ref(&self) -> UrnRef { - UrnRef::from_uuid_ref(self) - } - - /// Creates a [`UrnRef`] instance from a [`Uuid`] reference. - /// - /// [`Uuid`]: ../struct.Uuid.html - /// [`UrnRef`]: adapter/struct.UrnRef.html - #[cfg(feature = "const_fn")] - #[inline] - pub const fn to_urn_ref(&self) -> UrnRef { + pub const fn to_urn_ref(&self) -> UrnRef<'_> { UrnRef::from_uuid_ref(self) } } @@ -230,12 +159,11 @@ // before this point. That's exactly the (0-indexed) group // number. let hyphens_before = if hyphens { group } else { 0 }; - for idx in BYTE_POSITIONS[group]..BYTE_POSITIONS[group + 1] { let b = bytes[idx]; let out_idx = hyphens_before + 2 * idx; - buffer[out_idx + 0] = hex[(b >> 4) as usize]; + buffer[out_idx] = hex[(b >> 4) as usize]; buffer[out_idx + 1] = hex[(b & 0b1111) as usize]; } @@ -259,115 +187,99 @@ /// /// [`Uuid`]: ../struct.Uuid.html /// [`Hyphenated`]: struct.Hyphenated.html - #[cfg(not(feature = "const_fn"))] - pub fn from_uuid(uuid: Uuid) -> Self { + pub const fn from_uuid(uuid: Uuid) -> Self { Hyphenated(uuid) } - /// Creates a [`Hyphenated`] from a [`Uuid`]. + /// Writes the [`Uuid`] as a lower-case hyphenated string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html - /// [`Hyphenated`]: struct.Hyphenated.html - #[cfg(feature = "const_fn")] - pub const fn from_uuid(uuid: Uuid) -> Self { - Hyphenated(uuid) - } - - // Writes the [`Uuid`] as a lower-case hyphenated string to - // `buffer`, and returns the subslice of the buffer that contains the - // encoded UUID. - // - // This is slightly more efficient than using the formatting - // infrastructure as it avoids virtual calls, and may avoid - // double buffering. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_hyphenated() - // .encode_lower(&mut Uuid::encode_buffer()), - // "936da01f-9abd-4d9d-80c7-02af85c822a8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 40]; - // uuid.to_hyphenated().encode_lower(&mut buf); - // assert_eq!( - // &buf as &[_], - // b"936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_lower<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_hyphenated() + /// .encode_lower(&mut Uuid::encode_buffer()), + /// "936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 40]; + /// uuid.to_hyphenated().encode_lower(&mut buf); + /// assert_eq!( + /// &buf as &[_], + /// b"936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode(buffer, 0, &self.0, true, false) } - // Writes the [`Uuid`] as an upper-case hyphenated string to - // `buffer`, and returns the subslice of the buffer that contains the - // encoded UUID. - // - // This is slightly more efficient than using the formatting - // infrastructure as it avoids virtual calls, and may avoid - // double buffering. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_hyphenated() - // .encode_upper(&mut Uuid::encode_buffer()), - // "936DA01F-9ABD-4D9D-80C7-02AF85C822A8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 40]; - // uuid.to_hyphenated().encode_upper(&mut buf); - // assert_eq!( - // &buf as &[_], - // b"936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_upper<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// Writes the [`Uuid`] as an upper-case hyphenated string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_hyphenated() + /// .encode_upper(&mut Uuid::encode_buffer()), + /// "936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 40]; + /// uuid.to_hyphenated().encode_upper(&mut buf); + /// assert_eq!( + /// &buf as &[_], + /// b"936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode(buffer, 0, &self.0, true, true) } } @@ -382,122 +294,106 @@ /// /// [`Uuid`]: ../struct.Uuid.html /// [`HyphenatedRef`]: struct.HyphenatedRef.html - #[cfg(not(feature = "const_fn"))] - pub fn from_uuid_ref(uuid: &'a Uuid) -> Self { + pub const fn from_uuid_ref(uuid: &'a Uuid) -> Self { HyphenatedRef(uuid) } - /// Creates a [`HyphenatedRef`] from a [`Uuid`] reference. + /// Writes the [`Uuid`] as a lower-case hyphenated string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html - /// [`HyphenatedRef`]: struct.HyphenatedRef.html - #[cfg(feature = "const_fn")] - pub const fn from_uuid_ref(uuid: &'a Uuid) -> Self { - HyphenatedRef(uuid) - } - - // Writes the [`Uuid`] as a lower-case hyphenated string to - // `buffer`, and returns the subslice of the buffer that contains the - // encoded UUID. - // - // This is slightly more efficient than using the formatting - // infrastructure as it avoids virtual calls, and may avoid - // double buffering. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_hyphenated() - // .encode_lower(&mut Uuid::encode_buffer()), - // "936da01f-9abd-4d9d-80c7-02af85c822a8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 40]; - // uuid.to_hyphenated().encode_lower(&mut buf); - // assert_eq!( - // uuid.to_hyphenated().encode_lower(&mut buf), - // "936da01f-9abd-4d9d-80c7-02af85c822a8" - // ); - // assert_eq!( - // &buf as &[_], - // b"936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_lower<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_hyphenated() + /// .encode_lower(&mut Uuid::encode_buffer()), + /// "936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 40]; + /// uuid.to_hyphenated().encode_lower(&mut buf); + /// assert_eq!( + /// uuid.to_hyphenated().encode_lower(&mut buf), + /// "936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode(buffer, 0, self.0, true, false) } - // Writes the [`Uuid`] as an upper-case hyphenated string to - // `buffer`, and returns the subslice of the buffer that contains the - // encoded UUID. - // - // This is slightly more efficient than using the formatting - // infrastructure as it avoids virtual calls, and may avoid - // double buffering. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_hyphenated() - // .encode_upper(&mut Uuid::encode_buffer()), - // "936DA01F-9ABD-4D9D-80C7-02AF85C822A8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 40]; - // assert_eq!( - // uuid.to_hyphenated().encode_upper(&mut buf), - // "936DA01F-9ABD-4D9D-80C7-02AF85C822A8" - // ); - // assert_eq!( - // &buf as &[_], - // b"936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_upper<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// Writes the [`Uuid`] as an upper-case hyphenated string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_hyphenated() + /// .encode_upper(&mut Uuid::encode_buffer()), + /// "936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 40]; + /// assert_eq!( + /// uuid.to_hyphenated().encode_upper(&mut buf), + /// "936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode(buffer, 0, self.0, true, true) } } @@ -512,113 +408,97 @@ /// /// [`Uuid`]: ../struct.Uuid.html /// [`Simple`]: struct.Simple.html - #[cfg(not(feature = "const_fn"))] - pub fn from_uuid(uuid: Uuid) -> Self { + pub const fn from_uuid(uuid: Uuid) -> Self { Simple(uuid) } - /// Creates a [`Simple`] from a [`Uuid`]. + /// Writes the [`Uuid`] as a lower-case simple string to `buffer`, + /// and returns the subslice of the buffer that contains the encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html - /// [`Simple`]: struct.Simple.html - #[cfg(feature = "const_fn")] - pub const fn from_uuid(uuid: Uuid) -> Self { - Simple(uuid) - } - - // Writes the [`Uuid`] as a lower-case simple string to `buffer`, - // and returns the subslice of the buffer that contains the encoded UUID. - // - // This is slightly more efficient than using the formatting - // infrastructure as it avoids virtual calls, and may avoid - // double buffering. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()), - // "936da01f9abd4d9d80c702af85c822a8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 36]; - // assert_eq!( - // uuid.to_simple().encode_lower(&mut buf), - // "936da01f9abd4d9d80c702af85c822a8" - // ); - // assert_eq!( - // &buf as &[_], - // b"936da01f9abd4d9d80c702af85c822a8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_lower<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()), + /// "936da01f9abd4d9d80c702af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 36]; + /// assert_eq!( + /// uuid.to_simple().encode_lower(&mut buf), + /// "936da01f9abd4d9d80c702af85c822a8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936da01f9abd4d9d80c702af85c822a8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode(buffer, 0, &self.0, false, false) } - // Writes the [`Uuid`] as an upper-case simple string to `buffer`, - // and returns the subslice of the buffer that contains the encoded UUID. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_simple().encode_upper(&mut Uuid::encode_buffer()), - // "936DA01F9ABD4D9D80C702AF85C822A8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 36]; - // assert_eq!( - // uuid.to_simple().encode_upper(&mut buf), - // "936DA01F9ABD4D9D80C702AF85C822A8" - // ); - // assert_eq!( - // &buf as &[_], - // b"936DA01F9ABD4D9D80C702AF85C822A8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_upper<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// Writes the [`Uuid`] as an upper-case simple string to `buffer`, + /// and returns the subslice of the buffer that contains the encoded UUID. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_simple().encode_upper(&mut Uuid::encode_buffer()), + /// "936DA01F9ABD4D9D80C702AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 36]; + /// assert_eq!( + /// uuid.to_simple().encode_upper(&mut buf), + /// "936DA01F9ABD4D9D80C702AF85C822A8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936DA01F9ABD4D9D80C702AF85C822A8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode(buffer, 0, &self.0, false, true) } } @@ -633,113 +513,97 @@ /// /// [`Uuid`]: ../struct.Uuid.html /// [`SimpleRef`]: struct.SimpleRef.html - #[cfg(not(feature = "const_fn"))] - pub fn from_uuid_ref(uuid: &'a Uuid) -> Self { + pub const fn from_uuid_ref(uuid: &'a Uuid) -> Self { SimpleRef(uuid) } - /// Creates a [`SimpleRef`] from a [`Uuid`] reference. + /// Writes the [`Uuid`] as a lower-case simple string to `buffer`, + /// and returns the subslice of the buffer that contains the encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html - /// [`SimpleRef`]: struct.SimpleRef.html - #[cfg(feature = "const_fn")] - pub const fn from_uuid_ref(uuid: &'a Uuid) -> Self { - SimpleRef(uuid) - } - - // Writes the [`Uuid`] as a lower-case simple string to `buffer`, - // and returns the subslice of the buffer that contains the encoded UUID. - // - // This is slightly more efficient than using the formatting - // infrastructure as it avoids virtual calls, and may avoid - // double buffering. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()), - // "936da01f9abd4d9d80c702af85c822a8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 36]; - // assert_eq!( - // uuid.to_simple().encode_lower(&mut buf), - // "936da01f9abd4d9d80c702af85c822a8" - // ); - // assert_eq!( - // &buf as &[_], - // b"936da01f9abd4d9d80c702af85c822a8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_lower<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()), + /// "936da01f9abd4d9d80c702af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 36]; + /// assert_eq!( + /// uuid.to_simple().encode_lower(&mut buf), + /// "936da01f9abd4d9d80c702af85c822a8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936da01f9abd4d9d80c702af85c822a8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode(buffer, 0, self.0, false, false) } - // Writes the [`Uuid`] as an upper-case simple string to `buffer`, - // and returns the subslice of the buffer that contains the encoded UUID. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_simple().encode_upper(&mut Uuid::encode_buffer()), - // "936DA01F9ABD4D9D80C702AF85C822A8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 36]; - // assert_eq!( - // uuid.to_simple().encode_upper(&mut buf), - // "936DA01F9ABD4D9D80C702AF85C822A8" - // ); - // assert_eq!( - // &buf as &[_], - // b"936DA01F9ABD4D9D80C702AF85C822A8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_upper<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// Writes the [`Uuid`] as an upper-case simple string to `buffer`, + /// and returns the subslice of the buffer that contains the encoded UUID. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_simple().encode_upper(&mut Uuid::encode_buffer()), + /// "936DA01F9ABD4D9D80C702AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 36]; + /// assert_eq!( + /// uuid.to_simple().encode_upper(&mut buf), + /// "936DA01F9ABD4D9D80C702AF85C822A8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"936DA01F9ABD4D9D80C702AF85C822A8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { encode(buffer, 0, self.0, false, true) } } @@ -754,121 +618,105 @@ /// /// [`Uuid`]: ../struct.Uuid.html /// [`Urn`]: struct.Urn.html - #[cfg(not(feature = "const_fn"))] - pub fn from_uuid(uuid: Uuid) -> Self { + pub const fn from_uuid(uuid: Uuid) -> Self { Urn(uuid) } - /// Creates a [`Urn`] from a [`Uuid`]. + /// Writes the [`Uuid`] as a lower-case URN string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. /// /// [`Uuid`]: ../struct.Uuid.html - /// [`Urn`]: struct.Urn.html - #[cfg(feature = "const_fn")] - pub const fn from_uuid(uuid: Uuid) -> Self { - Urn(uuid) - } - - // Writes the [`Uuid`] as a lower-case URN string to - // `buffer`, and returns the subslice of the buffer that contains the - // encoded UUID. - // - // This is slightly more efficient than using the formatting - // infrastructure as it avoids virtual calls, and may avoid - // double buffering. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()), - // "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 49]; - // uuid.to_urn().encode_lower(&mut buf); - // assert_eq!( - // uuid.to_urn().encode_lower(&mut buf), - // "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" - // ); - // assert_eq!( - // &buf as &[_], - // b"urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_lower<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()), + /// "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 49]; + /// uuid.to_urn().encode_lower(&mut buf); + /// assert_eq!( + /// uuid.to_urn().encode_lower(&mut buf), + /// "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { buffer[..9].copy_from_slice(b"urn:uuid:"); encode(buffer, 9, &self.0, true, false) } - // Writes the [`Uuid`] as an upper-case URN string to - // `buffer`, and returns the subslice of the buffer that contains the - // encoded UUID. - // - // This is slightly more efficient than using the formatting - // infrastructure as it avoids virtual calls, and may avoid - // double buffering. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_urn().encode_upper(&mut Uuid::encode_buffer()), - // "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 49]; - // assert_eq!( - // uuid.to_urn().encode_upper(&mut buf), - // "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" - // ); - // assert_eq!( - // &buf as &[_], - // b"urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_upper<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// Writes the [`Uuid`] as an upper-case URN string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_urn().encode_upper(&mut Uuid::encode_buffer()), + /// "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 49]; + /// assert_eq!( + /// uuid.to_urn().encode_upper(&mut buf), + /// "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { buffer[..9].copy_from_slice(b"urn:uuid:"); encode(buffer, 9, &self.0, true, true) } @@ -884,205 +732,247 @@ /// /// [`Uuid`]: ../struct.Uuid.html /// [`UrnRef`]: struct.UrnRef.html - #[cfg(not(feature = "const_fn"))] - pub fn from_uuid_ref(uuid: &'a Uuid) -> Self { - UrnRef(uuid) - } - - /// Creates a [`UrnRef`] from a [`Uuid`] reference. - /// - /// [`Uuid`]: ../struct.Uuid.html - /// [`UrnRef`]: struct.UrnRef.html - #[cfg(feature = "const_fn")] pub const fn from_uuid_ref(uuid: &'a Uuid) -> Self { UrnRef(&uuid) } - // Writes the [`Uuid`] as a lower-case URN string to - // `buffer`, and returns the subslice of the buffer that contains the - // encoded UUID. - // - // This is slightly more efficient than using the formatting - // infrastructure as it avoids virtual calls, and may avoid - // double buffering. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()), - // "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 49]; - // uuid.to_urn().encode_lower(&mut buf); - // assert_eq!( - // uuid.to_urn().encode_lower(&mut buf), - // "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" - // ); - // assert_eq!( - // &buf as &[_], - // b"urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_lower<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// Writes the [`Uuid`] as a lower-case URN string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()), + /// "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 49]; + /// uuid.to_urn().encode_lower(&mut buf); + /// assert_eq!( + /// uuid.to_urn().encode_lower(&mut buf), + /// "urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"urn:uuid:936da01f-9abd-4d9d-80c7-02af85c822a8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_lower<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { buffer[..9].copy_from_slice(b"urn:uuid:"); encode(buffer, 9, self.0, true, false) } - // Writes the [`Uuid`] as an upper-case URN string to - // `buffer`, and returns the subslice of the buffer that contains the - // encoded UUID. - // - // This is slightly more efficient than using the formatting - // infrastructure as it avoids virtual calls, and may avoid - // double buffering. - // - // [`Uuid`]: ../struct.Uuid.html - // - // # Panics - // - // Panics if the buffer is not large enough: it must have length at least - // [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a - // sufficiently-large temporary buffer. - // - // [`LENGTH`]: #associatedconstant.LENGTH - // [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); - // - // // the encoded portion is returned - // assert_eq!( - // uuid.to_urn().encode_upper(&mut Uuid::encode_buffer()), - // "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" - // ); - // - // // the buffer is mutated directly, and trailing contents remains - // let mut buf = [b'!'; 49]; - // assert_eq!( - // uuid.to_urn().encode_upper(&mut buf), - // "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" - // ); - // assert_eq!( - // &buf as &[_], - // b"urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] - // ); - // ``` - // */ - pub(crate) fn encode_upper<'buf>( - &self, - buffer: &'buf mut [u8], - ) -> &'buf mut str { + /// Writes the [`Uuid`] as an upper-case URN string to + /// `buffer`, and returns the subslice of the buffer that contains the + /// encoded UUID. + /// + /// This is slightly more efficient than using the formatting + /// infrastructure as it avoids virtual calls, and may avoid + /// double buffering. + /// + /// [`Uuid`]: ../struct.Uuid.html + /// + /// # Panics + /// + /// Panics if the buffer is not large enough: it must have length at least + /// [`LENGTH`]. [`Uuid::encode_buffer`] can be used to get a + /// sufficiently-large temporary buffer. + /// + /// [`LENGTH`]: #associatedconstant.LENGTH + /// [`Uuid::encode_buffer`]: ../struct.Uuid.html#method.encode_buffer + /// + /// # Examples + /// + /// ```rust + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8").unwrap(); + /// + /// // the encoded portion is returned + /// assert_eq!( + /// uuid.to_urn().encode_upper(&mut Uuid::encode_buffer()), + /// "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// + /// // the buffer is mutated directly, and trailing contents remains + /// let mut buf = [b'!'; 49]; + /// assert_eq!( + /// uuid.to_urn().encode_upper(&mut buf), + /// "urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8" + /// ); + /// assert_eq!( + /// &buf as &[_], + /// b"urn:uuid:936DA01F-9ABD-4D9D-80C7-02AF85C822A8!!!!" as &[_] + /// ); + /// ``` + /// */ + pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str { buffer[..9].copy_from_slice(b"urn:uuid:"); encode(buffer, 9, self.0, true, true) } } -// TODO: uncomment when we undo the pub(crate) change -// #[cfg(test)] -// mod tests { -// use Uuid; -// -// #[test] -// fn hyphenated_trailing() { -// let mut buf = [b'x'; 100]; -// let len = Uuid::nil().to_hyphenated().encode_lower(&mut buf).len(); -// assert_eq!(len, super::Hyphenated::LENGTH); -// assert!(buf[len..].iter().all(|x| *x == b'x')); -// } -// #[test] -// fn hyphenated_ref_trailing() { -// let mut buf = [b'x'; 100]; -// let len = Uuid::nil().to_hyphenated().encode_lower(&mut buf).len(); -// assert_eq!(len, super::HyphenatedRef::LENGTH); -// assert!(buf[len..].iter().all(|x| *x == b'x')); -// } -// -// #[test] -// fn simple_trailing() { -// let mut buf = [b'x'; 100]; -// let len = Uuid::nil().to_simple().encode_lower(&mut buf).len(); -// assert_eq!(len, super::Simple::LENGTH); -// assert!(buf[len..].iter().all(|x| *x == b'x')); -// } -// #[test] -// fn simple_ref_trailing() { -// let mut buf = [b'x'; 100]; -// let len = Uuid::nil().to_simple().encode_lower(&mut buf).len(); -// assert_eq!(len, super::SimpleRef::LENGTH); -// assert!(buf[len..].iter().all(|x| *x == b'x')); -// } -// -// #[test] -// fn urn_trailing() { -// let mut buf = [b'x'; 100]; -// let len = Uuid::nil().to_urn().encode_lower(&mut buf).len(); -// assert_eq!(len, super::Urn::LENGTH); -// assert!(buf[len..].iter().all(|x| *x == b'x')); -// } -// #[test] -// fn urn_ref_trailing() { -// let mut buf = [b'x'; 100]; -// let len = Uuid::nil().to_urn().encode_lower(&mut buf).len(); -// assert_eq!(len, super::UrnRef::LENGTH); -// assert!(buf[len..].iter().all(|x| *x == b'x')); -// } -// -// #[test] -// #[should_panic] -// fn hyphenated_too_small() { -// Uuid::nil().to_hyphenated().encode_lower(&mut [0; 35]); -// } -// #[test] -// #[should_panic] -// fn hyphenated_ref_too_small() { -// Uuid::nil().to_hyphenated_ref().encode_lower(&mut [0; 35]); -// } -// -// #[test] -// #[should_panic] -// fn simple_too_small() { -// Uuid::nil().to_simple().encode_lower(&mut [0; 31]); -// } -// #[test] -// #[should_panic] -// fn simple_ref_too_small() { -// Uuid::nil().to_simple_ref().encode_lower(&mut [0; 31]); -// } -// #[test] -// #[should_panic] -// fn urn_too_small() { -// Uuid::nil().to_urn().encode_lower(&mut [0; 44]); -// } -// #[test] -// #[should_panic] -// fn urn_ref_too_small() { -// Uuid::nil().to_urn_ref().encode_lower(&mut [0; 44]); -// } -// } +macro_rules! impl_adapter_traits { + ($($T:ident<$($a:lifetime),*>),+) => {$( + impl<$($a),*> fmt::Display for $T<$($a),*> { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(self, f) + } + } + + impl<$($a),*> fmt::LowerHex for $T<$($a),*> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808 + f.write_str(self.encode_lower(&mut [0; $T::LENGTH])) + } + } + + impl<$($a),*> fmt::UpperHex for $T<$($a),*> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // TODO: Self doesn't work https://github.com/rust-lang/rust/issues/52808 + f.write_str(self.encode_upper(&mut [0; $T::LENGTH])) + } + } + + impl_adapter_from!($T<$($a),*>); + )+} +} + +macro_rules! impl_adapter_from { + ($T:ident<>) => { + impl From for $T { + #[inline] + fn from(f: Uuid) -> Self { + $T::from_uuid(f) + } + } + }; + ($T:ident<$a:lifetime>) => { + impl<$a> From<&$a Uuid> for $T<$a> { + #[inline] + fn from(f: &$a Uuid) -> Self { + $T::from_uuid_ref(f) + } + } + }; +} + +impl_adapter_traits! { + Hyphenated<>, + HyphenatedRef<'a>, + Simple<>, + SimpleRef<'a>, + Urn<>, + UrnRef<'a> +} + +#[cfg(test)] +mod tests { + use crate::prelude::*; + + #[test] + fn hyphenated_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_hyphenated().encode_lower(&mut buf).len(); + assert_eq!(len, super::Hyphenated::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + fn hyphenated_ref_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_hyphenated().encode_lower(&mut buf).len(); + assert_eq!(len, super::HyphenatedRef::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + fn simple_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_simple().encode_lower(&mut buf).len(); + assert_eq!(len, super::Simple::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + fn simple_ref_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_simple().encode_lower(&mut buf).len(); + assert_eq!(len, super::SimpleRef::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + fn urn_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_urn().encode_lower(&mut buf).len(); + assert_eq!(len, super::Urn::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + fn urn_ref_trailing() { + let mut buf = [b'x'; 100]; + let len = Uuid::nil().to_urn().encode_lower(&mut buf).len(); + assert_eq!(len, super::UrnRef::LENGTH); + assert!(buf[len..].iter().all(|x| *x == b'x')); + } + + #[test] + #[should_panic] + fn hyphenated_too_small() { + Uuid::nil().to_hyphenated().encode_lower(&mut [0; 35]); + } + + #[test] + #[should_panic] + fn hyphenated_ref_too_small() { + Uuid::nil().to_hyphenated_ref().encode_lower(&mut [0; 35]); + } + + #[test] + #[should_panic] + fn simple_too_small() { + Uuid::nil().to_simple().encode_lower(&mut [0; 31]); + } + #[test] + #[should_panic] + fn simple_ref_too_small() { + Uuid::nil().to_simple_ref().encode_lower(&mut [0; 31]); + } + #[test] + #[should_panic] + fn urn_too_small() { + Uuid::nil().to_urn().encode_lower(&mut [0; 44]); + } + #[test] + #[should_panic] + fn urn_ref_too_small() { + Uuid::nil().to_urn_ref().encode_lower(&mut [0; 44]); + } +} diff -Nru rust-uuid-0.7.1/src/builder/error.rs rust-uuid-0.8.1/src/builder/error.rs --- rust-uuid-0.7.1/src/builder/error.rs 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/src/builder/error.rs 2019-10-17 04:22:56.000000000 +0000 @@ -0,0 +1,52 @@ +use crate::std::fmt; + +/// The error that can occur when creating a [`Uuid`]. +/// +/// [`Uuid`]: struct.Uuid.html +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub(crate) struct Error { + expected: usize, + found: usize, +} + +impl Error { + /// The expected number of bytes. + #[inline] + const fn expected(&self) -> usize { + self.expected + } + + /// The number of bytes found. + #[inline] + const fn found(&self) -> usize { + self.found + } + + /// Create a new [`UuidError`]. + /// + /// [`UuidError`]: struct.UuidError.html + #[inline] + pub(crate) const fn new(expected: usize, found: usize) -> Self { + Error { expected, found } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!( + f, + "invalid bytes length: expected {}, found {}", + self.expected(), + self.found() + ) + } +} + +#[cfg(feature = "std")] +mod std_support { + use super::*; + + use crate::std::error; + + impl error::Error for Error {} +} diff -Nru rust-uuid-0.7.1/src/builder/mod.rs rust-uuid-0.8.1/src/builder/mod.rs --- rust-uuid-0.7.1/src/builder/mod.rs 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/src/builder/mod.rs 2019-10-18 22:08:23.000000000 +0000 @@ -0,0 +1,474 @@ +// Copyright 2013-2014 The Rust Project Developers. +// Copyright 2018 The Uuid Project Developers. +// +// See the COPYRIGHT file at the top-level directory of this distribution. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A Builder type for [`Uuid`]s. +//! +//! [`Uuid`]: ../struct.Uuid.html + +mod error; +pub(crate) use self::error::Error; + +use crate::prelude::*; + +impl Uuid { + /// The 'nil UUID'. + /// + /// The nil UUID is special form of UUID that is specified to have all + /// 128 bits set to zero, as defined in [IETF RFC 4122 Section 4.1.7][RFC]. + /// + /// [RFC]: https://tools.ietf.org/html/rfc4122.html#section-4.1.7 + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let uuid = Uuid::nil(); + /// + /// assert_eq!( + /// uuid.to_hyphenated().to_string(), + /// "00000000-0000-0000-0000-000000000000" + /// ); + /// ``` + pub const fn nil() -> Self { + Uuid::from_bytes([0; 16]) + } + + /// Creates a UUID from four field values in big-endian order. + /// + /// # Errors + /// + /// This function will return an error if `d4`'s length is not 8 bytes. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; + /// + /// let uuid = Uuid::from_fields(42, 12, 5, &d4); + /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string()); + /// + /// let expected_uuid = + /// Ok(String::from("0000002a-000c-0005-0c03-0938362b0809")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + pub fn from_fields( + d1: u32, + d2: u16, + d3: u16, + d4: &[u8], + ) -> Result { + const D4_LEN: usize = 8; + + let len = d4.len(); + + if len != D4_LEN { + Err(Error::new(D4_LEN, len))?; + } + + Ok(Uuid::from_bytes([ + (d1 >> 24) as u8, + (d1 >> 16) as u8, + (d1 >> 8) as u8, + d1 as u8, + (d2 >> 8) as u8, + d2 as u8, + (d3 >> 8) as u8, + d3 as u8, + d4[0], + d4[1], + d4[2], + d4[3], + d4[4], + d4[5], + d4[6], + d4[7], + ])) + } + + /// Creates a UUID from four field values in little-endian order. + /// + /// The bytes in the `d1`, `d2` and `d3` fields will + /// be converted into big-endian order. + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// let d1 = 0xAB3F1097u32; + /// let d2 = 0x501Eu16; + /// let d3 = 0xB736u16; + /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; + /// + /// let uuid = Uuid::from_fields_le(d1, d2, d3, &d4); + /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string()); + /// + /// let expected_uuid = + /// Ok(String::from("97103fab-1e50-36b7-0c03-0938362b0809")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + pub fn from_fields_le( + d1: u32, + d2: u16, + d3: u16, + d4: &[u8], + ) -> Result { + const D4_LEN: usize = 8; + + let len = d4.len(); + + if len != D4_LEN { + Err(Error::new(D4_LEN, len))?; + } + + Ok(Uuid::from_bytes([ + d1 as u8, + (d1 >> 8) as u8, + (d1 >> 16) as u8, + (d1 >> 24) as u8, + (d2) as u8, + (d2 >> 8) as u8, + d3 as u8, + (d3 >> 8) as u8, + d4[0], + d4[1], + d4[2], + d4[3], + d4[4], + d4[5], + d4[6], + d4[7], + ])) + } + + /// Creates a UUID from a 128bit value in big-endian order. + pub const fn from_u128(v: u128) -> Self { + Uuid::from_bytes([ + (v >> 120) as u8, + (v >> 112) as u8, + (v >> 104) as u8, + (v >> 96) as u8, + (v >> 88) as u8, + (v >> 80) as u8, + (v >> 72) as u8, + (v >> 64) as u8, + (v >> 56) as u8, + (v >> 48) as u8, + (v >> 40) as u8, + (v >> 32) as u8, + (v >> 24) as u8, + (v >> 16) as u8, + (v >> 8) as u8, + v as u8, + ]) + } + + /// Creates a UUID from a 128bit value in little-endian order. + pub const fn from_u128_le(v: u128) -> Self { + Uuid::from_bytes([ + v as u8, + (v >> 8) as u8, + (v >> 16) as u8, + (v >> 24) as u8, + (v >> 32) as u8, + (v >> 40) as u8, + (v >> 48) as u8, + (v >> 56) as u8, + (v >> 64) as u8, + (v >> 72) as u8, + (v >> 80) as u8, + (v >> 88) as u8, + (v >> 96) as u8, + (v >> 104) as u8, + (v >> 112) as u8, + (v >> 120) as u8, + ]) + } + + /// Creates a UUID using the supplied big-endian bytes. + /// + /// # Errors + /// + /// This function will return an error if `b` has any length other than 16. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87]; + /// + /// let uuid = Uuid::from_slice(&bytes); + /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string()); + /// + /// let expected_uuid = + /// Ok(String::from("0436430c-2b02-624c-2032-570501212b57")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + /// + /// An incorrect number of bytes: + /// + /// ``` + /// use uuid::Uuid; + /// + /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76]; + /// + /// let uuid = Uuid::from_slice(&bytes); + /// + /// assert!(uuid.is_err()); + /// ``` + pub fn from_slice(b: &[u8]) -> Result { + const BYTES_LEN: usize = 16; + + let len = b.len(); + + if len != BYTES_LEN { + Err(Error::new(BYTES_LEN, len))?; + } + + let mut bytes: Bytes = [0; 16]; + bytes.copy_from_slice(b); + Ok(Uuid::from_bytes(bytes)) + } + + /// Creates a UUID using the supplied big-endian bytes. + pub const fn from_bytes(bytes: Bytes) -> Uuid { + Uuid(bytes) + } +} + +/// A builder struct for creating a UUID. +/// +/// # Examples +/// +/// Creating a v4 UUID from externally generated bytes: +/// +/// ``` +/// 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_bytes(random_bytes) +/// .set_variant(Variant::RFC4122) +/// .set_version(Version::Random) +/// .build(); +/// ``` +#[allow(missing_copy_implementations)] +#[derive(Debug)] +pub struct Builder(crate::Bytes); + +impl Builder { + /// Creates a `Builder` using the supplied big-endian bytes. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let bytes: uuid::Bytes = [ + /// 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, 145, 63, 62, + /// ]; + /// + /// let mut builder = uuid::Builder::from_bytes(bytes); + /// let uuid = builder.build().to_hyphenated().to_string(); + /// + /// let expected_uuid = String::from("46ebd0ee-0e6d-43c9-b90d-ccc35a913f3e"); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + /// + /// An incorrect number of bytes: + /// + /// ```compile_fail + /// let bytes: uuid::Bytes = [4, 54, 67, 12, 43, 2, 98, 76]; // doesn't compile + /// + /// let uuid = uuid::Builder::from_bytes(bytes); + /// ``` + pub const fn from_bytes(b: Bytes) -> Self { + Builder(b) + } + + /// Creates a `Builder` using the supplied big-endian bytes. + /// + /// # 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, 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()); + /// + /// let expected_uuid = + /// Ok(String::from("0436430c-2b02-624c-2032-570501212b57")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + /// + /// An incorrect number of bytes: + /// + /// ``` + /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76]; + /// + /// let builder = uuid::Builder::from_slice(&bytes); + /// + /// assert!(builder.is_err()); + /// ``` + pub fn from_slice(b: &[u8]) -> Result { + const BYTES_LEN: usize = 16; + + let len = b.len(); + + if len != BYTES_LEN { + Err(Error::new(BYTES_LEN, len))?; + } + + let mut bytes: crate::Bytes = [0; 16]; + bytes.copy_from_slice(b); + Ok(Self::from_bytes(bytes)) + } + + /// Creates a `Builder` from four big-endian field values. + /// + /// # Errors + /// + /// This function will return an error if `d4`'s length is not 8 bytes. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; + /// + /// let builder = uuid::Builder::from_fields(42, 12, 5, &d4); + /// let uuid = + /// builder.map(|mut builder| builder.build().to_hyphenated().to_string()); + /// + /// let expected_uuid = + /// Ok(String::from("0000002a-000c-0005-0c03-0938362b0809")); + /// + /// assert_eq!(expected_uuid, uuid); + /// ``` + /// + /// An invalid length: + /// + /// ``` + /// let d4 = [12]; + /// + /// let builder = uuid::Builder::from_fields(42, 12, 5, &d4); + /// + /// assert!(builder.is_err()); + /// ``` + pub fn from_fields( + d1: u32, + d2: u16, + d3: u16, + d4: &[u8], + ) -> Result { + Uuid::from_fields(d1, d2, d3, d4).map(|uuid| { + let bytes = *uuid.as_bytes(); + + Builder::from_bytes(bytes) + }) + } + + /// Creates a `Builder` from a big-endian 128bit value. + pub fn from_u128(v: u128) -> Self { + Builder::from_bytes(*Uuid::from_u128(v).as_bytes()) + } + + /// Creates a `Builder` with an initial [`Uuid::nil`]. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Builder; + /// + /// let mut builder = Builder::nil(); + /// + /// assert_eq!( + /// builder.build().to_hyphenated().to_string(), + /// "00000000-0000-0000-0000-000000000000" + /// ); + /// ``` + pub const fn nil() -> Self { + Builder([0; 16]) + } + + /// Specifies the variant of the UUID. + pub fn set_variant(&mut self, v: crate::Variant) -> &mut Self { + let byte = self.0[8]; + + self.0[8] = match v { + crate::Variant::NCS => byte & 0x7f, + crate::Variant::RFC4122 => (byte & 0x3f) | 0x80, + crate::Variant::Microsoft => (byte & 0x1f) | 0xc0, + crate::Variant::Future => (byte & 0x1f) | 0xe0, + }; + + self + } + + /// Specifies the version number of the UUID. + pub fn set_version(&mut self, v: crate::Version) -> &mut Self { + self.0[6] = (self.0[6] & 0x0f) | ((v as u8) << 4); + + self + } + + /// Hands over the internal constructed [`Uuid`]. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use uuid::Builder; + /// + /// let uuid = Builder::nil().build(); + /// + /// assert_eq!( + /// uuid.to_hyphenated().to_string(), + /// "00000000-0000-0000-0000-000000000000" + /// ); + /// ``` + /// + /// [`Uuid`]: struct.Uuid.html + pub fn build(&mut self) -> Uuid { + let uuid = Uuid::from_bytes(self.0); + + uuid + } +} diff -Nru rust-uuid-0.7.1/src/core_support.rs rust-uuid-0.8.1/src/core_support.rs --- rust-uuid-0.7.1/src/core_support.rs 2018-09-14 20:25:04.000000000 +0000 +++ rust-uuid-0.8.1/src/core_support.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,179 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. -// Copyright 2018 The Uuid Project Developers. -// -// See the COPYRIGHT file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use core::{fmt, str}; -use parser; -use prelude::*; - -impl fmt::Display for Uuid { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(self, f) - } -} - -impl fmt::Display for Variant { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - Variant::NCS => write!(f, "NCS"), - Variant::RFC4122 => write!(f, "RFC4122"), - Variant::Microsoft => write!(f, "Microsoft"), - Variant::Future => write!(f, "Future"), - } - } -} - -impl fmt::Display for ::BytesError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "invalid bytes length: expected {}, found {}", - self.expected(), - self.found() - ) - } -} - -impl fmt::LowerHex for Uuid { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::LowerHex::fmt(&self.to_hyphenated_ref(), f) - } -} - -impl fmt::UpperHex for Uuid { - #[inline] - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - fmt::UpperHex::fmt(&self.to_hyphenated_ref(), f) - } -} - -impl str::FromStr for Uuid { - type Err = parser::ParseError; - - fn from_str(uuid_str: &str) -> Result { - Uuid::parse_str(uuid_str) - } -} - -impl Default for Uuid { - #[inline] - fn default() -> Self { - Uuid::nil() - } -} - -#[cfg(test)] -mod tests { - extern crate std; - - use self::std::prelude::v1::*; - use prelude::*; - use test_util; - - macro_rules! check { - ($buf:ident, $format:expr, $target:expr, $len:expr, $cond:expr) => { - $buf.clear(); - write!($buf, $format, $target).unwrap(); - assert!($buf.len() == $len); - assert!($buf.chars().all($cond), "{}", $buf); - }; - } - - #[test] - fn test_uuid_compare() { - let uuid1 = test_util::new(); - let uuid2 = test_util::new2(); - - assert_eq!(uuid1, uuid1); - assert_eq!(uuid2, uuid2); - - assert_ne!(uuid1, uuid2); - assert_ne!(uuid2, uuid1); - } - - #[test] - fn test_uuid_default() { - let default_uuid = Uuid::default(); - let nil_uuid = Uuid::nil(); - - assert_eq!(default_uuid, nil_uuid); - } - - #[test] - fn test_uuid_display() { - use super::fmt::Write; - - let uuid = test_util::new(); - let s = uuid.to_string(); - let mut buffer = String::new(); - - assert_eq!(s, uuid.to_hyphenated().to_string()); - - check!(buffer, "{}", uuid, 36, |c| c.is_lowercase() - || c.is_digit(10) - || c == '-'); - } - - #[test] - fn test_uuid_lowerhex() { - use super::fmt::Write; - - let mut buffer = String::new(); - let uuid = test_util::new(); - - check!(buffer, "{:x}", uuid, 36, |c| c.is_lowercase() - || c.is_digit(10) - || c == '-'); - } - - // noinspection RsAssertEqual - #[test] - fn test_uuid_operator_eq() { - let uuid1 = test_util::new(); - let uuid1_dup = uuid1.clone(); - let uuid2 = test_util::new2(); - - assert!(uuid1 == uuid1); - assert!(uuid1 == uuid1_dup); - assert!(uuid1_dup == uuid1); - - assert!(uuid1 != uuid2); - assert!(uuid2 != uuid1); - assert!(uuid1_dup != uuid2); - assert!(uuid2 != uuid1_dup); - } - - #[test] - fn test_uuid_to_string() { - use super::fmt::Write; - - let uuid = test_util::new(); - let s = uuid.to_string(); - let mut buffer = String::new(); - - assert_eq!(s.len(), 36); - - check!(buffer, "{}", s, 36, |c| c.is_lowercase() - || c.is_digit(10) - || c == '-'); - } - - #[test] - fn test_uuid_upperhex() { - use super::fmt::Write; - - let mut buffer = String::new(); - let uuid = test_util::new(); - - check!(buffer, "{:X}", uuid, 36, |c| c.is_uppercase() - || c.is_digit(10) - || c == '-'); - } -} diff -Nru rust-uuid-0.7.1/src/error.rs rust-uuid-0.8.1/src/error.rs --- rust-uuid-0.7.1/src/error.rs 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/src/error.rs 2019-10-18 22:08:23.000000000 +0000 @@ -0,0 +1,79 @@ +use crate::std::fmt; +use crate::{builder, parser}; + +/// A general error that can occur when working with UUIDs. +// TODO: improve the doc +// BODY: This detail should be fine for initial merge +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +pub struct Error(Inner); + +// TODO: write tests for Error +// BODY: not immediately blocking, but should be covered for 1.0 +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +enum Inner { + /// An error occurred while handling [`Uuid`] bytes. + /// + /// See [`BytesError`] + /// + /// [`BytesError`]: struct.BytesError.html + /// [`Uuid`]: struct.Uuid.html + Build(builder::Error), + + /// An error occurred while parsing a [`Uuid`] string. + /// + /// See [`parser::ParseError`] + /// + /// [`parser::ParseError`]: parser/enum.ParseError.html + /// [`Uuid`]: struct.Uuid.html + Parser(parser::Error), +} + +impl From for Error { + fn from(err: builder::Error) -> Self { + Error(Inner::Build(err)) + } +} + +impl From for Error { + fn from(err: parser::Error) -> Self { + Error(Inner::Parser(err)) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.0 { + Inner::Build(ref err) => fmt::Display::fmt(&err, f), + Inner::Parser(ref err) => fmt::Display::fmt(&err, f), + } + } +} + +#[cfg(feature = "std")] +mod std_support { + use super::*; + use crate::std::error; + + impl error::Error for Error { + fn source(&self) -> Option<&(dyn error::Error + 'static)> { + match self.0 { + Inner::Build(ref err) => Some(err), + Inner::Parser(ref err) => Some(err), + } + } + } +} + +#[cfg(test)] +mod test_util { + use super::*; + + impl Error { + pub(crate) fn expect_parser(self) -> parser::Error { + match self.0 { + Inner::Parser(err) => err, + _ => panic!("expected a `parser::Error` variant"), + } + } + } +} diff -Nru rust-uuid-0.7.1/src/lib.rs rust-uuid-0.8.1/src/lib.rs --- rust-uuid-0.7.1/src/lib.rs 2018-09-14 20:25:43.000000000 +0000 +++ rust-uuid-0.8.1/src/lib.rs 2019-10-18 22:08:23.000000000 +0000 @@ -12,7 +12,7 @@ //! Generate and parse UUIDs. //! //! Provides support for Universally Unique Identifiers (UUIDs). A UUID is a -//! unique 128-bit number, stored as 16 octets. UUIDs are used to assign +//! unique 128-bit number, stored as 16 octets. UUIDs are used to assign //! unique identifiers to entities without requiring a central allocating //! authority. //! @@ -28,40 +28,48 @@ //! # Dependencies //! //! By default, this crate depends on nothing but `std` and cannot generate -//! [`Uuid`]s. You need to enable the following Cargo features to enable +//! UUIDs. You need to enable the following Cargo features to enable //! various pieces of functionality: //! -//! * `v1` - adds the `Uuid::new_v1` function and the ability to create a V1 -//! using an implementation of `uuid::v1::ClockSequence` (usually -//! `uuid::v1::Context`) and a timestamp from `time::timespec`. -//! * `v3` - adds the `Uuid::new_v3` function and the ability to create a V3 +//! * `v1` - adds the [`Uuid::new_v1`] function and the ability to create a V1 +//! using an implementation of [`v1::ClockSequence`] (usually +//! [`v1::Context`]) and a timestamp from `time::timespec`. +//! * `v3` - adds the [`Uuid::new_v3`] function and the ability to create a V3 //! UUID based on the MD5 hash of some data. -//! * `v4` - adds the `Uuid::new_v4` function and the ability to randomly -//! generate a `Uuid`. -//! * `v5` - adds the `Uuid::new_v5` function and the ability to create a V5 +//! * `v4` - adds the [`Uuid::new_v4`] function and the ability to randomly +//! generate a UUID. +//! * `v5` - adds the [`Uuid::new_v5`] function and the ability to create a V5 //! UUID based on the SHA1 hash of some data. -//! * `serde` - adds the ability to serialize and deserialize a `Uuid` using the +//! * `serde` - adds the ability to serialize and deserialize a UUID using the //! `serde` crate. //! +//! You need to enable one of the following Cargo features together with +//! `v3`, `v4` or `v5` feature if you're targeting `wasm32` architecture: +//! +//! * `stdweb` - enables support for `OsRng` on `wasm32-unknown-unknown` via +//! [`stdweb`] combined with [`cargo-web`] +//! * `wasm-bindgen` - enables support for `OsRng` on `wasm32-unknown-unknown` +//! via [`wasm-bindgen`] +//! //! By default, `uuid` can be depended on with: //! //! ```toml //! [dependencies] -//! uuid = "0.7" +//! uuid = "0.8" //! ``` //! //! To activate various features, use syntax like: //! //! ```toml //! [dependencies] -//! uuid = { version = "0.7", features = ["serde", "v4"] } +//! uuid = { version = "0.8", features = ["serde", "v4"] } //! ``` //! //! You can disable default features with: //! //! ```toml //! [dependencies] -//! uuid = { version = "0.7", default-features = false } +//! uuid = { version = "0.8", default-features = false } //! ``` //! //! # Examples @@ -101,492 +109,156 @@ //! //! # References //! -//! * [Wikipedia: Universally Unique Identifier]( -//! http://en.wikipedia.org/wiki/Universally_unique_identifier) -//! * [RFC4122: A Universally Unique IDentifier (UUID) URN Namespace]( -//! http://tools.ietf.org/html/rfc4122) - -#![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(feature = "const_fn", feature(const_fn))] -#![deny( - missing_copy_implementations, - missing_debug_implementations, - missing_docs -)] +//! * [Wikipedia: Universally Unique +//! Identifier](http://en.wikipedia.org/wiki/Universally_unique_identifier) +//! * [RFC4122: A Universally Unique IDentifier (UUID) URN +//! Namespace](http://tools.ietf.org/html/rfc4122) +//! +//! [`wasm-bindgen`]: https://crates.io/crates/wasm-bindgen +//! [`cargo-web`]: https://crates.io/crates/cargo-web +//! [`stdweb`]: https://crates.io/crates/stdweb +//! [`Uuid`]: struct.Uuid.html +//! [`Uuid::new_v1`]: struct.Uuid.html#method.new_v1 +//! [`Uuid::new_v3`]: struct.Uuid.html#method.new_v3 +//! [`Uuid::new_v4`]: struct.Uuid.html#method.new_v4 +//! [`Uuid::new_v5`]: struct.Uuid.html#method.new_v5 +//! [`v1::ClockSequence`]: v1/trait.ClockSequence.html +//! [`v1::Context`]: v1/struct.Context.html + +#![no_std] +#![deny(missing_debug_implementations, missing_docs)] #![doc( html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", html_favicon_url = "https://www.rust-lang.org/favicon.ico", - html_root_url = "https://docs.rs/uuid" + html_root_url = "https://docs.rs/uuid/0.8.1" )] -#[cfg(feature = "byteorder")] -extern crate byteorder; -#[cfg(feature = "std")] -extern crate core; -#[cfg(feature = "md5")] -extern crate md5; -#[cfg(feature = "rand")] -extern crate rand; -#[cfg(feature = "serde")] -extern crate serde; -#[cfg(all(feature = "serde", test))] -extern crate serde_test; -#[cfg(feature = "sha1")] -extern crate sha1; -#[cfg(feature = "slog")] -#[cfg_attr(test, macro_use)] -extern crate slog; +#[cfg(any(feature = "std", test))] +#[macro_use] +extern crate std; + +#[cfg(all(not(feature = "std"), not(test)))] +#[macro_use] +extern crate core as std; + +mod builder; +mod error; +mod parser; +mod prelude; pub mod adapter; -pub mod parser; -pub mod prelude; #[cfg(feature = "v1")] pub mod v1; -mod core_support; #[cfg(feature = "serde")] mod serde_support; #[cfg(feature = "slog")] mod slog_support; -#[cfg(feature = "std")] -mod std_support; #[cfg(test)] mod test_util; -#[cfg(feature = "u128")] -mod u128_support; -#[cfg(feature = "v3")] +#[cfg(all( + feature = "v3", + any( + not(target_arch = "wasm32"), + all( + target_arch = "wasm32", + any(feature = "stdweb", feature = "wasm-bindgen") + ) + ) +))] mod v3; -#[cfg(feature = "v4")] +#[cfg(all( + feature = "v4", + any( + not(target_arch = "wasm32"), + all( + target_arch = "wasm32", + any(feature = "stdweb", feature = "wasm-bindgen") + ) + ) +))] mod v4; -#[cfg(feature = "v5")] +#[cfg(all( + feature = "v5", + any( + not(target_arch = "wasm32"), + all( + target_arch = "wasm32", + any(feature = "stdweb", feature = "wasm-bindgen") + ) + ) +))] mod v5; +#[cfg(all(windows, feature = "winapi"))] +mod winapi_support; + +use crate::std::{fmt, str}; + +pub use crate::{builder::Builder, error::Error}; /// A 128-bit (16 byte) buffer containing the ID. pub type Bytes = [u8; 16]; -/// The error that can occur when creating a [`Uuid`]. -/// -/// [`Uuid`]: struct.Uuid.html -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub struct BytesError { - expected: usize, - found: usize, -} - /// The version of the UUID, denoting the generating algorithm. -#[derive(Debug, PartialEq, Copy, Clone)] -#[repr(C)] +#[derive(Clone, Copy, Debug, PartialEq)] pub enum Version { - /// Special case for `nil` [`Uuid`]. - /// - /// [`Uuid`]: struct.Uuid.html + /// Special case for `nil` UUID. Nil = 0, - /// Version 1: MAC address + /// Version 1: MAC address. Mac, - /// Version 2: DCE Security + /// Version 2: DCE Security. Dce, - /// Version 3: MD5 hash + /// Version 3: MD5 hash. Md5, - /// Version 4: Random + /// Version 4: Random. Random, - /// Version 5: SHA-1 hash + /// Version 5: SHA-1 hash. Sha1, } /// The reserved variants of UUIDs. #[derive(Clone, Copy, Debug, PartialEq)] -#[repr(C)] pub enum Variant { - /// Reserved by the NCS for backward compatibility + /// Reserved by the NCS for backward compatibility. NCS = 0, - /// As described in the RFC4122 Specification (default) + /// As described in the RFC4122 Specification (default). RFC4122, - /// Reserved by Microsoft for backward compatibility + /// Reserved by Microsoft for backward compatibility. Microsoft, - /// Reserved for future expansion + /// Reserved for future expansion. Future, } /// A Universally Unique Identifier (UUID). -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct Uuid(Bytes); -impl BytesError { - /// The expected number of bytes. - #[cfg(feature = "const_fn")] - #[inline] - pub const fn expected(&self) -> usize { - self.expected - } - - /// The expected number of bytes. - #[cfg(not(feature = "const_fn"))] - #[inline] - pub fn expected(&self) -> usize { - self.expected - } - - /// The number of bytes found. - #[cfg(feature = "const_fn")] - #[inline] - pub const fn found(&self) -> usize { - self.found - } - - /// The number of bytes found. - #[cfg(not(feature = "const_fn"))] - #[inline] - pub fn found(&self) -> usize { - self.found - } - - /// Create a new [`UuidError`]. - /// - /// [`UuidError`]: struct.UuidError.html - #[cfg(feature = "const_fn")] - #[inline] - pub const fn new(expected: usize, found: usize) -> Self { - BytesError { - expected: expected, - found: found, - } - } - - /// Create a new [`UuidError`]. - /// - /// [`UuidError`]: struct.UuidError.html - #[cfg(not(feature = "const_fn"))] - #[inline] - pub fn new(expected: usize, found: usize) -> Self { - BytesError { expected, found } - } -} - impl Uuid { - /// [`Uuid`] namespace for Domain Name System (DNS). - /// - /// [`Uuid`]: struct.Uuid.html + /// UUID namespace for Domain Name System (DNS). pub const NAMESPACE_DNS: Self = Uuid([ 0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, ]); - /// [`Uuid`] namespace for ISO Object Identifiers (OIDs). - /// - /// [`Uuid`]: struct.Uuid.html + /// UUID namespace for ISO Object Identifiers (OIDs). pub const NAMESPACE_OID: Self = Uuid([ 0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, ]); - /// [`Uuid`] namespace for Uniform Resource Locators (URLs). - /// - /// [`Uuid`]: struct.Uuid.html + /// UUID namespace for Uniform Resource Locators (URLs). pub const NAMESPACE_URL: Self = Uuid([ 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, ]); - /// [`Uuid`] namespace for X.500 Distinguished Names (DNs). - /// - /// [`Uuid`]: struct.Uuid.html + /// UUID namespace for X.500 Distinguished Names (DNs). pub const NAMESPACE_X500: Self = Uuid([ 0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8, ]); - /// The 'nil UUID'. - /// - /// The nil UUID is special form of UUID that is specified to have all - /// 128 bits set to zero, as defined in [IETF RFC 4122 Section 4.1.7][RFC]. - /// - /// [RFC]: https://tools.ietf.org/html/rfc4122.html#section-4.1.7 - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use uuid::Uuid; - /// - /// let uuid = Uuid::nil(); - /// - /// assert_eq!( - /// uuid.to_hyphenated().to_string(), - /// "00000000-0000-0000-0000-000000000000" - /// ); - /// ``` - #[cfg(feature = "const_fn")] - pub const fn nil() -> Self { - Uuid::from_bytes([0; 16]) - } - - /// The 'nil UUID'. - /// - /// The nil UUID is special form of UUID that is specified to have all - /// 128 bits set to zero, as defined in [IETF RFC 4122 Section 4.1.7][RFC]. - /// - /// [RFC]: https://tools.ietf.org/html/rfc4122.html#section-4.1.7 - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use uuid::Uuid; - /// - /// let uuid = Uuid::nil(); - /// - /// assert_eq!( - /// uuid.to_hyphenated().to_string(), - /// "00000000-0000-0000-0000-000000000000" - /// ); - /// ``` - #[cfg(not(feature = "const_fn"))] - pub fn nil() -> Uuid { - Uuid::from_bytes([0; 16]) - } - - /// Creates a `Uuid` from four field values. - /// - /// # Errors - /// - /// This function will return an error if `d4`'s length is not 8 bytes. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use uuid::Uuid; - /// - /// let d4 = [12, 3, 9, 56, 54, 43, 8, 9]; - /// - /// let uuid = Uuid::from_fields(42, 12, 5, &d4); - /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string()); - /// - /// let expected_uuid = - /// Ok(String::from("0000002a-000c-0005-0c03-0938362b0809")); - /// - /// assert_eq!(expected_uuid, uuid); - /// ``` - /// - /// An invalid length: - /// - /// ``` - /// use uuid::prelude::*; - /// - /// let d4 = [12]; - /// - /// let uuid = uuid::Uuid::from_fields(42, 12, 5, &d4); - /// - /// let expected_uuid = Err(uuid::BytesError::new(8, d4.len())); - /// - /// assert_eq!(expected_uuid, uuid); - /// ``` - pub fn from_fields( - d1: u32, - d2: u16, - d3: u16, - d4: &[u8], - ) -> Result { - const D4_LEN: usize = 8; - - let len = d4.len(); - - if len != D4_LEN { - return Err(BytesError::new(D4_LEN, len)); - } - - Ok(Uuid::from_bytes([ - (d1 >> 24) as u8, - (d1 >> 16) as u8, - (d1 >> 8) as u8, - d1 as u8, - (d2 >> 8) as u8, - d2 as u8, - (d3 >> 8) as u8, - d3 as u8, - d4[0], - d4[1], - d4[2], - d4[3], - d4[4], - d4[5], - d4[6], - d4[7], - ])) - } - - /// Creates a `Uuid` using the supplied bytes. - /// - /// # Errors - /// - /// This function will return an error if `b` has any length other than 16. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use uuid::Uuid; - /// - /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76, 32, 50, 87, 5, 1, 33, 43, 87]; - /// - /// let uuid = Uuid::from_slice(&bytes); - /// let uuid = uuid.map(|uuid| uuid.to_hyphenated().to_string()); - /// - /// let expected_uuid = - /// Ok(String::from("0436430c-2b02-624c-2032-570501212b57")); - /// - /// assert_eq!(expected_uuid, uuid); - /// ``` - /// - /// An incorrect number of bytes: - /// - /// ``` - /// use uuid::prelude::*; - /// - /// let bytes = [4, 54, 67, 12, 43, 2, 98, 76]; - /// - /// let uuid = Uuid::from_slice(&bytes); - /// - /// let expected_uuid = Err(uuid::BytesError::new(16, 8)); - /// - /// assert_eq!(expected_uuid, uuid); - /// ``` - pub fn from_slice(b: &[u8]) -> Result { - const BYTES_LEN: usize = 16; - - let len = b.len(); - - if len != BYTES_LEN { - return Err(BytesError::new(BYTES_LEN, len)); - } - - let mut bytes: Bytes = [0; 16]; - bytes.copy_from_slice(b); - Ok(Uuid::from_bytes(bytes)) - } - - /// Creates a `Uuid` using the supplied bytes. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use uuid::Bytes; - /// use uuid::Uuid; - /// - /// let bytes: Bytes = [ - /// 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, 145, 63, - /// 62, - /// ]; - /// - /// let uuid = Uuid::from_bytes(bytes); - /// let uuid = uuid.to_hyphenated().to_string(); - /// - /// let expected_uuid = String::from("46ebd0ee-0e6d-43c9-b90d-ccc35a913f3e"); - /// - /// assert_eq!(expected_uuid, uuid); - /// ``` - /// - /// An incorrect number of bytes: - /// - /// ```compile_fail - /// use uuid::Uuid; - /// use uuid::UuidBytes; - /// - /// let bytes: UuidBytes = [4, 54, 67, 12, 43, 2, 98, 76]; // doesn't - /// compile - /// - /// let uuid = Uuid::from_bytes(bytes); - /// ``` - #[cfg(not(feature = "const_fn"))] - pub fn from_bytes(bytes: Bytes) -> Uuid { - Uuid(bytes) - } - - /// Creates a `Uuid` using the supplied bytes. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use uuid::Bytes; - /// use uuid::Uuid; - /// - /// let bytes: Bytes = [ - /// 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, 145, 63, - /// 62, - /// ]; - /// - /// let uuid = Uuid::from_bytes(bytes); - /// let uuid = uuid.to_hyphenated().to_string(); - /// - /// let expected_uuid = String::from("46ebd0ee-0e6d-43c9-b90d-ccc35a913f3e"); - /// - /// assert_eq!(expected_uuid, uuid); - /// ``` - /// - /// An incorrect number of bytes: - /// - /// ```compile_fail - /// use uuid::Bytes; - /// use uuid::Uuid; - /// - /// let bytes: Bytes = [4, 54, 67, 12, 43, 2, 98, 76]; // doesn't compile - /// - /// let uuid = Uuid::from_bytes(bytes); - /// ``` - #[cfg(feature = "const_fn")] - pub const fn from_bytes(bytes: Bytes) -> Uuid { - Uuid(bytes) - } - - /// Creates a v4 Uuid from random bytes (e.g. bytes supplied from `Rand` - /// crate) - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use uuid::Bytes; - /// use uuid::Uuid; - /// - /// let bytes: Bytes = [ - /// 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90, 145, 63, - /// 62, - /// ]; - /// let uuid = Uuid::from_random_bytes(bytes); - /// let uuid = uuid.to_hyphenated().to_string(); - /// - /// let expected_uuid = String::from("46ebd0ee-0e6d-43c9-b90d-ccc35a913f3e"); - /// - /// assert_eq!(expected_uuid, uuid); - /// ``` - pub fn from_random_bytes(bytes: Bytes) -> Uuid { - let mut uuid = Uuid::from_bytes(bytes); - uuid.set_variant(Variant::RFC4122); - uuid.set_version(Version::Random); - uuid - } - - /// Specifies the variant of the UUID structure - fn set_variant(&mut self, v: Variant) { - // Octet 8 contains the variant in the most significant 3 bits - self.0[8] = match v { - Variant::NCS => self.as_bytes()[8] & 0x7f, // b0xx... - Variant::RFC4122 => (self.as_bytes()[8] & 0x3f) | 0x80, // b10x... - Variant::Microsoft => (self.as_bytes()[8] & 0x1f) | 0xc0, // b110... - Variant::Future => (self.as_bytes()[8] & 0x1f) | 0xe0, // b111... - } - } - - /// Returns the variant of the `Uuid` structure. + /// Returns the variant of the UUID structure. /// /// This determines the interpretation of the structure of the UUID. /// Currently only the RFC4122 variant is generated by this module. @@ -602,12 +274,7 @@ } } - /// Specifies the version number of the `Uuid`. - fn set_version(&mut self, v: Version) { - self.0[6] = (self.as_bytes()[6] & 0xF) | ((v as u8) << 4); - } - - /// Returns the version number of the `Uuid`. + /// Returns the version number of the UUID. /// /// This represents the algorithm used to generate the contents. /// @@ -618,11 +285,11 @@ /// details. /// /// * [Version Reference](http://tools.ietf.org/html/rfc4122#section-4.1.3) - pub fn get_version_num(&self) -> usize { + pub const fn get_version_num(&self) -> usize { (self.as_bytes()[6] >> 4) as usize } - /// Returns the version of the `Uuid`. + /// Returns the version of the UUID. /// /// This represents the algorithm used to generate the contents pub fn get_version(&self) -> Option { @@ -638,7 +305,7 @@ } } - /// Returns the four field values of the UUID. + /// Returns the four field values of the UUID in big-endian order. /// /// These values can be passed to the `from_fields()` method to get the /// original `Uuid` back. @@ -649,15 +316,14 @@ /// * The second field value represents the second group of (four) hex /// digits, taken as a big-endian `u16` value. For V1 UUIDs, this field /// represents the middle 16 bits of the timestamp. - /// * The third field value represents the third group of (four) hex - /// digits, taken as a big-endian `u16` value. The 4 most significant - /// bits give the UUID version, and for V1 UUIDs, the last 12 bits - /// represent the high 12 bits of the timestamp. - /// * The last field value represents the last two groups of four and - /// twelve hex digits, taken in order. The first 1-3 bits of this - /// indicate the UUID variant, and for V1 UUIDs, the next 13-15 bits - /// indicate the clock sequence and the last 48 bits indicate the node - /// ID. + /// * The third field value represents the third group of (four) hex digits, + /// taken as a big-endian `u16` value. The 4 most significant bits give + /// the UUID version, and for V1 UUIDs, the last 12 bits represent the + /// high 12 bits of the timestamp. + /// * The last field value represents the last two groups of four and twelve + /// hex digits, taken in order. The first 1-3 bits of this indicate the + /// UUID variant, and for V1 UUIDs, the next 13-15 bits indicate the clock + /// sequence and the last 48 bits indicate the node ID. /// /// # Examples /// @@ -695,272 +361,317 @@ (d1, d2, d3, d4) } - /// Returns an array of 16 octets containing the UUID data. + /// Returns the four field values of the UUID in little-endian order. + /// + /// The bytes in the returned integer fields will + /// be converted from big-endian order. /// /// # Examples /// /// ``` /// use uuid::Uuid; /// - /// let uuid = Uuid::nil(); - /// assert_eq!(uuid.as_bytes(), &[0; 16]); - /// - /// let uuid = Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap(); + /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8").unwrap(); /// assert_eq!( - /// uuid.as_bytes(), - /// &[ - /// 147, 109, 160, 31, 154, 189, 77, 157, 128, 199, 2, 175, 133, 200, - /// 34, 168, - /// ] + /// uuid.to_fields_le(), + /// ( + /// 0x1FA06D93, + /// 0xBD9A, + /// 0x9D4D, + /// b"\x80\xC7\x02\xAF\x85\xC8\x22\xA8" + /// ) /// ); /// ``` - #[cfg(feature = "const_fn")] + pub fn to_fields_le(&self) -> (u32, u16, u16, &[u8; 8]) { + let d1 = u32::from(self.as_bytes()[0]) + | u32::from(self.as_bytes()[1]) << 8 + | u32::from(self.as_bytes()[2]) << 16 + | u32::from(self.as_bytes()[3]) << 24; + + let d2 = + u16::from(self.as_bytes()[4]) | u16::from(self.as_bytes()[5]) << 8; + + let d3 = + u16::from(self.as_bytes()[6]) | u16::from(self.as_bytes()[7]) << 8; + + let d4: &[u8; 8] = + unsafe { &*(self.as_bytes()[8..16].as_ptr() as *const [u8; 8]) }; + (d1, d2, d3, d4) + } + + /// Returns a 128bit value containing the UUID data. + /// + /// The bytes in the UUID will be packed into a `u128`, like the + /// [`Uuid::as_bytes`] method. + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8").unwrap(); + /// assert_eq!( + /// uuid.as_u128(), + /// 0x936DA01F9ABD4D9D80C702AF85C822A8, + /// ) + /// ``` + pub fn as_u128(&self) -> u128 { + u128::from(self.as_bytes()[0]) << 120 + | u128::from(self.as_bytes()[1]) << 112 + | u128::from(self.as_bytes()[2]) << 104 + | u128::from(self.as_bytes()[3]) << 96 + | u128::from(self.as_bytes()[4]) << 88 + | u128::from(self.as_bytes()[5]) << 80 + | u128::from(self.as_bytes()[6]) << 72 + | u128::from(self.as_bytes()[7]) << 64 + | u128::from(self.as_bytes()[8]) << 56 + | u128::from(self.as_bytes()[9]) << 48 + | u128::from(self.as_bytes()[10]) << 40 + | u128::from(self.as_bytes()[11]) << 32 + | u128::from(self.as_bytes()[12]) << 24 + | u128::from(self.as_bytes()[13]) << 16 + | u128::from(self.as_bytes()[14]) << 8 + | u128::from(self.as_bytes()[15]) + } + + /// Returns a 128bit little-endian value containing the UUID data. + /// + /// The bytes in the UUID will be reversed and packed into a `u128`. + /// Note that this will produce a different result than + /// [`Uuid::to_fields_le`], because the entire UUID is reversed, rather + /// than reversing the individual fields in-place. + /// + /// # Examples + /// + /// ``` + /// use uuid::Uuid; + /// + /// let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8").unwrap(); + /// + /// assert_eq!( + /// uuid.to_u128_le(), + /// 0xA822C885AF02C7809D4DBD9A1FA06D93, + /// ) + /// ``` + pub fn to_u128_le(&self) -> u128 { + u128::from(self.as_bytes()[0]) + | u128::from(self.as_bytes()[1]) << 8 + | u128::from(self.as_bytes()[2]) << 16 + | u128::from(self.as_bytes()[3]) << 24 + | u128::from(self.as_bytes()[4]) << 32 + | u128::from(self.as_bytes()[5]) << 40 + | u128::from(self.as_bytes()[6]) << 48 + | u128::from(self.as_bytes()[7]) << 56 + | u128::from(self.as_bytes()[8]) << 64 + | u128::from(self.as_bytes()[9]) << 72 + | u128::from(self.as_bytes()[10]) << 80 + | u128::from(self.as_bytes()[11]) << 88 + | u128::from(self.as_bytes()[12]) << 96 + | u128::from(self.as_bytes()[13]) << 104 + | u128::from(self.as_bytes()[14]) << 112 + | u128::from(self.as_bytes()[15]) << 120 + } + + /// Returns an array of 16 octets containing the UUID data. pub const fn as_bytes(&self) -> &Bytes { &self.0 } - /// Returns an array of 16 octets containing the UUID data. + /// Tests if the UUID is nil. + pub fn is_nil(&self) -> bool { + self.as_bytes().iter().all(|&b| b == 0) + } + + /// A buffer that can be used for `encode_...` calls, that is + /// guaranteed to be long enough for any of the adapters. /// /// # Examples /// - /// ``` + /// ```rust /// use uuid::Uuid; /// /// let uuid = Uuid::nil(); - /// assert_eq!(uuid.as_bytes(), &[0; 16]); /// - /// let uuid = Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8").unwrap(); /// assert_eq!( - /// uuid.as_bytes(), - /// &[ - /// 147, 109, 160, 31, 154, 189, 77, 157, 128, 199, 2, 175, 133, 200, - /// 34, 168 - /// ] + /// uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()), + /// "00000000000000000000000000000000" + /// ); + /// + /// assert_eq!( + /// uuid.to_hyphenated() + /// .encode_lower(&mut Uuid::encode_buffer()), + /// "00000000-0000-0000-0000-000000000000" + /// ); + /// + /// assert_eq!( + /// uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()), + /// "urn:uuid:00000000-0000-0000-0000-000000000000" /// ); /// ``` - #[cfg(not(feature = "const_fn"))] - pub fn as_bytes(&self) -> &Bytes { - &self.0 + pub const fn encode_buffer() -> [u8; adapter::Urn::LENGTH] { + [0; adapter::Urn::LENGTH] } +} - /// Returns an Optional Tuple of (u64, u16) representing the timestamp and - /// counter portion of a V1 UUID. If the supplied UUID is not V1, this - /// will return None - pub fn to_timestamp(&self) -> Option<(u64, u16)> { - if self - .get_version() - .map(|v| v != Version::Mac) - .unwrap_or(true) - { - return None; - } +impl fmt::Debug for Uuid { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(self, f) + } +} - let ts: u64 = u64::from(self.as_bytes()[6] & 0x0F) << 56 - | u64::from(self.as_bytes()[7]) << 48 - | u64::from(self.as_bytes()[4]) << 40 - | u64::from(self.as_bytes()[5]) << 32 - | u64::from(self.as_bytes()[0]) << 24 - | u64::from(self.as_bytes()[1]) << 16 - | u64::from(self.as_bytes()[2]) << 8 - | u64::from(self.as_bytes()[3]); - - let count: u16 = u16::from(self.as_bytes()[8] & 0x3F) << 8 - | u16::from(self.as_bytes()[9]); - - Some((ts, count)) - } - - /// Parses a `Uuid` from a string of hexadecimal digits with optional - /// hyphens. - /// - /// Any of the formats generated by this module (simple, hyphenated, urn) - /// are supported by this parsing function. - pub fn parse_str(mut input: &str) -> Result { - // Ensure length is valid for any of the supported formats - let len = input.len(); - - if len == adapter::Urn::LENGTH && input.starts_with("urn:uuid:") { - input = &input[9..]; - } else if !parser::len_matches_any( - len, - &[adapter::Hyphenated::LENGTH, adapter::Simple::LENGTH], - ) { - return Err(parser::ParseError::InvalidLength { - expected: parser::Expected::Any(&[ - adapter::Hyphenated::LENGTH, - adapter::Simple::LENGTH, - ]), - found: len, - }); - } +impl fmt::Display for Uuid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(self, f) + } +} - // `digit` counts only hexadecimal digits, `i_char` counts all chars. - let mut digit = 0; - let mut group = 0; - let mut acc = 0; - let mut buffer = [0u8; 16]; - - for (i_char, chr) in input.bytes().enumerate() { - if digit as usize >= adapter::Simple::LENGTH && group != 4 { - if group == 0 { - return Err(parser::ParseError::InvalidLength { - expected: parser::Expected::Any(&[ - adapter::Hyphenated::LENGTH, - adapter::Simple::LENGTH, - ]), - found: len, - }); - } - - return Err(parser::ParseError::InvalidGroupCount { - expected: parser::Expected::Any(&[1, 5]), - found: group + 1, - }); - } - - if digit % 2 == 0 { - // First digit of the byte. - match chr { - // Calulate upper half. - b'0'...b'9' => acc = chr - b'0', - b'a'...b'f' => acc = chr - b'a' + 10, - b'A'...b'F' => acc = chr - b'A' + 10, - // Found a group delimiter - b'-' => { - // TODO: remove the u8 cast - // BODY: this only needed until we switch to - // ParseError - if parser::ACC_GROUP_LENS[group] as u8 != digit { - // Calculate how many digits this group consists of - // in the input. - let found = if group > 0 { - // TODO: remove the u8 cast - // BODY: this only needed until we switch to - // ParseError - digit - parser::ACC_GROUP_LENS[group - 1] as u8 - } else { - digit - }; - - return Err( - parser::ParseError::InvalidGroupLength { - expected: parser::Expected::Exact( - parser::GROUP_LENS[group], - ), - found: found as usize, - group, - }, - ); - } - // Next group, decrement digit, it is incremented again - // at the bottom. - group += 1; - digit -= 1; - } - _ => { - return Err(parser::ParseError::InvalidCharacter { - expected: "0123456789abcdefABCDEF-", - found: input[i_char..].chars().next().unwrap(), - index: i_char, - }); - } - } - } else { - // Second digit of the byte, shift the upper half. - acc *= 16; - match chr { - b'0'...b'9' => acc += chr - b'0', - b'a'...b'f' => acc += chr - b'a' + 10, - b'A'...b'F' => acc += chr - b'A' + 10, - b'-' => { - // The byte isn't complete yet. - let found = if group > 0 { - // TODO: remove the u8 cast - // BODY: this only needed until we switch to - // ParseError - digit - parser::ACC_GROUP_LENS[group - 1] as u8 - } else { - digit - }; - - return Err(parser::ParseError::InvalidGroupLength { - expected: parser::Expected::Exact( - parser::GROUP_LENS[group], - ), - found: found as usize, - group, - }); - } - _ => { - return Err(parser::ParseError::InvalidCharacter { - expected: "0123456789abcdefABCDEF-", - found: input[i_char..].chars().next().unwrap(), - index: i_char, - }); - } - } - buffer[(digit / 2) as usize] = acc; - } - digit += 1; +impl fmt::Display for Variant { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + Variant::NCS => write!(f, "NCS"), + Variant::RFC4122 => write!(f, "RFC4122"), + Variant::Microsoft => write!(f, "Microsoft"), + Variant::Future => write!(f, "Future"), } + } +} - // Now check the last group. - // TODO: remove the u8 cast - // BODY: this only needed until we switch to - // ParseError - if parser::ACC_GROUP_LENS[4] as u8 != digit { - return Err(parser::ParseError::InvalidGroupLength { - expected: parser::Expected::Exact(parser::GROUP_LENS[4]), - found: (digit as usize - parser::ACC_GROUP_LENS[3]), - group, - }); - } +impl fmt::LowerHex for Uuid { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(&self.to_hyphenated_ref(), f) + } +} - Ok(Uuid::from_bytes(buffer)) +impl fmt::UpperHex for Uuid { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::UpperHex::fmt(&self.to_hyphenated_ref(), f) } +} - /// Tests if the UUID is nil - pub fn is_nil(&self) -> bool { - self.as_bytes().iter().all(|&b| b == 0) +impl str::FromStr for Uuid { + type Err = Error; + + fn from_str(uuid_str: &str) -> Result { + Uuid::parse_str(uuid_str) } - // A buffer that can be used for `encode_...` calls, that is - // guaranteed to be long enough for any of the adapters. - // - // # Examples - // - // ```rust - // use uuid::Uuid; - // - // let uuid = Uuid::nil(); - // - // assert_eq!( - // uuid.to_simple().encode_lower(&mut Uuid::encode_buffer()), - // "00000000000000000000000000000000" - // ); - // - // assert_eq!( - // uuid.to_hyphenated() - // .encode_lower(&mut Uuid::encode_buffer()), - // "00000000-0000-0000-0000-000000000000" - // ); - // - // assert_eq!( - // uuid.to_urn().encode_lower(&mut Uuid::encode_buffer()), - // "urn:uuid:00000000-0000-0000-0000-000000000000" - // ); - // ``` - pub(crate) fn encode_buffer() -> [u8; adapter::Urn::LENGTH] { - [0; adapter::Urn::LENGTH] +} + +impl Default for Uuid { + #[inline] + fn default() -> Self { + Uuid::nil() } } #[cfg(test)] mod tests { - extern crate std; + use crate::{ + prelude::*, + std::string::{String, ToString}, + test_util, + }; + + macro_rules! check { + ($buf:ident, $format:expr, $target:expr, $len:expr, $cond:expr) => { + $buf.clear(); + write!($buf, $format, $target).unwrap(); + assert!($buf.len() == $len); + assert!($buf.chars().all($cond), "{}", $buf); + }; + } + + #[test] + fn test_uuid_compare() { + let uuid1 = test_util::new(); + let uuid2 = test_util::new2(); + + assert_eq!(uuid1, uuid1); + assert_eq!(uuid2, uuid2); + + assert_ne!(uuid1, uuid2); + assert_ne!(uuid2, uuid1); + } + + #[test] + fn test_uuid_default() { + let default_uuid = Uuid::default(); + let nil_uuid = Uuid::nil(); + + assert_eq!(default_uuid, nil_uuid); + } + + #[test] + fn test_uuid_display() { + use super::fmt::Write; + + let uuid = test_util::new(); + let s = uuid.to_string(); + let mut buffer = String::new(); + + assert_eq!(s, uuid.to_hyphenated().to_string()); + + check!(buffer, "{}", uuid, 36, |c| c.is_lowercase() + || c.is_digit(10) + || c == '-'); + } + + #[test] + fn test_uuid_lowerhex() { + use super::fmt::Write; + + let mut buffer = String::new(); + let uuid = test_util::new(); + + check!(buffer, "{:x}", uuid, 36, |c| c.is_lowercase() + || c.is_digit(10) + || c == '-'); + } - use self::std::prelude::v1::*; - use super::test_util; - use prelude::*; + // noinspection RsAssertEqual + #[test] + fn test_uuid_operator_eq() { + let uuid1 = test_util::new(); + let uuid1_dup = uuid1.clone(); + let uuid2 = test_util::new2(); + + assert!(uuid1 == uuid1); + assert!(uuid1 == uuid1_dup); + assert!(uuid1_dup == uuid1); + + assert!(uuid1 != uuid2); + assert!(uuid2 != uuid1); + assert!(uuid1_dup != uuid2); + assert!(uuid2 != uuid1_dup); + } + + #[test] + fn test_uuid_to_string() { + use super::fmt::Write; + + let uuid = test_util::new(); + let s = uuid.to_string(); + let mut buffer = String::new(); + + assert_eq!(s.len(), 36); + + check!(buffer, "{}", s, 36, |c| c.is_lowercase() + || c.is_digit(10) + || c == '-'); + } + + #[test] + fn test_uuid_upperhex() { + use super::fmt::Write; + + let mut buffer = String::new(); + let uuid = test_util::new(); + + check!(buffer, "{:X}", uuid, 36, |c| c.is_uppercase() + || c.is_digit(10) + || c == '-'); + } #[test] fn test_nil() { @@ -1032,233 +743,6 @@ } #[test] - fn test_parse_uuid_v4() { - use adapter; - use parser; - - const EXPECTED_UUID_LENGTHS: parser::Expected = - parser::Expected::Any(&[ - adapter::Hyphenated::LENGTH, - adapter::Simple::LENGTH, - ]); - - const EXPECTED_GROUP_COUNTS: parser::Expected = - parser::Expected::Any(&[1, 5]); - - const EXPECTED_CHARS: &'static str = "0123456789abcdefABCDEF-"; - - // Invalid - assert_eq!( - Uuid::parse_str(""), - Err(parser::ParseError::InvalidLength { - expected: EXPECTED_UUID_LENGTHS, - found: 0, - }) - ); - - assert_eq!( - Uuid::parse_str("!"), - Err(parser::ParseError::InvalidLength { - expected: EXPECTED_UUID_LENGTHS, - found: 1 - }) - ); - - assert_eq!( - Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45"), - Err(parser::ParseError::InvalidLength { - expected: EXPECTED_UUID_LENGTHS, - found: 37, - }) - ); - - assert_eq!( - Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4"), - Err(parser::ParseError::InvalidLength { - expected: EXPECTED_UUID_LENGTHS, - found: 35 - }) - ); - - assert_eq!( - Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4"), - Err(parser::ParseError::InvalidCharacter { - expected: EXPECTED_CHARS, - found: 'G', - index: 20, - }) - ); - - assert_eq!( - Uuid::parse_str("F9168C5E-CEB2F4faaFB6BFF329BF39FA1E4"), - Err(parser::ParseError::InvalidGroupCount { - expected: EXPECTED_GROUP_COUNTS, - found: 2 - }) - ); - - assert_eq!( - Uuid::parse_str("F9168C5E-CEB2-4faaFB6BFF329BF39FA1E4"), - Err(parser::ParseError::InvalidGroupCount { - expected: EXPECTED_GROUP_COUNTS, - found: 3, - }) - ); - - assert_eq!( - Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4"), - Err(parser::ParseError::InvalidGroupCount { - expected: EXPECTED_GROUP_COUNTS, - found: 4, - }) - ); - - assert_eq!( - Uuid::parse_str("F9168C5E-CEB2-4faa"), - Err(parser::ParseError::InvalidLength { - expected: EXPECTED_UUID_LENGTHS, - found: 18, - }) - ); - - assert_eq!( - Uuid::parse_str("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4"), - Err(parser::ParseError::InvalidCharacter { - expected: EXPECTED_CHARS, - found: 'X', - index: 18, - }) - ); - - assert_eq!( - Uuid::parse_str("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4"), - Err(parser::ParseError::InvalidGroupLength { - expected: parser::Expected::Exact(4), - found: 3, - group: 1, - }) - ); - // (group, found, expecting) - // - assert_eq!( - Uuid::parse_str("01020304-1112-2122-3132-41424344"), - Err(parser::ParseError::InvalidGroupLength { - expected: parser::Expected::Exact(12), - found: 8, - group: 4, - }) - ); - - assert_eq!( - Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c"), - Err(parser::ParseError::InvalidLength { - expected: EXPECTED_UUID_LENGTHS, - found: 31, - }) - ); - - assert_eq!( - Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c88"), - Err(parser::ParseError::InvalidLength { - expected: EXPECTED_UUID_LENGTHS, - found: 33, - }) - ); - - assert_eq!( - Uuid::parse_str("67e5504410b1426f9247bb680e5fe0cg8"), - Err(parser::ParseError::InvalidLength { - expected: EXPECTED_UUID_LENGTHS, - found: 33, - }) - ); - - assert_eq!( - Uuid::parse_str("67e5504410b1426%9247bb680e5fe0c8"), - Err(parser::ParseError::InvalidCharacter { - expected: EXPECTED_CHARS, - found: '%', - index: 15, - }) - ); - - assert_eq!( - Uuid::parse_str("231231212212423424324323477343246663"), - Err(parser::ParseError::InvalidLength { - expected: EXPECTED_UUID_LENGTHS, - found: 36, - }) - ); - - // Valid - assert!(Uuid::parse_str("00000000000000000000000000000000").is_ok()); - assert!( - Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok() - ); - assert!( - Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").is_ok() - ); - assert!(Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8").is_ok()); - assert!( - Uuid::parse_str("01020304-1112-2122-3132-414243444546").is_ok() - ); - assert!( - Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8") - .is_ok() - ); - - // Nil - let nil = Uuid::nil(); - assert_eq!( - Uuid::parse_str("00000000000000000000000000000000").unwrap(), - nil - ); - assert_eq!( - Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap(), - nil - ); - - // Round-trip - let uuid_orig = test_util::new(); - let orig_str = uuid_orig.to_string(); - let uuid_out = Uuid::parse_str(&orig_str).unwrap(); - assert_eq!(uuid_orig, uuid_out); - - // Test error reporting - assert_eq!( - Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c"), - Err(parser::ParseError::InvalidLength { - expected: EXPECTED_UUID_LENGTHS, - found: 31, - }) - ); - assert_eq!( - Uuid::parse_str("67e550X410b1426f9247bb680e5fe0cd"), - Err(parser::ParseError::InvalidCharacter { - expected: EXPECTED_CHARS, - found: 'X', - index: 6, - }) - ); - assert_eq!( - Uuid::parse_str("67e550-4105b1426f9247bb680e5fe0c"), - Err(parser::ParseError::InvalidGroupLength { - expected: parser::Expected::Exact(8), - found: 6, - group: 0, - }) - ); - assert_eq!( - Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4"), - Err(parser::ParseError::InvalidGroupLength { - expected: parser::Expected::Exact(4), - found: 5, - group: 3, - }) - ); - } - - #[test] fn test_to_simple_string() { let uuid1 = test_util::new(); let s = uuid1.to_simple().to_string(); @@ -1278,7 +762,7 @@ #[test] fn test_upper_lower_hex() { - use tests::std::fmt::Write; + use std::fmt::Write; let mut buf = String::new(); let u = test_util::new(); @@ -1359,6 +843,20 @@ } #[test] + fn test_from_fields_le() { + let d1: u32 = 0xa4a3a2a1; + let d2: u16 = 0xb2b1; + let d3: u16 = 0xc2c1; + let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; + + let u = Uuid::from_fields_le(d1, d2, d3, &d4).unwrap(); + + let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"; + let result = u.to_simple().to_string(); + assert_eq!(result, expected); + } + + #[test] fn test_as_fields() { let u = test_util::new(); let (d1, d2, d3, d4) = u.as_fields(); @@ -1387,6 +885,90 @@ } #[test] + fn test_fields_le_roundtrip() { + let d1_in: u32 = 0xa4a3a2a1; + let d2_in: u16 = 0xb2b1; + let d3_in: u16 = 0xc2c1; + let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; + + let u = Uuid::from_fields_le(d1_in, d2_in, d3_in, d4_in).unwrap(); + let (d1_out, d2_out, d3_out, d4_out) = u.to_fields_le(); + + assert_eq!(d1_in, d1_out); + assert_eq!(d2_in, d2_out); + assert_eq!(d3_in, d3_out); + assert_eq!(d4_in, d4_out); + } + + #[test] + fn test_fields_le_are_actually_le() { + let d1_in: u32 = 0xa1a2a3a4; + let d2_in: u16 = 0xb1b2; + let d3_in: u16 = 0xc1c2; + let d4_in = &[0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8]; + + let u = Uuid::from_fields(d1_in, d2_in, d3_in, d4_in).unwrap(); + let (d1_out, d2_out, d3_out, d4_out) = u.to_fields_le(); + + assert_eq!(d1_in, d1_out.swap_bytes()); + assert_eq!(d2_in, d2_out.swap_bytes()); + assert_eq!(d3_in, d3_out.swap_bytes()); + assert_eq!(d4_in, d4_out); + } + + #[test] + fn test_from_u128() { + let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8; + + let u = Uuid::from_u128(v_in); + + let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"; + let result = u.to_simple().to_string(); + assert_eq!(result, expected); + } + + #[test] + fn test_from_u128_le() { + let v_in: u128 = 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1; + + let u = Uuid::from_u128_le(v_in); + + let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8"; + let result = u.to_simple().to_string(); + assert_eq!(result, expected); + } + + #[test] + fn test_u128_roundtrip() { + let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8; + + let u = Uuid::from_u128(v_in); + let v_out = u.as_u128(); + + assert_eq!(v_in, v_out); + } + + #[test] + fn test_u128_le_roundtrip() { + let v_in: u128 = 0xd8d7d6d5d4d3d2d1c2c1b2b1a4a3a2a1; + + let u = Uuid::from_u128_le(v_in); + let v_out = u.to_u128_le(); + + assert_eq!(v_in, v_out); + } + + #[test] + fn test_u128_le_is_actually_le() { + let v_in: u128 = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8; + + let u = Uuid::from_u128(v_in); + let v_out = u.to_u128_le(); + + assert_eq!(v_in, v_out.swap_bytes()); + } + + #[test] fn test_from_slice() { let b = [ 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, @@ -1423,7 +1005,7 @@ #[test] fn test_bytes_roundtrip() { - let b_in: ::Bytes = [ + let b_in: crate::Bytes = [ 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, ]; @@ -1436,19 +1018,6 @@ } #[test] - fn test_from_random_bytes() { - let b = [ - 0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3, - 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, - ]; - - let u = Uuid::from_random_bytes(b); - let expected = "a1a2a3a4b1b241c291d2d3d4d5d6d7d8"; - - assert_eq!(u.to_simple().to_string(), expected); - } - - #[test] fn test_iterbytes_impl_for_uuid() { let mut set = std::collections::HashSet::new(); let id1 = test_util::new(); diff -Nru rust-uuid-0.7.1/src/parser/core_support.rs rust-uuid-0.8.1/src/parser/core_support.rs --- rust-uuid-0.7.1/src/parser/core_support.rs 2018-09-14 20:25:04.000000000 +0000 +++ rust-uuid-0.8.1/src/parser/core_support.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,62 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. -// Copyright 2018 The Uuid Project Developers. -// -// See the COPYRIGHT file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use core::fmt; -use parser; - -impl<'a> fmt::Display for parser::Expected { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match *self { - parser::Expected::Any(ref crits) => write!(f, "one of {:?}", crits), - parser::Expected::Exact(crit) => write!(f, "{}", crit), - parser::Expected::Range { min, max } => { - write!(f, "{}..{} inclusive", min, max) - } - } - } -} - -impl fmt::Display for parser::ParseError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}: ", self._description())?; - - match *self { - parser::ParseError::InvalidCharacter { - expected, - found, - index, - } => write!( - f, - "expected {:?}, found {} at {}", - expected.chars(), - found, - index - ), - parser::ParseError::InvalidGroupCount { - ref expected, - found, - } => write!(f, "expected {}, found {}", expected, found), - parser::ParseError::InvalidGroupLength { - ref expected, - found, - group, - } => write!( - f, - "expected {}, found {} in group {}", - expected, found, group, - ), - parser::ParseError::InvalidLength { - ref expected, - found, - } => write!(f, "expected {}, found {}", expected, found), - } - } -} diff -Nru rust-uuid-0.7.1/src/parser/error.rs rust-uuid-0.8.1/src/parser/error.rs --- rust-uuid-0.7.1/src/parser/error.rs 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/src/parser/error.rs 2019-10-18 22:08:23.000000000 +0000 @@ -0,0 +1,148 @@ +use crate::std::fmt; + +/// An error that can occur while parsing a [`Uuid`] string. +/// +/// [`Uuid`]: ../struct.Uuid.html +#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] +pub(crate) enum Error { + /// Invalid character in the [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + InvalidCharacter { + /// The expected characters. + expected: &'static str, + /// The invalid character found. + found: char, + /// The invalid character position. + index: usize, + /// Indicates the [`Uuid`] starts with `urn:uuid:`. + /// + /// This is a special case for [`Urn`] adapter parsing. + /// + /// [`Uuid`]: ../Uuid.html + urn: UrnPrefix, + }, + /// Invalid number of segments in the [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + InvalidGroupCount { + /// The expected number of segments. + // TODO: explain multiple segment count. + // BODY: Parsers can expect a range of Uuid segment count. + // This needs to be expanded on. + expected: ExpectedLength, + /// The number of segments found. + found: usize, + }, + /// Invalid length of a segment in a [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + InvalidGroupLength { + /// The expected length of the segment. + expected: ExpectedLength, + /// The length of segment found. + found: usize, + /// The segment with invalid length. + group: usize, + }, + /// Invalid length of the [`Uuid`] string. + /// + /// [`Uuid`]: ../struct.Uuid.html + InvalidLength { + /// The expected length(s). + // TODO: explain multiple lengths. + // BODY: Parsers can expect a range of Uuid lenghts. + // This needs to be expanded on. + expected: ExpectedLength, + /// The invalid length found. + found: usize, + }, +} + +/// The expected length. +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub(crate) enum ExpectedLength { + /// Expected any one of the given values. + Any(&'static [usize]), + /// Expected the given value. + Exact(usize), +} + +/// Urn prefix value. +#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] +pub(crate) enum UrnPrefix { + /// The `urn:uuid:` prefix should optionally provided. + Optional, +} + +impl Error { + fn _description(&self) -> &str { + match *self { + Error::InvalidCharacter { .. } => "invalid character", + Error::InvalidGroupCount { .. } => "invalid number of groups", + Error::InvalidGroupLength { .. } => "invalid group length", + Error::InvalidLength { .. } => "invalid length", + } + } +} + +impl fmt::Display for ExpectedLength { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + ExpectedLength::Any(crits) => write!(f, "one of {:?}", crits), + ExpectedLength::Exact(crit) => write!(f, "{}", crit), + } + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}: ", self._description())?; + + match *self { + Error::InvalidCharacter { + expected, + found, + index, + urn, + } => { + let urn_str = match urn { + UrnPrefix::Optional => { + " an optional prefix of `urn:uuid:` followed by" + } + }; + + write!( + f, + "expected{} {}, found {} at {}", + urn_str, expected, found, index + ) + } + Error::InvalidGroupCount { + ref expected, + found, + } => write!(f, "expected {}, found {}", expected, found), + Error::InvalidGroupLength { + ref expected, + found, + group, + } => write!( + f, + "expected {}, found {} in group {}", + expected, found, group, + ), + Error::InvalidLength { + ref expected, + found, + } => write!(f, "expected {}, found {}", expected, found), + } + } +} + +#[cfg(feature = "std")] +mod std_support { + use super::*; + use crate::std::error; + + impl error::Error for Error {} +} diff -Nru rust-uuid-0.7.1/src/parser/mod.rs rust-uuid-0.8.1/src/parser/mod.rs --- rust-uuid-0.7.1/src/parser/mod.rs 2018-09-14 20:25:05.000000000 +0000 +++ rust-uuid-0.8.1/src/parser/mod.rs 2019-10-17 04:22:56.000000000 +0000 @@ -13,92 +13,13 @@ //! //! [`Uuid`]: ../struct.Uuid.html -mod core_support; -#[cfg(feature = "std")] -mod std_support; - -/// The expected value. -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub enum Expected { - /// Expected any one of the given values. - Any(&'static [usize]), - /// Expected the given value. - Exact(usize), - /// Expected any values in the given range. - Range { - /// The minimum expected value. - min: usize, - /// The maximum expected value. - max: usize, - }, -} +pub(crate) mod error; +pub(crate) use self::error::Error; -/// An error that can occur while parsing a [`Uuid`] string. -/// -/// [`Uuid`]: ../struct.Uuid.html -#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] -pub enum ParseError { - /// Invalid character in the [`Uuid`] string. - /// - /// [`Uuid`]: ../struct.Uuid.html - InvalidCharacter { - /// The expected characters. - expected: &'static str, - /// The invalid character found. - found: char, - /// The invalid character position. - index: usize, - }, - /// Invalid number of segments in the [`Uuid`] string. - /// - /// [`Uuid`]: ../struct.Uuid.html - InvalidGroupCount { - /// The expected number of segments. - // TODO: explain multiple segment count. - // BODY: Parsers can expect a range of Uuid segment count. - // This needs to be expanded on. - expected: Expected, - /// The number of segments found. - found: usize, - }, - /// Invalid length of a segment in a [`Uuid`] string. - /// - /// [`Uuid`]: ../struct.Uuid.html - InvalidGroupLength { - /// The expected length of the segment. - expected: Expected, - /// The length of segment found. - found: usize, - /// The segment with invalid length. - group: usize, - }, - /// Invalid length of the [`Uuid`] string. - /// - /// [`Uuid`]: ../struct.Uuid.html - InvalidLength { - /// The expected length(s). - // TODO: explain multiple lengths. - // BODY: Parsers can expect a range of Uuid lenghts. - // This needs to be expanded on. - expected: Expected, - /// The invalid length found. - found: usize, - }, -} - -impl ParseError { - fn _description(&self) -> &str { - match *self { - ParseError::InvalidCharacter { .. } => "invalid character", - ParseError::InvalidGroupCount { .. } => "invalid number of groups", - ParseError::InvalidGroupLength { .. } => "invalid group length", - ParseError::InvalidLength { .. } => "invalid length", - } - } -} +use crate::{adapter, Uuid}; /// Check if the length matches any of the given criteria lengths. -pub(crate) fn len_matches_any(len: usize, crits: &[usize]) -> bool { +fn len_matches_any(len: usize, crits: &[usize]) -> bool { for crit in crits { if len == *crit { return true; @@ -111,7 +32,7 @@ /// Check if the length matches any criteria lengths in the given range /// (inclusive). #[allow(dead_code)] -pub(crate) fn len_matches_range(len: usize, min: usize, max: usize) -> bool { +fn len_matches_range(len: usize, min: usize, max: usize) -> bool { for crit in min..(max + 1) { if len == crit { return true; @@ -122,7 +43,405 @@ } // Accumulated length of each hyphenated group in hex digits. -pub(crate) const ACC_GROUP_LENS: [usize; 5] = [8, 12, 16, 20, 32]; +const ACC_GROUP_LENS: [usize; 5] = [8, 12, 16, 20, 32]; // Length of each hyphenated group in hex digits. -pub(crate) const GROUP_LENS: [usize; 5] = [8, 4, 4, 4, 12]; +const GROUP_LENS: [usize; 5] = [8, 4, 4, 4, 12]; + +impl Uuid { + /// Parses a `Uuid` from a string of hexadecimal digits with optional + /// hyphens. + /// + /// Any of the formats generated by this module (simple, hyphenated, urn) + /// are supported by this parsing function. + pub fn parse_str(mut input: &str) -> Result { + // Ensure length is valid for any of the supported formats + let len = input.len(); + + if len == adapter::Urn::LENGTH && input.starts_with("urn:uuid:") { + input = &input[9..]; + } else if !len_matches_any( + len, + &[adapter::Hyphenated::LENGTH, adapter::Simple::LENGTH], + ) { + Err(Error::InvalidLength { + expected: error::ExpectedLength::Any(&[ + adapter::Hyphenated::LENGTH, + adapter::Simple::LENGTH, + ]), + found: len, + })?; + } + + // `digit` counts only hexadecimal digits, `i_char` counts all chars. + let mut digit = 0; + let mut group = 0; + let mut acc = 0; + let mut buffer = [0u8; 16]; + + for (i_char, chr) in input.bytes().enumerate() { + if digit as usize >= adapter::Simple::LENGTH && group != 4 { + if group == 0 { + Err(Error::InvalidLength { + expected: error::ExpectedLength::Any(&[ + adapter::Hyphenated::LENGTH, + adapter::Simple::LENGTH, + ]), + found: len, + })?; + } + + Err(Error::InvalidGroupCount { + expected: error::ExpectedLength::Any(&[1, 5]), + found: group + 1, + })?; + } + + if digit % 2 == 0 { + // First digit of the byte. + match chr { + // Calulate upper half. + b'0'..=b'9' => acc = chr - b'0', + b'a'..=b'f' => acc = chr - b'a' + 10, + b'A'..=b'F' => acc = chr - b'A' + 10, + // Found a group delimiter + b'-' => { + // TODO: remove the u8 cast + // BODY: this only needed until we switch to + // ParseError + if ACC_GROUP_LENS[group] as u8 != digit { + // Calculate how many digits this group consists of + // in the input. + let found = if group > 0 { + // TODO: remove the u8 cast + // BODY: this only needed until we switch to + // ParseError + digit - ACC_GROUP_LENS[group - 1] as u8 + } else { + digit + }; + + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact( + GROUP_LENS[group], + ), + found: found as usize, + group, + })?; + } + // Next group, decrement digit, it is incremented again + // at the bottom. + group += 1; + digit -= 1; + } + _ => { + Err(Error::InvalidCharacter { + expected: "0123456789abcdefABCDEF-", + found: input[i_char..].chars().next().unwrap(), + index: i_char, + urn: error::UrnPrefix::Optional, + })?; + } + } + } else { + // Second digit of the byte, shift the upper half. + acc *= 16; + match chr { + b'0'..=b'9' => acc += chr - b'0', + b'a'..=b'f' => acc += chr - b'a' + 10, + b'A'..=b'F' => acc += chr - b'A' + 10, + b'-' => { + // The byte isn't complete yet. + let found = if group > 0 { + // TODO: remove the u8 cast + // BODY: this only needed until we switch to + // ParseError + digit - ACC_GROUP_LENS[group - 1] as u8 + } else { + digit + }; + + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact( + GROUP_LENS[group], + ), + found: found as usize, + group, + })?; + } + _ => { + Err(Error::InvalidCharacter { + expected: "0123456789abcdefABCDEF-", + found: input[i_char..].chars().next().unwrap(), + index: i_char, + urn: error::UrnPrefix::Optional, + })?; + } + } + buffer[(digit / 2) as usize] = acc; + } + digit += 1; + } + + // Now check the last group. + // TODO: remove the u8 cast + // BODY: this only needed until we switch to + // ParseError + if ACC_GROUP_LENS[4] as u8 != digit { + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact(GROUP_LENS[4]), + found: (digit as usize - ACC_GROUP_LENS[3]), + group, + })?; + } + + Ok(Uuid::from_bytes(buffer)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::{adapter, std::string::ToString, test_util}; + + #[test] + fn test_parse_uuid_v4() { + const EXPECTED_UUID_LENGTHS: error::ExpectedLength = + error::ExpectedLength::Any(&[ + adapter::Hyphenated::LENGTH, + adapter::Simple::LENGTH, + ]); + + const EXPECTED_GROUP_COUNTS: error::ExpectedLength = + error::ExpectedLength::Any(&[1, 5]); + + const EXPECTED_CHARS: &'static str = "0123456789abcdefABCDEF-"; + + // Invalid + assert_eq!( + Uuid::parse_str("").map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 0, + }) + ); + + assert_eq!( + Uuid::parse_str("!").map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 1 + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 37, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 35 + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidCharacter { + expected: EXPECTED_CHARS, + found: 'G', + index: 20, + urn: error::UrnPrefix::Optional, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2F4faaFB6BFF329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupCount { + expected: EXPECTED_GROUP_COUNTS, + found: 2 + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faaFB6BFF329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupCount { + expected: EXPECTED_GROUP_COUNTS, + found: 3, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupCount { + expected: EXPECTED_GROUP_COUNTS, + found: 4, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 18, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidCharacter { + expected: EXPECTED_CHARS, + found: 'X', + index: 18, + urn: error::UrnPrefix::Optional, + }) + ); + + assert_eq!( + Uuid::parse_str("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact(4), + found: 3, + group: 1, + }) + ); + // (group, found, expecting) + // + assert_eq!( + Uuid::parse_str("01020304-1112-2122-3132-41424344") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact(12), + found: 8, + group: 4, + }) + ); + + assert_eq!( + Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 31, + }) + ); + + assert_eq!( + Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c88") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 33, + }) + ); + + assert_eq!( + Uuid::parse_str("67e5504410b1426f9247bb680e5fe0cg8") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 33, + }) + ); + + assert_eq!( + Uuid::parse_str("67e5504410b1426%9247bb680e5fe0c8") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidCharacter { + expected: EXPECTED_CHARS, + found: '%', + index: 15, + urn: error::UrnPrefix::Optional, + }) + ); + + assert_eq!( + Uuid::parse_str("231231212212423424324323477343246663") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 36, + }) + ); + + // Valid + assert!(Uuid::parse_str("00000000000000000000000000000000").is_ok()); + assert!(Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").is_ok()); + assert!(Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").is_ok()); + assert!(Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8").is_ok()); + assert!(Uuid::parse_str("01020304-1112-2122-3132-414243444546").is_ok()); + assert!(Uuid::parse_str( + "urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8" + ) + .is_ok()); + + // Nil + let nil = Uuid::nil(); + assert_eq!( + Uuid::parse_str("00000000000000000000000000000000").unwrap(), + nil + ); + assert_eq!( + Uuid::parse_str("00000000-0000-0000-0000-000000000000").unwrap(), + nil + ); + + // Round-trip + let uuid_orig = test_util::new(); + let orig_str = uuid_orig.to_string(); + let uuid_out = Uuid::parse_str(&orig_str).unwrap(); + assert_eq!(uuid_orig, uuid_out); + + // Test error reporting + assert_eq!( + Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidLength { + expected: EXPECTED_UUID_LENGTHS, + found: 31, + }) + ); + assert_eq!( + Uuid::parse_str("67e550X410b1426f9247bb680e5fe0cd") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidCharacter { + expected: EXPECTED_CHARS, + found: 'X', + index: 6, + urn: error::UrnPrefix::Optional, + }) + ); + assert_eq!( + Uuid::parse_str("67e550-4105b1426f9247bb680e5fe0c") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact(8), + found: 6, + group: 0, + }) + ); + assert_eq!( + Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4") + .map_err(crate::Error::expect_parser), + Err(Error::InvalidGroupLength { + expected: error::ExpectedLength::Exact(4), + found: 5, + group: 3, + }) + ); + } +} diff -Nru rust-uuid-0.7.1/src/parser/std_support.rs rust-uuid-0.8.1/src/parser/std_support.rs --- rust-uuid-0.7.1/src/parser/std_support.rs 2018-09-14 20:25:05.000000000 +0000 +++ rust-uuid-0.8.1/src/parser/std_support.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,19 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. -// Copyright 2018 The Uuid Project Developers. -// -// See the COPYRIGHT file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use parser; -use std::error; - -impl error::Error for parser::ParseError { - fn description(&self) -> &str { - self._description() - } -} diff -Nru rust-uuid-0.7.1/src/prelude.rs rust-uuid-0.8.1/src/prelude.rs --- rust-uuid-0.7.1/src/prelude.rs 2018-09-14 20:25:43.000000000 +0000 +++ rust-uuid-0.8.1/src/prelude.rs 2019-10-17 04:22:56.000000000 +0000 @@ -19,23 +19,19 @@ //! extern crate uuid; //! ``` //! -//! and the following in every module: -//! -//! ```rust -//! use uuid::prelude::*; -//! ``` -//! //! # Prelude Contents //! //! Currently the prelude reexports the following: //! -//! [`uuid`]`::{`[`Uuid`], [`Variant`], [`Version`]`}`: The fundamental -//! types used in [`uuid`] crate. +//! [`uuid`]`::{`[`Error`], [`Uuid`], [`Variant`], [`Version`], +//! builder::[`Builder`]`}`: The fundamental types used in [`uuid`] crate. //! //! [`uuid`]: ../index.html +//! [`Error`]: ../enum.Error.html //! [`Uuid`]: ../struct.Uuid.html //! [`Variant`]: ../enum.Variant.html //! [`Version`]: ../enum.Version.html +//! [`Builder`]: ../builder/struct.Builder.html //! #![cfg_attr(feature = "v1", doc = " @@ -46,6 +42,6 @@ [`Context`]: ../v1/struct.Context.html [`ClockSequence`]: ../v1/trait.ClockSequence.html")] -pub use super::{Bytes, Uuid, Variant, Version}; +pub use super::{Builder, Bytes, Error, Uuid, Variant, Version}; #[cfg(feature = "v1")] -pub use v1::{ClockSequence, Context}; +pub use crate::v1::{ClockSequence, Context}; diff -Nru rust-uuid-0.7.1/src/serde_support.rs rust-uuid-0.8.1/src/serde_support.rs --- rust-uuid-0.7.1/src/serde_support.rs 2018-09-14 20:25:05.000000000 +0000 +++ rust-uuid-0.8.1/src/serde_support.rs 2019-04-09 03:51:03.000000000 +0000 @@ -9,10 +9,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use crate::prelude::*; use core::fmt; -use prelude::*; use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +#[cfg(feature = "serde")] impl Serialize for Uuid { fn serialize( &self, @@ -27,6 +28,7 @@ } } +#[cfg(feature = "serde")] impl<'de> Deserialize<'de> for Uuid { fn deserialize>( deserializer: D, @@ -39,7 +41,7 @@ fn expecting( &self, - formatter: &mut fmt::Formatter, + formatter: &mut fmt::Formatter<'_>, ) -> fmt::Result { write!(formatter, "a UUID string") } @@ -68,7 +70,7 @@ fn expecting( &self, - formatter: &mut fmt::Formatter, + formatter: &mut fmt::Formatter<'_>, ) -> fmt::Result { write!(formatter, "bytes") } @@ -86,11 +88,11 @@ } } -#[cfg(test)] -mod tests { +#[cfg(all(test, feature = "serde"))] +mod serde_tests { use serde_test; - use prelude::*; + use crate::prelude::*; #[test] fn test_serialize_readable() { diff -Nru rust-uuid-0.7.1/src/slog_support.rs rust-uuid-0.8.1/src/slog_support.rs --- rust-uuid-0.7.1/src/slog_support.rs 2018-09-02 10:45:54.000000000 +0000 +++ rust-uuid-0.8.1/src/slog_support.rs 2019-04-09 03:51:03.000000000 +0000 @@ -9,15 +9,15 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use prelude::*; +use crate::prelude::*; use slog; impl slog::Value for Uuid { fn serialize( &self, - _: &slog::Record, + _: &slog::Record<'_>, key: slog::Key, - serializer: &mut slog::Serializer, + serializer: &mut dyn slog::Serializer, ) -> Result<(), slog::Error> { serializer.emit_arguments(key, &format_args!("{}", self)) } @@ -28,11 +28,11 @@ #[test] fn test_slog_kv() { + use crate::test_util; use slog; - use slog::Drain; - use test_util; + use slog::{crit, Drain}; - let root = slog::Logger::root(slog::Discard.fuse(), o!()); + let root = slog::Logger::root(slog::Discard.fuse(), slog::o!()); let u1 = test_util::new(); crit!(root, "test"; "u1" => u1); } diff -Nru rust-uuid-0.7.1/src/std_support.rs rust-uuid-0.8.1/src/std_support.rs --- rust-uuid-0.7.1/src/std_support.rs 2018-09-02 10:45:54.000000000 +0000 +++ rust-uuid-0.8.1/src/std_support.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. -// Copyright 2018 The Uuid Project Developers. -// -// See the COPYRIGHT file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::error; - -impl error::Error for ::BytesError { - fn description(&self) -> &str { - "invalid number of uuid bytes" - } -} diff -Nru rust-uuid-0.7.1/src/test_util.rs rust-uuid-0.8.1/src/test_util.rs --- rust-uuid-0.7.1/src/test_util.rs 2018-09-02 10:45:54.000000000 +0000 +++ rust-uuid-0.8.1/src/test_util.rs 2019-04-09 03:51:03.000000000 +0000 @@ -9,16 +9,16 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use prelude::*; +use crate::prelude::*; -pub fn new() -> Uuid { +pub const fn new() -> Uuid { Uuid::from_bytes([ 0xF9, 0x16, 0x8C, 0x5E, 0xCE, 0xB2, 0x4F, 0xAA, 0xB6, 0xBF, 0x32, 0x9B, 0xF3, 0x9F, 0xA1, 0xE4, ]) } -pub fn new2() -> Uuid { +pub const fn new2() -> Uuid { Uuid::from_bytes([ 0xF9, 0x16, 0x8C, 0x5E, 0xCE, 0xB2, 0x4F, 0xAB, 0xB6, 0xBF, 0x32, 0x9B, 0xF3, 0x9F, 0xA1, 0xE4, diff -Nru rust-uuid-0.7.1/src/u128_support.rs rust-uuid-0.8.1/src/u128_support.rs --- rust-uuid-0.7.1/src/u128_support.rs 2018-09-02 10:45:54.000000000 +0000 +++ rust-uuid-0.8.1/src/u128_support.rs 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. -// Copyright 2018 The Uuid Project Developers. -// -// See the COPYRIGHT file at the top-level directory of this distribution. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use byteorder; -use prelude::*; - -impl Uuid { - /// Creates a new [`Uuid`] from a `u128` value. - /// - /// To create a [`Uuid`] from `u128`s, you need `u128` feature enabled for - /// this crate. - /// - /// [`Uuid`]: ../struct.Uuid.html - #[inline] - pub fn from_u128(quad: u128) -> Self { - Uuid::from(quad) - } -} - -impl From for Uuid { - fn from(f: u128) -> Self { - let mut bytes: ::Bytes = [0; 16]; - - { - use byteorder::ByteOrder; - - byteorder::NativeEndian::write_u128(&mut bytes[..], f); - } - - Uuid::from_bytes(bytes) - } -} - -#[cfg(test)] -mod tests { - use prelude::*; - - #[test] - fn test_from_u128() { - const U128: u128 = 0x3a0724b4_93a0_4d87_ac28_759c6caa13c4; - - let uuid = Uuid::from(U128); - - let uuid2: Uuid = U128.into(); - - assert_eq!(uuid, uuid2) - } - -} diff -Nru rust-uuid-0.7.1/src/v1.rs rust-uuid-0.8.1/src/v1.rs --- rust-uuid-0.7.1/src/v1.rs 2018-09-14 20:25:43.000000000 +0000 +++ rust-uuid-0.8.1/src/v1.rs 2019-10-18 22:08:23.000000000 +0000 @@ -1,11 +1,13 @@ -//! The implementation for Version 1 [`Uuid`]s. +//! The implementation for Version 1 UUIDs. //! //! Note that you need feature `v1` in order to use these features. -//! -//! [`Uuid`]: ../struct.Uuid.html +use crate::prelude::*; use core::sync::atomic; -use prelude::*; + +/// The number of 100 ns ticks between the UUID epoch +/// `1582-10-15 00:00:00` and the Unix epoch `1970-01-01 00:00:00`. +const UUID_TICKS_BETWEEN_EPOCHS: u64 = 0x01B2_1DD2_1381_4000; /// A thread-safe, stateful context for the v1 generator to help ensure /// process-wide uniqueness. @@ -14,118 +16,241 @@ count: atomic::AtomicUsize, } -/// A trait that abstracts over generation of Uuid v1 "Clock Sequence" values. +/// Stores the number of nanoseconds from an epoch and a counter for ensuring +/// V1 ids generated on the same host are unique. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct Timestamp { + ticks: u64, + counter: u16, +} + +impl Timestamp { + /// Construct a `Timestamp` from its raw component values: an RFC4122 + /// timestamp and counter. + /// + /// RFC4122, which defines the V1 UUID, specifies a 60-byte timestamp format + /// as the number of 100-nanosecond intervals elapsed since 00:00:00.00, + /// 15 Oct 1582, "the date of the Gregorian reform of the Christian + /// calendar." + /// + /// The counter value is used to differentiate between ids generated by + /// the same host computer in rapid succession (i.e. with the same observed + /// time). See the [`ClockSequence`] trait for a generic interface to any + /// counter generators that might be used. + /// + /// Internally, the timestamp is stored as a `u64`. For this reason, dates + /// prior to October 1582 are not supported. + /// + /// [`ClockSequence`]: trait.ClockSequence.html + pub const fn from_rfc4122(ticks: u64, counter: u16) -> Self { + Timestamp { ticks, counter } + } + + /// Construct a `Timestamp` from a unix timestamp and sequence-generating + /// `context`. + /// + /// A unix timestamp represents the elapsed time since Jan 1 1970. Libc's + /// `clock_gettime` and other popular implementations traditionally + /// represent this duration as a `timespec`: a struct with `u64` and + /// `u32` fields representing the seconds, and "subsecond" or fractional + /// nanoseconds elapsed since the timestamp's second began, + /// respectively. + /// + /// This constructs a `Timestamp` from the seconds and fractional + /// nanoseconds of a unix timestamp, converting the duration since 1970 + /// into the number of 100-nanosecond intervals since 00:00:00.00, 15 + /// Oct 1982 specified by RFC4122 and used internally by `Timestamp`. + /// + /// The function is not guaranteed to produce monotonically increasing + /// values however. There is a slight possibility that two successive + /// equal time values could be supplied and the sequence counter wraps back + /// over to 0. + /// + /// If uniqueness and monotonicity is required, the user is responsible for + /// ensuring that the time value always increases between calls (including + /// between restarts of the process and device). + pub fn from_unix( + context: impl ClockSequence, + seconds: u64, + subsec_nanos: u32, + ) -> Self { + let counter = context.generate_sequence(seconds, subsec_nanos); + let ticks = UUID_TICKS_BETWEEN_EPOCHS + + seconds * 10_000_000 + + (subsec_nanos as u64 / 100); + Timestamp { ticks, counter } + } + + /// Returns the raw RFC4122 timestamp and counter values stored by the + /// `Timestamp`. + /// + /// The timestamp (the first, `u64` element in the tuple) represents the + /// number of 100-nanosecond intervals since 00:00:00.00, 15 Oct 1582. + /// The counter is used to differentiate between ids generated on the + /// same host computer with the same observed time. + pub const fn to_rfc4122(&self) -> (u64, u16) { + (self.ticks, self.counter) + } + + /// Returns the timestamp converted to the seconds and fractional + /// nanoseconds since Jan 1 1970. + /// + /// Internally, the time is stored in 100-nanosecond intervals, + /// thus the maximum precision represented by the fractional nanoseconds + /// value is less than its unit size (100 ns vs. 1 ns). + pub const fn to_unix(&self) -> (u64, u32) { + let unix_ticks = self.ticks - UUID_TICKS_BETWEEN_EPOCHS; + ( + unix_ticks / 10_000_000, + (unix_ticks % 10_000_000) as u32 * 100, + ) + } + + /// Returns the timestamp converted into nanoseconds elapsed since Jan 1 + /// 1970. Internally, the time is stored in 100-nanosecond intervals, + /// thus the maximum precision represented is less than the units it is + /// measured in (100 ns vs. 1 ns). The value returned represents the + /// same duration as [`Timestamp::to_unix`]; this provides it in nanosecond + /// units for convenience. + pub const fn to_unix_nanos(&self) -> u64 { + (self.ticks - UUID_TICKS_BETWEEN_EPOCHS) * 100 + } +} + +/// A trait that abstracts over generation of UUID v1 "Clock Sequence" values. 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 + /// the UUID. The number must be different if the time has changed since /// the last time a clock sequence was requested. - fn generate_sequence(&self, seconds: u64, nano_seconds: u32) -> u16; + fn generate_sequence(&self, seconds: u64, subsec_nanos: u32) -> u16; +} + +impl<'a, T: ClockSequence + ?Sized> ClockSequence for &'a T { + fn generate_sequence(&self, seconds: u64, subsec_nanos: u32) -> u16 { + (**self).generate_sequence(seconds, subsec_nanos) + } } impl Uuid { - /// Create a new [`Uuid`] (version 1) using a time value + sequence + + /// Create a new UUID (version 1) using a time value + sequence + /// *NodeId*. /// - /// This expects two values representing a monotonically increasing value - /// as well as a unique 6 byte NodeId, and an implementation of - /// [`ClockSequence`]. This function is only guaranteed to produce - /// unique values if the following conditions hold: + /// When generating [`Timestamp`]s using a [`ClockSequence`], this function + /// is only guaranteed to produce unique values if the following conditions + /// hold: /// /// 1. The *NodeId* is unique for this process, /// 2. The *Context* is shared across all threads which are generating v1 - /// [`Uuid`]s, + /// UUIDs, /// 3. The [`ClockSequence`] implementation reliably returns unique /// clock sequences (this crate provides [`Context`] for this /// purpose. However you can create your own [`ClockSequence`] /// implementation, if [`Context`] does not meet your needs). /// - /// The NodeID must be exactly 6 bytes long. If the NodeID is not a valid - /// length this will return a [`ParseError`]`::InvalidLength`. - /// - /// The function is not guaranteed to produce monotonically increasing - /// values however. There is a slight possibility that two successive - /// equal time values could be supplied and the sequence counter wraps back - /// over to 0. - /// - /// If uniqueness and monotonicity is required, the user is responsible for - /// ensuring that the time value always increases between calls (including - /// between restarts of the process and device). + /// The NodeID must be exactly 6 bytes long. /// /// Note that usage of this method requires the `v1` feature of this crate /// to be enabled. /// /// # Examples /// - /// Basic usage: + /// A UUID can be created from a unix [`Timestamp`] with a + /// [`ClockSequence`]: /// /// ```rust - /// use uuid::v1::Context; + /// use uuid::v1::{Timestamp, Context}; /// use uuid::Uuid; /// /// let context = Context::new(42); - /// if let Ok(uuid) = - /// Uuid::new_v1(&context, 1497624119, 1234, &[1, 2, 3, 4, 5, 6]) - /// { - /// assert_eq!( - /// uuid.to_hyphenated().to_string(), - /// "f3b4958c-52a1-11e7-802a-010203040506" - /// ) - /// } else { - /// panic!() - /// } + /// let ts = Timestamp::from_unix(&context, 1497624119, 1234); + /// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]).expect("failed to generate UUID"); + /// + /// assert_eq!( + /// uuid.to_hyphenated().to_string(), + /// "f3b4958c-52a1-11e7-802a-010203040506" + /// ); /// ``` /// - /// [`ParseError`]: ../enum.ParseError.html - /// [`Uuid`]: ../struct.Uuid.html - /// [`ClockSequence`]: struct.ClockSequence.html - /// [`Context`]: struct.Context.html - pub fn new_v1( - context: &T, - seconds: u64, - nano_seconds: u32, - node_id: &[u8], - ) -> Result - where - T: ClockSequence, - { + /// The timestamp can also be created manually as per RFC4122: + /// + /// ``` + /// use uuid::v1::{Timestamp, Context}; + /// use uuid::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]).expect("failed to generate UUID"); + /// + /// assert_eq!( + /// uuid.to_hyphenated().to_string(), + /// "5943ee37-0000-1000-8000-010203040506" + /// ); + /// ``` + /// + /// [`Timestamp`]: v1/struct.Timestamp.html + /// [`ClockSequence`]: v1/struct.ClockSequence.html + /// [`Context`]: v1/struct.Context.html + pub fn new_v1(ts: Timestamp, node_id: &[u8]) -> Result { const NODE_ID_LEN: usize = 6; let len = node_id.len(); if len != NODE_ID_LEN { - return Err(::BytesError::new(NODE_ID_LEN, len)); + Err(crate::builder::Error::new(NODE_ID_LEN, len))?; } - let time_low; - let time_mid; - let time_high_and_version; - - { - /// The number of 100 ns ticks between the UUID epoch - /// `1582-10-15 00:00:00` and the Unix epoch `1970-01-01 00:00:00`. - const UUID_TICKS_BETWEEN_EPOCHS: u64 = 0x01B2_1DD2_1381_4000; - - let timestamp = - seconds * 10_000_000 + u64::from(nano_seconds / 100); - let uuid_time = timestamp + UUID_TICKS_BETWEEN_EPOCHS; - - time_low = (uuid_time & 0xFFFF_FFFF) as u32; - time_mid = ((uuid_time >> 32) & 0xFFFF) as u16; - time_high_and_version = - (((uuid_time >> 48) & 0x0FFF) as u16) | (1 << 12); - } + let time_low = (ts.ticks & 0xFFFF_FFFF) as u32; + let time_mid = ((ts.ticks >> 32) & 0xFFFF) as u16; + let time_high_and_version = + (((ts.ticks >> 48) & 0x0FFF) as u16) | (1 << 12); let mut d4 = [0; 8]; { - let count = context.generate_sequence(seconds, nano_seconds); - d4[0] = (((count & 0x3F00) >> 8) as u8) | 0x80; - d4[1] = (count & 0xFF) as u8; + d4[0] = (((ts.counter & 0x3F00) >> 8) as u8) | 0x80; + d4[1] = (ts.counter & 0xFF) as u8; } d4[2..].copy_from_slice(node_id); Uuid::from_fields(time_low, time_mid, time_high_and_version, &d4) } + + /// Returns an optional [`Timestamp`] storing the timestamp and + /// counter portion parsed from a V1 UUID. + /// + /// Returns `None` if the supplied UUID is not V1. + /// + /// The V1 timestamp format defined in RFC4122 specifies a 60-bit + /// integer representing the number of 100-nanosecond intervals + /// since 00:00:00.00, 15 Oct 1582. + /// + /// [`Timestamp`] offers several options for converting the raw RFC4122 + /// value into more commonly-used formats, such as a unix timestamp. + /// + /// [`Timestamp`]: v1/struct.Timestamp.html + pub fn to_timestamp(&self) -> Option { + if self + .get_version() + .map(|v| v != Version::Mac) + .unwrap_or(true) + { + return None; + } + + let ticks: u64 = u64::from(self.as_bytes()[6] & 0x0F) << 56 + | u64::from(self.as_bytes()[7]) << 48 + | u64::from(self.as_bytes()[4]) << 40 + | u64::from(self.as_bytes()[5]) << 32 + | u64::from(self.as_bytes()[0]) << 24 + | u64::from(self.as_bytes()[1]) << 16 + | u64::from(self.as_bytes()[2]) << 8 + | u64::from(self.as_bytes()[3]); + + let counter: u16 = u16::from(self.as_bytes()[8] & 0x3F) << 8 + | u16::from(self.as_bytes()[9]); + + Some(Timestamp::from_rfc4122(ticks, counter)) + } } impl Context { @@ -134,12 +259,10 @@ /// /// This is a context which can be shared across threads. It maintains an /// internal counter that is incremented at every request, the value ends - /// up in the clock_seq portion of the [`Uuid`] (the fourth group). This - /// will improve the probability that the [`Uuid`] is unique across the + /// up in the clock_seq portion of the UUID (the fourth group). This + /// will improve the probability that the UUID is unique across the /// process. - /// - /// [`Uuid`]: ../struct.Uuid.html - pub fn new(count: u16) -> Self { + pub const fn new(count: u16) -> Self { Self { count: atomic::AtomicUsize::new(count as usize), } @@ -154,19 +277,23 @@ #[cfg(test)] mod tests { + use super::*; + + use crate::std::string::ToString; + #[test] fn test_new_v1() { - use super::Context; - use prelude::*; - 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 uuid = - Uuid::new_v1(&context, time, time_fraction, &node).unwrap(); + let uuid = Uuid::new_v1( + Timestamp::from_unix(&context, time, time_fraction), + &node, + ) + .unwrap(); assert_eq!(uuid.get_version(), Some(Version::Mac)); assert_eq!(uuid.get_variant(), Some(Variant::RFC4122)); @@ -175,21 +302,24 @@ "20616934-4ba2-11e7-8000-010203040506" ); - let ts = uuid.to_timestamp().unwrap(); + let ts = uuid.to_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(&context, time, time_fraction, &node).unwrap(); + let uuid2 = Uuid::new_v1( + Timestamp::from_unix(&context, time, time_fraction), + &node, + ) + .unwrap(); assert_eq!( uuid2.to_hyphenated().to_string(), "20616934-4ba2-11e7-8001-010203040506" ); - assert_eq!(uuid2.to_timestamp().unwrap().1, 1) + assert_eq!(uuid2.to_timestamp().unwrap().to_rfc4122().1, 1) }; } } diff -Nru rust-uuid-0.7.1/src/v3.rs rust-uuid-0.8.1/src/v3.rs --- rust-uuid-0.7.1/src/v3.rs 2018-09-02 10:45:54.000000000 +0000 +++ rust-uuid-0.8.1/src/v3.rs 2019-10-18 22:08:23.000000000 +0000 @@ -1,8 +1,8 @@ +use crate::prelude::*; use md5; -use prelude::*; impl Uuid { - /// Creates a [`Uuid`] using a name from a namespace, based on the MD5 + /// Creates a UUID using a name from a namespace, based on the MD5 /// hash. /// /// A number of namespaces are available as constants in this crate: @@ -15,28 +15,34 @@ /// Note that usage of this method requires the `v3` feature of this crate /// to be enabled. /// - /// [`NAMESPACE_DNS`]: ../ns/const.NAMESPACE_DNS.html - /// [`NAMESPACE_OID`]: ../ns/const.NAMESPACE_OID.html - /// [`NAMESPACE_URL`]: ../ns/const.NAMESPACE_URL.html - /// [`NAMESPACE_X500`]: ../ns/const.NAMESPACE_X500.html - /// [`Uuid`]: ../struct.Uuid.html + /// [`NAMESPACE_DNS`]: ns/const.NAMESPACE_DNS.html + /// [`NAMESPACE_OID`]: ns/const.NAMESPACE_OID.html + /// [`NAMESPACE_URL`]: ns/const.NAMESPACE_URL.html + /// [`NAMESPACE_X500`]: ns/const.NAMESPACE_X500.html pub fn new_v3(namespace: &Uuid, name: &[u8]) -> Uuid { let mut context = md5::Context::new(); context.consume(namespace.as_bytes()); context.consume(name); - let mut uuid = Uuid::from_bytes(context.compute().into()); + let computed = context.compute(); + let bytes = computed.into(); - uuid.set_variant(Variant::RFC4122); - uuid.set_version(Version::Md5); - uuid + let mut builder = crate::builder::Builder::from_bytes(bytes); + + builder + .set_variant(Variant::RFC4122) + .set_version(Version::Md5); + + builder.build() } } #[cfg(test)] mod tests { - use prelude::*; + use super::*; + + use crate::std::string::ToString; static FIXTURE: &'static [(&'static Uuid, &'static str, &'static str)] = &[ ( diff -Nru rust-uuid-0.7.1/src/v4.rs rust-uuid-0.8.1/src/v4.rs --- rust-uuid-0.7.1/src/v4.rs 2018-09-02 10:45:54.000000000 +0000 +++ rust-uuid-0.8.1/src/v4.rs 2019-10-18 22:08:23.000000000 +0000 @@ -1,8 +1,8 @@ -use prelude::*; +use crate::prelude::*; use rand; impl Uuid { - /// Creates a random [`Uuid`]. + /// Creates a random UUID. /// /// This uses the [`rand`] crate's default task RNG as the source of random /// numbers. If you'd like to use a custom generator, don't use this @@ -22,7 +22,6 @@ /// ``` /// /// [`rand`]: https://crates.io/crates/rand - /// [`Uuid`]: ../struct.Uuid.html pub fn new_v4() -> Self { use rand::RngCore; @@ -31,13 +30,16 @@ rng.fill_bytes(&mut bytes); - Self::from_random_bytes(bytes) + Builder::from_bytes(bytes) + .set_variant(Variant::RFC4122) + .set_version(Version::Random) + .build() } } #[cfg(test)] mod tests { - use prelude::*; + use crate::prelude::*; #[test] fn test_new() { diff -Nru rust-uuid-0.7.1/src/v5.rs rust-uuid-0.8.1/src/v5.rs --- rust-uuid-0.7.1/src/v5.rs 2018-09-14 20:25:05.000000000 +0000 +++ rust-uuid-0.8.1/src/v5.rs 2019-10-17 04:22:56.000000000 +0000 @@ -1,4 +1,4 @@ -use prelude::*; +use crate::prelude::*; use sha1; impl Uuid { @@ -25,19 +25,24 @@ hash.update(name); let buffer = hash.digest().bytes(); - let mut uuid = Uuid::default(); - uuid.0.copy_from_slice(&buffer[..16]); - uuid.set_variant(Variant::RFC4122); - uuid.set_version(Version::Sha1); + let mut bytes = crate::Bytes::default(); + bytes.copy_from_slice(&buffer[..16]); - uuid + let mut builder = crate::builder::Builder::from_bytes(bytes); + builder + .set_variant(Variant::RFC4122) + .set_version(Version::Sha1); + + builder.build() } } #[cfg(test)] mod tests { - use prelude::*; + use super::*; + + use crate::std::string::ToString; static FIXTURE: &'static [(&'static Uuid, &'static str, &'static str)] = &[ ( diff -Nru rust-uuid-0.7.1/src/winapi_support.rs rust-uuid-0.8.1/src/winapi_support.rs --- rust-uuid-0.7.1/src/winapi_support.rs 1970-01-01 00:00:00.000000000 +0000 +++ rust-uuid-0.8.1/src/winapi_support.rs 2019-10-17 04:22:56.000000000 +0000 @@ -0,0 +1,79 @@ +use crate::prelude::*; +use winapi::shared::guiddef; + +#[cfg(feature = "guid")] +impl Uuid { + /// Attempts to create a [`Uuid`] from a little endian winapi `GUID` + /// + /// [`Uuid`]: ../struct.Uuid.html + pub fn from_guid(guid: guiddef::GUID) -> Result { + Uuid::from_fields_le( + guid.Data1 as u32, + guid.Data2 as u16, + guid.Data3 as u16, + &(guid.Data4 as [u8; 8]), + ) + } + + /// Converts a [`Uuid`] into a little endian winapi `GUID` + /// + /// [`Uuid`]: ../struct.Uuid.html + pub fn to_guid(&self) -> guiddef::GUID { + let (data1, data2, data3, data4) = self.to_fields_le(); + + guiddef::GUID { + Data1: data1, + Data2: data2, + Data3: data3, + Data4: *data4, + } + } +} + +#[cfg(feature = "guid")] +#[cfg(test)] +mod tests { + use super::*; + + use crate::std::string::ToString; + use winapi::shared::guiddef; + + #[test] + fn test_from_guid() { + let guid = guiddef::GUID { + Data1: 0x4a35229d, + Data2: 0x5527, + Data3: 0x4f30, + Data4: [0x86, 0x47, 0x9d, 0xc5, 0x4e, 0x1e, 0xe1, 0xe8], + }; + + let uuid = Uuid::from_guid(guid).unwrap(); + assert_eq!( + "9d22354a-2755-304f-8647-9dc54e1ee1e8", + uuid.to_hyphenated().to_string() + ); + } + + #[test] + fn test_guid_roundtrip() { + let guid_in = guiddef::GUID { + Data1: 0x4a35229d, + Data2: 0x5527, + Data3: 0x4f30, + Data4: [0x86, 0x47, 0x9d, 0xc5, 0x4e, 0x1e, 0xe1, 0xe8], + }; + + let uuid = Uuid::from_guid(guid_in).unwrap(); + let guid_out = uuid.to_guid(); + + assert_eq!( + (guid_in.Data1, guid_in.Data2, guid_in.Data3, guid_in.Data4), + ( + guid_out.Data1, + guid_out.Data2, + guid_out.Data3, + guid_out.Data4 + ) + ); + } +}