Import 'uuid' crate version 0.8.2

Test: presubmit
Change-Id: I17e47a7d1e4725b94b514a48a306a6b87e178837
diff --git a/.cargo/.gitignore b/.cargo/.gitignore
new file mode 100644
index 0000000..9bff75a
--- /dev/null
+++ b/.cargo/.gitignore
@@ -0,0 +1 @@
+/config

diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
new file mode 100644
index 0000000..87a7cbe
--- /dev/null
+++ b/.cargo_vcs_info.json
@@ -0,0 +1,5 @@
+{
+  "git": {
+    "sha1": "b68733dfafb4cc384c50ca24af56221bfd2458d7"
+  }
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..fb93c9d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,33 @@
+### CLion ###

+# CMake

+cmake-build-debug/

+

+### IntelliJ ###

+.idea

+*.iws

+*.iml

+*.ipr

+

+### 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/

+Cargo.lock

+

diff --git a/.rustfmt.toml b/.rustfmt.toml
new file mode 100644
index 0000000..313c070
--- /dev/null
+++ b/.rustfmt.toml
@@ -0,0 +1,9 @@
+max_width = 80

+hard_tabs = false

+tab_spaces = 4

+newline_style = "Unix"

+wrap_comments = true

+normalize_comments = true

+merge_derives = true

+force_explicit_abi = true

+unstable_features = false

diff --git a/Android.bp b/Android.bp
new file mode 100644
index 0000000..2963741
--- /dev/null
+++ b/Android.bp
@@ -0,0 +1,20 @@
+// This file is generated by cargo2android.py --run --device --dependencies --features=v1,serde.
+// Do not modify this file as changes will be overridden on upgrade.
+
+rust_library {
+    name: "libuuid",
+    host_supported: true,
+    crate_name: "uuid",
+    srcs: ["src/lib.rs"],
+    edition: "2018",
+    features: [
+        "serde",
+        "v1",
+    ],
+    rustlibs: [
+        "libserde",
+    ],
+}
+
+// dependent_library ["feature_list"]
+//   serde-1.0.124 "default,std"
diff --git a/CODEOWNERS b/CODEOWNERS
new file mode 100644
index 0000000..4846ccc
--- /dev/null
+++ b/CODEOWNERS
@@ -0,0 +1,16 @@
+# CI

+.travis.yml     @kinggoesgaming @KodrAus @Dylan-DPC @radix

+appveyor.yml    @kinggoesgaming @KodrAus @Dylan-DPC @radix

+

+# Cargo.toml

+Cargo.toml      @kinggoesgaming @KodrAus @Dylan-DPC @radix

+

+# Rust

+*.rs            @kinggoesgaming @KodrAus @Dylan-DPC @radix

+

+# CODEOWNERS

+CODEOWNERS      @kinggoesgaming @KodrAus @Dylan-DPC @radix

+

+#>> Critical

+# bors.toml file

+bors.toml       @kinggoesgaming @KodrAus @Dylan-DPC @radix

diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..8ffa6a4
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,77 @@
+# Contributor Covenant Code of Conduct

+

+The latest version of the CODE OF CONDUCT can be found [here].

+

+[here]: https://github.com/uuid-rs/conduct

+

+## Our Pledge

+

+In the interest of fostering an open and welcoming environment, we as

+contributors and maintainers pledge to making participation in our project and

+our community a harassment-free experience for everyone, regardless of age, body

+size, disability, ethnicity, gender identity and expression, level of experience,

+education, socio-economic status, nationality, personal appearance, race,

+religion, or sexual identity and orientation.

+

+## Our Standards

+

+Examples of behavior that contributes to creating a positive environment

+include:

+

+* Using welcoming and inclusive language

+* Being respectful of differing viewpoints and experiences

+* Gracefully accepting constructive criticism

+* Focusing on what is best for the community

+* Showing empathy towards other community members

+

+Examples of unacceptable behavior by participants include:

+

+* The use of sexualized language or imagery and unwelcome sexual attention or

+  advances

+* Trolling, insulting/derogatory comments, and personal or political attacks

+* Public or private harassment

+* Publishing others' private information, such as a physical or electronic

+  address, without explicit permission

+* Other conduct which could reasonably be considered inappropriate in a

+  professional setting

+

+## Our Responsibilities

+

+Project maintainers are responsible for clarifying the standards of acceptable

+behavior and are expected to take appropriate and fair corrective action in

+response to any instances of unacceptable behavior.

+

+Project maintainers have the right and responsibility to remove, edit, or

+reject comments, commits, code, wiki edits, issues, and other contributions

+that are not aligned to this Code of Conduct, or to ban temporarily or

+permanently any contributor for other behaviors that they deem inappropriate,

+threatening, offensive, or harmful.

+

+## Scope

+

+This Code of Conduct applies both within project spaces and in public spaces

+when an individual is representing the project or its community. Examples of

+representing a project or community include using an official project e-mail

+address, posting via an official social media account, or acting as an appointed

+representative at an online or offline event. Representation of a project may be

+further defined and clarified by project maintainers.

+

+## Enforcement

+

+Instances of abusive, harassing, or otherwise unacceptable behavior may be

+reported by contacting the project team at report@uuid-rs.groups.io. All

+complaints will be reviewed and investigated and will result in a response that

+is deemed necessary and appropriate to the circumstances. The project team is

+obligated to maintain confidentiality with regard to the reporter of an incident.

+Further details of specific enforcement policies may be posted separately.

+

+Project maintainers who do not follow or enforce the Code of Conduct in good

+faith may face temporary or permanent repercussions as determined by other

+members of the project's leadership.

+

+## Attribution

+

+This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,

+available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

+

+[homepage]: https://www.contributor-covenant.org
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..baa7535
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,149 @@
+Contributing to Uuid

+---

+[Contributing to Uuid]: #contributing-to-uuid

+

+Thank you for your interest in contributing to the Uuid Project!

+

+* [Feature Requests](#feature-requests)

+* [Bug Reports](#bug-reports)

+* [Pull Requests](#pull-requests)

+* [Writing Documentation](#writing-documentation)

+* [Issue Triage](#issue-triage)

+* [Out-of-tree Contributions](#out-of-tree-contributions)

+* [Helpful Links](#helpful-links)

+

+For any questions, please make a post on [users.rust-lang.org][u-r-l-o], post

+on [uuid-rs mailing list] or join our [gitter] channel.

+

+> All contributors need to follow our [Code of Conduct].

+

+[Code of Conduct]: CODE_OF_CONDUCT.md

+

+# Feature Requests

+[Feature Requests]: #feature-requests

+

+The `uuid` crate is still in flux. All features desired may not be present. As

+such you are welcome to request for new features. Keep in mind that `uuid` is

+a general purpose library. We want to provide features that most users would

+find useful. As such not every feature may be accepted.

+

+If you have the chance, please [search existing issues], as there is a chance

+that someone has already requested your feature.

+

+File your feature request with a descriptive title, as this helps others find

+your request.

+

+You can request your feature by following [this link][Feature Request Link] and

+filling it in. 

+

+> We welcome pull requests for your own feature requests, provided they have

+been discussed.

+

+[Feature Request Link]: https://github.com/uuid-rs/uuid/issues/new?template=Feature_request.md

+

+# Bug Reports

+[Bug Reports]: #bug-reports

+

+While no one likes bugs, they are an unfortunate reality in software. Remember

+we can't fix bugs we don't know about, so don't be shy about reporting.

+

+If you have the chance, please [search existing issues], as there is a chance

+that someone has already reported your error. This isn't strictly needed, as

+sometimes you might not what exactly you are looking for.

+

+File your issue with a descriptive title, as this helps others find your issue.

+

+Reporting a bug is as easy as following [this link][Bug Report Link] and

+filling it in.

+

+Sometimes a backtrace may be needed. In that case, set `RUST_BACKTRACE`

+environment variable to `1`. For example:

+

+```bash

+$ RUST_BACKTRACE=1 cargo build

+```

+

+> We welcome pull requests for your own bug reports, provided they have been

+discussed.

+

+[Bug Report Link]: https://github.com/uuid-rs/uuid/issues/new?template=Bug_report.md

+

+# Pull Requests

+[Pull Requests]: #pull-requests

+

+Pull requests(PRs) are the primary mechanism we use to change Uuid. GitHub itself

+has some [great documentation] on using the Pull Request feature. We use the

+"fork and pull" model described [here][fnp], where contributors push changes to

+their personal fork and create pull requests to bring those changes into the

+source repository.

+

+Unless the changes are fairly minor (like documentation changes or tiny

+patches), we require PRs to relevant issues.

+

+Please open PRs against branch:

+* `master` when making non-breaking changes 

+* `breaking` when your changes alter the public API in a breaking manner

+

+If the pull request is still a work in progress, prepend`[WIP] ` in your 

+title. `WIP bot` will make sure that the PR doesn't accidentally get merged.

+

+> Uuid Project has a minimum rust version policy. Currently `uuid` should 

+compile with atleast `1.22.0`, and is enforced on our CI builds.

+

+When you feel that the PR is ready, please ping one of the maintainers so

+they can review your changes.

+

+[great documentation]: https://help.github.com/articles/about-pull-requests/

+[fnp]: https://help.github.com/articles/about-collaborative-development-models/

+

+# Writing Documentation

+[Writing Documentation]: #writing-documentation

+

+Documentation is an important part of Uuid. Lackluster or incorrect

+documentation can cause headaches for the users of `uuid`. Therefore,

+improvements to documentation are always welcome.

+

+We follow the documentation style guidelines as given by [RFC 1574].

+

+[RFC 1574]: https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text

+

+# Issue Triage

+[Issue Triage]: #issue-triage

+

+Sometimes, an issue might stay open even after the relevant bug has been fixed.

+Other times, the bug report may become invalid. Or we may just forget about the

+bug.

+

+You can help to go through old bug reports and check if they are still valid.

+You can follow [this link][lrus] to look for issues like this.

+

+[lrus]: https://github.com/uuid-rs/uuid/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-asc

+

+# Out-of-tree Contributions

+[Out-of-tree Contributions]: #out-of-tree-contributions

+

+You can contribute to Uuid in other ways:

+

+* Answer questions on [users.rust-lang.org][u-r-l-o], [uuid-rs mailing list] and/or

+[gitter] channel.

+* Find the [crates depending on `uuid`][dependent] and sending PRs to them,

+helping them keep their version of `uuid` up-to-date.

+

+[dependent]: https://crates.io/crates/uuid/reverse_dependencies

+

+# Helpful Links

+[Helpful Links]: #helpful-links

+

+For people new to Uuid, and just starting to contribute, or even for more

+seasoned developers, some useful places to look for information are:

+

+* The Wikipedia entry on [Universally Unique Identifier][wiki-uuid].

+* [RFC 4122] which gives the specification of Uuids.

+

+[wiki-uuid]: https://en.wikipedia.org/wiki/Universally_unique_identifier

+[RFC 4122]: https://www.ietf.org/rfc/rfc4122.txt

+

+[u-r-l-o]: https://users.rust-lang.org

+[uuid-rs mailing list]: https://uuid-rs.groups.io

+[gitter]: https://gitter.im/uuid-rs/Lobby

+[search existing issues]: https://github.com/uuid-rs/uuid/search?q=&type=Issues&utf8=%E2%9C%93

diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
index 0000000..fbcde1c
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,8 @@
+The Uuid Project is copyright 2013-2014, The Rust Project Developers and

+copyright 2018, The Uuid Developers.

+

+Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or

+http://www.apache.org/licenses/LICENSE-2.0> or the MIT License <LICENSE-MIT or

+http://opensource.org/licenses/MIT>, at your option. All files in the project

+carrying such notice may not be copied, modified, or distributed except

+according to those terms.

diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..1803f73
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,91 @@
+# 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]
+edition = "2018"
+name = "uuid"
+version = "0.8.2"
+authors = ["Ashley Mannix<ashleymannix@live.com.au>", "Christopher Armstrong", "Dylan DPC<dylan.dpc@gmail.com>", "Hunar Roop Kahlon<hunar.roop@gmail.com>"]
+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]
+default-target = "x86_64-pc-windows-msvc"
+features = ["guid", "serde", "slog", "v1", "v3", "v4", "v5"]
+
+[package.metadata.playground]
+features = ["serde", "v1", "v3", "v4", "v5"]
+[dependencies.getrandom]
+version = "0.2.0"
+optional = true
+
+[dependencies.md5]
+version = "0.7"
+optional = true
+
+[dependencies.serde]
+version = "1.0.56"
+optional = true
+default-features = false
+
+[dependencies.sha1]
+version = "0.6"
+optional = true
+
+[dependencies.slog]
+version = "2"
+optional = true
+[dev-dependencies.bincode]
+version = "1.0"
+
+[dev-dependencies.serde_derive]
+version = "1.0.79"
+
+[dev-dependencies.serde_json]
+version = "1.0"
+
+[dev-dependencies.serde_test]
+version = "1.0.56"
+
+[features]
+default = ["std"]
+guid = ["winapi"]
+std = []
+stdweb = ["getrandom", "getrandom/js"]
+v1 = []
+v3 = ["md5"]
+v4 = ["getrandom"]
+v5 = ["sha1"]
+wasm-bindgen = ["getrandom", "getrandom/js"]
+[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 --git a/Cargo.toml.orig b/Cargo.toml.orig
new file mode 100644
index 0000000..cafaecd
--- /dev/null
+++ b/Cargo.toml.orig
@@ -0,0 +1,104 @@
+[package]

+authors = [

+    "Ashley Mannix<ashleymannix@live.com.au>",

+    "Christopher Armstrong",

+    "Dylan DPC<dylan.dpc@gmail.com>",

+    "Hunar Roop Kahlon<hunar.roop@gmail.com>"

+]

+categories = [

+    "data-structures",

+    "no-std",

+    "parser-implementations",

+    "wasm"

+]

+description = "A library to generate and parse UUIDs."

+documentation = "https://docs.rs/uuid"

+edition = "2018"

+exclude = [

+    ".github/**",

+    ".travis.yml",

+    "appveyor.yml",

+    "bors.toml"

+]

+keywords = [

+    "guid",

+    "unique",

+    "uuid"

+]

+license = "Apache-2.0 OR MIT"

+homepage = "https://github.com/uuid-rs/uuid"

+name = "uuid"

+readme = "README.md"

+repository = "https://github.com/uuid-rs/uuid"

+version = "0.8.2" # remember to update html_root_url in lib.rs

+

+[package.metadata.docs.rs]

+features = [ "guid", "serde", "slog", "v1", "v3", "v4", "v5" ]

+default-target = "x86_64-pc-windows-msvc"

+

+[package.metadata.playground]

+features = ["serde", "v1", "v3", "v4", "v5"]

+

+[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"

+

+[dependencies.getrandom]

+optional = true

+version = "0.2.0"

+

+[dependencies.md5]

+optional = true

+version = "0.7"

+

+[dependencies.serde]

+default-features = false

+optional = true

+version = "1.0.56"

+

+[dependencies.sha1]

+optional = true

+version = "0.6"

+

+[dependencies.slog]

+optional = true

+version = "2"

+

+[dev-dependencies.bincode]

+version = "1.0"

+

+[dev-dependencies.serde_derive]

+version = "1.0.79"

+

+[dev-dependencies.serde_json]

+version = "1.0"

+

+[dev-dependencies.serde_test]

+version = "1.0.56"

+

+[features]

+default = ["std"]

+guid = ["winapi"]

+std = []

+stdweb = ["getrandom", "getrandom/js"]

+v1 = []

+v3 = ["md5"]

+v4 = ["getrandom"]

+v5 = ["sha1"]

+wasm-bindgen = ["getrandom", "getrandom/js"]

+

+[target.'cfg(windows)'.dependencies.winapi]

+optional = true

+version = "0.3"

+

diff --git a/LICENSE b/LICENSE
new file mode 120000
index 0000000..6b579aa
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1 @@
+LICENSE-APACHE
\ No newline at end of file
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
new file mode 100644
index 0000000..f47c941
--- /dev/null
+++ b/LICENSE-APACHE
@@ -0,0 +1,201 @@
+                              Apache License

+                        Version 2.0, January 2004

+                     http://www.apache.org/licenses/

+

+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

+

+1. Definitions.

+

+   "License" shall mean the terms and conditions for use, reproduction,

+   and distribution as defined by Sections 1 through 9 of this document.

+

+   "Licensor" shall mean the copyright owner or entity authorized by

+   the copyright owner that is granting the License.

+

+   "Legal Entity" shall mean the union of the acting entity and all

+   other entities that control, are controlled by, or are under common

+   control with that entity. For the purposes of this definition,

+   "control" means (i) the power, direct or indirect, to cause the

+   direction or management of such entity, whether by contract or

+   otherwise, or (ii) ownership of fifty percent (50%) or more of the

+   outstanding shares, or (iii) beneficial ownership of such entity.

+

+   "You" (or "Your") shall mean an individual or Legal Entity

+   exercising permissions granted by this License.

+

+   "Source" form shall mean the preferred form for making modifications,

+   including but not limited to software source code, documentation

+   source, and configuration files.

+

+   "Object" form shall mean any form resulting from mechanical

+   transformation or translation of a Source form, including but

+   not limited to compiled object code, generated documentation,

+   and conversions to other media types.

+

+   "Work" shall mean the work of authorship, whether in Source or

+   Object form, made available under the License, as indicated by a

+   copyright notice that is included in or attached to the work

+   (an example is provided in the Appendix below).

+

+   "Derivative Works" shall mean any work, whether in Source or Object

+   form, that is based on (or derived from) the Work and for which the

+   editorial revisions, annotations, elaborations, or other modifications

+   represent, as a whole, an original work of authorship. For the purposes

+   of this License, Derivative Works shall not include works that remain

+   separable from, or merely link (or bind by name) to the interfaces of,

+   the Work and Derivative Works thereof.

+

+   "Contribution" shall mean any work of authorship, including

+   the original version of the Work and any modifications or additions

+   to that Work or Derivative Works thereof, that is intentionally

+   submitted to Licensor for inclusion in the Work by the copyright owner

+   or by an individual or Legal Entity authorized to submit on behalf of

+   the copyright owner. For the purposes of this definition, "submitted"

+   means any form of electronic, verbal, or written communication sent

+   to the Licensor or its representatives, including but not limited to

+   communication on electronic mailing lists, source code control systems,

+   and issue tracking systems that are managed by, or on behalf of, the

+   Licensor for the purpose of discussing and improving the Work, but

+   excluding communication that is conspicuously marked or otherwise

+   designated in writing by the copyright owner as "Not a Contribution."

+

+   "Contributor" shall mean Licensor and any individual or Legal Entity

+   on behalf of whom a Contribution has been received by Licensor and

+   subsequently incorporated within the Work.

+

+2. Grant of Copyright License. Subject to the terms and conditions of

+   this License, each Contributor hereby grants to You a perpetual,

+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+   copyright license to reproduce, prepare Derivative Works of,

+   publicly display, publicly perform, sublicense, and distribute the

+   Work and such Derivative Works in Source or Object form.

+

+3. Grant of Patent License. Subject to the terms and conditions of

+   this License, each Contributor hereby grants to You a perpetual,

+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable

+   (except as stated in this section) patent license to make, have made,

+   use, offer to sell, sell, import, and otherwise transfer the Work,

+   where such license applies only to those patent claims licensable

+   by such Contributor that are necessarily infringed by their

+   Contribution(s) alone or by combination of their Contribution(s)

+   with the Work to which such Contribution(s) was submitted. If You

+   institute patent litigation against any entity (including a

+   cross-claim or counterclaim in a lawsuit) alleging that the Work

+   or a Contribution incorporated within the Work constitutes direct

+   or contributory patent infringement, then any patent licenses

+   granted to You under this License for that Work shall terminate

+   as of the date such litigation is filed.

+

+4. Redistribution. You may reproduce and distribute copies of the

+   Work or Derivative Works thereof in any medium, with or without

+   modifications, and in Source or Object form, provided that You

+   meet the following conditions:

+

+   (a) You must give any other recipients of the Work or

+       Derivative Works a copy of this License; and

+

+   (b) You must cause any modified files to carry prominent notices

+       stating that You changed the files; and

+

+   (c) You must retain, in the Source form of any Derivative Works

+       that You distribute, all copyright, patent, trademark, and

+       attribution notices from the Source form of the Work,

+       excluding those notices that do not pertain to any part of

+       the Derivative Works; and

+

+   (d) If the Work includes a "NOTICE" text file as part of its

+       distribution, then any Derivative Works that You distribute must

+       include a readable copy of the attribution notices contained

+       within such NOTICE file, excluding those notices that do not

+       pertain to any part of the Derivative Works, in at least one

+       of the following places: within a NOTICE text file distributed

+       as part of the Derivative Works; within the Source form or

+       documentation, if provided along with the Derivative Works; or,

+       within a display generated by the Derivative Works, if and

+       wherever such third-party notices normally appear. The contents

+       of the NOTICE file are for informational purposes only and

+       do not modify the License. You may add Your own attribution

+       notices within Derivative Works that You distribute, alongside

+       or as an addendum to the NOTICE text from the Work, provided

+       that such additional attribution notices cannot be construed

+       as modifying the License.

+

+   You may add Your own copyright statement to Your modifications and

+   may provide additional or different license terms and conditions

+   for use, reproduction, or distribution of Your modifications, or

+   for any such Derivative Works as a whole, provided Your use,

+   reproduction, and distribution of the Work otherwise complies with

+   the conditions stated in this License.

+

+5. Submission of Contributions. Unless You explicitly state otherwise,

+   any Contribution intentionally submitted for inclusion in the Work

+   by You to the Licensor shall be under the terms and conditions of

+   this License, without any additional terms or conditions.

+   Notwithstanding the above, nothing herein shall supersede or modify

+   the terms of any separate license agreement you may have executed

+   with Licensor regarding such Contributions.

+

+6. Trademarks. This License does not grant permission to use the trade

+   names, trademarks, service marks, or product names of the Licensor,

+   except as required for reasonable and customary use in describing the

+   origin of the Work and reproducing the content of the NOTICE file.

+

+7. Disclaimer of Warranty. Unless required by applicable law or

+   agreed to in writing, Licensor provides the Work (and each

+   Contributor provides its Contributions) on an "AS IS" BASIS,

+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or

+   implied, including, without limitation, any warranties or conditions

+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A

+   PARTICULAR PURPOSE. You are solely responsible for determining the

+   appropriateness of using or redistributing the Work and assume any

+   risks associated with Your exercise of permissions under this License.

+

+8. Limitation of Liability. In no event and under no legal theory,

+   whether in tort (including negligence), contract, or otherwise,

+   unless required by applicable law (such as deliberate and grossly

+   negligent acts) or agreed to in writing, shall any Contributor be

+   liable to You for damages, including any direct, indirect, special,

+   incidental, or consequential damages of any character arising as a

+   result of this License or out of the use or inability to use the

+   Work (including but not limited to damages for loss of goodwill,

+   work stoppage, computer failure or malfunction, or any and all

+   other commercial damages or losses), even if such Contributor

+   has been advised of the possibility of such damages.

+

+9. Accepting Warranty or Additional Liability. While redistributing

+   the Work or Derivative Works thereof, You may choose to offer,

+   and charge a fee for, acceptance of support, warranty, indemnity,

+   or other liability obligations and/or rights consistent with this

+   License. However, in accepting such obligations, You may act only

+   on Your own behalf and on Your sole responsibility, not on behalf

+   of any other Contributor, and only if You agree to indemnify,

+   defend, and hold each Contributor harmless for any liability

+   incurred by, or claims asserted against, such Contributor by reason

+   of your accepting any such warranty or additional liability.

+

+END OF TERMS AND CONDITIONS

+

+APPENDIX: How to apply the Apache License to your work.

+

+   To apply the Apache License to your work, attach the following

+   boilerplate notice, with the fields enclosed by brackets "[]"

+   replaced with your own identifying information. (Don't include

+   the brackets!)  The text should be enclosed in the appropriate

+   comment syntax for the file format. We also recommend that a

+   file or class name and description of purpose be included on the

+   same "printed page" as the copyright notice for easier

+   identification within third-party archives.

+

+Copyright [yyyy] [name of copyright owner]

+

+Licensed under the Apache License, Version 2.0 (the "License");

+you may not use this file except in compliance with the License.

+You may obtain a copy of the License at

+

+	http://www.apache.org/licenses/LICENSE-2.0

+

+Unless required by applicable law or agreed to in writing, software

+distributed under the License is distributed on an "AS IS" BASIS,

+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+See the License for the specific language governing permissions and

+limitations under the License.

diff --git a/LICENSE-MIT b/LICENSE-MIT
new file mode 100644
index 0000000..21d90fa
--- /dev/null
+++ b/LICENSE-MIT
@@ -0,0 +1,26 @@
+Copyright (c) 2014 The Rust Project Developers

+Copyright (c) 2018 Ashley Mannix, Christopher Armstrong, Dylan DPC, Hunar Roop Kahlon

+

+Permission is hereby granted, free of charge, to any

+person obtaining a copy of this software and associated

+documentation files (the "Software"), to deal in the

+Software without restriction, including without

+limitation the rights to use, copy, modify, merge,

+publish, distribute, sublicense, and/or sell copies of

+the Software, and to permit persons to whom the Software

+is furnished to do so, subject to the following

+conditions:

+

+The above copyright notice and this permission notice

+shall be included in all copies or substantial portions

+of the Software.

+

+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF

+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED

+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A

+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT

+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY

+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION

+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR

+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER

+DEALINGS IN THE SOFTWARE.

diff --git a/METADATA b/METADATA
new file mode 100644
index 0000000..4d608b1
--- /dev/null
+++ b/METADATA
@@ -0,0 +1,20 @@
+name: "uuid"
+description: "A library to generate and parse UUIDs."
+third_party {
+  url {
+    type: HOMEPAGE
+    value: "https://crates.io/crates/uuid"
+  }
+  url {
+    type: ARCHIVE
+    value: "https://static.crates.io/crates/uuid/uuid-0.8.2.crate"
+  }
+  version: "0.8.2"
+  # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same.
+  license_type: NOTICE
+  last_upgrade_date {
+    year: 2021
+    month: 3
+    day: 12
+  }
+}
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/OWNERS b/OWNERS
new file mode 100644
index 0000000..46fc303
--- /dev/null
+++ b/OWNERS
@@ -0,0 +1 @@
+include platform/prebuilts/rust:/OWNERS
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..1592ffd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,141 @@
+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.34.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")

+[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fuuid-rs%2Fuuid.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fuuid-rs%2Fuuid?ref=badge_shield)

+

+---

+

+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 they 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,

+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.

+

+## 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-unknown-unknown` target:

+

+* `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`]

+

+By default, `uuid` can be depended on with:

+

+```toml

+[dependencies]

+uuid = "0.8"

+```

+

+To activate various features, use syntax like:

+

+```toml

+[dependencies]

+uuid = { version = "0.8", features = ["serde", "v4"] }

+```

+

+You can disable default features with:

+

+```toml

+[dependencies]

+uuid = { version = "0.8", default-features = false }

+```

+

+## Examples

+

+To parse a UUID given in the simple format and print it as a urn:

+

+```rust

+use uuid::Uuid;

+

+fn main() -> Result<(), uuid::Error> {

+    let my_uuid =

+        Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8")?;

+    println!("{}", my_uuid.to_urn());

+    Ok(())

+}

+```

+

+To create a new random (V4) UUID and print it out in hexadecimal form:

+

+```rust

+// Note that this requires the `v4` feature enabled in the uuid crate.

+

+use uuid::Uuid;

+

+fn main() {

+    let my_uuid = Uuid::new_v4();

+    println!("{}", my_uuid);

+    Ok(())

+}

+```

+

+## Strings

+

+Examples of string representations:

+

+* simple: `936DA01F9ABD4d9d80C702AF85C822A8`

+* hyphenated: `550e8400-e29b-41d4-a716-446655440000`

+* urn: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4`

+

+## 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)

+

+[`wasm-bindgen`]: https://github.com/rustwasm/wasm-bindgen

+

+[`Uuid`]: https://docs.rs/uuid/0.8.2/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.

+

+

+[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fuuid-rs%2Fuuid.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fuuid-rs%2Fuuid?ref=badge_large)

+

+## 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.
\ No newline at end of file
diff --git a/README.tpl b/README.tpl
new file mode 100644
index 0000000..85faa79
--- /dev/null
+++ b/README.tpl
@@ -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.34.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 --git a/benches/format_str.rs b/benches/format_str.rs
new file mode 100644
index 0000000..0ae576d
--- /dev/null
+++ b/benches/format_str.rs
@@ -0,0 +1,66 @@
+#![feature(test)]

+extern crate test;

+

+use std::io::Write;

+use test::Bencher;

+use uuid::Uuid;

+

+#[bench]

+fn bench_hyphen(b: &mut Bencher) {

+    let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap();

+    b.iter(|| {

+        let mut buffer = [0_u8; 36];

+        write!(&mut buffer as &mut [_], "{:x}", uuid.to_hyphenated()).unwrap();

+        test::black_box(buffer);

+    });

+}

+

+#[bench]

+fn bench_simple(b: &mut Bencher) {

+    let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap();

+    b.iter(|| {

+        let mut buffer = [0_u8; 32];

+        write!(&mut buffer as &mut [_], "{:x}", uuid.to_simple()).unwrap();

+        test::black_box(buffer);

+    })

+}

+

+#[bench]

+fn bench_urn(b: &mut Bencher) {

+    let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap();

+    b.iter(|| {

+        let mut buffer = [0_u8; 36 + 9];

+        write!(&mut buffer as &mut [_], "{:x}", uuid.to_urn()).unwrap();

+        test::black_box(buffer);

+    })

+}

+

+#[bench]

+fn bench_encode_hyphen(b: &mut Bencher) {

+    let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap();

+    b.iter(|| {

+        let mut buffer = [0_u8; 36];

+        uuid.to_hyphenated().encode_lower(&mut buffer);

+        test::black_box(buffer);

+    });

+}

+

+#[bench]

+fn bench_encode_simple(b: &mut Bencher) {

+    let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap();

+    b.iter(|| {

+        let mut buffer = [0_u8; 32];

+        uuid.to_simple().encode_lower(&mut buffer);

+        test::black_box(buffer);

+    })

+}

+

+#[bench]

+fn bench_encode_urn(b: &mut Bencher) {

+    let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap();

+    b.iter(|| {

+        let mut buffer = [0_u8; 36 + 9];

+        uuid.to_urn().encode_lower(&mut buffer);

+        test::black_box(buffer);

+    })

+}

diff --git a/benches/invalid_parse_str.rs b/benches/invalid_parse_str.rs
new file mode 100644
index 0000000..447fa80
--- /dev/null
+++ b/benches/invalid_parse_str.rs
@@ -0,0 +1,58 @@
+#![feature(test)]

+extern crate test;

+

+use test::Bencher;

+use uuid::Uuid;

+

+#[bench]

+fn bench_parse_invalid_strings(b: &mut Bencher) {

+    b.iter(|| {

+        let _ = Uuid::parse_str("");

+        let _ = Uuid::parse_str("!");

+        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45");

+        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4");

+        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4");

+        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4");

+        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa");

+        let _ = Uuid::parse_str("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4");

+        let _ = Uuid::parse_str("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4");

+        let _ = Uuid::parse_str("01020304-1112-2122-3132-41424344");

+        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c88");

+        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0cg8");

+        let _ = Uuid::parse_str("67e5504410b1426%9247bb680e5fe0c8");

+

+        // Test error reporting

+        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c");

+        let _ = Uuid::parse_str("67e550X410b1426f9247bb680e5fe0cd");

+        let _ = Uuid::parse_str("67e550-4105b1426f9247bb680e5fe0c");

+        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4");

+    });

+}

+

+#[bench]

+fn bench_parse_invalid_len(b: &mut Bencher) {

+    b.iter(|| {

+        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4");

+    })

+}

+

+#[bench]

+fn bench_parse_invalid_character(b: &mut Bencher) {

+    b.iter(|| {

+        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4");

+    })

+}

+

+#[bench]

+fn bench_parse_invalid_group_len(b: &mut Bencher) {

+    b.iter(|| {

+        let _ = Uuid::parse_str("01020304-1112-2122-3132-41424344");

+    });

+}

+

+#[bench]

+fn bench_parse_invalid_groups(b: &mut Bencher) {

+    b.iter(|| {

+        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4");

+    });

+}

diff --git a/benches/mod.rs b/benches/mod.rs
new file mode 100644
index 0000000..61045c6
--- /dev/null
+++ b/benches/mod.rs
@@ -0,0 +1,4 @@
+#![feature(test)]

+

+#[cfg(feature = "slog")]

+pub mod slog_support;

diff --git a/benches/serde_support.rs b/benches/serde_support.rs
new file mode 100644
index 0000000..9ec38a6
--- /dev/null
+++ b/benches/serde_support.rs
@@ -0,0 +1,48 @@
+#![cfg(feature = "serde")]

+#![feature(test)]

+

+use bincode;

+use serde_json;

+extern crate test;

+

+use test::Bencher;

+use uuid::Uuid;

+

+#[bench]

+fn bench_json_encode(b: &mut Bencher) {

+    let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap();

+    let mut buffer = [0_u8; 38];

+    b.iter(|| {

+        serde_json::to_writer(&mut buffer as &mut [u8], &uuid).unwrap();

+        test::black_box(buffer);

+    });

+    b.bytes = buffer.len() as u64;

+}

+

+#[bench]

+fn bench_json_decode(b: &mut Bencher) {

+    let s = "\"F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4\"";

+    b.iter(|| serde_json::from_str::<Uuid>(s).unwrap());

+    b.bytes = s.len() as u64;

+}

+

+#[bench]

+fn bench_bincode_encode(b: &mut Bencher) {

+    let uuid = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4").unwrap();

+    let mut buffer = [0_u8; 24];

+    b.iter(|| {

+        bincode::serialize_into(&mut buffer as &mut [u8], &uuid).unwrap();

+        test::black_box(buffer);

+    });

+    b.bytes = buffer.len() as u64;

+}

+

+#[bench]

+fn bench_bincode_decode(b: &mut Bencher) {

+    let bytes = [

+        16, 0, 0, 0, 0, 0, 0, 0, 249, 22, 140, 94, 206, 178, 79, 170, 182, 191,

+        50, 155, 243, 159, 161, 228,

+    ];

+    b.iter(|| bincode::deserialize::<Uuid>(&bytes).unwrap());

+    b.bytes = bytes.len() as u64;

+}

diff --git a/benches/slog_support/mod.rs b/benches/slog_support/mod.rs
new file mode 100644
index 0000000..12b38c8
--- /dev/null
+++ b/benches/slog_support/mod.rs
@@ -0,0 +1 @@
+pub mod parse_str;

diff --git a/benches/slog_support/parse_str.rs b/benches/slog_support/parse_str.rs
new file mode 100644
index 0000000..1c837f5
--- /dev/null
+++ b/benches/slog_support/parse_str.rs
@@ -0,0 +1,15 @@
+extern crate test;

+

+#[bench]

+#[cfg(feature = "slog")]

+pub fn bench_log_discard_kv(b: &mut test::Bencher) {

+    let u1 =

+        uuid::Uuid::parse_str("F9168C5E-CEB2-4FAB-B6BF-329BF39FA1E4").unwrap();

+    let root =

+        slog::Logger::root(::slog::Drain::fuse(::slog::Discard), slog::o!());

+

+    b.iter(|| {

+        #[cfg(feature = "slog")]

+        slog::crit!(root, "test"; "u1" => u1);

+    });

+}

diff --git a/benches/valid_parse_str.rs b/benches/valid_parse_str.rs
new file mode 100644
index 0000000..7e36676
--- /dev/null
+++ b/benches/valid_parse_str.rs
@@ -0,0 +1,39 @@
+#![feature(test)]

+

+extern crate test;

+

+use test::Bencher;

+use uuid::Uuid;

+

+#[bench]

+fn bench_parse_valid_strings(b: &mut Bencher) {

+    b.iter(|| {

+        // Valid

+        let _ = Uuid::parse_str("00000000000000000000000000000000");

+        let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8");

+        let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8");

+        let _ = Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4");

+        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8");

+        let _ = Uuid::parse_str("01020304-1112-2122-3132-414243444546");

+        let _ =

+            Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8");

+

+        // Nil

+        let _ = Uuid::parse_str("00000000000000000000000000000000");

+        let _ = Uuid::parse_str("00000000-0000-0000-0000-000000000000");

+    });

+}

+

+#[bench]

+fn bench_valid_hyphenated(b: &mut Bencher) {

+    b.iter(|| {

+        let _ = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8");

+    });

+}

+

+#[bench]

+fn bench_valid_short(b: &mut Bencher) {

+    b.iter(|| {

+        let _ = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8");

+    });

+}

diff --git a/src/adapter/compact.rs b/src/adapter/compact.rs
new file mode 100644
index 0000000..1b53682
--- /dev/null
+++ b/src/adapter/compact.rs
@@ -0,0 +1,81 @@
+//! 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<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>

+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<crate::Uuid, D::Error>

+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_derive::Serialize, Debug, serde_derive::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 --git a/src/adapter/mod.rs b/src/adapter/mod.rs
new file mode 100644
index 0000000..412920e
--- /dev/null
+++ b/src/adapter/mod.rs
@@ -0,0 +1,1027 @@
+// 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 <LICENSE-APACHE or

+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license

+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your

+// option. This file may not be copied, modified, or distributed

+// except according to those terms.

+

+//! Adapters for various formats for UUIDs

+

+use crate::prelude::*;

+use crate::std::{fmt, str};

+

+#[cfg(feature = "serde")]

+pub mod compact;

+

+/// An adaptor for formatting an [`Uuid`] as a hyphenated string.

+///

+/// Takes an owned instance of the [`Uuid`].

+///

+/// [`Uuid`]: ../struct.Uuid.html

+#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]

+pub struct Hyphenated(Uuid);

+

+/// An adaptor for formatting an [`Uuid`] as a hyphenated string.

+///

+/// Takes a reference of the [`Uuid`].

+///

+/// [`Uuid`]: ../struct.Uuid.html

+#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]

+pub struct HyphenatedRef<'a>(&'a Uuid);

+

+/// An adaptor for formatting an [`Uuid`] as a simple string.

+///

+/// Takes an owned instance of the [`Uuid`].

+///

+/// [`Uuid`]: ../struct.Uuid.html

+#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]

+pub struct Simple(Uuid);

+

+/// An adaptor for formatting an [`Uuid`] as a simple string.

+///

+/// Takes a reference of the [`Uuid`].

+///

+/// [`Uuid`]: ../struct.Uuid.html

+#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]

+pub struct SimpleRef<'a>(&'a Uuid);

+

+/// An adaptor for formatting an [`Uuid`] as a URN string.

+///

+/// Takes an owned instance of the [`Uuid`].

+///

+/// [`Uuid`]: ../struct.Uuid.html

+#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]

+pub struct Urn(Uuid);

+

+/// An adaptor for formatting an [`Uuid`] as a URN string.

+///

+/// Takes a reference of the [`Uuid`].

+///

+/// [`Uuid`]: ../struct.Uuid.html

+#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]

+pub struct UrnRef<'a>(&'a Uuid);

+

+impl Uuid {

+    /// Get a [`Hyphenated`] formatter.

+    ///

+    /// [`Hyphenated`]: adapter/struct.Hyphenated.html

+    #[inline]

+    pub const fn to_hyphenated(self) -> Hyphenated {

+        Hyphenated::from_uuid(self)

+    }

+

+    /// Get a borrowed [`HyphenatedRef`] formatter.

+    ///

+    /// [`HyphenatedRef`]: adapter/struct.HyphenatedRef.html

+    #[inline]

+    pub const fn to_hyphenated_ref(&self) -> HyphenatedRef<'_> {

+        HyphenatedRef::from_uuid_ref(self)

+    }

+

+    /// Get a [`Simple`] formatter.

+    ///

+    /// [`Simple`]: adapter/struct.Simple.html

+    #[inline]

+    pub const fn to_simple(self) -> Simple {

+        Simple::from_uuid(self)

+    }

+

+    /// Get a borrowed [`SimpleRef`] formatter.

+    ///

+    /// [`SimpleRef`]: adapter/struct.SimpleRef.html

+    #[inline]

+    pub const fn to_simple_ref(&self) -> SimpleRef<'_> {

+        SimpleRef::from_uuid_ref(self)

+    }

+

+    /// Get a [`Urn`] formatter.

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    /// [`Urn`]: adapter/struct.Urn.html

+    #[inline]

+    pub const fn to_urn(self) -> Urn {

+        Urn::from_uuid(self)

+    }

+

+    /// Get a borrowed [`UrnRef`] formatter.

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    /// [`UrnRef`]: adapter/struct.UrnRef.html

+    #[inline]

+    pub const fn to_urn_ref(&self) -> UrnRef<'_> {

+        UrnRef::from_uuid_ref(self)

+    }

+}

+

+const UPPER: [u8; 16] = [

+    b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'A', b'B',

+    b'C', b'D', b'E', b'F',

+];

+const LOWER: [u8; 16] = [

+    b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9', b'a', b'b',

+    b'c', b'd', b'e', b'f',

+];

+/// The segments of a UUID's [u8; 16] corresponding to each group.

+const BYTE_POSITIONS: [usize; 6] = [0, 4, 6, 8, 10, 16];

+/// The locations that hyphens are written into the buffer, after each

+/// group.

+const HYPHEN_POSITIONS: [usize; 4] = [8, 13, 18, 23];

+

+/// Encodes the `uuid` possibly with hyphens, and possibly in upper

+/// case, to full_buffer[start..] and returns the str sliced from

+/// full_buffer[..start + encoded_length].

+///

+/// The `start` parameter allows writing a prefix (such as

+/// "urn:uuid:") to the buffer that's included in the final encoded

+/// UUID.

+#[allow(clippy::needless_range_loop)]

+fn encode<'a>(

+    full_buffer: &'a mut [u8],

+    start: usize,

+    uuid: &Uuid,

+    hyphens: bool,

+    upper: bool,

+) -> &'a mut str {

+    let len = if hyphens { 36 } else { 32 };

+

+    {

+        let buffer = &mut full_buffer[start..start + len];

+        let bytes = uuid.as_bytes();

+

+        let hex = if upper { &UPPER } else { &LOWER };

+

+        for group in 0..5 {

+            // If we're writing hyphens, we need to shift the output

+            // location along by how many of them have been written

+            // 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] = hex[(b >> 4) as usize];

+                buffer[out_idx + 1] = hex[(b & 0b1111) as usize];

+            }

+

+            if group != 4 && hyphens {

+                buffer[HYPHEN_POSITIONS[group]] = b'-';

+            }

+        }

+    }

+

+    str::from_utf8_mut(&mut full_buffer[..start + len])

+        .expect("found non-ASCII output characters while encoding a UUID")

+}

+

+impl Hyphenated {

+    /// The length of a hyphenated [`Uuid`] string.

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    pub const LENGTH: usize = 36;

+

+    /// Creates a [`Hyphenated`] from a [`Uuid`].

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    /// [`Hyphenated`]: struct.Hyphenated.html

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {

+        encode(buffer, 0, &self.0, true, true)

+    }

+}

+

+impl<'a> HyphenatedRef<'a> {

+    /// The length of a hyphenated [`Uuid`] string.

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    pub const LENGTH: usize = 36;

+

+    /// Creates a [`HyphenatedRef`] from a [`Uuid`] reference.

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    /// [`HyphenatedRef`]: struct.HyphenatedRef.html

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {

+        encode(buffer, 0, self.0, true, true)

+    }

+}

+

+impl Simple {

+    /// The length of a simple [`Uuid`] string.

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    pub const LENGTH: usize = 32;

+

+    /// Creates a [`Simple`] from a [`Uuid`].

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    /// [`Simple`]: struct.Simple.html

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {

+        encode(buffer, 0, &self.0, false, true)

+    }

+}

+

+impl<'a> SimpleRef<'a> {

+    /// The length of a simple [`Uuid`] string.

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    pub const LENGTH: usize = 32;

+

+    /// Creates a [`SimpleRef`] from a [`Uuid`] reference.

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    /// [`SimpleRef`]: struct.SimpleRef.html

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    pub fn encode_upper<'buf>(&self, buffer: &'buf mut [u8]) -> &'buf mut str {

+        encode(buffer, 0, self.0, false, true)

+    }

+}

+

+impl Urn {

+    /// The length of a URN [`Uuid`] string.

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    pub const LENGTH: usize = 45;

+

+    /// Creates a [`Urn`] from a [`Uuid`].

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    /// [`Urn`]: struct.Urn.html

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///     

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    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)

+    }

+}

+

+impl<'a> UrnRef<'a> {

+    /// The length of a URN [`Uuid`] string.

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    pub const LENGTH: usize = 45;

+

+    /// Creates a [`UrnRef`] from a [`Uuid`] reference.

+    ///

+    /// [`Uuid`]: ../struct.Uuid.html

+    /// [`UrnRef`]: struct.UrnRef.html

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936DA01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936da01f9abd4d9d80c702af85c822a8")?;

+    ///

+    ///     // 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 &[_]

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    /// */

+    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)

+    }

+}

+

+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<Uuid> 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 --git a/src/builder/error.rs b/src/builder/error.rs
new file mode 100644
index 0000000..ec7c2ac
--- /dev/null
+++ b/src/builder/error.rs
@@ -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 --git a/src/builder/mod.rs b/src/builder/mod.rs
new file mode 100644
index 0000000..4360964
--- /dev/null
+++ b/src/builder/mod.rs
@@ -0,0 +1,473 @@
+// 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 <LICENSE-APACHE or

+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license

+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<Uuid, crate::Error> {

+        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<Uuid, crate::Error> {

+        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<Uuid, crate::Error> {

+        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();

+/// ```

+// TODO: remove in 1.0.0

+#[allow(dead_code)]

+#[deprecated]

+pub type Builder = crate::Builder;

+

+impl crate::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<Self, crate::Error> {

+        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<Self, crate::Error> {

+        Uuid::from_fields(d1, d2, d3, d4).map(|uuid| {

+            let bytes = *uuid.as_bytes();

+

+            crate::Builder::from_bytes(bytes)

+        })

+    }

+

+    /// Creates a `Builder` from a big-endian 128bit value.

+    pub fn from_u128(v: u128) -> Self {

+        crate::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 {

+        Uuid::from_bytes(self.0)

+    }

+}

diff --git a/src/error.rs b/src/error.rs
new file mode 100644
index 0000000..59f3f5e
--- /dev/null
+++ b/src/error.rs
@@ -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<builder::Error> for Error {

+    fn from(err: builder::Error) -> Self {

+        Error(Inner::Build(err))

+    }

+}

+

+impl From<parser::Error> 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 --git a/src/lib.rs b/src/lib.rs
new file mode 100644
index 0000000..51d3877
--- /dev/null
+++ b/src/lib.rs
@@ -0,0 +1,1070 @@
+// 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 <LICENSE-APACHE or

+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license

+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your

+// option. This file may not be copied, modified, or distributed

+// except according to those terms.

+

+//! 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,

+//! 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.

+//!

+//! # Dependencies

+//!

+//! By default, this crate depends on nothing but `std` and cannot generate

+//! 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 [`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

+//!   UUID based on the SHA1 hash of some data.

+//! * `serde` - adds the ability to serialize and deserialize a UUID using the

+//!   `serde` crate.

+//!

+//! For WebAssembly, enable one of the following features depending

+//! on your JavaScript interop toolchain of choice:

+//!

+//! * `stdweb` - for [`stdweb`] combined with [`cargo-web`]

+//! * `wasm-bindgen` - for [`wasm-bindgen`]

+//!

+//! By default, `uuid` can be depended on with:

+//!

+//! ```toml

+//! [dependencies]

+//! uuid = "0.8"

+//! ```

+//!

+//! To activate various features, use syntax like:

+//!

+//! ```toml

+//! [dependencies]

+//! uuid = { version = "0.8", features = ["serde", "v4"] }

+//! ```

+//!

+//! You can disable default features with:

+//!

+//! ```toml

+//! [dependencies]

+//! uuid = { version = "0.8", default-features = false }

+//! ```

+//!

+//! # Examples

+//!

+//! To parse a UUID given in the simple format and print it as a urn:

+//!

+//! ```rust

+//! use uuid::Uuid;

+//!

+//! fn main() -> Result<(), uuid::Error> {

+//!     let my_uuid =

+//!         Uuid::parse_str("936DA01F9ABD4d9d80C702AF85C822A8")?;

+//!     println!("{}", my_uuid.to_urn());

+//!     Ok(())

+//! }

+//! ```

+//!

+//! To create a new random (V4) UUID and print it out in hexadecimal form:

+//!

+//! ```ignore,rust

+//! // Note that this requires the `v4` feature enabled in the uuid crate.

+//!

+//! use uuid::Uuid;

+//!

+//! fn main() -> Result<(), Box<dyn std::error::Error>> {

+//!     #[cfg(feature = "v4")] {

+//!         let my_uuid = Uuid::new_v4()?;

+//!         println!("{}", my_uuid);

+//!     }

+//!     Ok(())

+//! }

+//! ```

+//!

+//! # Strings

+//!

+//! Examples of string representations:

+//!

+//! * simple: `936DA01F9ABD4d9d80C702AF85C822A8`

+//! * hyphenated: `550e8400-e29b-41d4-a716-446655440000`

+//! * urn: `urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4`

+//!

+//! # 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)

+//!

+//! [`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/0.8.2"

+)]

+

+#[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;

+#[cfg(feature = "v1")]

+pub mod v1;

+

+#[cfg(feature = "serde")]

+mod serde_support;

+#[cfg(feature = "slog")]

+mod slog_support;

+#[cfg(test)]

+mod test_util;

+#[cfg(all(

+    feature = "v3",

+    any(

+        not(target_arch = "wasm32"),

+        target_os = "wasi",

+        all(

+            target_arch = "wasm32",

+            any(feature = "stdweb", feature = "wasm-bindgen")

+        )

+    )

+))]

+mod v3;

+#[cfg(all(

+    feature = "v4",

+    any(

+        not(target_arch = "wasm32"),

+        target_os = "wasi",

+        all(

+            target_arch = "wasm32",

+            any(feature = "stdweb", feature = "wasm-bindgen")

+        )

+    )

+))]

+mod v4;

+#[cfg(all(

+    feature = "v5",

+    any(

+        not(target_arch = "wasm32"),

+        target_os = "wasi",

+        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::error::Error;

+

+/// 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(Bytes);

+

+/// A 128-bit (16 byte) buffer containing the ID.

+pub type Bytes = [u8; 16];

+

+/// The version of the UUID, denoting the generating algorithm.

+#[derive(Clone, Copy, Debug, PartialEq)]

+pub enum Version {

+    /// Special case for `nil` UUID.

+    Nil = 0,

+    /// Version 1: MAC address.

+    Mac,

+    /// Version 2: DCE Security.

+    Dce,

+    /// Version 3: MD5 hash.

+    Md5,

+    /// Version 4: Random.

+    Random,

+    /// Version 5: SHA-1 hash.

+    Sha1,

+}

+

+/// The reserved variants of UUIDs.

+#[derive(Clone, Copy, Debug, PartialEq)]

+pub enum Variant {

+    /// Reserved by the NCS for backward compatibility.

+    NCS = 0,

+    /// As described in the RFC4122 Specification (default).

+    RFC4122,

+    /// Reserved by Microsoft for backward compatibility.

+    Microsoft,

+    /// Reserved for future expansion.

+    Future,

+}

+

+/// A Universally Unique Identifier (UUID).

+#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]

+#[repr(transparent)]

+pub struct Uuid(Bytes);

+

+impl Uuid {

+    /// 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).

+    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).

+    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).

+    pub const NAMESPACE_X500: Self = Uuid([

+        0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0,

+        0x4f, 0xd4, 0x30, 0xc8,

+    ]);

+

+    /// 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.

+    ///

+    /// * [Variant Reference](http://tools.ietf.org/html/rfc4122#section-4.1.1)

+    pub fn get_variant(&self) -> Option<Variant> {

+        match self.as_bytes()[8] {

+            x if x & 0x80 == 0x00 => Some(Variant::NCS),

+            x if x & 0xc0 == 0x80 => Some(Variant::RFC4122),

+            x if x & 0xe0 == 0xc0 => Some(Variant::Microsoft),

+            x if x & 0xe0 == 0xe0 => Some(Variant::Future),

+            _ => None,

+        }

+    }

+

+    /// Returns the version number of the UUID.

+    ///

+    /// This represents the algorithm used to generate the contents.

+    ///

+    /// Currently only the Random (V4) algorithm is supported by this

+    /// module.  There are security and privacy implications for using

+    /// older versions - see [Wikipedia: Universally Unique Identifier](

+    /// http://en.wikipedia.org/wiki/Universally_unique_identifier) for

+    /// details.

+    ///

+    /// * [Version Reference](http://tools.ietf.org/html/rfc4122#section-4.1.3)

+    pub const fn get_version_num(&self) -> usize {

+        (self.as_bytes()[6] >> 4) as usize

+    }

+

+    /// Returns the version of the UUID.

+    ///

+    /// This represents the algorithm used to generate the contents

+    pub fn get_version(&self) -> Option<Version> {

+        let v = self.as_bytes()[6] >> 4;

+        match v {

+            0 if self.is_nil() => Some(Version::Nil),

+            1 => Some(Version::Mac),

+            2 => Some(Version::Dce),

+            3 => Some(Version::Md5),

+            4 => Some(Version::Random),

+            5 => Some(Version::Sha1),

+            _ => None,

+        }

+    }

+

+    /// 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.

+    ///

+    /// * The first field value represents the first group of (eight) hex

+    ///   digits, taken as a big-endian `u32` value.  For V1 UUIDs, this field

+    ///   represents the low 32 bits of the timestamp.

+    /// * 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.

+    ///

+    /// # Examples

+    ///

+    /// ```

+    /// use uuid::Uuid;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::nil();

+    ///     assert_eq!(uuid.as_fields(), (0, 0, 0, &[0u8; 8]));

+    ///

+    ///     let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?;

+    ///     assert_eq!(

+    ///         uuid.as_fields(),

+    ///         (

+    ///             0x936DA01F,

+    ///             0x9ABD,

+    ///             0x4D9D,

+    ///             b"\x80\xC7\x02\xAF\x85\xC8\x22\xA8"

+    ///         )

+    ///     );

+    ///

+    ///     Ok(())

+    /// }

+    /// ```

+    pub fn as_fields(&self) -> (u32, u16, u16, &[u8; 8]) {

+        let d1 = u32::from(self.as_bytes()[0]) << 24

+            | u32::from(self.as_bytes()[1]) << 16

+            | u32::from(self.as_bytes()[2]) << 8

+            | u32::from(self.as_bytes()[3]);

+

+        let d2 =

+            u16::from(self.as_bytes()[4]) << 8 | u16::from(self.as_bytes()[5]);

+

+        let d3 =

+            u16::from(self.as_bytes()[6]) << 8 | u16::from(self.as_bytes()[7]);

+

+        let d4: &[u8; 8] =

+            unsafe { &*(self.as_bytes()[8..16].as_ptr() as *const [u8; 8]) };

+        (d1, d2, d3, d4)

+    }

+

+    /// 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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?;

+    ///     assert_eq!(

+    ///         uuid.to_fields_le(),

+    ///         (

+    ///             0x1FA06D93,

+    ///             0xBD9A,

+    ///             0x9D4D,

+    ///             b"\x80\xC7\x02\xAF\x85\xC8\x22\xA8"

+    ///         )

+    ///     );

+    ///     Ok(())

+    /// }

+    /// ```

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?;

+    ///     assert_eq!(

+    ///         uuid.as_u128(),

+    ///         0x936DA01F9ABD4D9D80C702AF85C822A8,

+    ///     );

+    ///     Ok(())

+    /// }

+    /// ```

+    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;

+    ///

+    /// fn main() -> Result<(), uuid::Error> {

+    ///     let uuid = Uuid::parse_str("936DA01F-9ABD-4D9D-80C7-02AF85C822A8")?;

+    ///

+    ///     assert_eq!(

+    ///         uuid.to_u128_le(),

+    ///         0xA822C885AF02C7809D4DBD9A1FA06D93,

+    ///     );

+    ///     Ok(())

+    /// }

+    /// ```

+    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

+    }

+

+    /// 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.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 const fn encode_buffer() -> [u8; adapter::Urn::LENGTH] {

+        [0; adapter::Urn::LENGTH]

+    }

+}

+

+impl fmt::Debug for Uuid {

+    #[inline]

+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {

+        fmt::LowerHex::fmt(self, f)

+    }

+}

+

+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::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 = Error;

+

+    fn from_str(uuid_str: &str) -> Result<Self, Self::Err> {

+        Uuid::parse_str(uuid_str)

+    }

+}

+

+impl Default for Uuid {

+    #[inline]

+    fn default() -> Self {

+        Uuid::nil()

+    }

+}

+

+#[cfg(test)]

+mod tests {

+    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 == '-');

+    }

+

+    // 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() {

+        let nil = Uuid::nil();

+        let not_nil = test_util::new();

+        let from_bytes = Uuid::from_bytes([

+            4, 54, 67, 12, 43, 2, 2, 76, 32, 50, 87, 5, 1, 33, 43, 87,

+        ]);

+

+        assert_eq!(from_bytes.get_version(), None);

+

+        assert!(nil.is_nil());

+        assert!(!not_nil.is_nil());

+

+        assert_eq!(nil.get_version(), Some(Version::Nil));

+        assert_eq!(not_nil.get_version(), Some(Version::Random))

+    }

+

+    #[test]

+    fn test_predefined_namespaces() {

+        assert_eq!(

+            Uuid::NAMESPACE_DNS.to_hyphenated().to_string(),

+            "6ba7b810-9dad-11d1-80b4-00c04fd430c8"

+        );

+        assert_eq!(

+            Uuid::NAMESPACE_URL.to_hyphenated().to_string(),

+            "6ba7b811-9dad-11d1-80b4-00c04fd430c8"

+        );

+        assert_eq!(

+            Uuid::NAMESPACE_OID.to_hyphenated().to_string(),

+            "6ba7b812-9dad-11d1-80b4-00c04fd430c8"

+        );

+        assert_eq!(

+            Uuid::NAMESPACE_X500.to_hyphenated().to_string(),

+            "6ba7b814-9dad-11d1-80b4-00c04fd430c8"

+        );

+    }

+

+    #[cfg(feature = "v3")]

+    #[test]

+    fn test_get_version_v3() {

+        let uuid =

+            Uuid::new_v3(&Uuid::NAMESPACE_DNS, "rust-lang.org".as_bytes());

+

+        assert_eq!(uuid.get_version().unwrap(), Version::Md5);

+        assert_eq!(uuid.get_version_num(), 3);

+    }

+

+    #[test]

+    fn test_get_variant() {

+        let uuid1 = test_util::new();

+        let uuid2 =

+            Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000").unwrap();

+        let uuid3 =

+            Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap();

+        let uuid4 =

+            Uuid::parse_str("936DA01F9ABD4d9dC0C702AF85C822A8").unwrap();

+        let uuid5 =

+            Uuid::parse_str("F9168C5E-CEB2-4faa-D6BF-329BF39FA1E4").unwrap();

+        let uuid6 =

+            Uuid::parse_str("f81d4fae-7dec-11d0-7765-00a0c91e6bf6").unwrap();

+

+        assert_eq!(uuid1.get_variant().unwrap(), Variant::RFC4122);

+        assert_eq!(uuid2.get_variant().unwrap(), Variant::RFC4122);

+        assert_eq!(uuid3.get_variant().unwrap(), Variant::RFC4122);

+        assert_eq!(uuid4.get_variant().unwrap(), Variant::Microsoft);

+        assert_eq!(uuid5.get_variant().unwrap(), Variant::Microsoft);

+        assert_eq!(uuid6.get_variant().unwrap(), Variant::NCS);

+    }

+

+    #[test]

+    fn test_to_simple_string() {

+        let uuid1 = test_util::new();

+        let s = uuid1.to_simple().to_string();

+

+        assert_eq!(s.len(), 32);

+        assert!(s.chars().all(|c| c.is_digit(16)));

+    }

+

+    #[test]

+    fn test_to_hyphenated_string() {

+        let uuid1 = test_util::new();

+        let s = uuid1.to_hyphenated().to_string();

+

+        assert!(s.len() == 36);

+        assert!(s.chars().all(|c| c.is_digit(16) || c == '-'));

+    }

+

+    #[test]

+    fn test_upper_lower_hex() {

+        use std::fmt::Write;

+

+        let mut buf = String::new();

+        let u = test_util::new();

+

+        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);

+            };

+        }

+

+        check!(buf, "{:X}", u, 36, |c| c.is_uppercase()

+            || c.is_digit(10)

+            || c == '-');

+        check!(buf, "{:X}", u.to_hyphenated(), 36, |c| c.is_uppercase()

+            || c.is_digit(10)

+            || c == '-');

+        check!(buf, "{:X}", u.to_simple(), 32, |c| c.is_uppercase()

+            || c.is_digit(10));

+

+        check!(buf, "{:x}", u.to_hyphenated(), 36, |c| c.is_lowercase()

+            || c.is_digit(10)

+            || c == '-');

+        check!(buf, "{:x}", u.to_simple(), 32, |c| c.is_lowercase()

+            || c.is_digit(10));

+    }

+

+    #[test]

+    fn test_to_urn_string() {

+        let uuid1 = test_util::new();

+        let ss = uuid1.to_urn().to_string();

+        let s = &ss[9..];

+

+        assert!(ss.starts_with("urn:uuid:"));

+        assert_eq!(s.len(), 36);

+        assert!(s.chars().all(|c| c.is_digit(16) || c == '-'));

+    }

+

+    #[test]

+    fn test_to_simple_string_matching() {

+        let uuid1 = test_util::new();

+

+        let hs = uuid1.to_hyphenated().to_string();

+        let ss = uuid1.to_simple().to_string();

+

+        let hsn = hs.chars().filter(|&c| c != '-').collect::<String>();

+

+        assert_eq!(hsn, ss);

+    }

+

+    #[test]

+    fn test_string_roundtrip() {

+        let uuid = test_util::new();

+

+        let hs = uuid.to_hyphenated().to_string();

+        let uuid_hs = Uuid::parse_str(&hs).unwrap();

+        assert_eq!(uuid_hs, uuid);

+

+        let ss = uuid.to_string();

+        let uuid_ss = Uuid::parse_str(&ss).unwrap();

+        assert_eq!(uuid_ss, uuid);

+    }

+

+    #[test]

+    fn test_from_fields() {

+        let d1: u32 = 0xa1a2a3a4;

+        let d2: u16 = 0xb1b2;

+        let d3: u16 = 0xc1c2;

+        let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];

+

+        let u = Uuid::from_fields(d1, d2, d3, &d4).unwrap();

+

+        let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";

+        let result = u.to_simple().to_string();

+        assert_eq!(result, expected);

+    }

+

+    #[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();

+

+        assert_ne!(d1, 0);

+        assert_ne!(d2, 0);

+        assert_ne!(d3, 0);

+        assert_eq!(d4.len(), 8);

+        assert!(!d4.iter().all(|&b| b == 0));

+    }

+

+    #[test]

+    fn test_fields_roundtrip() {

+        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.as_fields();

+

+        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_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,

+            0xd4, 0xd5, 0xd6, 0xd7, 0xd8,

+        ];

+

+        let u = Uuid::from_slice(&b).unwrap();

+        let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";

+

+        assert_eq!(u.to_simple().to_string(), expected);

+    }

+

+    #[test]

+    fn test_from_bytes() {

+        let b = [

+            0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3,

+            0xd4, 0xd5, 0xd6, 0xd7, 0xd8,

+        ];

+

+        let u = Uuid::from_bytes(b);

+        let expected = "a1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8";

+

+        assert_eq!(u.to_simple().to_string(), expected);

+    }

+

+    #[test]

+    fn test_as_bytes() {

+        let u = test_util::new();

+        let ub = u.as_bytes();

+

+        assert_eq!(ub.len(), 16);

+        assert!(!ub.iter().all(|&b| b == 0));

+    }

+

+    #[test]

+    fn test_bytes_roundtrip() {

+        let b_in: crate::Bytes = [

+            0xa1, 0xa2, 0xa3, 0xa4, 0xb1, 0xb2, 0xc1, 0xc2, 0xd1, 0xd2, 0xd3,

+            0xd4, 0xd5, 0xd6, 0xd7, 0xd8,

+        ];

+

+        let u = Uuid::from_slice(&b_in).unwrap();

+

+        let b_out = u.as_bytes();

+

+        assert_eq!(&b_in, b_out);

+    }

+

+    #[test]

+    fn test_iterbytes_impl_for_uuid() {

+        let mut set = std::collections::HashSet::new();

+        let id1 = test_util::new();

+        let id2 = test_util::new2();

+        set.insert(id1.clone());

+

+        assert!(set.contains(&id1));

+        assert!(!set.contains(&id2));

+    }

+}

diff --git a/src/parser/error.rs b/src/parser/error.rs
new file mode 100644
index 0000000..01d76e8
--- /dev/null
+++ b/src/parser/error.rs
@@ -0,0 +1,149 @@
+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)]

+#[allow(clippy::enum_variant_names)]

+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 --git a/src/parser/mod.rs b/src/parser/mod.rs
new file mode 100644
index 0000000..a80f696
--- /dev/null
+++ b/src/parser/mod.rs
@@ -0,0 +1,447 @@
+// 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 <LICENSE-APACHE or

+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license

+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your

+// option. This file may not be copied, modified, or distributed

+// except according to those terms.

+

+//! [`Uuid`] parsing constructs and utilities.

+//!

+//! [`Uuid`]: ../struct.Uuid.html

+

+pub(crate) mod error;

+pub(crate) use self::error::Error;

+

+use crate::{adapter, Uuid};

+

+/// Check if the length matches any of the given criteria lengths.

+fn len_matches_any(len: usize, crits: &[usize]) -> bool {

+    for crit in crits {

+        if len == *crit {

+            return true;

+        }

+    }

+

+    false

+}

+

+/// Check if the length matches any criteria lengths in the given range

+/// (inclusive).

+#[allow(dead_code)]

+fn len_matches_range(len: usize, min: usize, max: usize) -> bool {

+    for crit in min..=max {

+        if len == crit {

+            return true;

+        }

+    }

+

+    false

+}

+

+// Accumulated length of each hyphenated group in hex digits.

+const ACC_GROUP_LENS: [usize; 5] = [8, 12, 16, 20, 32];

+

+// Length of each hyphenated group in hex digits.

+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<Uuid, crate::Error> {

+        // 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 --git a/src/prelude.rs b/src/prelude.rs
new file mode 100644
index 0000000..63fbb4b
--- /dev/null
+++ b/src/prelude.rs
@@ -0,0 +1,47 @@
+// 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 <LICENSE-APACHE or

+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license

+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your

+// option. This file may not be copied, modified, or distributed

+// except according to those terms.

+

+//! The [`uuid`] prelude.

+//!

+//! This module contains the most important items of the [`uuid`] crate.

+//!

+//! To use the prelude, include the following in your crate root:

+//!

+//! ```rust

+//! extern crate uuid;

+//! ```

+//!

+//! # Prelude Contents

+//!

+//! Currently the prelude reexports the following:

+//!

+//! [`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 = "

+[`uuid::v1`]`::{`[`ClockSequence`],[`Context`]`}`: The types useful for

+handling uuid version 1. Requires feature `v1`.

+

+[`uuid::v1`]: ../v1/index.html

+[`Context`]: ../v1/struct.Context.html

+[`ClockSequence`]: ../v1/trait.ClockSequence.html")]

+

+pub use super::{Builder, Bytes, Error, Uuid, Variant, Version};

+#[cfg(feature = "v1")]

+pub use crate::v1::{ClockSequence, Context};

diff --git a/src/serde_support.rs b/src/serde_support.rs
new file mode 100644
index 0000000..4ec2ffb
--- /dev/null
+++ b/src/serde_support.rs
@@ -0,0 +1,125 @@
+// 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 <LICENSE-APACHE or

+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license

+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your

+// option. This file may not be copied, modified, or distributed

+// except according to those terms.

+

+use crate::prelude::*;

+use core::fmt;

+use serde::{de, Deserialize, Deserializer, Serialize, Serializer};

+

+impl Serialize for Uuid {

+    fn serialize<S: Serializer>(

+        &self,

+        serializer: S,

+    ) -> Result<S::Ok, S::Error> {

+        if serializer.is_human_readable() {

+            serializer

+                .serialize_str(&self.to_hyphenated().encode_lower(&mut [0; 36]))

+        } else {

+            serializer.serialize_bytes(self.as_bytes())

+        }

+    }

+}

+

+impl<'de> Deserialize<'de> for Uuid {

+    fn deserialize<D: Deserializer<'de>>(

+        deserializer: D,

+    ) -> Result<Self, D::Error> {

+        fn de_error<E: de::Error>(e: crate::Error) -> E {

+            E::custom(format_args!("UUID parsing failed: {}", e))

+        }

+

+        if deserializer.is_human_readable() {

+            struct UuidStringVisitor;

+

+            impl<'vi> de::Visitor<'vi> for UuidStringVisitor {

+                type Value = Uuid;

+

+                fn expecting(

+                    &self,

+                    formatter: &mut fmt::Formatter<'_>,

+                ) -> fmt::Result {

+                    write!(formatter, "a UUID string")

+                }

+

+                fn visit_str<E: de::Error>(

+                    self,

+                    value: &str,

+                ) -> Result<Uuid, E> {

+                    value.parse::<Uuid>().map_err(de_error)

+                }

+

+                fn visit_bytes<E: de::Error>(

+                    self,

+                    value: &[u8],

+                ) -> Result<Uuid, E> {

+                    Uuid::from_slice(value).map_err(de_error)

+                }

+            }

+

+            deserializer.deserialize_str(UuidStringVisitor)

+        } else {

+            struct UuidBytesVisitor;

+

+            impl<'vi> de::Visitor<'vi> for UuidBytesVisitor {

+                type Value = Uuid;

+

+                fn expecting(

+                    &self,

+                    formatter: &mut fmt::Formatter<'_>,

+                ) -> fmt::Result {

+                    write!(formatter, "bytes")

+                }

+

+                fn visit_bytes<E: de::Error>(

+                    self,

+                    value: &[u8],

+                ) -> Result<Uuid, E> {

+                    Uuid::from_slice(value).map_err(de_error)

+                }

+            }

+

+            deserializer.deserialize_bytes(UuidBytesVisitor)

+        }

+    }

+}

+

+#[cfg(test)]

+mod serde_tests {

+    use serde_test::{Compact, Configure, Readable, Token};

+

+    use crate::prelude::*;

+

+    #[test]

+    fn test_serialize_readable() {

+        let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";

+        let u = Uuid::parse_str(uuid_str).unwrap();

+        serde_test::assert_tokens(&u.readable(), &[Token::Str(uuid_str)]);

+    }

+

+    #[test]

+    fn test_serialize_compact() {

+        let uuid_bytes = b"F9168C5E-CEB2-4F";

+        let u = Uuid::from_slice(uuid_bytes).unwrap();

+        serde_test::assert_tokens(&u.compact(), &[Token::Bytes(uuid_bytes)]);

+    }

+

+    #[test]

+    fn test_de_failure() {

+        serde_test::assert_de_tokens_error::<Readable<Uuid>>(

+            &[Token::Str("hello_world")],

+            "UUID parsing failed: invalid length: expected one of [36, 32], found 11",

+        );

+

+        serde_test::assert_de_tokens_error::<Compact<Uuid>>(

+            &[Token::Bytes(b"hello_world")],

+            "UUID parsing failed: invalid bytes length: expected 16, found 11",

+        );

+    }

+}

diff --git a/src/slog_support.rs b/src/slog_support.rs
new file mode 100644
index 0000000..472b39a
--- /dev/null
+++ b/src/slog_support.rs
@@ -0,0 +1,39 @@
+// 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 <LICENSE-APACHE or

+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license

+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your

+// option. This file may not be copied, modified, or distributed

+// except according to those terms.

+

+use crate::prelude::*;

+use slog;

+

+impl slog::Value for Uuid {

+    fn serialize(

+        &self,

+        _: &slog::Record<'_>,

+        key: slog::Key,

+        serializer: &mut dyn slog::Serializer,

+    ) -> Result<(), slog::Error> {

+        serializer.emit_arguments(key, &format_args!("{}", self))

+    }

+}

+

+#[cfg(test)]

+mod tests {

+

+    #[test]

+    fn test_slog_kv() {

+        use crate::test_util;

+        use slog;

+        use slog::{crit, Drain};

+

+        let root = slog::Logger::root(slog::Discard.fuse(), slog::o!());

+        let u1 = test_util::new();

+        crit!(root, "test"; "u1" => u1);

+    }

+}

diff --git a/src/test_util.rs b/src/test_util.rs
new file mode 100644
index 0000000..ebb45ab
--- /dev/null
+++ b/src/test_util.rs
@@ -0,0 +1,26 @@
+// 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 <LICENSE-APACHE or

+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license

+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your

+// option. This file may not be copied, modified, or distributed

+// except according to those terms.

+

+use crate::prelude::*;

+

+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 const fn new2() -> Uuid {

+    Uuid::from_bytes([

+        0xF9, 0x16, 0x8C, 0x5E, 0xCE, 0xB2, 0x4F, 0xAB, 0xB6, 0xBF, 0x32, 0x9B,

+        0xF3, 0x9F, 0xA1, 0xE4,

+    ])

+}

diff --git a/src/v1.rs b/src/v1.rs
new file mode 100644
index 0000000..de692b7
--- /dev/null
+++ b/src/v1.rs
@@ -0,0 +1,326 @@
+//! The implementation for Version 1 UUIDs.

+//!

+//! Note that you need feature `v1` in order to use these features.

+

+use crate::prelude::*;

+use core::sync::atomic;

+

+/// 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.

+#[derive(Debug)]

+pub struct Context {

+    count: atomic::AtomicUsize,

+}

+

+/// 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 1582 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

+            + u64::from(subsec_nanos) / 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) {

+        (

+            (self.ticks - UUID_TICKS_BETWEEN_EPOCHS) / 10_000_000,

+            ((self.ticks - UUID_TICKS_BETWEEN_EPOCHS) % 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 last time a clock sequence was requested.

+    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 +

+    /// *NodeId*.

+    ///

+    /// 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

+    ///    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.

+    ///

+    /// Note that usage of this method requires the `v1` feature of this crate

+    /// to be enabled.

+    ///

+    /// # Examples

+    ///

+    /// A UUID can be created from a unix [`Timestamp`] with a

+    /// [`ClockSequence`]:

+    ///

+    /// ```rust

+    /// use uuid::v1::{Timestamp, Context};

+    /// use uuid::Uuid;

+    ///

+    /// let context = Context::new(42);

+    /// let ts = Timestamp::from_unix(&context, 1497624119, 1234);

+    /// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]).expect("failed to generate UUID");

+    ///

+    /// assert_eq!(

+    ///     uuid.to_hyphenated().to_string(),

+    ///     "f3b4958c-52a1-11e7-802a-010203040506"

+    /// );

+    /// ```

+    ///

+    /// 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<Self, crate::Error> {

+        const NODE_ID_LEN: usize = 6;

+

+        let len = node_id.len();

+        if len != NODE_ID_LEN {

+            Err(crate::builder::Error::new(NODE_ID_LEN, len))?;

+        }

+

+        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];

+

+        {

+            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<Timestamp> {

+        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 {

+    /// Creates a thread-safe, internally mutable context to help ensure

+    /// uniqueness.

+    ///

+    /// 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

+    /// process.

+    pub const fn new(count: u16) -> Self {

+        Self {

+            count: atomic::AtomicUsize::new(count as usize),

+        }

+    }

+}

+

+impl ClockSequence for Context {

+    fn generate_sequence(&self, _: u64, _: u32) -> u16 {

+        (self.count.fetch_add(1, atomic::Ordering::SeqCst) & 0xffff) as u16

+    }

+}

+

+#[cfg(test)]

+mod tests {

+    use super::*;

+

+    use crate::std::string::ToString;

+

+    #[test]

+    fn test_new_v1() {

+        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(

+                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));

+            assert_eq!(

+                uuid.to_hyphenated().to_string(),

+                "20616934-4ba2-11e7-8000-010203040506"

+            );

+

+            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(

+                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().to_rfc4122().1, 1)

+        };

+    }

+}

diff --git a/src/v3.rs b/src/v3.rs
new file mode 100644
index 0000000..5be542b
--- /dev/null
+++ b/src/v3.rs
@@ -0,0 +1,146 @@
+use crate::prelude::*;

+use md5;

+

+impl Uuid {

+    /// 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:

+    ///

+    /// * [`NAMESPACE_DNS`]

+    /// * [`NAMESPACE_OID`]

+    /// * [`NAMESPACE_URL`]

+    /// * [`NAMESPACE_X500`]

+    ///

+    /// Note that usage of this method requires the `v3` feature of this crate

+    /// to be enabled.

+    ///

+    /// [`NAMESPACE_DNS`]: #associatedconstant.NAMESPACE_DNS

+    /// [`NAMESPACE_OID`]: #associatedconstant.NAMESPACE_OID

+    /// [`NAMESPACE_URL`]: #associatedconstant.NAMESPACE_URL

+    /// [`NAMESPACE_X500`]: #associatedconstant.NAMESPACE_X500

+    pub fn new_v3(namespace: &Uuid, name: &[u8]) -> Uuid {

+        let mut context = md5::Context::new();

+

+        context.consume(namespace.as_bytes());

+        context.consume(name);

+

+        let computed = context.compute();

+        let bytes = computed.into();

+

+        let mut builder = crate::Builder::from_bytes(bytes);

+

+        builder

+            .set_variant(Variant::RFC4122)

+            .set_version(Version::Md5);

+

+        builder.build()

+    }

+}

+

+#[cfg(test)]

+mod tests {

+    use super::*;

+

+    use crate::std::string::ToString;

+

+    static FIXTURE: &'static [(&'static Uuid, &'static str, &'static str)] = &[

+        (

+            &Uuid::NAMESPACE_DNS,

+            "example.org",

+            "04738bdf-b25a-3829-a801-b21a1d25095b",

+        ),

+        (

+            &Uuid::NAMESPACE_DNS,

+            "rust-lang.org",

+            "c6db027c-615c-3b4d-959e-1a917747ca5a",

+        ),

+        (

+            &Uuid::NAMESPACE_DNS,

+            "42",

+            "5aab6e0c-b7d3-379c-92e3-2bfbb5572511",

+        ),

+        (

+            &Uuid::NAMESPACE_DNS,

+            "lorem ipsum",

+            "4f8772e9-b59c-3cc9-91a9-5c823df27281",

+        ),

+        (

+            &Uuid::NAMESPACE_URL,

+            "example.org",

+            "39682ca1-9168-3da2-a1bb-f4dbcde99bf9",

+        ),

+        (

+            &Uuid::NAMESPACE_URL,

+            "rust-lang.org",

+            "7ed45aaf-e75b-3130-8e33-ee4d9253b19f",

+        ),

+        (

+            &Uuid::NAMESPACE_URL,

+            "42",

+            "08998a0c-fcf4-34a9-b444-f2bfc15731dc",

+        ),

+        (

+            &Uuid::NAMESPACE_URL,

+            "lorem ipsum",

+            "e55ad2e6-fb89-34e8-b012-c5dde3cd67f0",

+        ),

+        (

+            &Uuid::NAMESPACE_OID,

+            "example.org",

+            "f14eec63-2812-3110-ad06-1625e5a4a5b2",

+        ),

+        (

+            &Uuid::NAMESPACE_OID,

+            "rust-lang.org",

+            "6506a0ec-4d79-3e18-8c2b-f2b6b34f2b6d",

+        ),

+        (

+            &Uuid::NAMESPACE_OID,

+            "42",

+            "ce6925a5-2cd7-327b-ab1c-4b375ac044e4",

+        ),

+        (

+            &Uuid::NAMESPACE_OID,

+            "lorem ipsum",

+            "5dd8654f-76ba-3d47-bc2e-4d6d3a78cb09",

+        ),

+        (

+            &Uuid::NAMESPACE_X500,

+            "example.org",

+            "64606f3f-bd63-363e-b946-fca13611b6f7",

+        ),

+        (

+            &Uuid::NAMESPACE_X500,

+            "rust-lang.org",

+            "bcee7a9c-52f1-30c6-a3cc-8c72ba634990",

+        ),

+        (

+            &Uuid::NAMESPACE_X500,

+            "42",

+            "c1073fa2-d4a6-3104-b21d-7a6bdcf39a23",

+        ),

+        (

+            &Uuid::NAMESPACE_X500,

+            "lorem ipsum",

+            "02f09a3f-1624-3b1d-8409-44eff7708208",

+        ),

+    ];

+

+    #[test]

+    fn test_new() {

+        for &(ref ns, ref name, _) in FIXTURE {

+            let uuid = Uuid::new_v3(*ns, name.as_bytes());

+            assert_eq!(uuid.get_version().unwrap(), Version::Md5);

+            assert_eq!(uuid.get_variant().unwrap(), Variant::RFC4122);

+        }

+    }

+

+    #[test]

+    fn test_to_hyphenated_string() {

+        for &(ref ns, ref name, ref expected) in FIXTURE {

+            let uuid = Uuid::new_v3(*ns, name.as_bytes());

+            assert_eq!(uuid.to_hyphenated().to_string(), *expected);

+        }

+    }

+}

diff --git a/src/v4.rs b/src/v4.rs
new file mode 100644
index 0000000..0928dc7
--- /dev/null
+++ b/src/v4.rs
@@ -0,0 +1,60 @@
+use crate::prelude::*;

+

+impl Uuid {

+    /// Creates a random UUID.

+    ///

+    /// This uses the [`getrandom`] crate to utilise the operating system's RNG

+    /// as the source of random numbers. If you'd like to use a custom

+    /// generator, don't use this method: generate random bytes using your

+    /// custom generator and pass them to the

+    /// [`uuid::Builder::from_bytes`][from_bytes] function instead.

+    ///

+    /// Note that usage of this method requires the `v4` feature of this crate

+    /// to be enabled.

+    ///

+    /// # Examples

+    ///

+    /// Basic usage:

+    ///

+    /// ```

+    /// use uuid::Uuid;

+    ///

+    /// let uuid = Uuid::new_v4();

+    /// ```

+    ///

+    /// [`getrandom`]: https://crates.io/crates/getrandom

+    /// [from_bytes]: struct.Builder.html#method.from_bytes

+    pub fn new_v4() -> Uuid {

+        let mut bytes = [0u8; 16];

+        getrandom::getrandom(&mut bytes).unwrap_or_else(|err| {

+            // NB: getrandom::Error has no source; this is adequate display

+            panic!("could not retreive random bytes for uuid: {}", err)

+        });

+

+        crate::Builder::from_bytes(bytes)

+            .set_variant(Variant::RFC4122)

+            .set_version(Version::Random)

+            .build()

+    }

+}

+

+#[cfg(test)]

+mod tests {

+    use crate::prelude::*;

+

+    #[test]

+    fn test_new() {

+        let uuid = Uuid::new_v4();

+

+        assert_eq!(uuid.get_version(), Some(Version::Random));

+        assert_eq!(uuid.get_variant(), Some(Variant::RFC4122));

+    }

+

+    #[test]

+    fn test_get_version() {

+        let uuid = Uuid::new_v4();

+

+        assert_eq!(uuid.get_version(), Some(Version::Random));

+        assert_eq!(uuid.get_version_num(), 4)

+    }

+}

diff --git a/src/v5.rs b/src/v5.rs
new file mode 100644
index 0000000..e42d70d
--- /dev/null
+++ b/src/v5.rs
@@ -0,0 +1,158 @@
+use crate::prelude::*;

+use sha1;

+

+impl Uuid {

+    /// Creates a UUID using a name from a namespace, based on the SHA-1 hash.

+    ///

+    /// A number of namespaces are available as constants in this crate:

+    ///

+    /// * [`NAMESPACE_DNS`]

+    /// * [`NAMESPACE_OID`]

+    /// * [`NAMESPACE_URL`]

+    /// * [`NAMESPACE_X500`]

+    ///

+    /// Note that usage of this method requires the `v5` feature of this crate

+    /// to be enabled.

+    ///

+    /// [`NAMESPACE_DNS`]: struct.Uuid.html#associatedconst.NAMESPACE_DNS

+    /// [`NAMESPACE_OID`]: struct.Uuid.html#associatedconst.NAMESPACE_OID

+    /// [`NAMESPACE_URL`]: struct.Uuid.html#associatedconst.NAMESPACE_URL

+    /// [`NAMESPACE_X500`]: struct.Uuid.html#associatedconst.NAMESPACE_X500

+    pub fn new_v5(namespace: &Uuid, name: &[u8]) -> Uuid {

+        let mut hash = sha1::Sha1::new();

+

+        hash.update(namespace.as_bytes());

+        hash.update(name);

+

+        let buffer = hash.digest().bytes();

+

+        let mut bytes = crate::Bytes::default();

+        bytes.copy_from_slice(&buffer[..16]);

+

+        let mut builder = crate::Builder::from_bytes(bytes);

+        builder

+            .set_variant(Variant::RFC4122)

+            .set_version(Version::Sha1);

+

+        builder.build()

+    }

+}

+

+#[cfg(test)]

+mod tests {

+    use super::*;

+

+    use crate::std::string::ToString;

+

+    static FIXTURE: &'static [(&'static Uuid, &'static str, &'static str)] = &[

+        (

+            &Uuid::NAMESPACE_DNS,

+            "example.org",

+            "aad03681-8b63-5304-89e0-8ca8f49461b5",

+        ),

+        (

+            &Uuid::NAMESPACE_DNS,

+            "rust-lang.org",

+            "c66bbb60-d62e-5f17-a399-3a0bd237c503",

+        ),

+        (

+            &Uuid::NAMESPACE_DNS,

+            "42",

+            "7c411b5e-9d3f-50b5-9c28-62096e41c4ed",

+        ),

+        (

+            &Uuid::NAMESPACE_DNS,

+            "lorem ipsum",

+            "97886a05-8a68-5743-ad55-56ab2d61cf7b",

+        ),

+        (

+            &Uuid::NAMESPACE_URL,

+            "example.org",

+            "54a35416-963c-5dd6-a1e2-5ab7bb5bafc7",

+        ),

+        (

+            &Uuid::NAMESPACE_URL,

+            "rust-lang.org",

+            "c48d927f-4122-5413-968c-598b1780e749",

+        ),

+        (

+            &Uuid::NAMESPACE_URL,

+            "42",

+            "5c2b23de-4bad-58ee-a4b3-f22f3b9cfd7d",

+        ),

+        (

+            &Uuid::NAMESPACE_URL,

+            "lorem ipsum",

+            "15c67689-4b85-5253-86b4-49fbb138569f",

+        ),

+        (

+            &Uuid::NAMESPACE_OID,

+            "example.org",

+            "34784df9-b065-5094-92c7-00bb3da97a30",

+        ),

+        (

+            &Uuid::NAMESPACE_OID,

+            "rust-lang.org",

+            "8ef61ecb-977a-5844-ab0f-c25ef9b8d5d6",

+        ),

+        (

+            &Uuid::NAMESPACE_OID,

+            "42",

+            "ba293c61-ad33-57b9-9671-f3319f57d789",

+        ),

+        (

+            &Uuid::NAMESPACE_OID,

+            "lorem ipsum",

+            "6485290d-f79e-5380-9e64-cb4312c7b4a6",

+        ),

+        (

+            &Uuid::NAMESPACE_X500,

+            "example.org",

+            "e3635e86-f82b-5bbc-a54a-da97923e5c76",

+        ),

+        (

+            &Uuid::NAMESPACE_X500,

+            "rust-lang.org",

+            "26c9c3e9-49b7-56da-8b9f-a0fb916a71a3",

+        ),

+        (

+            &Uuid::NAMESPACE_X500,

+            "42",

+            "e4b88014-47c6-5fe0-a195-13710e5f6e27",

+        ),

+        (

+            &Uuid::NAMESPACE_X500,

+            "lorem ipsum",

+            "b11f79a5-1e6d-57ce-a4b5-ba8531ea03d0",

+        ),

+    ];

+

+    #[test]

+    fn test_get_version() {

+        let uuid =

+            Uuid::new_v5(&Uuid::NAMESPACE_DNS, "rust-lang.org".as_bytes());

+

+        assert_eq!(uuid.get_version(), Some(Version::Sha1));

+        assert_eq!(uuid.get_version_num(), 5);

+    }

+

+    #[test]

+    fn test_hyphenated() {

+        for &(ref ns, ref name, ref expected) in FIXTURE {

+            let uuid = Uuid::new_v5(*ns, name.as_bytes());

+

+            assert_eq!(uuid.to_hyphenated().to_string(), *expected)

+        }

+    }

+

+    #[test]

+    fn test_new() {

+        for &(ref ns, ref name, ref u) in FIXTURE {

+            let uuid = Uuid::new_v5(*ns, name.as_bytes());

+

+            assert_eq!(uuid.get_variant(), Some(Variant::RFC4122));

+            assert_eq!(uuid.get_version(), Some(Version::Sha1));

+            assert_eq!(Ok(uuid), u.parse());

+        }

+    }

+}

diff --git a/src/winapi_support.rs b/src/winapi_support.rs
new file mode 100644
index 0000000..29bed06
--- /dev/null
+++ b/src/winapi_support.rs
@@ -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, crate::Error> {

+        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

+            )

+        );

+    }

+}