Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

1
vendor/uuid/.cargo-checksum.json vendored Normal file
View File

@@ -0,0 +1 @@
{"files":{"Cargo.lock":"91740983de38c21e2e5eb59456f2a8e66edbe51102e7f406f019411ba3e92cf9","Cargo.toml":"b86522e1e8554556ee4016d1f72f60833b073b601d4a1d867b3057d0db388d4b","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"436bc5a105d8e57dcd8778730f3754f7bf39c14d2f530e4cde4bd2d17a83ec3d","README.md":"f259b8f88189530623f65b6886ee22a4090b4483933cacfdb7979c1ad3495f01","src/builder.rs":"a1973c39e9a6841af6c4d96303ac8b9c9383625367d63860d3e4022c11e65097","src/error.rs":"d46fae4d66ac25a0fa63e3fca6f5d5bdf9c13b70bf65192e7b1c3609390ad077","src/external.rs":"a0640bdb98de1c24fcc9851a438a5abe6f7e3acb195885c817a64fac25521b9d","src/external/arbitrary_support.rs":"a7e0f0686c7c79e3af797f6d3f1976bee13fa9c3d8cb40f58bd10ff6ebdadae3","src/external/borsh_support.rs":"b49d82a59653445ba26db46a1515294b1ab480c0671dbe5499dfd1fb02588b3b","src/external/serde_support.rs":"cd5cf95fc393ac2f28f21b435f6b134ab6a9089d59c889359f1f0ee44385a8d7","src/external/slog_support.rs":"d9bab6f91a80c773e77326ce40d84976beb2b2946ab708de21f25afe5b9ece13","src/fmt.rs":"1fd997da8252059d25cc13fa2818d8cc4f4ae638ab55ed9308fe91d52ea49b72","src/lib.rs":"375064c2db2815ed462511de2be4e8c4f136eadedb772cd5c96471129d94607b","src/macros.rs":"35de4bc09674ce76b77b145925e79f5d35372255854124bdc25cc28aed4af26d","src/md5.rs":"316d65b760ffa58beb6aa678be24359eb21a744e9e143bc99c11fe1907659245","src/non_nil.rs":"817595606edcf1bf228c6f31486245800d2e4e02a89e8e9f235cfb0ce3d857e8","src/parser.rs":"b9563849d23fa58829a4381fffc4a8ad03a4a83e06822c8b3052d92a14abc68d","src/rng.rs":"845ff9a728e8c9d7a3c6783260fd7d0ddaa63f2424de074bc50d820c311580bc","src/sha1.rs":"e1a9657e11f1ed1ede33c0655f9c2641059b7c24f17be4ac425c930cc216e019","src/timestamp.rs":"ccbf700f9e4c15d88c88d396e00e18a94791855f587f981197a112de6c4760df","src/v1.rs":"281ede6fe2b96fca062ad4dc4d150e6fd15d35c5cf98eda4daaa7be70ededd78","src/v3.rs":"74da9be0eebf49ca44a255c4441a3b8be936f3bc578968be32e026aebe1bdecc","src/v4.rs":"083012653ceff1b1306998176b333863b515ebb46a22aa5c17c172462eb9bd4c","src/v5.rs":"b4c0c06bf467170f4859a6ff128c22372c28ff1e435a949cb0da01aa6d40a2ff","src/v6.rs":"d2866bae073946b5b5bfcd8737f1a0a7238eca5698e1e6dd333fbd8dcf6de7b7","src/v7.rs":"27ac8aba5f2b99def98fd08df4ab3af425f752ec583ff0a9e0e1d86f4b12df18","src/v8.rs":"6e847f7307c6ec78cbc6616412cc7ace914a157ac2bd7aa9caf0d629ae57d0c7"},"package":"2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"}

815
vendor/uuid/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,815 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "arbitrary"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1"
[[package]]
name = "atomic"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340"
dependencies = [
"bytemuck",
]
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "block-buffer"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
dependencies = [
"generic-array",
]
[[package]]
name = "borsh"
version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad8646f98db542e39fc66e68a20b2144f6a732636df7c2354e74645faaa433ce"
dependencies = [
"cfg_aliases",
]
[[package]]
name = "borsh-derive"
version = "1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdd1d3c0c2f5833f22386f252fe8ed005c7f59fdcddeef025c01b4c3b9fd9ac3"
dependencies = [
"once_cell",
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "bumpalo"
version = "3.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
[[package]]
name = "bytemuck"
version = "1.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677"
dependencies = [
"bytemuck_derive",
]
[[package]]
name = "bytemuck_derive"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "cc"
version = "1.2.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "590f9024a68a8c40351881787f1934dc11afd69090f5edb6831464694d836ea3"
dependencies = [
"find-msvc-tools",
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "cfg_aliases"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
[[package]]
name = "crypto-common"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
dependencies = [
"generic-array",
"typenum",
]
[[package]]
name = "digest"
version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"crypto-common",
]
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "find-msvc-tools"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e178e4fba8a2726903f6ba98a6d221e76f9c12c650d5dc0e6afdc50677b49650"
[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
]
[[package]]
name = "getrandom"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi",
]
[[package]]
name = "glob"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
[[package]]
name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
[[package]]
name = "indexmap"
version = "2.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "js-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]]
name = "libc"
version = "0.2.175"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "md-5"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
dependencies = [
"cfg-if",
"digest",
]
[[package]]
name = "memchr"
version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "minicov"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27fe9f1cc3c22e1687f9446c2083c4c5fc7f0bcf1c7a86bdbded14985895b4b"
dependencies = [
"cc",
"walkdir",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]]
name = "proc-macro-crate"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35"
dependencies = [
"toml_edit",
]
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rand"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom",
]
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "serde"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.219"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
]
[[package]]
name = "serde_spanned"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83"
dependencies = [
"serde",
]
[[package]]
name = "serde_test"
version = "1.0.177"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f901ee573cab6b3060453d2d5f0bae4e6d628c23c0a962ff9b5f1d7c8d4f1ed"
dependencies = [
"serde",
]
[[package]]
name = "sha1_smol"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d"
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "slog"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06"
[[package]]
name = "syn"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "target-triple"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ac9aa371f599d22256307c24a9d748c041e548cbf599f35d890f9d365361790"
[[package]]
name = "termcolor"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
dependencies = [
"winapi-util",
]
[[package]]
name = "toml"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime 0.7.0",
"toml_parser",
"toml_writer",
"winnow",
]
[[package]]
name = "toml_datetime"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
[[package]]
name = "toml_datetime"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.22.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
dependencies = [
"indexmap",
"toml_datetime 0.6.11",
"winnow",
]
[[package]]
name = "toml_parser"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10"
dependencies = [
"winnow",
]
[[package]]
name = "toml_writer"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
[[package]]
name = "trybuild"
version = "1.0.110"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32e257d7246e7a9fd015fb0b28b330a8d4142151a33f03e6a497754f4b1f6a8e"
dependencies = [
"glob",
"serde",
"serde_derive",
"serde_json",
"target-triple",
"termcolor",
"toml",
]
[[package]]
name = "typenum"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"
[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
[[package]]
name = "uuid"
version = "1.18.1"
dependencies = [
"arbitrary",
"atomic",
"bincode",
"borsh",
"borsh-derive",
"bytemuck",
"getrandom",
"js-sys",
"md-5",
"rand",
"rustversion",
"serde",
"serde_derive",
"serde_json",
"serde_test",
"sha1_smol",
"slog",
"trybuild",
"uuid-macro-internal",
"uuid-rng-internal",
"wasm-bindgen",
"wasm-bindgen-test",
"zerocopy",
]
[[package]]
name = "uuid-macro-internal"
version = "1.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9384a660318abfbd7f8932c34d67e4d1ec511095f95972ddc01e19d7ba8413f"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "uuid-rng-internal"
version = "1.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23426b4394875bbc29a3074f94e1b52cd0eed2c8410c21a6edbfb033daef0aa1"
dependencies = [
"getrandom",
"rand",
]
[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.14.3+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "wasm-bindgen"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5"
dependencies = [
"cfg-if",
"once_cell",
"rustversion",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6"
dependencies = [
"bumpalo",
"log",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61"
dependencies = [
"cfg-if",
"js-sys",
"once_cell",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.100"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d"
dependencies = [
"unicode-ident",
]
[[package]]
name = "wasm-bindgen-test"
version = "0.3.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66c8d5e33ca3b6d9fa3b4676d774c5778031d27a578c2b007f905acf816152c3"
dependencies = [
"js-sys",
"minicov",
"wasm-bindgen",
"wasm-bindgen-futures",
"wasm-bindgen-test-macro",
]
[[package]]
name = "wasm-bindgen-test-macro"
version = "0.3.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "web-sys"
version = "0.3.77"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "winapi-util"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22"
dependencies = [
"windows-sys",
]
[[package]]
name = "windows-link"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
dependencies = [
"windows-link",
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winnow"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen"
version = "0.45.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814"
[[package]]
name = "zerocopy"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

247
vendor/uuid/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,247 @@
# 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 are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2018"
rust-version = "1.63.0"
name = "uuid"
version = "1.18.1"
authors = [
"Ashley Mannix<ashleymannix@live.com.au>",
"Dylan DPC<dylan.dpc@gmail.com>",
"Hunar Roop Kahlon<hunar.roop@gmail.com>",
]
build = false
include = [
"src",
"README.md",
"LICENSE-APACHE",
"LICENSE-MIT",
]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
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]
rustc-args = [
"--cfg",
"uuid_unstable",
]
rustdoc-args = [
"--cfg",
"uuid_unstable",
]
targets = ["x86_64-unknown-linux-gnu"]
features = [
"serde",
"arbitrary",
"slog",
"borsh",
"v1",
"v3",
"v4",
"v5",
"v6",
"v7",
"v8",
]
[package.metadata.playground]
features = [
"serde",
"v1",
"v3",
"v4",
"v5",
"v6",
"v7",
"v8",
]
[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"
[features]
atomic = ["dep:atomic"]
borsh = [
"dep:borsh",
"dep:borsh-derive",
]
default = ["std"]
fast-rng = [
"rng",
"dep:rand",
]
js = [
"dep:wasm-bindgen",
"dep:js-sys",
]
macro-diagnostics = ["dep:uuid-macro-internal"]
md5 = ["dep:md-5"]
rng = ["dep:getrandom"]
rng-getrandom = [
"rng",
"dep:getrandom",
"uuid-rng-internal-lib",
"uuid-rng-internal-lib/getrandom",
]
rng-rand = [
"rng",
"dep:rand",
"uuid-rng-internal-lib",
"uuid-rng-internal-lib/rand",
]
sha1 = ["dep:sha1_smol"]
std = [
"wasm-bindgen?/std",
"js-sys?/std",
]
v1 = ["atomic"]
v3 = ["md5"]
v4 = ["rng"]
v5 = ["sha1"]
v6 = ["atomic"]
v7 = ["rng"]
v8 = []
[lib]
name = "uuid"
path = "src/lib.rs"
[dependencies.arbitrary]
version = "1.1.3"
optional = true
[dependencies.atomic]
version = "0.6"
optional = true
default-features = false
[dependencies.borsh]
version = "1"
optional = true
default-features = false
[dependencies.borsh-derive]
version = "1"
optional = true
default-features = false
[dependencies.bytemuck]
version = "1.18.1"
features = ["derive"]
optional = true
[dependencies.md-5]
version = "0.10"
optional = true
default-features = false
[dependencies.serde]
version = "1.0.56"
optional = true
default-features = false
[dependencies.sha1_smol]
version = "1"
optional = true
default-features = false
[dependencies.slog]
version = "2"
optional = true
[dependencies.uuid-macro-internal]
version = "1.18.1"
optional = true
[dependencies.zerocopy]
version = "0.8"
features = ["derive"]
optional = true
[dev-dependencies.bincode]
version = "1.0"
[dev-dependencies.rustversion]
version = "1"
[dev-dependencies.serde_derive]
version = "1.0.79"
[dev-dependencies.serde_json]
version = "1.0"
[dev-dependencies.serde_test]
version = "1.0.56"
[dev-dependencies.trybuild]
version = "1.0.52"
[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dependencies.uuid-rng-internal-lib]
version = "1.18.1"
optional = true
package = "uuid-rng-internal"
[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dependencies.wasm-bindgen]
version = "0.2"
features = ["msrv"]
optional = true
default-features = false
[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dev-dependencies.wasm-bindgen]
version = "0.2"
[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))'.dev-dependencies.wasm-bindgen-test]
version = "0.3"
[target.'cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"), target_feature = "atomics"))'.dependencies.js-sys]
version = "0.3"
optional = true
default-features = false
[target.'cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))'.dependencies.getrandom]
version = "0.3"
optional = true
[target.'cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))'.dependencies.rand]
version = "0.9"
optional = true
[lints.rust.unexpected_cfgs]
level = "allow"
priority = 0
check-cfg = ["cfg(uuid_unstable)"]

201
vendor/uuid/LICENSE-APACHE vendored Normal file
View File

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

26
vendor/uuid/LICENSE-MIT vendored Normal file
View File

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

89
vendor/uuid/README.md vendored Normal file
View File

@@ -0,0 +1,89 @@
# `uuid`
[![Latest Version](https://img.shields.io/crates/v/uuid.svg)](https://crates.io/crates/uuid)
[![Continuous integration](https://github.com/uuid-rs/uuid/actions/workflows/ci.yml/badge.svg)](https://github.com/uuid-rs/uuid/actions/workflows/ci.yml)
Here's an example of a UUID:
```text
67e55044-10b1-426f-9247-bb680e5fe0c8
```
A UUID is a unique 128-bit value, stored as 16 octets, and regularly
formatted as a hex string in five groups. 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.
## Getting started
Add the following to your `Cargo.toml`:
```toml
[dependencies.uuid]
version = "1.18.1"
# Lets you generate random UUIDs
features = [
"v4",
]
```
When you want a UUID, you can generate one:
```rust
use uuid::Uuid;
let id = Uuid::new_v4();
```
If you have a UUID value, you can use its string literal form inline:
```rust
use uuid::{uuid, Uuid};
const ID: Uuid = uuid!("67e55044-10b1-426f-9247-bb680e5fe0c8");
```
You can also parse UUIDs without needing any crate features:
```rust
use uuid::{Uuid, Version};
let my_uuid = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8")?;
assert_eq!(Some(Version::Random), my_uuid.get_version());
```
If you'd like to parse UUIDs _really_ fast, check out the [`uuid-simd`](https://github.com/nugine/uuid-simd)
library.
For more details on using `uuid`, [see the library documentation](https://docs.rs/uuid/1.18.1/uuid).
## References
* [`uuid` library docs](https://docs.rs/uuid/1.18.1/uuid).
* [Wikipedia: Universally Unique Identifier](http://en.wikipedia.org/wiki/Universally_unique_identifier).
* [RFC 9562: Universally Unique IDentifiers (UUID)](https://www.ietf.org/rfc/rfc9562.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.

878
vendor/uuid/src/builder.rs vendored Normal file
View File

@@ -0,0 +1,878 @@
// 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
use crate::{error::*, timestamp, Bytes, Uuid, Variant, Version};
/// A builder for creating a UUID.
///
/// This type is useful if you need to mutate individual fields of a [`Uuid`]
/// while constructing it. Since the [`Uuid`] type is `Copy`, it doesn't offer
/// any methods to mutate in place. They live on the `Builder` instead.
///
/// The `Builder` type also always exposes APIs to construct [`Uuid`]s for any
/// version without needing crate features or additional dependencies. It's a
/// lower-level API than the methods on [`Uuid`].
///
/// # Examples
///
/// Creating a version 4 UUID from externally generated random bytes:
///
/// ```
/// # use uuid::{Builder, Version, Variant};
/// # let rng = || [
/// # 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90,
/// # 145, 63, 62,
/// # ];
/// let random_bytes = rng();
///
/// let uuid = Builder::from_random_bytes(random_bytes).into_uuid();
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// ```
#[allow(missing_copy_implementations)]
#[derive(Debug)]
pub struct Builder(Uuid);
impl Uuid {
/// The 'nil UUID' (all zeros).
///
/// The nil UUID is a special form of UUID that is specified to have all
/// 128 bits set to zero.
///
/// # References
///
/// * [Nil UUID in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.9)
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let uuid = Uuid::nil();
///
/// assert_eq!(
/// "00000000-0000-0000-0000-000000000000",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn nil() -> Self {
Uuid::from_bytes([0; 16])
}
/// The 'max UUID' (all ones).
///
/// The max UUID is a special form of UUID that is specified to have all
/// 128 bits set to one.
///
/// # References
///
/// * [Max UUID in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.10)
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let uuid = Uuid::max();
///
/// assert_eq!(
/// "ffffffff-ffff-ffff-ffff-ffffffffffff",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn max() -> Self {
Uuid::from_bytes([0xFF; 16])
}
/// Creates a UUID from four field values.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let d1 = 0xa1a2a3a4;
/// let d2 = 0xb1b2;
/// let d3 = 0xc1c2;
/// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
///
/// let uuid = Uuid::from_fields(d1, d2, d3, &d4);
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Uuid {
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 flipped to convert
/// into big-endian order. This is based on the endianness of the UUID,
/// rather than the target environment so bytes will be flipped on both
/// big and little endian machines.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let d1 = 0xa1a2a3a4;
/// let d2 = 0xb1b2;
/// let d3 = 0xc1c2;
/// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
///
/// let uuid = Uuid::from_fields_le(d1, d2, d3, &d4);
///
/// assert_eq!(
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_fields_le(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Uuid {
Uuid::from_bytes([
d1 as u8,
(d1 >> 8) as u8,
(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.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
///
/// let uuid = Uuid::from_u128(v);
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_u128(v: u128) -> Self {
Uuid::from_bytes(v.to_be_bytes())
}
/// Creates a UUID from a 128bit value in little-endian order.
///
/// The entire value will be flipped to convert into big-endian order.
/// This is based on the endianness of the UUID, rather than the target
/// environment so bytes will be flipped on both big and little endian
/// machines.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
///
/// let uuid = Uuid::from_u128_le(v);
///
/// assert_eq!(
/// "d8d7d6d5-d4d3-d2d1-c2c1-b2b1a4a3a2a1",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_u128_le(v: u128) -> Self {
Uuid::from_bytes(v.to_le_bytes())
}
/// Creates a UUID from two 64bit values.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Uuid;
/// let hi = 0xa1a2a3a4b1b2c1c2u64;
/// let lo = 0xd1d2d3d4d5d6d7d8u64;
///
/// let uuid = Uuid::from_u64_pair(hi, lo);
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_u64_pair(high_bits: u64, low_bits: u64) -> Self {
Uuid::from_u128(((high_bits as u128) << 64) | low_bits as u128)
}
/// Creates a UUID using the supplied bytes.
///
/// # Errors
///
/// This function will return an error if `b` has any length other than 16.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::Uuid;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Uuid::from_slice(&bytes)?;
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// # Ok(())
/// # }
/// ```
pub fn from_slice(b: &[u8]) -> Result<Uuid, Error> {
if b.len() != 16 {
return Err(Error(ErrorKind::ParseByteLength { len: b.len() }));
}
let mut bytes: Bytes = [0; 16];
bytes.copy_from_slice(b);
Ok(Uuid::from_bytes(bytes))
}
/// Creates a UUID using the supplied bytes in little endian order.
///
/// The individual fields encoded in the buffer will be flipped.
///
/// # Errors
///
/// This function will return an error if `b` has any length other than 16.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::Uuid;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Uuid::from_slice_le(&bytes)?;
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8"
/// );
/// # Ok(())
/// # }
/// ```
pub fn from_slice_le(b: &[u8]) -> Result<Uuid, Error> {
if b.len() != 16 {
return Err(Error(ErrorKind::ParseByteLength { len: b.len() }));
}
let mut bytes: Bytes = [0; 16];
bytes.copy_from_slice(b);
Ok(Uuid::from_bytes_le(bytes))
}
/// Creates a UUID using the supplied bytes.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::Uuid;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Uuid::from_bytes(bytes);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8"
/// );
/// # Ok(())
/// # }
/// ```
#[inline]
pub const fn from_bytes(bytes: Bytes) -> Uuid {
Uuid(bytes)
}
/// Creates a UUID using the supplied bytes in little endian order.
///
/// The individual fields encoded in the buffer will be flipped.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::Uuid;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Uuid::from_bytes_le(bytes);
///
/// assert_eq!(
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// # Ok(())
/// # }
/// ```
pub const fn from_bytes_le(b: Bytes) -> Uuid {
Uuid([
b[3], b[2], b[1], b[0], b[5], b[4], b[7], b[6], b[8], b[9], b[10], b[11], b[12], b[13],
b[14], b[15],
])
}
/// Creates a reference to a UUID from a reference to the supplied bytes.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::Uuid;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Uuid::from_bytes_ref(&bytes);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8"
/// );
///
/// assert!(std::ptr::eq(
/// uuid as *const Uuid as *const u8,
/// &bytes as *const [u8; 16] as *const u8,
/// ));
/// # Ok(())
/// # }
/// ```
#[inline]
pub fn from_bytes_ref(bytes: &Bytes) -> &Uuid {
unsafe_transmute_ref!(bytes)
}
// NOTE: There is no `from_u128_ref` because in little-endian
// environments the value isn't properly encoded. Callers would
// need to use `.to_be()` themselves.
}
impl Builder {
/// Creates a `Builder` using the supplied bytes.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Builder::from_bytes(bytes).into_uuid();
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_bytes(b: Bytes) -> Self {
Builder(Uuid::from_bytes(b))
}
/// Creates a `Builder` using the supplied bytes in little endian order.
///
/// The individual fields encoded in the buffer will be flipped.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # fn main() -> Result<(), uuid::Error> {
/// # use uuid::{Builder, Uuid};
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Builder::from_bytes_le(bytes).into_uuid();
///
/// assert_eq!(
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// # Ok(())
/// # }
/// ```
pub const fn from_bytes_le(b: Bytes) -> Self {
Builder(Uuid::from_bytes_le(b))
}
/// Creates a `Builder` for a version 1 UUID using the supplied timestamp, counter, and node ID.
pub const fn from_gregorian_timestamp(ticks: u64, counter: u16, node_id: &[u8; 6]) -> Self {
Builder(timestamp::encode_gregorian_timestamp(
ticks, counter, node_id,
))
}
/// Creates a `Builder` for a version 3 UUID using the supplied MD5 hashed bytes.
pub const fn from_md5_bytes(md5_bytes: Bytes) -> Self {
Builder(Uuid::from_bytes(md5_bytes))
.with_variant(Variant::RFC4122)
.with_version(Version::Md5)
}
/// Creates a `Builder` for a version 4 UUID using the supplied random bytes.
///
/// This method assumes the bytes are already sufficiently random, it will only
/// set the appropriate bits for the UUID version and variant.
///
/// # Examples
///
/// ```
/// # use uuid::{Builder, Variant, Version};
/// # let rng = || [
/// # 70, 235, 208, 238, 14, 109, 67, 201, 185, 13, 204, 195, 90,
/// # 145, 63, 62,
/// # ];
/// let random_bytes = rng();
/// let uuid = Builder::from_random_bytes(random_bytes).into_uuid();
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// ```
pub const fn from_random_bytes(random_bytes: Bytes) -> Self {
Builder(Uuid::from_bytes(random_bytes))
.with_variant(Variant::RFC4122)
.with_version(Version::Random)
}
/// Creates a `Builder` for a version 5 UUID using the supplied SHA-1 hashed bytes.
///
/// This method assumes the bytes are already a SHA-1 hash, it will only set the appropriate
/// bits for the UUID version and variant.
pub const fn from_sha1_bytes(sha1_bytes: Bytes) -> Self {
Builder(Uuid::from_bytes(sha1_bytes))
.with_variant(Variant::RFC4122)
.with_version(Version::Sha1)
}
/// Creates a `Builder` for a version 6 UUID using the supplied timestamp, counter, and node ID.
///
/// This method will encode the ticks, counter, and node ID in a sortable UUID.
pub const fn from_sorted_gregorian_timestamp(
ticks: u64,
counter: u16,
node_id: &[u8; 6],
) -> Self {
Builder(timestamp::encode_sorted_gregorian_timestamp(
ticks, counter, node_id,
))
}
/// Creates a `Builder` for a version 7 UUID using the supplied Unix timestamp and counter bytes.
///
/// This method will set the variant field within the counter bytes without attempting to shift
/// the data around it. Callers using the counter as a monotonic value should be careful not to
/// store significant data in the 2 least significant bits of the 3rd byte.
///
/// # Examples
///
/// Creating a UUID using the current system timestamp:
///
/// ```
/// # use std::convert::TryInto;
/// use std::time::{Duration, SystemTime};
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
/// # use uuid::{Builder, Uuid, Variant, Version, Timestamp, NoContext};
/// # let rng = || [
/// # 70, 235, 208, 238, 14, 109, 67, 201, 185, 13
/// # ];
/// let ts = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH)?;
///
/// let random_bytes = rng();
///
/// let uuid = Builder::from_unix_timestamp_millis(ts.as_millis().try_into()?, &random_bytes).into_uuid();
///
/// assert_eq!(Some(Version::SortRand), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// # Ok(())
/// # }
/// ```
pub const fn from_unix_timestamp_millis(millis: u64, counter_random_bytes: &[u8; 10]) -> Self {
Builder(timestamp::encode_unix_timestamp_millis(
millis,
counter_random_bytes,
))
}
/// Creates a `Builder` for a version 8 UUID using the supplied user-defined bytes.
///
/// This method won't interpret the given bytes in any way, except to set the appropriate
/// bits for the UUID version and variant.
pub const fn from_custom_bytes(custom_bytes: Bytes) -> Self {
Builder::from_bytes(custom_bytes)
.with_variant(Variant::RFC4122)
.with_version(Version::Custom)
}
/// Creates a `Builder` using the supplied bytes.
///
/// # Errors
///
/// This function will return an error if `b` has any length other than 16.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// # fn main() -> Result<(), uuid::Error> {
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Builder::from_slice(&bytes)?.into_uuid();
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// # Ok(())
/// # }
/// ```
pub fn from_slice(b: &[u8]) -> Result<Self, Error> {
Ok(Builder(Uuid::from_slice(b)?))
}
/// Creates a `Builder` using the supplied bytes in little endian order.
///
/// The individual fields encoded in the buffer will be flipped.
///
/// # Errors
///
/// This function will return an error if `b` has any length other than 16.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// # fn main() -> Result<(), uuid::Error> {
/// let bytes = [
/// 0xa1, 0xa2, 0xa3, 0xa4,
/// 0xb1, 0xb2,
/// 0xc1, 0xc2,
/// 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8,
/// ];
///
/// let uuid = Builder::from_slice_le(&bytes)?.into_uuid();
///
/// assert_eq!(
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// # Ok(())
/// # }
/// ```
pub fn from_slice_le(b: &[u8]) -> Result<Self, Error> {
Ok(Builder(Uuid::from_slice_le(b)?))
}
/// Creates a `Builder` from four field values.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let d1 = 0xa1a2a3a4;
/// let d2 = 0xb1b2;
/// let d3 = 0xc1c2;
/// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
///
/// let uuid = Builder::from_fields(d1, d2, d3, &d4).into_uuid();
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8"
/// );
/// ```
pub const fn from_fields(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Self {
Builder(Uuid::from_fields(d1, d2, d3, d4))
}
/// Creates a `Builder` from four field values.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let d1 = 0xa1a2a3a4;
/// let d2 = 0xb1b2;
/// let d3 = 0xc1c2;
/// let d4 = [0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8];
///
/// let uuid = Builder::from_fields_le(d1, d2, d3, &d4).into_uuid();
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "a4a3a2a1-b2b1-c2c1-d1d2-d3d4d5d6d7d8"
/// );
/// ```
pub const fn from_fields_le(d1: u32, d2: u16, d3: u16, d4: &[u8; 8]) -> Self {
Builder(Uuid::from_fields_le(d1, d2, d3, d4))
}
/// Creates a `Builder` from a 128bit value.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
///
/// let uuid = Builder::from_u128(v).into_uuid();
///
/// assert_eq!(
/// "a1a2a3a4-b1b2-c1c2-d1d2-d3d4d5d6d7d8",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_u128(v: u128) -> Self {
Builder(Uuid::from_u128(v))
}
/// Creates a UUID from a 128bit value in little-endian order.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let v = 0xa1a2a3a4b1b2c1c2d1d2d3d4d5d6d7d8u128;
///
/// let uuid = Builder::from_u128_le(v).into_uuid();
///
/// assert_eq!(
/// "d8d7d6d5-d4d3-d2d1-c2c1-b2b1a4a3a2a1",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn from_u128_le(v: u128) -> Self {
Builder(Uuid::from_u128_le(v))
}
/// Creates a `Builder` with an initial [`Uuid::nil`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let uuid = Builder::nil().into_uuid();
///
/// assert_eq!(
/// "00000000-0000-0000-0000-000000000000",
/// uuid.hyphenated().to_string(),
/// );
/// ```
pub const fn nil() -> Self {
Builder(Uuid::nil())
}
/// Specifies the variant of the UUID.
pub fn set_variant(&mut self, v: Variant) -> &mut Self {
*self = Builder(self.0).with_variant(v);
self
}
/// Specifies the variant of the UUID.
pub const fn with_variant(mut self, v: Variant) -> Self {
let byte = (self.0).0[8];
(self.0).0[8] = match v {
Variant::NCS => byte & 0x7f,
Variant::RFC4122 => (byte & 0x3f) | 0x80,
Variant::Microsoft => (byte & 0x1f) | 0xc0,
Variant::Future => byte | 0xe0,
};
self
}
/// Specifies the version number of the UUID.
pub fn set_version(&mut self, v: Version) -> &mut Self {
*self = Builder(self.0).with_version(v);
self
}
/// Specifies the version number of the UUID.
pub const fn with_version(mut self, v: Version) -> Self {
(self.0).0[6] = ((self.0).0[6] & 0x0f) | ((v as u8) << 4);
self
}
/// Get a reference to the underlying [`Uuid`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let builder = Builder::nil();
///
/// let uuid1 = builder.as_uuid();
/// let uuid2 = builder.as_uuid();
///
/// assert_eq!(uuid1, uuid2);
/// ```
pub const fn as_uuid(&self) -> &Uuid {
&self.0
}
/// Convert the builder into a [`Uuid`].
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::Builder;
/// let uuid = Builder::nil().into_uuid();
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "00000000-0000-0000-0000-000000000000"
/// );
/// ```
pub const fn into_uuid(self) -> Uuid {
self.0
}
}
#[doc(hidden)]
impl Builder {
#[deprecated(
since = "1.10.0",
note = "use `Builder::from_gregorian_timestamp(ticks, counter, node_id)`"
)]
pub const fn from_rfc4122_timestamp(ticks: u64, counter: u16, node_id: &[u8; 6]) -> Self {
Builder::from_gregorian_timestamp(ticks, counter, node_id)
}
#[deprecated(
since = "1.10.0",
note = "use `Builder::from_sorted_gregorian_timestamp(ticks, counter, node_id)`"
)]
pub const fn from_sorted_rfc4122_timestamp(
ticks: u64,
counter: u16,
node_id: &[u8; 6],
) -> Self {
Builder::from_sorted_gregorian_timestamp(ticks, counter, node_id)
}
}

180
vendor/uuid/src/error.rs vendored Normal file
View File

@@ -0,0 +1,180 @@
use crate::std::fmt;
/// A general error that can occur when working with UUIDs.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct Error(pub(crate) ErrorKind);
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub(crate) enum ErrorKind {
/// Invalid character in the [`Uuid`] string.
///
/// [`Uuid`]: ../struct.Uuid.html
ParseChar { character: char, index: usize },
/// A simple [`Uuid`] didn't contain 32 characters.
///
/// [`Uuid`]: ../struct.Uuid.html
ParseSimpleLength { len: usize },
/// A byte array didn't contain 16 bytes
ParseByteLength { len: usize },
/// A hyphenated [`Uuid`] didn't contain 5 groups
///
/// [`Uuid`]: ../struct.Uuid.html
ParseGroupCount { count: usize },
/// A hyphenated [`Uuid`] had a group that wasn't the right length
///
/// [`Uuid`]: ../struct.Uuid.html
ParseGroupLength {
group: usize,
len: usize,
index: usize,
},
/// The input was not a valid UTF8 string
ParseInvalidUTF8,
/// Some other parsing error occurred.
ParseOther,
/// The UUID is nil.
Nil,
/// A system time was invalid.
#[cfg(feature = "std")]
InvalidSystemTime(&'static str),
}
/// A string that is guaranteed to fail to parse to a [`Uuid`].
///
/// This type acts as a lightweight error indicator, suggesting
/// that the string cannot be parsed but offering no error
/// details. To get details, use `InvalidUuid::into_err`.
///
/// [`Uuid`]: ../struct.Uuid.html
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct InvalidUuid<'a>(pub(crate) &'a [u8]);
impl<'a> InvalidUuid<'a> {
/// Converts the lightweight error type into detailed diagnostics.
pub fn into_err(self) -> Error {
// Check whether or not the input was ever actually a valid UTF8 string
let input_str = match std::str::from_utf8(self.0) {
Ok(s) => s,
Err(_) => return Error(ErrorKind::ParseInvalidUTF8),
};
let (uuid_str, offset, simple) = match input_str.as_bytes() {
[b'{', s @ .., b'}'] => (s, 1, false),
[b'u', b'r', b'n', b':', b'u', b'u', b'i', b'd', b':', s @ ..] => {
(s, "urn:uuid:".len(), false)
}
s => (s, 0, true),
};
let mut hyphen_count = 0;
let mut group_bounds = [0; 4];
// SAFETY: the byte array came from a valid utf8 string,
// and is aligned along char boundaries.
let uuid_str = unsafe { std::str::from_utf8_unchecked(uuid_str) };
for (index, character) in uuid_str.char_indices() {
let byte = character as u8;
if character as u32 - byte as u32 > 0 {
// Multibyte char
return Error(ErrorKind::ParseChar {
character,
index: index + offset + 1,
});
} else if byte == b'-' {
// While we search, also count group breaks
if hyphen_count < 4 {
group_bounds[hyphen_count] = index;
}
hyphen_count += 1;
} else if !byte.is_ascii_hexdigit() {
// Non-hex char
return Error(ErrorKind::ParseChar {
character: byte as char,
index: index + offset + 1,
});
}
}
if hyphen_count == 0 && simple {
// This means that we tried and failed to parse a simple uuid.
// Since we verified that all the characters are valid, this means
// that it MUST have an invalid length.
Error(ErrorKind::ParseSimpleLength {
len: input_str.len(),
})
} else if hyphen_count != 4 {
// We tried to parse a hyphenated variant, but there weren't
// 5 groups (4 hyphen splits).
Error(ErrorKind::ParseGroupCount {
count: hyphen_count + 1,
})
} else {
// There are 5 groups, one of them has an incorrect length
const BLOCK_STARTS: [usize; 5] = [0, 9, 14, 19, 24];
for i in 0..4 {
if group_bounds[i] != BLOCK_STARTS[i + 1] - 1 {
return Error(ErrorKind::ParseGroupLength {
group: i,
len: group_bounds[i] - BLOCK_STARTS[i],
index: offset + BLOCK_STARTS[i] + 1,
});
}
}
// The last group must be too long
Error(ErrorKind::ParseGroupLength {
group: 4,
len: input_str.len() - BLOCK_STARTS[4],
index: offset + BLOCK_STARTS[4] + 1,
})
}
}
}
// NOTE: This impl is part of the public API. Breaking changes to it should be carefully considered
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.0 {
ErrorKind::ParseChar {
character, index, ..
} => {
write!(f, "invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found `{}` at {}", character, index)
}
ErrorKind::ParseSimpleLength { len } => {
write!(
f,
"invalid length: expected length 32 for simple format, found {}",
len
)
}
ErrorKind::ParseByteLength { len } => {
write!(f, "invalid length: expected 16 bytes, found {}", len)
}
ErrorKind::ParseGroupCount { count } => {
write!(f, "invalid group count: expected 5, found {}", count)
}
ErrorKind::ParseGroupLength { group, len, .. } => {
let expected = [8, 4, 4, 4, 12][group];
write!(
f,
"invalid group length in group {}: expected {}, found {}",
group, expected, len
)
}
ErrorKind::ParseInvalidUTF8 => write!(f, "non-UTF8 input"),
ErrorKind::Nil => write!(f, "the UUID is nil"),
ErrorKind::ParseOther => write!(f, "failed to parse a UUID"),
#[cfg(feature = "std")]
ErrorKind::InvalidSystemTime(ref e) => write!(f, "the system timestamp is invalid: {e}"),
}
}
}
#[cfg(feature = "std")]
mod std_support {
use super::*;
use crate::std::error;
impl error::Error for Error { }
}

8
vendor/uuid/src/external.rs vendored Normal file
View File

@@ -0,0 +1,8 @@
#[cfg(feature = "arbitrary")]
pub(crate) mod arbitrary_support;
#[cfg(feature = "borsh")]
pub(crate) mod borsh_support;
#[cfg(feature = "serde")]
pub(crate) mod serde_support;
#[cfg(feature = "slog")]
pub(crate) mod slog_support;

View File

@@ -0,0 +1,71 @@
use crate::{
non_nil::NonNilUuid,
std::convert::{TryFrom, TryInto},
Builder, Uuid,
};
use arbitrary::{Arbitrary, Unstructured};
impl Arbitrary<'_> for Uuid {
fn arbitrary(u: &mut Unstructured<'_>) -> arbitrary::Result<Self> {
let b = u
.bytes(16)?
.try_into()
.map_err(|_| arbitrary::Error::NotEnoughData)?;
Ok(Builder::from_random_bytes(b).into_uuid())
}
fn size_hint(_: usize) -> (usize, Option<usize>) {
(16, Some(16))
}
}
impl arbitrary::Arbitrary<'_> for NonNilUuid {
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
let uuid = Uuid::arbitrary(u)?;
Self::try_from(uuid).map_err(|_| arbitrary::Error::IncorrectFormat)
}
fn size_hint(_: usize) -> (usize, Option<usize>) {
(16, Some(16))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Variant, Version};
#[test]
fn test_arbitrary() {
let mut bytes = Unstructured::new(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
let uuid = Uuid::arbitrary(&mut bytes).unwrap();
assert_eq!(Some(Version::Random), uuid.get_version());
assert_eq!(Variant::RFC4122, uuid.get_variant());
}
#[test]
fn test_arbitrary_empty() {
let mut bytes = Unstructured::new(&[]);
// Ensure we don't panic when building an arbitrary `Uuid`
let uuid = Uuid::arbitrary(&mut bytes);
assert!(uuid.is_err());
}
#[test]
fn test_arbitrary_non_nil() {
let mut bytes = Unstructured::new(&[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
let non_nil_uuid = NonNilUuid::arbitrary(&mut bytes).unwrap();
let uuid: Uuid = non_nil_uuid.into();
assert_eq!(Some(Version::Random), uuid.get_version());
assert_eq!(Variant::RFC4122, uuid.get_variant());
assert!(!uuid.is_nil());
}
}

View File

@@ -0,0 +1,23 @@
#[cfg(test)]
mod borsh_tests {
use crate::Uuid;
use std::string::ToString;
#[test]
fn test_serialize() {
let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
let uuid = Uuid::parse_str(uuid_str).unwrap();
let uuid_bytes = uuid.as_bytes().to_vec();
let borsh_bytes = borsh::to_vec(&uuid).unwrap();
assert_eq!(uuid_bytes, borsh_bytes);
}
#[test]
fn test_deserialize() {
let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
let uuid = Uuid::parse_str(uuid_str).unwrap();
let uuid_bytes = uuid.as_bytes().to_vec();
let deserialized = borsh::from_slice::<Uuid>(&uuid_bytes).unwrap().to_string();
assert_eq!(uuid_str, deserialized);
}
}

View File

@@ -0,0 +1,769 @@
// 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::{
convert::TryFrom,
error::*,
fmt::{Braced, Hyphenated, Simple, Urn},
non_nil::NonNilUuid,
std::fmt,
Uuid,
};
use serde::{
de::{self, Error as _},
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.hyphenated().encode_lower(&mut Uuid::encode_buffer()))
} else {
serializer.serialize_bytes(self.as_bytes())
}
}
}
impl Serialize for NonNilUuid {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
Uuid::from(*self).serialize(serializer)
}
}
impl Serialize for Hyphenated {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
}
}
impl Serialize for Simple {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
}
}
impl Serialize for Urn {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
}
}
impl Serialize for Braced {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(self.encode_lower(&mut Uuid::encode_buffer()))
}
}
impl<'de> Deserialize<'de> for Uuid {
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
fn de_error<E: de::Error>(e: Error) -> E {
E::custom(format_args!("UUID parsing failed: {}", e))
}
if deserializer.is_human_readable() {
struct UuidVisitor;
impl<'vi> de::Visitor<'vi> for UuidVisitor {
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)
}
fn visit_seq<A>(self, mut seq: A) -> Result<Uuid, A::Error>
where
A: de::SeqAccess<'vi>,
{
#[rustfmt::skip]
let bytes = [
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(0, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(1, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(2, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(3, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(4, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(5, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(6, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(7, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(8, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(9, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(10, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(11, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(12, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(13, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(14, &self)) },
match seq.next_element()? { Some(e) => e, None => return Err(A::Error::invalid_length(15, &self)) },
];
Ok(Uuid::from_bytes(bytes))
}
}
deserializer.deserialize_str(UuidVisitor)
} 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)
}
}
}
impl<'de> Deserialize<'de> for NonNilUuid {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let uuid = Uuid::deserialize(deserializer)?;
NonNilUuid::try_from(uuid).map_err(|_| {
de::Error::invalid_value(de::Unexpected::Other("nil UUID"), &"a non-nil UUID")
})
}
}
enum ExpectedFormat {
Simple,
Braced,
Urn,
}
impl std::fmt::Display for ExpectedFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
ExpectedFormat::Simple => "a simple Uuid string like 67e5504410b1426f9247bb680e5fe0c8",
ExpectedFormat::Braced => {
"a braced Uuid string like {67e55044-10b1-426f-9247-bb680e5fe0c8}"
}
ExpectedFormat::Urn => {
"a URN Uuid string like urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8"
}
};
f.write_str(s)
}
}
impl de::Expected for ExpectedFormat {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
<ExpectedFormat as std::fmt::Display>::fmt(self, formatter)
}
}
pub mod compact {
//! Serialize a [`Uuid`] as a `[u8; 16]`.
//!
//! [`Uuid`]: ../../struct.Uuid.html
/// Serialize from a [`Uuid`] as 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)
}
/// Deserialize a `[u8; 16]` as 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_derive::*;
use serde_test::Configure;
#[test]
fn test_serialize_compact() {
#[derive(Serialize, Debug, Deserialize, PartialEq)]
struct UuidContainer {
#[serde(with = "crate::serde::compact")]
u: crate::Uuid,
}
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,
],
)
}
}
}
/// Serialize from a [`Uuid`] as a `uuid::fmt::Simple`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// ## Example
///
/// ```rust
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructA {
/// // This will change both serailization and deserialization
/// #[serde(with = "uuid::serde::simple")]
/// id: uuid::Uuid,
/// }
///
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructB {
/// // This will be serialized as uuid::fmt::Simple and deserialize from all valid formats
/// #[serde(serialize_with = "uuid::serde::simple::serialize")]
/// id: uuid::Uuid,
/// }
/// ```
pub mod simple {
use serde::{de, Deserialize};
use crate::{parser::parse_simple, Uuid};
use super::ExpectedFormat;
/// Serialize from a [`Uuid`] as a `uuid::fmt::Simple`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// # Example
///
/// ```rust
/// #[derive(serde_derive::Serialize)]
/// struct Struct {
/// // This will be serialize as uuid::fmt::Simple
/// #[serde(serialize_with = "uuid::serde::simple::serialize")]
/// id: uuid::Uuid,
/// }
///
/// ```
pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serde::Serialize::serialize(u.as_simple(), serializer)
}
/// Deserialize a simple Uuid string as a [`Uuid`]
///
/// [`Uuid`]: ../../struct.Uuid.html
pub fn deserialize<'de, D>(deserializer: D) -> Result<Uuid, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = <&str as Deserialize>::deserialize(deserializer)?;
let bytes = parse_simple(s.as_bytes()).map_err(|_| {
de::Error::invalid_value(de::Unexpected::Str(s), &ExpectedFormat::Simple)
})?;
Ok(Uuid::from_bytes(bytes))
}
#[cfg(test)]
mod tests {
use serde::de::{self, Error};
use serde_test::{Readable, Token};
use crate::{external::serde_support::ExpectedFormat, Uuid};
const HYPHENATED_UUID_STR: &'static str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
const SIMPLE_UUID_STR: &'static str = "f9168c5eceb24faab6bf329bf39fa1e4";
#[test]
fn test_serialize_as_simple() {
#[derive(serde_derive::Serialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
serde_test::assert_ser_tokens(
&u,
&[
Token::NewtypeStruct { name: "Struct" },
Token::Str(SIMPLE_UUID_STR),
],
);
}
#[test]
fn test_de_from_simple() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
serde_test::assert_de_tokens::<Struct>(
&s,
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(SIMPLE_UUID_STR),
Token::TupleStructEnd,
],
);
}
#[test]
fn test_de_reject_hypenated() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
serde_test::assert_de_tokens_error::<Readable<Struct>>(
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(HYPHENATED_UUID_STR),
Token::TupleStructEnd,
],
&format!(
"{}",
de::value::Error::invalid_value(
de::Unexpected::Str(HYPHENATED_UUID_STR),
&ExpectedFormat::Simple,
)
),
);
}
}
}
/// Serialize from a [`Uuid`] as a `uuid::fmt::Braced`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// ## Example
///
/// ```rust
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructA {
/// // This will change both serailization and deserialization
/// #[serde(with = "uuid::serde::braced")]
/// id: uuid::Uuid,
/// }
///
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructB {
/// // This will be serialized as uuid::fmt::Urn and deserialize from all valid formats
/// #[serde(serialize_with = "uuid::serde::braced::serialize")]
/// id: uuid::Uuid,
/// }
/// ```
pub mod braced {
use serde::{de, Deserialize};
use crate::parser::parse_braced;
use super::ExpectedFormat;
/// Serialize from a [`Uuid`] as a `uuid::fmt::Braced`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// # Example
///
/// ```rust
/// #[derive(serde_derive::Serialize)]
/// struct Struct {
/// // This will be serialize as uuid::fmt::Braced
/// #[serde(serialize_with = "uuid::serde::braced::serialize")]
/// id: uuid::Uuid,
/// }
///
/// ```
pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serde::Serialize::serialize(u.as_braced(), serializer)
}
/// Deserialize a braced Uuid string as a [`Uuid`]
///
/// [`Uuid`]: ../../struct.Uuid.html
pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = <&str as Deserialize>::deserialize(deserializer)?;
let bytes = parse_braced(s.as_bytes()).map_err(|_| {
de::Error::invalid_value(de::Unexpected::Str(s), &ExpectedFormat::Braced)
})?;
Ok(crate::Uuid::from_bytes(bytes))
}
#[cfg(test)]
mod tests {
use serde::de::{self, Error};
use serde_test::{Readable, Token};
use crate::{external::serde_support::ExpectedFormat, Uuid};
const HYPHENATED_UUID_STR: &'static str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
const BRACED_UUID_STR: &'static str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
#[test]
fn test_serialize_as_braced() {
#[derive(serde_derive::Serialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
serde_test::assert_ser_tokens(
&u,
&[
Token::NewtypeStruct { name: "Struct" },
Token::Str(BRACED_UUID_STR),
],
);
}
#[test]
fn test_de_from_braced() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
serde_test::assert_de_tokens::<Struct>(
&s,
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(BRACED_UUID_STR),
Token::TupleStructEnd,
],
);
}
#[test]
fn test_de_reject_hypenated() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
serde_test::assert_de_tokens_error::<Readable<Struct>>(
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(HYPHENATED_UUID_STR),
Token::TupleStructEnd,
],
&format!(
"{}",
de::value::Error::invalid_value(
de::Unexpected::Str(HYPHENATED_UUID_STR),
&ExpectedFormat::Braced,
)
),
);
}
}
}
/// Serialize from a [`Uuid`] as a `uuid::fmt::Urn`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// ## Example
///
/// ```rust
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructA {
/// // This will change both serailization and deserialization
/// #[serde(with = "uuid::serde::urn")]
/// id: uuid::Uuid,
/// }
///
/// #[derive(serde_derive::Serialize, serde_derive::Deserialize)]
/// struct StructB {
/// // This will be serialized as uuid::fmt::Urn and deserialize from all valid formats
/// #[serde(serialize_with = "uuid::serde::urn::serialize")]
/// id: uuid::Uuid,
/// }
/// ```
pub mod urn {
use serde::{de, Deserialize};
use crate::parser::parse_urn;
use super::ExpectedFormat;
/// Serialize from a [`Uuid`] as a `uuid::fmt::Urn`
///
/// [`Uuid`]: ../../struct.Uuid.html
///
/// # Example
///
/// ```rust
/// #[derive(serde_derive::Serialize)]
/// struct Struct {
/// // This will be serialize as uuid::fmt::Urn
/// #[serde(serialize_with = "uuid::serde::urn::serialize")]
/// id: uuid::Uuid,
/// }
///
/// ```
pub fn serialize<S>(u: &crate::Uuid, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serde::Serialize::serialize(u.as_urn(), serializer)
}
/// Deserialize a urn Uuid string as a [`Uuid`]
///
/// [`Uuid`]: ../../struct.Uuid.html
pub fn deserialize<'de, D>(deserializer: D) -> Result<crate::Uuid, D::Error>
where
D: serde::Deserializer<'de>,
{
let s = <&str as Deserialize>::deserialize(deserializer)?;
let bytes = parse_urn(s.as_bytes())
.map_err(|_| de::Error::invalid_value(de::Unexpected::Str(s), &ExpectedFormat::Urn))?;
Ok(crate::Uuid::from_bytes(bytes))
}
#[cfg(test)]
mod tests {
use serde::de::{self, Error};
use serde_test::{Readable, Token};
use crate::{external::serde_support::ExpectedFormat, Uuid};
const HYPHENATED_UUID_STR: &'static str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
const URN_UUID_STR: &'static str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
#[test]
fn test_serialize_as_urn() {
#[derive(serde_derive::Serialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let u = Struct(Uuid::parse_str(HYPHENATED_UUID_STR).unwrap());
serde_test::assert_ser_tokens(
&u,
&[
Token::NewtypeStruct { name: "Struct" },
Token::Str(URN_UUID_STR),
],
);
}
#[test]
fn test_de_from_urn() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
let s = Struct(HYPHENATED_UUID_STR.parse().unwrap());
serde_test::assert_de_tokens::<Struct>(
&s,
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(URN_UUID_STR),
Token::TupleStructEnd,
],
);
}
#[test]
fn test_de_reject_hypenated() {
#[derive(PartialEq, Debug, serde_derive::Deserialize)]
struct Struct(#[serde(with = "super")] crate::Uuid);
serde_test::assert_de_tokens_error::<Readable<Struct>>(
&[
Token::TupleStruct {
name: "Struct",
len: 1,
},
Token::BorrowedStr(HYPHENATED_UUID_STR),
Token::TupleStructEnd,
],
&format!(
"{}",
de::value::Error::invalid_value(
de::Unexpected::Str(HYPHENATED_UUID_STR),
&ExpectedFormat::Urn,
)
),
);
}
}
}
#[cfg(test)]
mod serde_tests {
use super::*;
use serde_test::{Compact, Configure, Readable, Token};
#[test]
fn test_serialize_readable_string() {
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_deserialize_readable_compact() {
let uuid_bytes = b"F9168C5E-CEB2-4F";
let u = Uuid::from_slice(uuid_bytes).unwrap();
serde_test::assert_de_tokens(
&u.readable(),
&[
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,
],
);
}
#[test]
fn test_deserialize_readable_bytes() {
let uuid_bytes = b"F9168C5E-CEB2-4F";
let u = Uuid::from_slice(uuid_bytes).unwrap();
serde_test::assert_de_tokens(&u.readable(), &[serde_test::Token::Bytes(uuid_bytes)]);
}
#[test]
fn test_serialize_hyphenated() {
let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
let u = Uuid::parse_str(uuid_str).unwrap();
serde_test::assert_ser_tokens(&u.hyphenated(), &[Token::Str(uuid_str)]);
}
#[test]
fn test_serialize_simple() {
let uuid_str = "f9168c5eceb24faab6bf329bf39fa1e4";
let u = Uuid::parse_str(uuid_str).unwrap();
serde_test::assert_ser_tokens(&u.simple(), &[Token::Str(uuid_str)]);
}
#[test]
fn test_serialize_urn() {
let uuid_str = "urn:uuid:f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
let u = Uuid::parse_str(uuid_str).unwrap();
serde_test::assert_ser_tokens(&u.urn(), &[Token::Str(uuid_str)]);
}
#[test]
fn test_serialize_braced() {
let uuid_str = "{f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4}";
let u = Uuid::parse_str(uuid_str).unwrap();
serde_test::assert_ser_tokens(&u.braced(), &[Token::Str(uuid_str)]);
}
#[test]
fn test_serialize_non_human_readable() {
let uuid_bytes = b"F9168C5E-CEB2-4F";
let u = Uuid::from_slice(uuid_bytes).unwrap();
serde_test::assert_tokens(
&u.compact(),
&[serde_test::Token::Bytes(&[
70, 57, 49, 54, 56, 67, 53, 69, 45, 67, 69, 66, 50, 45, 52, 70,
])],
);
}
#[test]
fn test_de_failure() {
serde_test::assert_de_tokens_error::<Readable<Uuid>>(
&[Token::Str("hello_world")],
"UUID parsing failed: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found `h` at 1",
);
serde_test::assert_de_tokens_error::<Compact<Uuid>>(
&[Token::Bytes(b"hello_world")],
"UUID parsing failed: invalid length: expected 16 bytes, found 11",
);
}
#[test]
fn test_serde_non_nil_uuid() {
let uuid_str = "f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4";
let uuid = Uuid::parse_str(uuid_str).unwrap();
let non_nil_uuid = NonNilUuid::try_from(uuid).unwrap();
serde_test::assert_ser_tokens(&non_nil_uuid.readable(), &[Token::Str(uuid_str)]);
serde_test::assert_de_tokens(&non_nil_uuid.readable(), &[Token::Str(uuid_str)]);
}
}

View File

@@ -0,0 +1,48 @@
// 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::{non_nil::NonNilUuid, Uuid};
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))
}
}
impl slog::Value for NonNilUuid {
fn serialize(
&self,
record: &slog::Record<'_>,
key: slog::Key,
serializer: &mut dyn slog::Serializer,
) -> Result<(), slog::Error> {
Uuid::from(*self).serialize(record, key, serializer)
}
}
#[cfg(test)]
mod tests {
use crate::tests::new;
use slog::{crit, Drain};
#[test]
fn test_slog_kv() {
let root = slog::Logger::root(slog::Discard.fuse(), slog::o!());
let u1 = new();
crit!(root, "test"; "u1" => u1);
}
}

1162
vendor/uuid/src/fmt.rs vendored Normal file

File diff suppressed because it is too large Load Diff

1744
vendor/uuid/src/lib.rs vendored Normal file

File diff suppressed because it is too large Load Diff

118
vendor/uuid/src/macros.rs vendored Normal file
View File

@@ -0,0 +1,118 @@
macro_rules! define_uuid_macro {
{$(#[$doc:meta])*} => {
$(#[$doc])*
#[cfg(feature = "macro-diagnostics")]
#[macro_export]
macro_rules! uuid {
($uuid:expr) => {{
const OUTPUT: $crate::Uuid = match $crate::Uuid::try_parse($uuid) {
$crate::__macro_support::Ok(u) => u,
$crate::__macro_support::Err(_) => panic!("invalid UUID"),
};
OUTPUT
}};
($uuid:literal) => {{
$crate::Uuid::from_bytes($crate::uuid_macro_internal::parse_lit!($uuid))
}};
}
$(#[$doc])*
#[cfg(not(feature = "macro-diagnostics"))]
#[macro_export]
macro_rules! uuid {
($uuid:expr) => {{
const OUTPUT: $crate::Uuid = match $crate::Uuid::try_parse($uuid) {
$crate::__macro_support::Ok(u) => u,
$crate::__macro_support::Err(_) => panic!("invalid UUID"),
};
OUTPUT
}};
}
}
}
define_uuid_macro! {
/// Parse [`Uuid`][uuid::Uuid]s from string literals at compile time.
///
/// ## Usage
///
/// This macro transforms the string literal representation of a
/// [`Uuid`][uuid::Uuid] into the bytes representation, raising a compilation
/// error if it cannot properly be parsed.
///
/// ## Examples
///
/// Setting a global constant:
///
/// ```
/// # use uuid::{uuid, Uuid};
/// pub const SCHEMA_ATTR_CLASS: Uuid = uuid!("00000000-0000-0000-0000-ffff00000000");
/// pub const SCHEMA_ATTR_UUID: Uuid = uuid!("00000000-0000-0000-0000-ffff00000001");
/// pub const SCHEMA_ATTR_NAME: Uuid = uuid!("00000000-0000-0000-0000-ffff00000002");
/// ```
///
/// Defining a local variable:
///
/// ```
/// # use uuid::uuid;
/// let uuid = uuid!("urn:uuid:F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4");
/// ```
/// Using a const variable:
/// ```
/// # use uuid::uuid;
/// const UUID_STR: &str = "12345678-1234-5678-1234-567812345678";
/// let UUID = uuid!(UUID_STR);
/// ```
///
/// ## Compilation Failures
///
/// Invalid UUIDs are rejected:
///
/// ```compile_fail
/// # use uuid::uuid;
/// let uuid = uuid!("F9168C5E-ZEB2-4FAA-B6BF-329BF39FA1E4");
/// ```
///
/// Enable the feature `macro-diagnostics` to see the error messages below.
///
/// Provides the following compilation error:
///
/// ```txt
/// error: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-fA-F-], found Z at 9
/// |
/// | let id = uuid!("F9168C5E-ZEB2-4FAA-B6BF-329BF39FA1E4");
/// | ^
/// ```
///
/// [uuid::Uuid]: https://docs.rs/uuid/*/uuid/struct.Uuid.html
}
// Internal macros
// These `transmute` macros are a stepping stone towards `zerocopy` integration.
// When the `zerocopy` feature is enabled, which it is in CI, the transmutes are
// checked by it
// SAFETY: Callers must ensure this call would be safe when handled by zerocopy
#[cfg(not(all(uuid_unstable, feature = "zerocopy")))]
macro_rules! unsafe_transmute_ref(
($e:expr) => { unsafe { core::mem::transmute::<&_, &_>($e) } }
);
// SAFETY: Callers must ensure this call would be safe when handled by zerocopy
#[cfg(all(uuid_unstable, feature = "zerocopy"))]
macro_rules! unsafe_transmute_ref(
($e:expr) => { zerocopy::transmute_ref!($e) }
);
// SAFETY: Callers must ensure this call would be safe when handled by zerocopy
#[cfg(not(all(uuid_unstable, feature = "zerocopy")))]
macro_rules! unsafe_transmute(
($e:expr) => { unsafe { core::mem::transmute::<_, _>($e) } }
);
// SAFETY: Callers must ensure this call would be safe when handled by zerocopy
#[cfg(all(uuid_unstable, feature = "zerocopy"))]
macro_rules! unsafe_transmute(
($e:expr) => { zerocopy::transmute!($e) }
);

14
vendor/uuid/src/md5.rs vendored Normal file
View File

@@ -0,0 +1,14 @@
#[cfg(feature = "v3")]
pub(crate) fn hash(ns: &[u8], src: &[u8]) -> [u8; 16] {
use md5::{Digest, Md5};
let mut hasher = Md5::new();
hasher.update(ns);
hasher.update(src);
let mut bytes = [0; 16];
bytes.copy_from_slice(&hasher.finalize()[..16]);
bytes
}

157
vendor/uuid/src/non_nil.rs vendored Normal file
View File

@@ -0,0 +1,157 @@
//! A wrapper type for nil UUIDs that provides a more memory-efficient
//! `Option<NonNilUuid>` representation.
use core::convert::TryFrom;
use std::{fmt, num::NonZeroU128};
use crate::{
error::{Error, ErrorKind},
Uuid,
};
/// A UUID that is guaranteed not to be the [nil UUID](https://www.ietf.org/rfc/rfc9562.html#name-nil-uuid).
///
/// This is useful for representing optional UUIDs more efficiently, as `Option<NonNilUuid>`
/// takes up the same space as `Uuid`.
///
/// Note that `Uuid`s created by the following methods are guaranteed to be non-nil:
///
/// - [`Uuid::new_v1`]
/// - [`Uuid::now_v1`]
/// - [`Uuid::new_v3`]
/// - [`Uuid::new_v4`]
/// - [`Uuid::new_v5`]
/// - [`Uuid::new_v6`]
/// - [`Uuid::now_v6`]
/// - [`Uuid::new_v7`]
/// - [`Uuid::now_v7`]
/// - [`Uuid::new_v8`]
///
/// # ABI
///
/// The `NonNilUuid` type does not yet have a stable ABI. Its representation or alignment
/// may change. It is currently only guaranteed that `NonNilUuid` and `Option<NonNilUuid>`
/// are the same size as `Uuid`.
#[repr(transparent)]
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
pub struct NonNilUuid(NonZeroU128);
impl fmt::Debug for NonNilUuid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&Uuid::from(*self), f)
}
}
impl fmt::Display for NonNilUuid {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&Uuid::from(*self), f)
}
}
impl PartialEq<Uuid> for NonNilUuid {
fn eq(&self, other: &Uuid) -> bool {
self.get() == *other
}
}
impl PartialEq<NonNilUuid> for Uuid {
fn eq(&self, other: &NonNilUuid) -> bool {
*self == other.get()
}
}
impl NonNilUuid {
/// Creates a non-nil UUID if the value is non-nil.
pub const fn new(uuid: Uuid) -> Option<Self> {
match NonZeroU128::new(uuid.as_u128()) {
Some(non_nil) => Some(NonNilUuid(non_nil)),
None => None,
}
}
/// Creates a non-nil without checking whether the value is non-nil. This results in undefined behavior if the value is nil.
///
/// # Safety
///
/// The value must not be nil.
pub const unsafe fn new_unchecked(uuid: Uuid) -> Self {
NonNilUuid(unsafe { NonZeroU128::new_unchecked(uuid.as_u128()) })
}
/// Get the underlying [`Uuid`] value.
#[inline]
pub const fn get(self) -> Uuid {
Uuid::from_u128(self.0.get())
}
}
impl From<NonNilUuid> for Uuid {
/// Converts a [`NonNilUuid`] back into a [`Uuid`].
///
/// # Examples
/// ```
/// # use std::convert::TryFrom;
/// # use uuid::{NonNilUuid, Uuid};
/// let uuid = Uuid::from_u128(0x0123456789abcdef0123456789abcdef);
/// let non_nil = NonNilUuid::try_from(uuid).unwrap();
/// let uuid_again = Uuid::from(non_nil);
///
/// assert_eq!(uuid, uuid_again);
/// ```
fn from(non_nil: NonNilUuid) -> Self {
Uuid::from_u128(non_nil.0.get())
}
}
impl TryFrom<Uuid> for NonNilUuid {
type Error = Error;
/// Attempts to convert a [`Uuid`] into a [`NonNilUuid`].
///
/// # Examples
/// ```
/// # use std::convert::TryFrom;
/// # use uuid::{NonNilUuid, Uuid};
/// let uuid = Uuid::from_u128(0x0123456789abcdef0123456789abcdef);
/// let non_nil = NonNilUuid::try_from(uuid).unwrap();
/// ```
fn try_from(uuid: Uuid) -> Result<Self, Self::Error> {
NonZeroU128::new(uuid.as_u128())
.map(Self)
.ok_or(Error(ErrorKind::Nil))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_non_nil_with_option_size() {
assert_eq!(
std::mem::size_of::<Option<NonNilUuid>>(),
std::mem::size_of::<Uuid>()
);
}
#[test]
fn test_non_nil() {
let uuid = Uuid::from_u128(0x0123456789abcdef0123456789abcdef);
assert_eq!(Uuid::from(NonNilUuid::try_from(uuid).unwrap()), uuid);
assert_eq!(NonNilUuid::new(uuid).unwrap(), uuid);
assert_eq!(unsafe { NonNilUuid::new_unchecked(uuid) }, uuid);
assert!(NonNilUuid::try_from(Uuid::nil()).is_err());
assert!(NonNilUuid::new(Uuid::nil()).is_none());
}
#[test]
fn test_non_nil_formatting() {
let uuid = Uuid::from_u128(0x0123456789abcdef0123456789abcdef);
let non_nil = NonNilUuid::try_from(uuid).unwrap();
assert_eq!(format!("{uuid}"), format!("{non_nil}"));
assert_eq!(format!("{uuid:?}"), format!("{non_nil:?}"));
}
}

574
vendor/uuid/src/parser.rs vendored Normal file
View File

@@ -0,0 +1,574 @@
// 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
use crate::{
error::*,
std::{convert::TryFrom, str},
Uuid,
};
#[cfg(feature = "std")]
use crate::std::string::String;
impl str::FromStr for Uuid {
type Err = Error;
fn from_str(uuid_str: &str) -> Result<Self, Self::Err> {
Uuid::parse_str(uuid_str)
}
}
impl TryFrom<&'_ str> for Uuid {
type Error = Error;
fn try_from(uuid_str: &'_ str) -> Result<Self, Self::Error> {
Uuid::parse_str(uuid_str)
}
}
#[cfg(feature = "std")]
impl TryFrom<String> for Uuid {
type Error = Error;
fn try_from(uuid_str: String) -> Result<Self, Self::Error> {
Uuid::try_from(uuid_str.as_ref())
}
}
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,
/// Microsoft GUID) are supported by this parsing function.
///
/// Prefer [`try_parse`] unless you need detailed user-facing diagnostics.
/// This method will be eventually deprecated in favor of `try_parse`.
///
/// # Examples
///
/// Parse a hyphenated UUID:
///
/// ```
/// # use uuid::{Uuid, Version, Variant};
/// # fn main() -> Result<(), uuid::Error> {
/// let uuid = Uuid::parse_str("550e8400-e29b-41d4-a716-446655440000")?;
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// # Ok(())
/// # }
/// ```
///
/// [`try_parse`]: #method.try_parse
pub fn parse_str(input: &str) -> Result<Uuid, Error> {
try_parse(input.as_bytes())
.map(Uuid::from_bytes)
.map_err(InvalidUuid::into_err)
}
/// Parses a `Uuid` from a string of hexadecimal digits with optional
/// hyphens.
///
/// This function is similar to [`parse_str`], in fact `parse_str` shares
/// the same underlying parser. The difference is that if `try_parse`
/// fails, it won't generate very useful error messages. The `parse_str`
/// function will eventually be deprecated in favor of `try_parse`.
///
/// To parse a UUID from a byte stream instead of a UTF8 string, see
/// [`try_parse_ascii`].
///
/// # Examples
///
/// Parse a hyphenated UUID:
///
/// ```
/// # use uuid::{Uuid, Version, Variant};
/// # fn main() -> Result<(), uuid::Error> {
/// let uuid = Uuid::try_parse("550e8400-e29b-41d4-a716-446655440000")?;
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// # Ok(())
/// # }
/// ```
///
/// [`parse_str`]: #method.parse_str
/// [`try_parse_ascii`]: #method.try_parse_ascii
pub const fn try_parse(input: &str) -> Result<Uuid, Error> {
Self::try_parse_ascii(input.as_bytes())
}
/// Parses a `Uuid` from a string of hexadecimal digits with optional
/// hyphens.
///
/// The input is expected to be a string of ASCII characters. This method
/// can be more convenient than [`try_parse`] if the UUID is being
/// parsed from a byte stream instead of from a UTF8 string.
///
/// # Examples
///
/// Parse a hyphenated UUID:
///
/// ```
/// # use uuid::{Uuid, Version, Variant};
/// # fn main() -> Result<(), uuid::Error> {
/// let uuid = Uuid::try_parse_ascii(b"550e8400-e29b-41d4-a716-446655440000")?;
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// assert_eq!(Variant::RFC4122, uuid.get_variant());
/// # Ok(())
/// # }
/// ```
///
/// [`try_parse`]: #method.try_parse
pub const fn try_parse_ascii(input: &[u8]) -> Result<Uuid, Error> {
match try_parse(input) {
Ok(bytes) => Ok(Uuid::from_bytes(bytes)),
// If parsing fails then we don't know exactly what went wrong
// In this case, we just return a generic error
Err(_) => Err(Error(ErrorKind::ParseOther)),
}
}
}
const fn try_parse(input: &'_ [u8]) -> Result<[u8; 16], InvalidUuid<'_>> {
match (input.len(), input) {
// Inputs of 32 bytes must be a non-hyphenated UUID
(32, s) => parse_simple(s),
// Hyphenated UUIDs may be wrapped in various ways:
// - `{UUID}` for braced UUIDs
// - `urn:uuid:UUID` for URNs
// - `UUID` for a regular hyphenated UUID
(36, s)
| (38, [b'{', s @ .., b'}'])
| (45, [b'u', b'r', b'n', b':', b'u', b'u', b'i', b'd', b':', s @ ..]) => {
parse_hyphenated(s)
}
// Any other shaped input is immediately invalid
_ => Err(InvalidUuid(input)),
}
}
#[inline]
#[allow(dead_code)]
pub(crate) const fn parse_braced(input: &'_ [u8]) -> Result<[u8; 16], InvalidUuid<'_>> {
if let (38, [b'{', s @ .., b'}']) = (input.len(), input) {
parse_hyphenated(s)
} else {
Err(InvalidUuid(input))
}
}
#[inline]
#[allow(dead_code)]
pub(crate) const fn parse_urn(input: &'_ [u8]) -> Result<[u8; 16], InvalidUuid<'_>> {
if let (45, [b'u', b'r', b'n', b':', b'u', b'u', b'i', b'd', b':', s @ ..]) =
(input.len(), input)
{
parse_hyphenated(s)
} else {
Err(InvalidUuid(input))
}
}
#[inline]
pub(crate) const fn parse_simple(s: &'_ [u8]) -> Result<[u8; 16], InvalidUuid<'_>> {
// This length check here removes all other bounds
// checks in this function
if s.len() != 32 {
return Err(InvalidUuid(s));
}
let mut buf: [u8; 16] = [0; 16];
let mut i = 0;
while i < 16 {
// Convert a two-char hex value (like `A8`)
// into a byte (like `10101000`)
let h1 = HEX_TABLE[s[i * 2] as usize];
let h2 = HEX_TABLE[s[i * 2 + 1] as usize];
// We use `0xff` as a sentinel value to indicate
// an invalid hex character sequence (like the letter `G`)
if h1 | h2 == 0xff {
return Err(InvalidUuid(s));
}
// The upper nibble needs to be shifted into position
// to produce the final byte value
buf[i] = SHL4_TABLE[h1 as usize] | h2;
i += 1;
}
Ok(buf)
}
#[inline]
pub(crate) const fn parse_hyphenated(s: &'_ [u8]) -> Result<[u8; 16], InvalidUuid<'_>> {
// This length check here removes all other bounds
// checks in this function
if s.len() != 36 {
return Err(InvalidUuid(s));
}
// We look at two hex-encoded values (4 chars) at a time because
// that's the size of the smallest group in a hyphenated UUID.
// The indexes we're interested in are:
//
// uuid : 936da01f-9abd-4d9d-80c7-02af85c822a8
// | | || || || || | |
// hyphens : | | 8| 13| 18| 23| | |
// positions: 0 4 9 14 19 24 28 32
// First, ensure the hyphens appear in the right places
match [s[8], s[13], s[18], s[23]] {
[b'-', b'-', b'-', b'-'] => {}
_ => return Err(InvalidUuid(s)),
}
let positions: [u8; 8] = [0, 4, 9, 14, 19, 24, 28, 32];
let mut buf: [u8; 16] = [0; 16];
let mut j = 0;
while j < 8 {
let i = positions[j];
// The decoding here is the same as the simple case
// We're just dealing with two values instead of one
let h1 = HEX_TABLE[s[i as usize] as usize];
let h2 = HEX_TABLE[s[(i + 1) as usize] as usize];
let h3 = HEX_TABLE[s[(i + 2) as usize] as usize];
let h4 = HEX_TABLE[s[(i + 3) as usize] as usize];
if h1 | h2 | h3 | h4 == 0xff {
return Err(InvalidUuid(s));
}
buf[j * 2] = SHL4_TABLE[h1 as usize] | h2;
buf[j * 2 + 1] = SHL4_TABLE[h3 as usize] | h4;
j += 1;
}
Ok(buf)
}
const HEX_TABLE: &[u8; 256] = &{
let mut buf = [0; 256];
let mut i: u8 = 0;
loop {
buf[i as usize] = match i {
b'0'..=b'9' => i - b'0',
b'a'..=b'f' => i - b'a' + 10,
b'A'..=b'F' => i - b'A' + 10,
_ => 0xff,
};
if i == 255 {
break buf;
}
i += 1
}
};
const SHL4_TABLE: &[u8; 256] = &{
let mut buf = [0; 256];
let mut i: u8 = 0;
loop {
buf[i as usize] = i.wrapping_shl(4);
if i == 255 {
break buf;
}
i += 1;
}
};
#[cfg(test)]
mod tests {
use super::*;
use crate::{std::string::ToString, tests::new};
#[test]
fn test_parse_uuid_v4_valid() {
let from_hyphenated = Uuid::parse_str("67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap();
let from_simple = Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c8").unwrap();
let from_urn = Uuid::parse_str("urn:uuid:67e55044-10b1-426f-9247-bb680e5fe0c8").unwrap();
let from_guid = Uuid::parse_str("{67e55044-10b1-426f-9247-bb680e5fe0c8}").unwrap();
assert_eq!(from_hyphenated, from_simple);
assert_eq!(from_hyphenated, from_urn);
assert_eq!(from_hyphenated, from_guid);
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());
assert!(Uuid::parse_str("{6d93bade-bd9f-4e13-8914-9474e1e3567b}").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
);
}
#[test]
fn test_parse_uuid_v4_invalid() {
// Invalid
assert_eq!(
Uuid::parse_str(""),
Err(Error(ErrorKind::ParseSimpleLength { len: 0 }))
);
assert_eq!(
Uuid::parse_str("!"),
Err(Error(ErrorKind::ParseChar {
character: '!',
index: 1,
}))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E45"),
Err(Error(ErrorKind::ParseGroupLength {
group: 4,
len: 13,
index: 25,
}))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa-BBF-329BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupLength {
group: 3,
len: 3,
index: 20,
}))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa-BGBF-329BF39FA1E4"),
Err(Error(ErrorKind::ParseChar {
character: 'G',
index: 21,
}))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2F4faaFB6BFF329BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupCount { count: 2 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faaFB6BFF329BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupCount { count: 3 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupCount { count: 4 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa"),
Err(Error(ErrorKind::ParseGroupCount { count: 3 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faaXB6BFF329BF39FA1E4"),
Err(Error(ErrorKind::ParseChar {
character: 'X',
index: 19,
}))
);
assert_eq!(
Uuid::parse_str("{F9168C5E-CEB2-4faa9B6BFF329BF39FA1E41"),
Err(Error(ErrorKind::ParseChar {
character: '{',
index: 1,
}))
);
assert_eq!(
Uuid::parse_str("{F9168C5E-CEB2-4faa9B6BFF329BF39FA1E41}"),
Err(Error(ErrorKind::ParseGroupCount { count: 3 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB-24fa-eB6BFF32-BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupLength {
group: 1,
len: 3,
index: 10,
}))
);
// // (group, found, expecting)
// //
assert_eq!(
Uuid::parse_str("01020304-1112-2122-3132-41424344"),
Err(Error(ErrorKind::ParseGroupLength {
group: 4,
len: 8,
index: 25,
}))
);
assert_eq!(
Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c"),
Err(Error(ErrorKind::ParseSimpleLength { len: 31 }))
);
assert_eq!(
Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c88"),
Err(Error(ErrorKind::ParseSimpleLength { len: 33 }))
);
assert_eq!(
Uuid::parse_str("67e5504410b1426f9247bb680e5fe0cg8"),
Err(Error(ErrorKind::ParseChar {
character: 'g',
index: 32,
}))
);
assert_eq!(
Uuid::parse_str("67e5504410b1426%9247bb680e5fe0c8"),
Err(Error(ErrorKind::ParseChar {
character: '%',
index: 16,
}))
);
assert_eq!(
Uuid::parse_str("231231212212423424324323477343246663"),
Err(Error(ErrorKind::ParseSimpleLength { len: 36 }))
);
assert_eq!(
Uuid::parse_str("{00000000000000000000000000000000}"),
Err(Error(ErrorKind::ParseGroupCount { count: 1 }))
);
assert_eq!(
Uuid::parse_str("67e5504410b1426f9247bb680e5fe0c"),
Err(Error(ErrorKind::ParseSimpleLength { len: 31 }))
);
assert_eq!(
Uuid::parse_str("67e550X410b1426f9247bb680e5fe0cd"),
Err(Error(ErrorKind::ParseChar {
character: 'X',
index: 7,
}))
);
assert_eq!(
Uuid::parse_str("67e550-4105b1426f9247bb680e5fe0c"),
Err(Error(ErrorKind::ParseGroupCount { count: 2 }))
);
assert_eq!(
Uuid::parse_str("F9168C5E-CEB2-4faa-B6BF1-02BF39FA1E4"),
Err(Error(ErrorKind::ParseGroupLength {
group: 3,
len: 5,
index: 20,
}))
);
assert_eq!(
Uuid::parse_str("\u{bcf3c}"),
Err(Error(ErrorKind::ParseChar {
character: '\u{bcf3c}',
index: 1
}))
);
}
#[test]
fn test_roundtrip_default() {
let uuid_orig = new();
let orig_str = uuid_orig.to_string();
let uuid_out = Uuid::parse_str(&orig_str).unwrap();
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_hyphenated() {
let uuid_orig = new();
let orig_str = uuid_orig.hyphenated().to_string();
let uuid_out = Uuid::parse_str(&orig_str).unwrap();
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_simple() {
let uuid_orig = new();
let orig_str = uuid_orig.simple().to_string();
let uuid_out = Uuid::parse_str(&orig_str).unwrap();
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_urn() {
let uuid_orig = new();
let orig_str = uuid_orig.urn().to_string();
let uuid_out = Uuid::parse_str(&orig_str).unwrap();
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_braced() {
let uuid_orig = new();
let orig_str = uuid_orig.braced().to_string();
let uuid_out = Uuid::parse_str(&orig_str).unwrap();
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_parse_urn() {
let uuid_orig = new();
let orig_str = uuid_orig.urn().to_string();
let uuid_out = Uuid::from_bytes(parse_urn(orig_str.as_bytes()).unwrap());
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_roundtrip_parse_braced() {
let uuid_orig = new();
let orig_str = uuid_orig.braced().to_string();
let uuid_out = Uuid::from_bytes(parse_braced(orig_str.as_bytes()).unwrap());
assert_eq!(uuid_orig, uuid_out);
}
#[test]
fn test_try_parse_ascii_non_utf8() {
assert!(Uuid::try_parse_ascii(b"67e55044-10b1-426f-9247-bb680e5\0e0c8").is_err());
}
}

311
vendor/uuid/src/rng.rs vendored Normal file
View File

@@ -0,0 +1,311 @@
#![allow(dead_code, unused_imports)] // Keeps our cfg's from becoming too convoluted in here
trait Rng {
fn u128() -> u128;
fn u64() -> u64;
fn u16() -> u16;
}
pub(crate) fn u128() -> u128 {
imp::RngImp::u128()
}
pub(crate) fn u64() -> u64 {
imp::RngImp::u64()
}
pub(crate) fn u16() -> u16 {
imp::RngImp::u16()
}
#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))]
mod imp {
/*
Random support for non `wasm32-unknown-unknown` platforms.
*/
use super::*;
// Using `rand`
#[cfg(any(feature = "rng-rand", feature = "fast-rng"))]
pub(super) struct RngImp;
#[cfg(any(feature = "rng-rand", feature = "fast-rng"))]
impl Rng for RngImp {
fn u128() -> u128 {
rand::random()
}
fn u64() -> u64 {
rand::random()
}
fn u16() -> u16 {
rand::random()
}
}
// Using `getrandom`
#[cfg(all(not(feature = "fast-rng"), not(feature = "rng-rand")))]
pub(super) struct RngImp;
#[cfg(all(not(feature = "fast-rng"), not(feature = "rng-rand")))]
impl Rng for RngImp {
fn u128() -> u128 {
let mut bytes = [0u8; 16];
getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u128::from_ne_bytes(bytes)
}
fn u64() -> u64 {
let mut bytes = [0u8; 8];
getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u64::from_ne_bytes(bytes)
}
fn u16() -> u16 {
let mut bytes = [0u8; 2];
getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u16::from_ne_bytes(bytes)
}
}
}
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
mod imp {
/*
Random support for `wasm32-unknown-unknown`.
*/
#![allow(dead_code, unused_imports)] // Keeps our cfg's from becoming too convoluted in here
use super::*;
#[cfg(all(
not(feature = "js"),
not(feature = "rng-getrandom"),
not(feature = "rng-rand")
))]
compile_error!("to use `uuid` on `wasm32-unknown-unknown`, specify a source of randomness using one of the `js`, `rng-getrandom`, or `rng-rand` features");
// Using `rand`
#[cfg(feature = "rng-rand")]
pub(super) struct RngImp;
#[cfg(feature = "rng-rand")]
impl Rng for RngImp {
fn u128() -> u128 {
uuid_rng_internal_lib::__private::rand::random()
}
fn u64() -> u64 {
uuid_rng_internal_lib::__private::rand::random()
}
fn u16() -> u16 {
uuid_rng_internal_lib::__private::rand::random()
}
}
// Using `getrandom`
#[cfg(all(feature = "rng-getrandom", not(feature = "rng-rand")))]
pub(super) struct RngImp;
#[cfg(all(feature = "rng-getrandom", not(feature = "rng-rand")))]
impl Rng for RngImp {
fn u128() -> u128 {
let mut bytes = [0u8; 16];
uuid_rng_internal_lib::__private::getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u128::from_ne_bytes(bytes)
}
fn u64() -> u64 {
let mut bytes = [0u8; 8];
uuid_rng_internal_lib::__private::getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u64::from_ne_bytes(bytes)
}
fn u16() -> u16 {
let mut bytes = [0u8; 2];
uuid_rng_internal_lib::__private::getrandom::fill(&mut bytes).unwrap_or_else(|err| {
// NB: getrandom::Error has no source; this is adequate display
panic!("could not retrieve random bytes for uuid: {}", err)
});
u16::from_ne_bytes(bytes)
}
}
// Using WebCrypto via `wasm-bindgen`
#[cfg(all(
feature = "js",
not(feature = "rng-rand"),
not(feature = "rng-getrandom")
))]
pub(super) struct RngImp;
#[cfg(all(
feature = "js",
not(feature = "rng-rand"),
not(feature = "rng-getrandom")
))]
impl Rng for RngImp {
fn u128() -> u128 {
let mut bytes = [0u8; 16];
if !webcrypto::fill(&mut bytes) {
panic!("could not retrieve random bytes for uuid")
}
u128::from_ne_bytes(bytes)
}
fn u64() -> u64 {
let mut bytes = [0u8; 8];
if !webcrypto::fill(&mut bytes) {
panic!("could not retrieve random bytes for uuid")
}
u64::from_ne_bytes(bytes)
}
fn u16() -> u16 {
let mut bytes = [0u8; 2];
if !webcrypto::fill(&mut bytes) {
panic!("could not retrieve random bytes for uuid")
}
u16::from_ne_bytes(bytes)
}
}
#[cfg(feature = "js")]
mod webcrypto {
/*
This module preserves the stabilized behavior of `uuid` that requires the
`js` feature to enable rng on `wasm32-unknown-unknown`, which it inherited
from `getrandom` `0.2`.
Vendored from `getrandom`: https://github.com/rust-random/getrandom/blob/ce3b017fdee0233c6ecd61e68b96a84bf6f911bf/src/backends/wasm_js.rs
Copyright (c) 2018-2024 The rust-random Project Developers
Copyright (c) 2014 The Rust Project Developers
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.
*/
use wasm_bindgen::{prelude::wasm_bindgen, JsValue};
#[cfg(target_feature = "atomics")]
use core::convert::TryInto;
// Maximum buffer size allowed in `Crypto.getRandomValuesSize` is 65536 bytes.
// See https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues
const MAX_BUFFER_SIZE: usize = 65536;
#[cfg(not(target_feature = "atomics"))]
#[inline]
pub fn fill(dest: &mut [u8]) -> bool {
for chunk in dest.chunks_mut(MAX_BUFFER_SIZE) {
if get_random_values(chunk).is_err() {
return false;
}
}
true
}
#[cfg(target_feature = "atomics")]
pub fn fill(dest: &mut [u8]) -> bool {
// getRandomValues does not work with all types of WASM memory,
// so we initially write to browser memory to avoid exceptions.
let buf_len = usize::min(dest.len(), MAX_BUFFER_SIZE);
let buf_len_u32 = buf_len
.try_into()
.expect("buffer length is bounded by MAX_BUFFER_SIZE");
let buf = js_sys::Uint8Array::new_with_length(buf_len_u32);
for chunk in dest.chunks_mut(buf_len) {
let chunk_len = chunk
.len()
.try_into()
.expect("chunk length is bounded by MAX_BUFFER_SIZE");
// The chunk can be smaller than buf's length, so we call to
// JS to create a smaller view of buf without allocation.
let sub_buf = if chunk_len == buf_len_u32 {
&buf
} else {
&buf.subarray(0, chunk_len)
};
if get_random_values(sub_buf).is_err() {
return false;
}
sub_buf.copy_to(chunk);
}
true
}
#[wasm_bindgen]
extern "C" {
// Crypto.getRandomValues()
#[cfg(not(target_feature = "atomics"))]
#[wasm_bindgen(js_namespace = ["globalThis", "crypto"], js_name = getRandomValues, catch)]
fn get_random_values(buf: &mut [u8]) -> Result<(), JsValue>;
#[cfg(target_feature = "atomics")]
#[wasm_bindgen(js_namespace = ["globalThis", "crypto"], js_name = getRandomValues, catch)]
fn get_random_values(buf: &js_sys::Uint8Array) -> Result<(), JsValue>;
}
}
}

14
vendor/uuid/src/sha1.rs vendored Normal file
View File

@@ -0,0 +1,14 @@
#[cfg(feature = "v5")]
pub(crate) fn hash(ns: &[u8], src: &[u8]) -> [u8; 16] {
use sha1_smol::Sha1;
let mut hasher = Sha1::new();
hasher.update(ns);
hasher.update(src);
let mut bytes = [0; 16];
bytes.copy_from_slice(&hasher.digest().bytes()[..16]);
bytes
}

1267
vendor/uuid/src/timestamp.rs vendored Normal file

File diff suppressed because it is too large Load Diff

157
vendor/uuid/src/v1.rs vendored Normal file
View File

@@ -0,0 +1,157 @@
//! The implementation for Version 1 UUIDs.
//!
//! This module is soft-deprecated. Instead of using the `Context` type re-exported here,
//! use the one from the crate root.
use crate::{Builder, Uuid};
#[deprecated(note = "use types from the crate root instead")]
pub use crate::{timestamp::context::Context, Timestamp};
impl Uuid {
/// Create a new version 1 UUID using the current system time and node ID.
///
/// This method is only available if both the `std` and `rng` features are enabled.
///
/// This method is a convenient alternative to [`Uuid::new_v1`] that uses the current system time
/// as the source timestamp.
///
/// Note that usage of this method requires the `v1`, `std`, and `rng` features of this crate
/// to be enabled.
#[cfg(all(feature = "std", feature = "rng"))]
pub fn now_v1(node_id: &[u8; 6]) -> Self {
let ts = Timestamp::now(crate::timestamp::context::shared_context());
Self::new_v1(ts, node_id)
}
/// Create a new version 1 UUID using the given timestamp and node ID.
///
/// Also see [`Uuid::now_v1`] for a convenient way to generate version 1
/// UUIDs using the current system time.
///
/// When generating [`Timestamp`]s using a [`ClockSequence`], this function
/// is only guaranteed to produce unique values if the following conditions
/// hold:
///
/// 1. The *node ID* is unique for this process,
/// 2. The *context* is shared across all threads which are generating version 1
/// 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).
///
/// 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`]. RFC 9562 requires the clock sequence
/// is seeded with a random value:
///
/// ```
/// # use uuid::{Timestamp, Context};
/// # use uuid::Uuid;
/// # fn random_seed() -> u16 { 42 }
/// let context = Context::new(random_seed());
/// let ts = Timestamp::from_unix(&context, 1497624119, 1234);
///
/// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "f3b4958c-52a1-11e7-802a-010203040506"
/// );
/// ```
///
/// The timestamp can also be created manually as per RFC 9562:
///
/// ```
/// # use uuid::{Uuid, Timestamp, Context, ClockSequence};
/// let context = Context::new(42);
/// let ts = Timestamp::from_gregorian(14976234442241191232, context.generate_sequence(0, 0));
///
/// let uuid = Uuid::new_v1(ts, &[1, 2, 3, 4, 5, 6]);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "b2c1ad40-45e0-1fd6-802a-010203040506"
/// );
/// ```
///
/// # References
///
/// * [UUID Version 1 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.1)
///
/// [`Timestamp`]: v1/struct.Timestamp.html
/// [`ClockSequence`]: v1/trait.ClockSequence.html
/// [`Context`]: v1/struct.Context.html
pub fn new_v1(ts: Timestamp, node_id: &[u8; 6]) -> Self {
let (ticks, counter) = ts.to_gregorian();
Builder::from_gregorian_timestamp(ticks, counter, node_id).into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{std::string::ToString, Variant, Version};
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new() {
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);
assert_eq!(uuid.get_version(), Some(Version::Mac));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
assert_eq!(
uuid.hyphenated().to_string(),
"20616934-4ba2-11e7-8000-010203040506"
);
let ts = uuid.get_timestamp().unwrap().to_gregorian();
assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460);
assert_eq!(Some(node), uuid.get_node_id(),);
// Ensure parsing the same UUID produces the same timestamp
let parsed = Uuid::parse_str("20616934-4ba2-11e7-8000-010203040506").unwrap();
assert_eq!(
uuid.get_timestamp().unwrap(),
parsed.get_timestamp().unwrap()
);
assert_eq!(uuid.get_node_id().unwrap(), parsed.get_node_id().unwrap(),);
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
#[cfg(all(feature = "std", feature = "rng"))]
fn test_now() {
let node = [1, 2, 3, 4, 5, 6];
let uuid = Uuid::now_v1(&node);
assert_eq!(uuid.get_version(), Some(Version::Mac));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
}
}

158
vendor/uuid/src/v3.rs vendored Normal file
View File

@@ -0,0 +1,158 @@
use crate::Uuid;
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.
///
/// # Examples
///
/// Generating a MD5 DNS UUID for `rust-lang.org`:
///
/// ```
/// # use uuid::{Uuid, Version};
/// let uuid = Uuid::new_v3(&Uuid::NAMESPACE_DNS, b"rust-lang.org");
///
/// assert_eq!(Some(Version::Md5), uuid.get_version());
/// ```
///
/// # References
///
/// * [UUID Version 3 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.3)
/// * [Name-Based UUID Generation in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-6.5)
///
/// [`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 {
crate::Builder::from_md5_bytes(crate::md5::hash(namespace.as_bytes(), name)).into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
use crate::{std::string::ToString, Variant, Version};
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]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_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(), Some(Version::Md5));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
}
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_hyphenated_string() {
for &(ref ns, ref name, ref expected) in FIXTURE {
let uuid = Uuid::new_v3(*ns, name.as_bytes());
assert_eq!(uuid.hyphenated().to_string(), *expected);
}
}
}

73
vendor/uuid/src/v4.rs vendored Normal file
View File

@@ -0,0 +1,73 @@
use crate::Uuid;
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_random_bytes`][from_random_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, Version};
/// let uuid = Uuid::new_v4();
///
/// assert_eq!(Some(Version::Random), uuid.get_version());
/// ```
///
/// # References
///
/// * [UUID Version 4 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.4)
///
/// [`getrandom`]: https://crates.io/crates/getrandom
/// [from_random_bytes]: struct.Builder.html#method.from_random_bytes
pub fn new_v4() -> Uuid {
// This is an optimized method for generating random UUIDs that just masks
// out the bits for the version and variant and sets them both together
Uuid::from_u128(
crate::rng::u128() & 0xFFFFFFFFFFFF4FFFBFFFFFFFFFFFFFFF | 0x40008000000000000000,
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Variant, Version};
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new() {
let uuid = Uuid::new_v4();
assert_eq!(uuid.get_version(), Some(Version::Random));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_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)
}
}

172
vendor/uuid/src/v5.rs vendored Normal file
View File

@@ -0,0 +1,172 @@
use crate::Uuid;
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.
///
/// # Examples
///
/// Generating a SHA1 DNS UUID for `rust-lang.org`:
///
/// ```
/// # use uuid::{Uuid, Version};
/// let uuid = Uuid::new_v5(&Uuid::NAMESPACE_DNS, b"rust-lang.org");
///
/// assert_eq!(Some(Version::Sha1), uuid.get_version());
/// ```
///
/// # References
///
/// * [UUID Version 5 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.5)
/// * [Name-Based UUID Generation in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-6.5)
///
/// [`NAMESPACE_DNS`]: struct.Uuid.html#associatedconstant.NAMESPACE_DNS
/// [`NAMESPACE_OID`]: struct.Uuid.html#associatedconstant.NAMESPACE_OID
/// [`NAMESPACE_URL`]: struct.Uuid.html#associatedconstant.NAMESPACE_URL
/// [`NAMESPACE_X500`]: struct.Uuid.html#associatedconstant.NAMESPACE_X500
pub fn new_v5(namespace: &Uuid, name: &[u8]) -> Uuid {
crate::Builder::from_sha1_bytes(crate::sha1::hash(namespace.as_bytes(), name)).into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
use crate::{std::string::ToString, Variant, Version};
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]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_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]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_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.hyphenated().to_string(), *expected)
}
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_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_version(), Some(Version::Sha1));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
assert_eq!(Ok(uuid), u.parse());
}
}
}

159
vendor/uuid/src/v6.rs vendored Normal file
View File

@@ -0,0 +1,159 @@
//! The implementation for Version 6 UUIDs.
//!
//! Note that you need to enable the `v6` Cargo feature
//! in order to use this module.
use crate::{Builder, Timestamp, Uuid};
impl Uuid {
/// Create a new version 6 UUID using the current system time and node ID.
///
/// This method is only available if the `std` feature is enabled.
///
/// This method is a convenient alternative to [`Uuid::new_v6`] that uses the current system time
/// as the source timestamp.
///
/// Note that usage of this method requires the `v6`, `std`, and `rng` features of this crate
/// to be enabled.
#[cfg(all(feature = "std", feature = "rng"))]
pub fn now_v6(node_id: &[u8; 6]) -> Self {
let ts = Timestamp::now(crate::timestamp::context::shared_context());
Self::new_v6(ts, node_id)
}
/// Create a new version 6 UUID using the given timestamp and a node ID.
///
/// This is similar to version 1 UUIDs, except that it is lexicographically sortable by timestamp.
///
/// Also see [`Uuid::now_v6`] for a convenient way to generate version 6
/// UUIDs using the current system time.
///
/// When generating [`Timestamp`]s using a [`ClockSequence`], this function
/// is only guaranteed to produce unique values if the following conditions
/// hold:
///
/// 1. The *node ID* is unique for this process,
/// 2. The *context* is shared across all threads which are generating version 6
/// 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 `v6` feature of this crate
/// to be enabled.
///
/// # Examples
///
/// A UUID can be created from a unix [`Timestamp`] with a
/// [`ClockSequence`]. RFC 9562 requires the clock sequence
/// is seeded with a random value:
///
/// ```rust
/// # use uuid::{Uuid, Timestamp, Context};
/// # fn random_seed() -> u16 { 42 }
/// let context = Context::new(random_seed());
/// let ts = Timestamp::from_unix(context, 1497624119, 1234);
///
/// let uuid = Uuid::new_v6(ts, &[1, 2, 3, 4, 5, 6]);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "1e752a1f-3b49-658c-802a-010203040506"
/// );
/// ```
///
/// The timestamp can also be created manually as per RFC 9562:
///
/// ```
/// # use uuid::{Uuid, Timestamp, Context, ClockSequence};
/// # fn random_seed() -> u16 { 42 }
/// let context = Context::new(random_seed());
/// let ts = Timestamp::from_gregorian(14976241191231231313, context.generate_sequence(0, 0));
///
/// let uuid = Uuid::new_v6(ts, &[1, 2, 3, 4, 5, 6]);
///
/// assert_eq!(
/// uuid.hyphenated().to_string(),
/// "fd64c041-1e91-6551-802a-010203040506"
/// );
/// ```
///
/// # References
///
/// * [UUID Version 6 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.6)
///
/// [`Timestamp`]: timestamp/struct.Timestamp.html
/// [`ClockSequence`]: timestamp/trait.ClockSequence.html
/// [`Context`]: timestamp/context/struct.Context.html
pub fn new_v6(ts: Timestamp, node_id: &[u8; 6]) -> Self {
let (ticks, counter) = ts.to_gregorian();
Builder::from_sorted_gregorian_timestamp(ticks, counter, node_id).into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Context, Variant, Version};
use std::string::ToString;
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new() {
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_v6(Timestamp::from_unix(context, time, time_fraction), &node);
assert_eq!(uuid.get_version(), Some(Version::SortMac));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
assert_eq!(
uuid.hyphenated().to_string(),
"1e74ba22-0616-6934-8000-010203040506"
);
let ts = uuid.get_timestamp().unwrap().to_gregorian();
assert_eq!(ts.0 - 0x01B2_1DD2_1381_4000, 14_968_545_358_129_460);
assert_eq!(Some(node), uuid.get_node_id(),);
// Ensure parsing the same UUID produces the same timestamp
let parsed = Uuid::parse_str("1e74ba22-0616-6934-8000-010203040506").unwrap();
assert_eq!(
uuid.get_timestamp().unwrap(),
parsed.get_timestamp().unwrap()
);
assert_eq!(uuid.get_node_id().unwrap(), parsed.get_node_id().unwrap(),);
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
#[cfg(all(feature = "std", feature = "rng"))]
fn test_now() {
let node = [1, 2, 3, 4, 5, 6];
let uuid = Uuid::now_v6(&node);
assert_eq!(uuid.get_version(), Some(Version::SortMac));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
}
}

218
vendor/uuid/src/v7.rs vendored Normal file
View File

@@ -0,0 +1,218 @@
//! The implementation for Version 7 UUIDs.
//!
//! Note that you need to enable the `v7` Cargo feature
//! in order to use this module.
use crate::{rng, std::convert::TryInto, timestamp::Timestamp, Builder, Uuid};
impl Uuid {
/// Create a new version 7 UUID using the current time value.
///
/// This method is a convenient alternative to [`Uuid::new_v7`] that uses the current system time
/// as the source timestamp. All UUIDs generated through this method by the same process are
/// guaranteed to be ordered by their creation.
#[cfg(feature = "std")]
pub fn now_v7() -> Self {
Self::new_v7(Timestamp::now(
crate::timestamp::context::shared_context_v7(),
))
}
/// Create a new version 7 UUID using a time value and random bytes.
///
/// When the `std` feature is enabled, you can also use [`Uuid::now_v7`].
///
/// Note that usage of this method requires the `v7` feature of this crate
/// to be enabled.
///
/// Also see [`Uuid::now_v7`] for a convenient way to generate version 7
/// UUIDs using the current system time.
///
/// # Examples
///
/// A v7 UUID can be created from a unix [`Timestamp`] plus a 128 bit
/// random number. When supplied as such, the data will be combined
/// to ensure uniqueness and sortability at millisecond granularity.
///
/// ```rust
/// # use uuid::{Uuid, Timestamp, NoContext};
/// let ts = Timestamp::from_unix(NoContext, 1497624119, 1234);
///
/// let uuid = Uuid::new_v7(ts);
///
/// assert!(
/// uuid.hyphenated().to_string().starts_with("015cb15a-86d8-7")
/// );
/// ```
///
/// A v7 UUID can also be created with a counter to ensure batches of
/// UUIDs created together remain sortable:
///
/// ```rust
/// # use uuid::{Uuid, Timestamp, ContextV7};
/// let context = ContextV7::new();
/// let uuid1 = Uuid::new_v7(Timestamp::from_unix(&context, 1497624119, 1234));
/// let uuid2 = Uuid::new_v7(Timestamp::from_unix(&context, 1497624119, 1234));
///
/// assert!(uuid1 < uuid2);
/// ```
///
/// # References
///
/// * [UUID Version 7 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.7)
pub fn new_v7(ts: Timestamp) -> Self {
let (secs, nanos) = ts.to_unix();
let millis = (secs * 1000).saturating_add(nanos as u64 / 1_000_000);
let mut counter_and_random = rng::u128();
let (mut counter, counter_bits) = ts.counter();
debug_assert!(counter_bits <= 128);
let mut counter_bits = counter_bits as u32;
// If the counter intersects the variant field then shift around it.
// This ensures that any bits set in the counter that would intersect
// the variant are still preserved
if counter_bits > 12 {
let mask = u128::MAX << (counter_bits - 12);
counter = (counter & !mask) | ((counter & mask) << 2);
counter_bits += 2;
}
counter_and_random &= u128::MAX.overflowing_shr(counter_bits).0;
counter_and_random |= counter
.overflowing_shl(128u32.saturating_sub(counter_bits))
.0;
Builder::from_unix_timestamp_millis(
millis,
&counter_and_random.to_be_bytes()[..10].try_into().unwrap(),
)
.into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{std::string::ToString, ClockSequence, NoContext, Variant, Version};
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new() {
let ts: u64 = 1645557742000;
let seconds = ts / 1000;
let nanos = ((ts % 1000) * 1_000_000) as u32;
let uuid = Uuid::new_v7(Timestamp::from_unix(NoContext, seconds, nanos));
let uustr = uuid.hyphenated().to_string();
assert_eq!(uuid.get_version(), Some(Version::SortRand));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
assert!(uuid.hyphenated().to_string().starts_with("017f22e2-79b0-7"));
// Ensure parsing the same UUID produces the same timestamp
let parsed = Uuid::parse_str(uustr.as_str()).unwrap();
assert_eq!(uuid, parsed);
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
#[cfg(feature = "std")]
fn test_now() {
let uuid = Uuid::now_v7();
assert_eq!(uuid.get_version(), Some(Version::SortRand));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_sorting() {
let time1: u64 = 1_496_854_535;
let time_fraction1: u32 = 812_000_000;
let time2 = time1 + 4000;
let time_fraction2 = time_fraction1;
let uuid1 = Uuid::new_v7(Timestamp::from_unix(NoContext, time1, time_fraction1));
let uuid2 = Uuid::new_v7(Timestamp::from_unix(NoContext, time2, time_fraction2));
assert!(uuid1.as_bytes() < uuid2.as_bytes());
assert!(uuid1.to_string() < uuid2.to_string());
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new_timestamp_roundtrip() {
let time: u64 = 1_496_854_535;
let time_fraction: u32 = 812_000_000;
let ts = Timestamp::from_unix(NoContext, time, time_fraction);
let uuid = Uuid::new_v7(ts);
let decoded_ts = uuid.get_timestamp().unwrap();
assert_eq!(ts.to_unix(), decoded_ts.to_unix());
}
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new_max_context() {
struct MaxContext;
#[cfg(test)]
impl ClockSequence for MaxContext {
type Output = u128;
fn generate_sequence(&self, _seconds: u64, _nanos: u32) -> Self::Output {
u128::MAX
}
fn usable_bits(&self) -> usize {
128
}
}
let time: u64 = 1_496_854_535;
let time_fraction: u32 = 812_000_000;
// Ensure we don't overflow here
let ts = Timestamp::from_unix(MaxContext, time, time_fraction);
let uuid = Uuid::new_v7(ts);
assert_eq!(uuid.get_version(), Some(Version::SortRand));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
let decoded_ts = uuid.get_timestamp().unwrap();
assert_eq!(ts.to_unix(), decoded_ts.to_unix());
}
}

60
vendor/uuid/src/v8.rs vendored Normal file
View File

@@ -0,0 +1,60 @@
use crate::{Builder, Uuid};
impl Uuid {
/// Creates a custom UUID comprised almost entirely of user-supplied bytes.
///
/// This will inject the UUID Version at 4 bits starting at the 48th bit
/// and the Variant into 2 bits 64th bit. Any existing bits in the user-supplied bytes
/// at those locations will be overridden.
///
/// Note that usage of this method requires the `v8` feature of this crate
/// to be enabled.
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// # use uuid::{Uuid, Version};
/// let buf: [u8; 16] = *b"abcdefghijklmnop";
/// let uuid = Uuid::new_v8(buf);
///
/// assert_eq!(Some(Version::Custom), uuid.get_version());
/// ```
///
/// # References
///
/// * [UUID Version 8 in RFC 9562](https://www.ietf.org/rfc/rfc9562.html#section-5.8)
pub const fn new_v8(buf: [u8; 16]) -> Uuid {
Builder::from_custom_bytes(buf).into_uuid()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{Variant, Version};
use std::string::ToString;
#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))]
use wasm_bindgen_test::*;
#[test]
#[cfg_attr(
all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")),
wasm_bindgen_test
)]
fn test_new() {
let buf: [u8; 16] = [
0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0,
];
let uuid = Uuid::new_v8(buf);
assert_eq!(uuid.get_version(), Some(Version::Custom));
assert_eq!(uuid.get_variant(), Variant::RFC4122);
assert_eq!(uuid.get_version_num(), 8);
assert_eq!(
uuid.hyphenated().to_string(),
"0f0e0d0c-0b0a-8908-8706-050403020100"
);
}
}