From a074b6932ab2c829749d316c5c9188171701cae5 Mon Sep 17 00:00:00 2001 From: Mark Langen Date: Sun, 11 Jan 2026 23:34:22 -0800 Subject: [PATCH 1/2] Type re-exporting similar to wally-package-types * Built a type re-exporting mechanism similar to wally-package-types directly into wally so that exported types from packages can be used by the consuming code. * We cannot directly use the same approach as wally-package-types did for a couple of key reasons: * It relies on a source map to locate where the root module of the package is located. Wally packages do not generally include this source map out of the box. Instead, we will assume that Rojo is being used and extract the location of the root package from the Rojo project file. You could theoretically use Wally with something other than Rojo but this is not done and practice, and even if you did the fail case would simply be not getting re-exported types. * It relies on an additional Luau parsing library dependency to do its work. This would not be an issue if Wally were regularly updated. However Wally is not well maintained, meaning that the type re-exporting code will ideally continue to work without needing future updates. If we used a Luau parsing library, that library would not understand future Luau syntax additions and failed parses for libraries using those new syntax features would break re-exporting. * Instead, we use a loose permissive parse which tries to make as few assumptions as possible while locating the export type statements of interest. The core assumptions are that the Module contains valid Luau code and that additional types of string constant / comment syntax will not be added in the future. With these assuptions, we can strip out any non-code text in the form of comments / string constants, and then do a simple parse for export type statements. * One additional complexity exists in the form of export type statements which depend on a non-exported type. In particular as a default type parameter. E.g.: `export type Foo = ...`. To avoid this problem we strip out any non-exported default type parameters. That prevents syntax errors while still allowing the types to remain as usable as possible. Fusion is an example of a package that currently has this issue. Bikeshedding welcome on the what name the MODULE variable in the stub modules should be called. --- Cargo.lock | 2451 ++++++++++++++++++++++++------------------ Cargo.toml | 2 +- src/extract_types.rs | 497 +++++++++ src/installation.rs | 224 ++-- src/lib.rs | 1 + 5 files changed, 2040 insertions(+), 1135 deletions(-) create mode 100644 src/extract_types.rs diff --git a/Cargo.lock b/Cargo.lock index fa8ea0db..a0b8269f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,49 +1,40 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] -name = "adler32" -version = "1.2.0" +name = "adler2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" -version = "0.7.4" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.2", + "getrandom 0.2.16", "once_cell", "version_check", ] [[package]] name = "aho-corasick" -version = "0.7.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" -dependencies = [ - "memchr", -] - -[[package]] -name = "aho-corasick" -version = "1.0.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] -name = "ansi_term" -version = "0.11.0" +name = "android_system_properties" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ - "winapi", + "libc", ] [[package]] @@ -57,15 +48,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.40" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arrayref" -version = "0.3.6" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -73,17 +64,11 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" -[[package]] -name = "ascii" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eab1c04a571841102f5345a8fc0f6bb3d31c315dec879b5c6e42e40ce7ffa34e" - [[package]] name = "async-stream" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", @@ -92,33 +77,39 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.114", ] [[package]] name = "async-trait" -version = "0.1.48" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea56748e10732c49404c153638a15ec3d6211ec5ff35d9bb20e13b93576adf" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 1.0.67", + "syn 2.0.114", ] [[package]] name = "atomic" -version = "0.5.0" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + +[[package]] +name = "atomic" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3410529e8288c463bedb5930f82833bc0c90e5d2fe639a56582a4d09220b281" +checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340" dependencies = [ - "autocfg", + "bytemuck", ] [[package]] @@ -127,16 +118,16 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.18", + "hermit-abi 0.1.19", "libc", "winapi", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base64" @@ -146,15 +137,15 @@ checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] name = "base64" -version = "0.13.0" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "binascii" @@ -170,9 +161,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.3.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6776fc96284a0bb647b615056fc496d1fe1644a7ab01829818a6d91cae888b84" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bitpacking" @@ -183,22 +174,11 @@ dependencies = [ "crunchy", ] -[[package]] -name = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - [[package]] name = "blake3" -version = "0.3.7" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9ff35b701f3914bdb8fad3368d822c766ef2858b2583198e41639b936f09d3f" +checksum = "b64485778c4f16a6a5a9d335e80d449ac6c70cdd6a06d2af18a6f6f775a125b3" dependencies = [ "arrayref", "arrayvec", @@ -220,44 +200,50 @@ dependencies = [ [[package]] name = "bstr" -version = "0.2.15" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a40b47ad93e1a5404e6c18dec46b628214fee441c70f4ab5d6942142cc268a3d" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ - "lazy_static", "memchr", "regex-automata", + "serde", ] [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "bytecount" -version = "0.6.3" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175812e0be2bccb6abe50bb8d566126198344f707e304f45c648fd8f2cc0365e" + +[[package]] +name = "bytemuck" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" [[package]] name = "byteorder" -version = "1.4.3" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.0.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "bzip2" -version = "0.3.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" dependencies = [ "bzip2-sys", "libc", @@ -265,29 +251,28 @@ dependencies = [ [[package]] name = "bzip2-sys" -version = "0.1.10+1.0.8" +version = "0.1.13+1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17fa3d1ac1ca21c5c4e36a97f3c3eb25084576f6fc47bf0139c1123434216c6c" +checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14" dependencies = [ "cc", - "libc", "pkg-config", ] [[package]] name = "camino" -version = "1.1.4" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c530edf18f37068ac2d977409ed5cd50d53d73bc653c7647b48eb78976ac9ae2" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" dependencies = [ - "serde", + "serde_core", ] [[package]] name = "cargo-platform" -version = "0.1.2" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbdb825da8a5df079a43676dbe042702f1707b1109f713a01420fbb4cc71fa27" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -300,25 +285,28 @@ checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" dependencies = [ "camino", "cargo-platform", - "semver 1.0.11", + "semver 1.0.27", "serde", "serde_json", ] [[package]] name = "cc" -version = "1.0.67" +version = "1.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c69b077ad434294d3ce9f1f6143a2a4b89a8a2d54ef813d85003a4fd1137fd" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" dependencies = [ + "find-msvc-tools", "jobserver", + "libc", + "shlex", ] [[package]] name = "census" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5927edd8345aef08578bcbb4aea7314f340d80c7f4931f99fbeb40b99d8f5060" +checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" [[package]] name = "cfg-if" @@ -328,36 +316,36 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.19" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "libc", - "num-integer", + "iana-time-zone", + "js-sys", "num-traits", "serde", - "time 0.1.43", - "winapi", + "wasm-bindgen", + "windows-link", ] [[package]] name = "clap" -version = "2.33.3" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ - "ansi_term 0.11.0", + "ansi_term", "atty", "bitflags 1.3.2", "strsim 0.8.0", "textwrap", - "unicode-width", + "unicode-width 0.1.14", "vec_map", ] @@ -385,50 +373,25 @@ dependencies = [ [[package]] name = "combine" -version = "3.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3da6baa321ec19e1cc41d31bf599f00c783d0517095cdaf0332e3fe8d20680" -dependencies = [ - "ascii", - "byteorder", - "either", - "memchr", - "unreachable", -] - -[[package]] -name = "combine" -version = "4.6.1" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a909e4d93292cd8e9c42e189f61681eff9d67b6541f96b8a1a737f23737bd001" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ + "bytes", "memchr", ] [[package]] name = "console" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3993e6445baa160675931ec041a5e03ca84b9c6e32a056150d3aa2bdda0a1f45" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "terminal_size", - "winapi", -] - -[[package]] -name = "console" -version = "0.15.7" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ "encode_unicode", - "lazy_static", "libc", - "unicode-width", - "windows-sys 0.45.0", + "once_cell", + "unicode-width 0.2.2", + "windows-sys 0.59.0", ] [[package]] @@ -450,9 +413,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.9.1" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a89e2ae426ea83155dccf10c0fa6b1463ef6d5fcb44cee0b224a408fa640a62" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -460,35 +423,34 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.2" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.2" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", ] [[package]] name = "crossbeam" -version = "0.8.1" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae5588f6b3c3cb05239e90bd110f257254aecd01e4635400391aeae07497845" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" dependencies = [ - "cfg-if 1.0.0", "crossbeam-channel", "crossbeam-deque", "crossbeam-epoch", @@ -498,57 +460,46 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ - "cfg-if 1.0.0", "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.1" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ - "cfg-if 1.0.0", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.14" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46bd5f3f85273295a9d14aedfb86f6aadbff6d8f5295c4a9edb08e819dcf5695" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if 1.0.0", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-queue" -version = "0.3.2" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b10ddc024425c88c2ad148c1b0fd53f4c6d38db9697c9f1588381212fa657c9" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" dependencies = [ - "cfg-if 1.0.0", "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.5" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" -dependencies = [ - "cfg-if 1.0.0", - "lazy_static", -] +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" @@ -559,8 +510,8 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio 0.7.11", - "parking_lot 0.11.1", + "mio 0.7.14", + "parking_lot 0.11.2", "signal-hook", "signal-hook-mio", "winapi", @@ -568,18 +519,18 @@ dependencies = [ [[package]] name = "crossterm_winapi" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" dependencies = [ "winapi", ] [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-mac" @@ -603,9 +554,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.12.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06d4a9551359071d1890820e3571252b91229e0712e7c36b08940e603c5a8fc" +checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" dependencies = [ "darling_core", "darling_macro", @@ -613,40 +564,40 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.12.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b443e5fb0ddd56e0c9bfa47dc060c5306ee500cb731f2b91432dd65589a77684" +checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim 0.10.0", - "syn 1.0.67", + "syn 1.0.109", ] [[package]] name = "darling_macro" -version = "0.12.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0220073ce504f12a70efc4e7cdaea9e9b1b324872e7ad96a208056d7a638b81" +checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", "quote", - "syn 1.0.67", + "syn 1.0.109", ] [[package]] name = "dashmap" -version = "5.4.0" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "cfg-if 1.0.0", - "hashbrown 0.12.3", + "cfg-if 1.0.4", + "hashbrown 0.14.5", "lock_api", "once_cell", - "parking_lot_core 0.9.7", + "parking_lot_core 0.9.12", ] [[package]] @@ -660,9 +611,9 @@ dependencies = [ [[package]] name = "devise" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6eacefd3f541c66fc61433d65e54e0e46e0a029a819a7dbbc7a7b489e8a85f8" +checksum = "f1d90b0c4c777a2cad215e3c7be59ac7c15adf45cf76317009b7d096d46f651d" dependencies = [ "devise_codegen", "devise_core", @@ -670,9 +621,9 @@ dependencies = [ [[package]] name = "devise_codegen" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8cf4b8dd484ede80fd5c547592c46c3745a617c8af278e2b72bea86b2dfed6" +checksum = "71b28680d8be17a570a2334922518be6adc3f58ecc880cbb404eaeb8624fd867" dependencies = [ "devise_core", "quote", @@ -680,15 +631,15 @@ dependencies = [ [[package]] name = "devise_core" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a" +checksum = "b035a542cf7abf01f2e3c4d5a7acbaebfefe120ae4efc7bde3df98186e4b8af7" dependencies = [ - "bitflags 2.3.1", + "bitflags 2.10.0", "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.43", + "syn 2.0.114", ] [[package]] @@ -702,9 +653,9 @@ dependencies = [ [[package]] name = "dirs" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "142995ed02755914747cc6ca76fc7e4583cd18578746716d0508ea6ed558b9ff" +checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" dependencies = [ "dirs-sys", ] @@ -715,18 +666,18 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "dirs-sys-next", ] [[package]] name = "dirs-sys" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e93d7f5705de3e49895a2b5e0b8855a1c27f080192ae9c32a6432d50741a57a" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", - "redox_users 0.3.5", + "redox_users", "winapi", ] @@ -737,48 +688,53 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" dependencies = [ "libc", - "redox_users 0.4.3", + "redox_users", "winapi", ] [[package]] -name = "downcast-rs" -version = "1.2.0" +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] [[package]] -name = "dtoa" -version = "0.4.8" +name = "downcast-rs" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] name = "either" -version = "1.6.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding_rs" -version = "0.8.28" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", ] [[package]] name = "env_logger" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17392a012ea30ef05a610aa97dfb49496e71c9f676b27879922ea5bdf60d9d3f" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" dependencies = [ "atty", "humantime", @@ -789,29 +745,18 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ - "cc", "libc", + "windows-sys 0.61.2", ] [[package]] @@ -850,29 +795,39 @@ dependencies = [ "tantivy-common", ] +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "figment" -version = "0.10.9" +version = "0.10.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d79dace1d256182aa00f1ead2e5042558f420af2e1ed24dd79e00214e9ed99" +checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3" dependencies = [ - "atomic", + "atomic 0.6.1", "pear", "serde", - "toml 0.7.4", + "toml 0.8.23", "uncased", "version_check", ] +[[package]] +name = "find-msvc-tools" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" + [[package]] name = "flate2" -version = "1.0.14" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cfff41391129e0a856d6d822600b8d71179d46879e310417eb9c762eb178b42" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ - "cfg-if 0.1.10", "crc32fast", - "libc", "miniz_oxide", ] @@ -899,19 +854,21 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ - "matches", "percent-encoding", ] [[package]] name = "fs-err" -version = "2.5.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd1163ae48bda72a20ae26d66a04d3094135cadab911cff418ae5e33f253431" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] [[package]] name = "fs2" @@ -925,9 +882,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.17" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -940,9 +897,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.17" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -950,15 +907,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.17" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.17" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -968,42 +925,39 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.17" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.17" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ - "autocfg", - "proc-macro-hack", "proc-macro2", "quote", - "syn 1.0.67", + "syn 2.0.114", ] [[package]] name = "futures-sink" -version = "0.3.17" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.17" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.17" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "autocfg", "futures-channel", "futures-core", "futures-io", @@ -1013,16 +967,14 @@ dependencies = [ "memchr", "pin-project-lite", "pin-utils", - "proc-macro-hack", - "proc-macro-nested", "slab", ] [[package]] name = "generator" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3e123d9ae7c02966b4d892e550bdc32164f05853cd40ab570650ad600596a8a" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" dependencies = [ "cc", "libc", @@ -1033,9 +985,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.4" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -1047,20 +999,32 @@ version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "libc", "wasi 0.9.0+wasi-snapshot-preview1", ] [[package]] name = "getrandom" -version = "0.2.2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if 1.0.4", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "libc", - "wasi 0.10.2+wasi-snapshot-preview1", + "r-efi", + "wasip2", ] [[package]] @@ -1080,28 +1044,28 @@ dependencies = [ [[package]] name = "glob" -version = "0.3.0" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "globset" -version = "0.4.8" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10463d9ff00a2a068db14231982f5132edebad0d7660cd956a1c30292dbcbfbd" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" dependencies = [ - "aho-corasick 0.7.18", + "aho-corasick", "bstr", - "fnv", "log", - "regex", + "regex-automata", + "regex-syntax 0.8.8", ] [[package]] name = "h2" -version = "0.3.26" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" dependencies = [ "bytes", "fnv", @@ -1109,7 +1073,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.6.0", + "indexmap 2.12.1", "slab", "tokio", "tokio-util", @@ -1133,33 +1097,39 @@ checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.15.1" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a9bfc1af68b1726ea47d3d5109de126281def866b33970e10fbab11b5dafab3" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "heck" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ "unicode-segmentation", ] [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] name = "hermit-abi" -version = "0.3.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" [[package]] name = "hex" @@ -1185,20 +1155,20 @@ checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" [[package]] name = "http" -version = "0.2.3" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", - "itoa 0.4.7", + "itoa", ] [[package]] name = "http-body" -version = "0.4.1" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfb77c123b4e2f72a2069aeae0b4b4949cc7e966df277813fc16347e7549737" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", "http", @@ -1207,27 +1177,27 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "hyper" -version = "0.14.26" +version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ "bytes", "futures-channel", @@ -1238,9 +1208,9 @@ dependencies = [ "http-body", "httparse", "httpdate", - "itoa 1.0.6", + "itoa", "pin-project-lite", - "socket2", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -1249,10 +1219,11 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.24.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0646026eb1b3eea4cd9ba47912ea5ce9cc07713d105b1a14698f4e6433d348b7" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" dependencies = [ + "futures-util", "http", "hyper", "rustls", @@ -1274,160 +1245,253 @@ dependencies = [ ] [[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "0.2.2" +name = "iana-time-zone" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", ] [[package]] -name = "indexmap" -version = "1.9.3" +name = "iana-time-zone-haiku" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "cc", ] [[package]] -name = "indexmap" -version = "2.6.0" +name = "icu_collections" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ - "equivalent", - "hashbrown 0.15.1", + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "indicatif" -version = "0.17.4" +name = "icu_locale_core" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db45317f37ef454e6519b6c3ed7d377e5f23346f0823f86e65ca36912d1d0ef8" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ - "console 0.15.7", - "instant", - "number_prefix", - "portable-atomic", - "unicode-width", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", ] [[package]] -name = "indoc" -version = "1.0.3" +name = "icu_normalizer" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a75aeaaef0ce18b58056d306c27b07436fbb34b8816c53094b76dd81803136" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ - "unindent", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", ] [[package]] -name = "inlinable_string" -version = "0.1.14" +name = "icu_normalizer_data" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3094308123a0e9fd59659ce45e22de9f53fc1d2ac6e1feb9fef988e4f76cad77" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] -name = "insta" -version = "1.7.1" +name = "icu_properties" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1b21a2971cea49ca4613c0e9fe8225ecaf5de64090fddc6002284726e9244" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ - "console 0.14.1", - "lazy_static", - "serde", - "serde_json", - "serde_yaml", - "similar", - "uuid 0.8.2", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", ] [[package]] -name = "instant" -version = "0.1.9" +name = "icu_properties_data" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] -name = "io-lifetimes" -version = "1.0.11" +name = "icu_provider" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ - "hermit-abi 0.3.1", - "libc", - "windows-sys 0.48.0", + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", ] [[package]] -name = "ipnet" -version = "2.3.0" +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47be2f14c678be2fdcab04ab1171db51b2762ce6f0a8ee87c8dd4a04ed216135" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "is-terminal" -version = "0.4.7" +name = "idna" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ - "hermit-abi 0.3.1", - "io-lifetimes", - "rustix", - "windows-sys 0.48.0", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "itertools" -version = "0.10.1" +name = "idna_adapter" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ - "either", + "icu_normalizer", + "icu_properties", ] [[package]] -name = "itoa" -version = "0.4.7" +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", +] + +[[package]] +name = "indicatif" +version = "0.17.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183b3088984b400f4cfac3620d5e076c84da5364016b4f49473de574b2586235" +dependencies = [ + "console", + "number_prefix", + "portable-atomic", + "unicode-width 0.2.2", + "web-time", +] + +[[package]] +name = "indoc" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" + +[[package]] +name = "inlinable_string" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" + +[[package]] +name = "insta" +version = "1.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b66886d14d18d420ab5052cbff544fc5d34d0b2cdd35eb5976aaa10a4a472e5" +dependencies = [ + "console", + "once_cell", + "similar", + "tempfile", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if 1.0.4", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "is-terminal" +version = "0.4.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +dependencies = [ + "hermit-abi 0.5.2", + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "itertools" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] [[package]] name = "itoa" -version = "1.0.6" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jobserver" -version = "0.1.21" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c71313ebb9439f74b00d9d2dcec36440beaf57a6aa0623068441dd7cd81a7f2" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ + "getrandom 0.3.4", "libc", ] [[package]] name = "js-sys" -version = "0.3.50" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d99f9e3e84b8f67f846ef5b4cbbc3b1c29f6c759fcbce6f01aa0e73d932a24c" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -1439,7 +1503,7 @@ checksum = "afabcc15e437a6484fc4f12d0fd63068fe457bf93f1c148d3d9649c60b103f32" dependencies = [ "base64 0.12.3", "pem", - "ring", + "ring 0.16.20", "serde", "serde_json", "simple_asn1", @@ -1447,9 +1511,9 @@ dependencies = [ [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "levenshtein_automata" @@ -1459,9 +1523,9 @@ checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" [[package]] name = "libc" -version = "0.2.144" +version = "0.2.179" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" [[package]] name = "libgit2-sys" @@ -1477,11 +1541,22 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libredox" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags 2.10.0", + "libc", + "redox_syscall 0.7.0", +] + [[package]] name = "libssh2-sys" -version = "0.2.21" +version = "0.2.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0186af0d8f171ae6b9c4c90ec51898bad5d08a2d5e470903a50d9ad8959cbee" +checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca" dependencies = [ "cc", "libc", @@ -1493,9 +1568,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.2" +version = "1.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "602113192b08db8f38796c4e85c39e960c145965140e918018bcde1952429655" +checksum = "15d118bbf3771060e7311cc7bb0545b01d08a8b4a7de949198dec1fa0ca1c0f7" dependencies = [ "cc", "libc", @@ -1505,31 +1580,36 @@ dependencies = [ [[package]] name = "linked-hash-map" -version = "0.5.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" -version = "0.4.10" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.18" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "518ef76f2f87365916b142844c16d8fefd85039bc5699050210a7778ee1cd1de" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "loom" @@ -1537,7 +1617,7 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "generator", "scoped-tls", "serde", @@ -1566,28 +1646,22 @@ dependencies = [ [[package]] name = "mach2" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d0d1830bcd151a6fc4aea1369af235b36c1528fe976b8ff678683c9995eade8" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" dependencies = [ "libc", ] [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ "regex-automata", ] -[[package]] -name = "matches" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" - [[package]] name = "md-5" version = "0.9.1" @@ -1610,9 +1684,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.5.0" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" @@ -1623,35 +1697,27 @@ dependencies = [ "libc", ] -[[package]] -name = "memoffset" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61c719bcfbcf5d62b3a09efa6088de8c54bc0bfcd3ea7ae39fcc186108b8de1" -dependencies = [ - "autocfg", -] - [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.3.7" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ - "adler32", + "adler2", + "simd-adler32", ] [[package]] name = "mio" -version = "0.7.11" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956" +checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", "log", @@ -1662,13 +1728,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.8" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.61.2", ] [[package]] @@ -1682,16 +1748,15 @@ dependencies = [ [[package]] name = "moka" -version = "0.11.1" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36506f2f935238463605f3bb13b362f1949daafc3b347d05d60ae08836db2bd2" +checksum = "fa6e72583bf6830c956235bff0d5afec8cf2952f579ebad18ae7821a917d950f" dependencies = [ "crossbeam-channel", "crossbeam-epoch", "crossbeam-utils", - "num_cpus", "once_cell", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "quanta", "rustc_version", "scheduled-thread-pool", @@ -1700,7 +1765,7 @@ dependencies = [ "tagptr", "thiserror", "triomphe", - "uuid 1.3.3", + "uuid 1.19.0", ] [[package]] @@ -1734,11 +1799,10 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -1752,13 +1816,22 @@ dependencies = [ [[package]] name = "ntapi" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" dependencies = [ "winapi", ] +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.2", +] + [[package]] name = "num-bigint" version = "0.2.6" @@ -1778,30 +1851,29 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-integer" -version = "0.1.44" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "num_cpus" -version = "1.13.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" dependencies = [ - "hermit-abi 0.1.18", + "hermit-abi 0.5.2", "libc", ] @@ -1813,21 +1885,21 @@ checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" [[package]] name = "once_cell" -version = "1.17.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "opener" -version = "0.5.0" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea3ebcd72a54701f56345f16785a6d3ac2df7e986d273eb4395c0b01db17952" +checksum = "293c15678e37254c15bd2f092314abb4e51d7fdde05c2021279c12631b54f005" dependencies = [ "bstr", "winapi", @@ -1835,12 +1907,12 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.68" +version = "0.10.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" dependencies = [ - "bitflags 2.3.1", - "cfg-if 1.0.0", + "bitflags 2.10.0", + "cfg-if 1.0.4", "foreign-types", "libc", "once_cell", @@ -1850,26 +1922,26 @@ dependencies = [ [[package]] name = "openssl-macros" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 1.0.67", + "syn 2.0.114", ] [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", @@ -1888,73 +1960,73 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" dependencies = [ "instant", "lock_api", - "parking_lot_core 0.8.3", + "parking_lot_core 0.8.6", ] [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", - "parking_lot_core 0.9.7", + "parking_lot_core 0.9.12", ] [[package]] name = "parking_lot_core" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7a782938e745763fe6907fc6ba86946d72f49fe7e21de074e08128a99fb018" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "instant", "libc", - "redox_syscall 0.2.13", + "redox_syscall 0.2.16", "smallvec", "winapi", ] [[package]] name = "parking_lot_core" -version = "0.9.7" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "libc", - "redox_syscall 0.2.13", + "redox_syscall 0.5.18", "smallvec", - "windows-sys 0.45.0", + "windows-link", ] [[package]] name = "pear" -version = "0.2.4" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec95680a7087503575284e5063e14b694b7a9c0b065e5dceec661e0497127e8" +checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467" dependencies = [ "inlinable_string", "pear_codegen", - "yansi", + "yansi 1.0.1", ] [[package]] name = "pear_codegen" -version = "0.2.4" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9661a3a53f93f09f2ea882018e4d7c88f6ff2956d809a276060476fd8c879d3c" +checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.43", + "syn 2.0.114", ] [[package]] @@ -1963,31 +2035,32 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "once_cell", "regex", ] [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pest" -version = "2.1.3" +version = "2.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +checksum = "2c9eb05c21a464ea704b53158d358a31e6425db2f63a1a7312268b05fe2b75f7" dependencies = [ + "memchr", "ucd-trie", ] [[package]] name = "pin-project-lite" -version = "0.2.6" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -1997,15 +2070,24 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" -version = "1.3.3" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f89776e4d69bb58bc6993e99ffa1d11f228b839984854c7daeb5d37f87cbe950" + +[[package]] +name = "potential_utf" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] [[package]] name = "powerfmt" @@ -2015,9 +2097,12 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.10" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro-error" @@ -2028,7 +2113,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn 1.0.67", + "syn 1.0.109", "version_check", ] @@ -2043,47 +2128,35 @@ dependencies = [ "version_check", ] -[[package]] -name = "proc-macro-hack" -version = "0.5.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" - -[[package]] -name = "proc-macro-nested" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" - [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" dependencies = [ "unicode-ident", ] [[package]] name = "proc-macro2-diagnostics" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "606c4ba35817e2922a308af55ad51bab3645b59eae5c570d4a6cf07e36bd493b" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.114", "version_check", - "yansi", + "yansi 1.0.1", ] [[package]] name = "pulldown-cmark" -version = "0.9.3" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" +checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "memchr", "unicase", ] @@ -2099,20 +2172,26 @@ dependencies = [ "mach2", "once_cell", "raw-cpuid", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", "web-sys", "winapi", ] [[package]] name = "quote" -version = "1.0.28" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" 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.7.3" @@ -2123,19 +2202,18 @@ dependencies = [ "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", - "rand_hc 0.2.0", + "rand_hc", ] [[package]] name = "rand" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha 0.3.0", - "rand_core 0.6.2", - "rand_hc 0.3.0", + "rand_chacha 0.3.1", + "rand_core 0.6.4", ] [[package]] @@ -2150,12 +2228,12 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.2", + "rand_core 0.6.4", ] [[package]] @@ -2169,11 +2247,11 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.2" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.2", + "getrandom 0.2.16", ] [[package]] @@ -2185,15 +2263,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_hc" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" -dependencies = [ - "rand_core 0.6.2", -] - [[package]] name = "raw-cpuid" version = "10.7.0" @@ -2205,113 +2274,103 @@ dependencies = [ [[package]] name = "rayon" -version = "1.5.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ - "autocfg", - "crossbeam-deque", "either", "rayon-core", ] [[package]] name = "rayon-core" -version = "1.9.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "lazy_static", - "num_cpus", ] [[package]] name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_syscall" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags 1.3.2", ] [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", ] [[package]] -name = "redox_users" -version = "0.3.5" +name = "redox_syscall" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" +checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" dependencies = [ - "getrandom 0.1.16", - "redox_syscall 0.1.57", - "rust-argon2", + "bitflags 2.10.0", ] [[package]] name = "redox_users" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.2", - "redox_syscall 0.2.13", + "getrandom 0.2.16", + "libredox", "thiserror", ] [[package]] name = "ref-cast" -version = "1.0.6" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "300f2a835d808734ee295d45007adacb9ebb29dd3ae2424acfa17930cae541da" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.6" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c38e3aecd2b21cb3959637b883bb3714bc7e43f0268b9a29d3743ee3e55cdd2" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 1.0.67", + "syn 2.0.114", ] [[package]] name = "regex" -version = "1.8.4" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ - "aho-corasick 1.0.2", + "aho-corasick", "memchr", - "regex-syntax 0.7.2", + "regex-automata", + "regex-syntax 0.8.8", ] [[package]] name = "regex-automata" -version = "0.1.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ - "regex-syntax 0.6.25", + "aho-corasick", + "memchr", + "regex-syntax 0.8.8", ] [[package]] @@ -2322,32 +2381,17 @@ checksum = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e" [[package]] name = "regex-syntax" -version = "0.6.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" - -[[package]] -name = "regex-syntax" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" - -[[package]] -name = "remove_dir_all" -version = "0.5.3" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "reqwest" -version = "0.11.18" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64 0.21.2", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", @@ -2371,6 +2415,8 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", + "system-configuration", "tokio", "tokio-native-tls", "tokio-rustls", @@ -2395,11 +2441,25 @@ dependencies = [ "libc", "once_cell", "spin 0.5.2", - "untrusted", + "untrusted 0.7.1", "web-sys", "winapi", ] +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if 1.0.4", + "getrandom 0.2.16", + "libc", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + [[package]] name = "rocket" version = "0.5.0-rc.3" @@ -2407,7 +2467,7 @@ source = "git+https://github.com/SergioBenitez/Rocket?rev=91f6288ea4aeb3d5a502b2 dependencies = [ "async-stream", "async-trait", - "atomic", + "atomic 0.5.3", "binascii", "bytes", "either", @@ -2419,9 +2479,9 @@ dependencies = [ "memchr", "multer", "num_cpus", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "pin-project-lite", - "rand 0.8.3", + "rand 0.8.5", "ref-cast", "rocket_codegen", "rocket_http", @@ -2435,7 +2495,7 @@ dependencies = [ "tokio-util", "ubyte", "version_check", - "yansi", + "yansi 0.5.1", ] [[package]] @@ -2449,7 +2509,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn 2.0.43", + "syn 2.0.114", "unicode-xid", ] @@ -2496,7 +2556,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1db30db44ea73551326269adcf7a2169428a054f14faf9e1768f2163494f2fa2" dependencies = [ "async-trait", - "base64 0.13.0", + "base64 0.13.1", "bytes", "crc32fast", "futures", @@ -2551,7 +2611,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5ae95491c8b4847931e291b151127eccd6ff8ca13f33603eb3d0035ecb05272" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "bytes", "chrono", "digest", @@ -2571,18 +2631,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "rust-argon2" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb" -dependencies = [ - "base64 0.13.0", - "blake2b_simd", - "constant_time_eq", - "crossbeam-utils", -] - [[package]] name = "rust-stemmers" version = "1.2.0" @@ -2595,69 +2643,68 @@ dependencies = [ [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.11", + "semver 1.0.27", ] [[package]] name = "rustix" -version = "0.37.27" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "errno", - "io-lifetimes", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.21.1" +version = "0.21.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c911ba11bc8433e811ce56fde130ccf32f5127cab0e0194e9c68c5a5b671791e" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" dependencies = [ "log", - "ring", + "ring 0.17.14", "rustls-webpki", "sct", ] [[package]] name = "rustls-pemfile" -version = "1.0.2" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.2", + "base64 0.21.7", ] [[package]] name = "rustls-webpki" -version = "0.100.2" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e98ff011474fa39949b7e5c0428f9b4937eda7da7848bbb947786b7be0b27dab" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring", - "untrusted", + "ring 0.17.14", + "untrusted 0.9.0", ] [[package]] name = "rustversion" -version = "1.0.4" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb5d2a036dc6d2d8fd16fde3498b04306e29bd193bf306a57427019b823d5acd" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.5" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" [[package]] name = "same-file" @@ -2670,12 +2717,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.19" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "lazy_static", - "winapi", + "windows-sys 0.61.2", ] [[package]] @@ -2684,38 +2730,38 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cbc66816425a074528352f5789333ecff06ca41b36b0b0efdfbb29edc391a19" dependencies = [ - "parking_lot 0.12.1", + "parking_lot 0.12.5", ] [[package]] name = "scoped-tls" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" [[package]] name = "scopeguard" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sct" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring", - "untrusted", + "ring 0.17.14", + "untrusted 0.9.0", ] [[package]] name = "security-framework" -version = "2.2.0" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3670b1d2fdf6084d192bc71ead7aabe6c06aa2ea3fbd9cc3ac111fa5c2b1bd84" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "core-foundation", "core-foundation-sys", "libc", @@ -2724,9 +2770,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.2.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3676258fd3cfe2c9a0ec99ce3038798d847ce3e4bb17746373eb9f0f1ac16339" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -2744,58 +2790,71 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.11" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d92beeab217753479be2f74e54187a6aed4c125ff0703a866c3147a02f0c6dd" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ] [[package]] name = "semver-parser" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" dependencies = [ "pest", ] [[package]] name = "serde" -version = "1.0.193" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.114", ] [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ - "itoa 0.4.7", - "ryu", + "itoa", + "memchr", "serde", + "serde_core", + "zmij", ] [[package]] name = "serde_spanned" -version = "0.6.2" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93107647184f6027e3b7dcb2e11034cf95ffa1e3a682c67951963ac69c1c007d" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" dependencies = [ "serde", ] @@ -2807,45 +2866,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.6", + "itoa", "ryu", "serde", ] [[package]] name = "serde_with" -version = "1.8.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e557c650adfb38b32a5aec07082053253c703bc3cec654b27a5dbcf61995bb9b" +checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" dependencies = [ "chrono", - "rustversion", "serde", "serde_with_macros", ] [[package]] name = "serde_with_macros" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48b35457e9d855d3dc05ef32a73e0df1e2c0fd72c38796a4ee909160c8eeec2" +checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.67", -] - -[[package]] -name = "serde_yaml" -version = "0.8.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15654ed4ab61726bf918a39cb8d98a2e2995b002387807fa6ba58fdf7f59bb23" -dependencies = [ - "dtoa", - "linked-hash-map", - "serde", - "yaml-rust", + "syn 1.0.109", ] [[package]] @@ -2858,7 +2904,7 @@ dependencies = [ "futures", "lazy_static", "log", - "parking_lot 0.12.1", + "parking_lot 0.12.5", "serial_test_derive", ] @@ -2870,7 +2916,7 @@ checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.114", ] [[package]] @@ -2880,7 +2926,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer", - "cfg-if 1.0.0", + "cfg-if 1.0.4", "cpufeatures", "digest", "opaque-debug", @@ -2888,9 +2934,9 @@ dependencies = [ [[package]] name = "sharded-slab" -version = "0.1.4" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" dependencies = [ "lazy_static", ] @@ -2903,9 +2949,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook" -version = "0.3.10" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c98891d737e271a2954825ef19e46bd16bdb98e2746f2eec4f7a4ef7946efd1" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" dependencies = [ "libc", "signal-hook-registry", @@ -2913,29 +2959,36 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.1" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29fd5867f1c4f2c5be079aee7a2adf1152ebb04a4bc4d341f504b7dece607ed4" +checksum = "b75a19a7a740b25bc7944bdee6172368f988763b744e3d4dfe753f6b4ece40cc" dependencies = [ "libc", - "mio 0.7.11", + "mio 0.7.14", "signal-hook", ] [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" dependencies = [ + "errno", "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + [[package]] name = "similar" -version = "1.3.0" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad1d488a557b235fc46dae55512ffbfc429d2482b08b4d9435ab07384ca8aec" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" [[package]] name = "simple_asn1" @@ -2965,24 +3018,34 @@ dependencies = [ [[package]] name = "slab" -version = "0.4.2" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" [[package]] name = "smallvec" -version = "1.10.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.4.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", - "winapi", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", ] [[package]] @@ -3008,9 +3071,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "state" @@ -3041,9 +3104,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "structopt" -version = "0.3.21" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" dependencies = [ "clap", "lazy_static", @@ -3052,45 +3115,83 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck", "proc-macro-error", "proc-macro2", "quote", - "syn 1.0.67", + "syn 1.0.109", ] [[package]] name = "subtle" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.67" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6498a9efc342871f91cc2d0d694c674368b4ceb40f62b65a7a08c3792935e702" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", ] [[package]] name = "syn" -version = "2.0.43" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tagptr" version = "0.2.0" @@ -3103,7 +3204,7 @@ version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "25e733d58e88c51fb0ed76305885ce617a49731e3476514cf7ad4394668dfbc7" dependencies = [ - "base64 0.13.0", + "base64 0.13.1", "bitpacking", "byteorder", "census", @@ -3178,88 +3279,77 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "466e0218472a9b276a73e38b2571ac02f9a1b270b4481c9cd8cc23a63d1307e9" dependencies = [ - "combine 4.6.1", + "combine", ] [[package]] name = "tempfile" -version = "3.2.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ - "cfg-if 1.0.0", - "libc", - "rand 0.8.3", - "redox_syscall 0.2.13", - "remove_dir_all", - "winapi", + "fastrand", + "getrandom 0.3.4", + "once_cell", + "rustix", + "windows-sys 0.61.2", ] [[package]] name = "termcolor" -version = "1.1.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] -[[package]] -name = "terminal_size" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ca8ced750734db02076f44132d802af0b33b09942331f4459dde8636fd2406" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "textwrap" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width", + "unicode-width 0.1.14", ] [[package]] name = "thiserror" -version = "1.0.24" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0f4a65597094d4483ddaed134f409b2cb7c1beccf25201a9f73c719254fa98e" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.24" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7765189610d8241a44529806d6fd1f2e0a08734313a35d5b3a556f92b381f3c0" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.67", + "syn 2.0.114", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ - "cfg-if 1.0.0", - "once_cell", + "cfg-if 1.0.4", ] [[package]] name = "time" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", + "wasi 0.10.0+wasi-snapshot-preview1", "winapi", ] @@ -3270,7 +3360,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef89ece63debf11bc32d1ed8d078ac870cbeb44da02afb02a9ff135ae7ca0582" dependencies = [ "deranged", - "itoa 1.0.6", + "itoa", "num-conv", "powerfmt", "serde", @@ -3295,54 +3385,47 @@ dependencies = [ ] [[package]] -name = "tinyvec" -version = "1.1.1" +name = "tinystr" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ - "tinyvec_macros", + "displaydoc", + "zerovec", ] -[[package]] -name = "tinyvec_macros" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" - [[package]] name = "tokio" -version = "1.28.2" +version = "1.49.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" dependencies = [ - "autocfg", "bytes", "libc", - "mio 0.8.8", - "num_cpus", + "mio 1.1.1", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.6.1", "tokio-macros", - "windows-sys 0.48.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.1.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.114", ] [[package]] name = "tokio-native-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", @@ -3350,9 +3433,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0d409377ff5b1e3ca6437aa86c1eb7d40c134bfec254e44c830defa92669db5" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ "rustls", "tokio", @@ -3360,9 +3443,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" dependencies = [ "futures-core", "pin-project-lite", @@ -3371,85 +3454,90 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.3" +version = "0.7.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml" -version = "0.5.8" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] [[package]] name = "toml" -version = "0.7.4" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6135d499e69981f9ff0ef2167955a5333c35e36f6937d382974566b3d5b94ec" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.19.10", + "toml_edit 0.22.27", ] [[package]] name = "toml_datetime" -version = "0.6.2" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a76a9312f5ba4c2dec6b9161fdf25d87ad8a09256ccea5a556fef03c706a10f" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09391a441b373597cf0888d2b052dcf82c5be4fee05da3636ae30fb57aad8484" +checksum = "dbbdcf4f749dd33b1f1ea19b547bf789d87442ec40767d6015e5e2d39158d69a" dependencies = [ "chrono", - "combine 3.8.1", + "combine", "linked-hash-map", ] [[package]] name = "toml_edit" -version = "0.19.10" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380d56e8670370eee6566b0bfd4265f65b3f432e8c6d85623f728d4fa31f739" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 1.9.3", + "indexmap 2.12.1", "serde", "serde_spanned", "toml_datetime", + "toml_write", "winnow", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.35" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ - "cfg-if 1.0.0", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -3457,20 +3545,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.24" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.43", + "syn 2.0.114", ] [[package]] name = "tracing-core" -version = "0.1.31" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0955b8137a1df6f1a2e9a37d8a6656291ff0297c1a97c24e0d8425fe2312f79a" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -3478,25 +3566,25 @@ dependencies = [ [[package]] name = "tracing-log" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" dependencies = [ - "lazy_static", "log", + "once_cell", "tracing-core", ] [[package]] name = "tracing-subscriber" -version = "0.3.15" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60db860322da191b40952ad9affe65ea23e7dd6a5c442c2c42865810c6ab8e6b" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ - "ansi_term 0.12.1", "matchers", + "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "sharded-slab", "smallvec", "thread_local", @@ -3507,52 +3595,52 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.8" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1ee9bd9239c339d714d657fac840c6d2a4f9c45f4f9ec7b0975113458be78db" +checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39" [[package]] name = "try-lock" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "twox-hash" -version = "1.6.1" +version = "1.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f559b464de2e2bdabcac6a210d12e9b5a5973c251e102c44c585c71d51bd78e" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.4", "static_assertions", ] [[package]] name = "typenum" -version = "1.13.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "ubyte" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c81f0dae7d286ad0d9366d7679a77934cfc3cf3a8d67e82669794412b2368fe6" +checksum = "f720def6ce1ee2fc44d40ac9ed6d3a59c361c80a75a7aa8e75bb9baed31cf2ea" dependencies = [ "serde", ] [[package]] name = "ucd-trie" -version = "0.1.3" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "uncased" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" dependencies = [ "serde", "version_check", @@ -3560,94 +3648,76 @@ dependencies = [ [[package]] name = "unicase" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -dependencies = [ - "matches", -] +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" [[package]] name = "unicode-ident" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" - -[[package]] -name = "unicode-normalization" -version = "0.1.17" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" -dependencies = [ - "tinyvec", -] +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-segmentation" -version = "1.7.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] -name = "unicode-xid" -version = "0.2.1" +name = "unicode-width" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] -name = "unindent" -version = "0.1.7" +name = "unicode-xid" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] -name = "unreachable" -version = "1.0.0" +name = "untrusted" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56" -dependencies = [ - "void", -] +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "untrusted" -version = "0.7.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.2.1" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", "serde", + "serde_derive", ] [[package]] name = "utf8-ranges" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" + +[[package]] +name = "utf8_iter" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ae116fef2b7fea257ed6440d3cfcff7f190865f170cdad00bb6465bf18ecba" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" @@ -3655,30 +3725,32 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.2", + "getrandom 0.2.16", "serde", ] [[package]] name = "uuid" -version = "1.3.3" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345444e32442451b267fc254ae85a209c64be56d2890e601a0c37ff0c3c5ecd2" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ - "getrandom 0.2.2", + "getrandom 0.3.4", + "js-sys", + "wasm-bindgen", ] [[package]] name = "valuable" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "vcpkg" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00bca6106a5e23f3eee943593759b7fcddb00554332e856d990c893966879fb" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vec_map" @@ -3688,24 +3760,17 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "void" -version = "1.0.2" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" -version = "2.3.2" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", - "winapi", "winapi-util", ] @@ -3738,8 +3803,8 @@ dependencies = [ "tempfile", "time 0.3.35", "tokio", - "toml 0.5.8", - "toml_edit 0.2.0", + "toml 0.5.11", + "toml_edit 0.2.1", "ubyte", "url", "walkdir", @@ -3780,11 +3845,10 @@ dependencies = [ [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] @@ -3796,15 +3860,24 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" [[package]] name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" +version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] [[package]] name = "wasite" @@ -3814,46 +3887,35 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.73" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83240549659d187488f91f33c0f8547cbfef0b2088bc470c116d1d260ef623d9" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", + "once_cell", + "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.73" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae70622411ca953215ca6d06d3ebeb1e915f0f6613e3b495122878d7ebec7dae" -dependencies = [ - "bumpalo", - "lazy_static", - "log", - "proc-macro2", - "quote", - "syn 1.0.67", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.23" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81b8b767af23de6ac18bf2168b690bed2902743ddf0fb39252e36f9e2bfc63ea" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if 1.0.4", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.73" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e734d91443f177bfdb41969de821e15c516931c3c3db3d318fa1b68975d0f6f" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3861,30 +3923,33 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.73" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53739ff08c8a68b0fdbcd54c372b8ab800b1449ab3c9d706503bc7dd1621b2c" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 1.0.67", - "wasm-bindgen-backend", + "syn 2.0.114", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.73" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9a543ae66aa233d14bb765ed9af4a33e81b8b58d1584cf1b47ff8cd0b9e4489" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +dependencies = [ + "unicode-ident", +] [[package]] name = "wasm-streams" -version = "0.2.2" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076e644811919817f3d28f9344a7d359d8a45cc72a7187c7ace7281d081a74ad" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ - "futures", + "futures-util", "js-sys", "wasm-bindgen", "wasm-bindgen-futures", @@ -3893,40 +3958,37 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.50" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a905d57e488fec8861446d3393670fb50d27a262344013181c2cdf9fff5481be" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] -name = "webpki" -version = "0.22.0" +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ - "ring", - "untrusted", + "js-sys", + "wasm-bindgen", ] [[package]] name = "webpki-roots" -version = "0.22.6" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" -dependencies = [ - "webpki", -] +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "whoami" -version = "1.5.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fec781d48b41f8163426ed18e8fc2864c12937df9ce54c88ede7bd47270893e" +checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" dependencies = [ - "redox_syscall 0.4.1", + "libredox", "wasite", "web-sys", ] @@ -3949,11 +4011,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "winapi", + "windows-sys 0.61.2", ] [[package]] @@ -3968,16 +4030,66 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.5", ] [[package]] -name = "windows-sys" -version = "0.45.0" +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ - "windows-targets 0.42.2", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", ] [[package]] @@ -3986,178 +4098,399 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.0", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", ] [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] name = "windows-targets" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.4.6" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61de7bac303dc551fe038e2b3cef0f571087a47571ea6e79a87692ac99b99699" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] [[package]] name = "winreg" -version = "0.10.1" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "winapi", + "cfg-if 1.0.4", + "windows-sys 0.48.0", ] +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + [[package]] name = "xml-rs" -version = "0.8.4" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f" + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "yansi" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] -name = "yaml-rust" -version = "0.4.5" +name = "yoke" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ - "linked-hash-map", + "stable_deref_trait", + "yoke-derive", + "zerofrom", ] [[package]] -name = "yansi" -version = "0.5.0" +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc79f4a1e39857fc00c3f662cbf2651c771f00e9c15fe2abc341806bd46bd71" +checksum = "1fabae64378cb18147bb18bca364e63bdbe72a0ffe4adf0addfec8aa166b2c56" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9c2d862265a8bb4471d87e033e730f536e2a285cc7cb05dbce09a2a97075f90" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure", +] [[package]] name = "zeroize" -version = "1.5.6" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20b578acffd8516a6c3f2a1bdefc1ec37e547bb4e0fb8b6b01a4cafc886b4442" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] [[package]] name = "zip" -version = "0.5.11" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8264fcea9b7a036a4a5103d7153e988dbc2ebbafb34f68a3c2d404b6b82d74b6" +checksum = "93ab48844d61251bb3835145c521d88aa4031d7139e8485990f60ca911fa0815" dependencies = [ "byteorder", "bzip2", "crc32fast", "flate2", "thiserror", - "time 0.1.43", + "time 0.1.45", ] + +[[package]] +name = "zmij" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8" diff --git a/Cargo.toml b/Cargo.toml index 6deccd31..73f2af78 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,7 +40,7 @@ indoc = "1.0.3" log = "0.4.11" once_cell = "1.5.2" opener = "0.5.0" -reqwest = { version = "0.11.18", features = ["blocking", "json"] } +reqwest = { version = "0.11.20", features = ["blocking", "json"] } rpassword = "5.0.1" semver = { version = "0.11.0", features = ["serde"] } serde = { version = "1.0.116", features = ["derive"] } diff --git a/src/extract_types.rs b/src/extract_types.rs new file mode 100644 index 00000000..c4967c1f --- /dev/null +++ b/src/extract_types.rs @@ -0,0 +1,497 @@ + +use std::collections::BTreeSet; +use std::fs; +use std::path::PathBuf; +use serde::Deserialize; +use std::mem::take; + +#[derive(Deserialize)] +struct ProjectFile { + tree: Option, +} + +#[derive(Deserialize)] +struct Tree { + #[serde(rename = "$path")] + path: String, +} + +fn get(code: &str, at: usize) -> char { + if at >= code.len() { + return '\0'; + } + code.as_bytes()[at] as char +} + +fn is_end_of_block(code: &str, at: usize, level: usize) -> bool { + if get(code, at) != ']' { + return false; + } + let mut index = at + 1; + for _ in 0..level { + if get(code, index) != '=' { + return false; + } + index += 1; + } + if get(code, index) != ']' { + return false; + } + true +} + +#[derive(Clone)] +enum LexState { + Code, + TemplateString, // `` + DoubleQuoteString, // "" + SingleQuoteString, // '' + BlockString(usize), // [=[ ]=] + LineComment, // -- + BlockComment(usize), // --[=[ ]=] +} + +fn strip_comments_and_strings(lua_code: &str) -> String { + // Buffer to write out to charater by character + let mut output = String::new(); + let mut index = 0; + let mut state = LexState::Code; + while index < lua_code.len() { + let c = get(lua_code, index); + let peek = get(lua_code, index + 1); + match (state.clone(), c, peek) { + // Checks to enter one of the states to ignore + (LexState::Code, '`', _) => { + state = LexState::TemplateString; + index += 1; + } + (LexState::Code, '"', _) => { + state = LexState::DoubleQuoteString; + index += 1; + } + (LexState::Code, '\'', _) => { + state = LexState::SingleQuoteString; + index += 1; + } + (LexState::Code, '[', '=' | '[') => { + index += 2; + let mut level = if peek == '=' { 1 } else { 0 }; + while get(lua_code, index) == '=' { + level += 1; + index += 1; + } + state = LexState::BlockString(level); + if level > 0 { + assert!(get(lua_code, index) == '['); + index += 1; + } + } + (LexState::Code, '-', '-') => { + index += 2; + if get(lua_code, index) == '[' { + index += 1; + let mut level = 0; + while get(lua_code, index) == '=' { + level += 1; + index += 1; + } + if get(lua_code, index) == '[' { + index += 1; + state = LexState::BlockComment(level); + } else { + state = LexState::LineComment; + } + } else { + state = LexState::LineComment; + } + } + + // Useful contents to not ignore + (LexState::Code, _, _) => { + output.push(c); + index += 1; + } + + // Template string + (LexState::TemplateString, '`', _) => { + state = LexState::Code; + index += 1; + } + (LexState::TemplateString, '\\', '`') => { + index += 2; + } + + // Double quote string + (LexState::DoubleQuoteString, '"', _) => { + state = LexState::Code; + index += 1; + } + (LexState::DoubleQuoteString, '\\', '"') => { + index += 2; + } + + // Single quote string + (LexState::SingleQuoteString, '\'', _) => { + state = LexState::Code; + index += 1; + } + (LexState::SingleQuoteString, '\\', '\'') => { + index += 2; + } + + // Block string + (LexState::BlockString(depth), ']', '=' | ']') => { + if is_end_of_block(lua_code, index, depth) { + state = LexState::Code; + index += depth + 2; + } else { + index += 1; + } + } + + // Block comment + (LexState::BlockComment(depth), ']', '=' | ']') => { + if is_end_of_block(lua_code, index, depth) { + state = LexState::Code; + index += depth + 2; + } else { + index += 1; + } + } + + // Line comment + (LexState::LineComment, '\n', _) => { + state = LexState::Code; + } + + // Other character to ignore + (_, _, _) => { + index += 1; + } + } + } + + output +} + +#[derive(Clone, PartialEq, Debug)] +enum ParseState { + Code, // expect "export" + Export, // expect "type" + Type, // expect type name + StartTypeParamList, // optionally expect '<' + TypeParam, // expect type param name + TypePack, // optionally expect "..." + TypeDefault, // optionally expect '=' and default value + TypeDefaultName, // expect default type name + NextTypeParam, // optionally expect ',' or '>' +} + +#[derive(Clone)] +pub struct TypeParam { + name: String, + is_pack: bool, + default: Option, +} + +impl TypeParam { + fn new() -> Self { + TypeParam { + name: String::new(), + is_pack: false, + default: None, + } + } +} + +impl Default for TypeParam { + fn default() -> Self { + Self::new() + } +} + +pub struct ExportStatement { + name: String, + is_exported: bool, + type_params: Vec, +} + +impl ExportStatement { + fn new() -> Self { + ExportStatement { + name: String::new(), + is_exported: false, + type_params: Vec::new(), + } + } + + pub fn to_forwarding_statement(&self, module_name: &str) -> String { + if self.type_params.len() == 0 { + format!("export type {} = {}.{}", self.name, module_name, self.name) + } else { + let params: Vec = self.type_params.iter().map(|param| { + let pack = if param.is_pack { "..." } else { "" }; + let default = param.default.as_ref().map(|d| format!(" = {}", d)).unwrap_or_default(); + format!("{}{}{}", param.name, pack, default) + }).collect(); + + let param_names: Vec = self.type_params.iter().map(|param| { + let pack = if param.is_pack { "..." } else { "" }; + format!("{}{}", param.name, pack) + }).collect(); + + format!( + "export type {}<{}> = {}.{}<{}>", + self.name, + params.join(", "), + module_name, + self.name, + param_names.join(", ") + ) + } + } +} + +impl Default for ExportStatement { + fn default() -> Self { + Self::new() + } +} + +pub struct ExtractTypesResult { + statements: Vec, +} + +impl ExtractTypesResult { + pub fn new() -> Self { + ExtractTypesResult { + statements: Vec::new(), + } + } + + pub fn format_forwarding_statements(&self, module_name: &str) -> String { + self.statements.iter().map(|stmt| { + stmt.to_forwarding_statement(module_name) + }).collect::>().join("\n") + } + + pub fn is_empty(&self) -> bool { + self.statements.is_empty() + } + + pub fn add_statement(&mut self, statement: ExportStatement) { + if statement.is_exported { + self.statements.push(statement); + } + } +} + +fn parse_types(lua_code: &str) -> ExtractTypesResult { + // First strip any comments / strings which could have extraneous "export type" text in them. + let lua_code = strip_comments_and_strings(lua_code); + + // Now use a permissive parse to find export type statements. + let mut index = 0; + let mut state = ParseState::Code; + let mut current_export_statement = ExportStatement::new(); + let mut current_type_param = TypeParam::new(); + let mut result = ExtractTypesResult::new(); + let mut non_exported_types: BTreeSet = BTreeSet::new(); + while index < lua_code.len() { + let mut c = get(&lua_code, index); + // Skip whitespace + while c.is_ascii_whitespace() { + index += 1; + c = get(&lua_code, index); + } + if index >= lua_code.len() { + break; + } + match (state.clone(), c) { + (ParseState::Code, 'e') => { + if lua_code[index..].starts_with("export") { + state = ParseState::Export; + current_export_statement.is_exported = true; + index += "export".len(); + } else { + index += 1; + } + } + (ParseState::Code, 't') => { + if lua_code[index..].starts_with("type") { + state = ParseState::Type; + current_export_statement.is_exported = false; + index += "type".len(); + } else { + index += 1; + } + } + (ParseState::Export, 't') => { + if lua_code[index..].starts_with("type") { + state = ParseState::Type; + index += "type".len(); + } else { + state = ParseState::Code; + } + } + (ParseState::Type, _) => { + let start = index; + while get(&lua_code, index).is_ascii_alphanumeric() || get(&lua_code, index) == '_' { + index += 1; + } + let type_name = &lua_code[start..index]; + current_export_statement.name = type_name.to_string(); + if !current_export_statement.is_exported { + non_exported_types.insert(type_name.to_string()); + } + state = ParseState::StartTypeParamList; + } + (ParseState::StartTypeParamList, '<') => { + state = ParseState::TypeParam; + index += 1; + } + (ParseState::StartTypeParamList, _) => { + result.add_statement(take(&mut current_export_statement)); + state = ParseState::Code; + } + (ParseState::TypeParam, _) => { + let start = index; + while get(&lua_code, index).is_ascii_alphanumeric() || get(&lua_code, index) == '_' { + index += 1; + } + let param_name = &lua_code[start..index]; + assert!(param_name.len() > 0); + current_type_param.name = param_name.to_string(); + state = ParseState::TypePack; + } + (ParseState::TypePack, '.') => { + if lua_code[index..].starts_with("...") { + current_type_param.is_pack = true; + index += 3; + } + state = ParseState::TypeDefault; + } + (ParseState::TypePack, _) => { + state = ParseState::TypeDefault; + } + (ParseState::TypeDefault, '=') => { + index += 1; + state = ParseState::TypeDefaultName; + } + (ParseState::TypeDefault, _) => { + current_export_statement.type_params.push(take(&mut current_type_param)); + state = ParseState::NextTypeParam; + } + (ParseState::TypeDefaultName, _) => { + let start = index; + while get(&lua_code, index).is_ascii_alphanumeric() || get(&lua_code, index) == '_' { + index += 1; + } + let default_name = &lua_code[start..index]; + assert!(default_name.len() > 0); + current_type_param.default = Some(default_name.to_string()); + current_export_statement.type_params.push(take(&mut current_type_param)); + state = ParseState::NextTypeParam; + } + (ParseState::NextTypeParam, ',') => { + index += 1; + state = ParseState::TypeParam; + } + (ParseState::NextTypeParam, '>') => { + result.add_statement(take(&mut current_export_statement)); + index += 1; + state = ParseState::Code; + } + _ => { + index += 1; + } + } + } + + // Post-process to remove type defaults which weren't exported. + // There's no way to reference these types from outside the module so there's + // no way to re-export them. The library author has to fix this if desired. + for statement in result.statements.iter_mut() { + for param in statement.type_params.iter_mut() { + if let Some(default) = ¶m.default { + if non_exported_types.contains(default) { + param.default = None; + } + } + } + } + + result +} + +pub fn extract_types(package_path: &PathBuf) -> ExtractTypesResult { + log::debug!("Processing types for package at {}", package_path.display()); + + let project_file_path = package_path.join("default.project.json"); + + if !project_file_path.exists() { + log::debug!("No default.project.json found for package at {}", package_path.display()); + return ExtractTypesResult::new(); + } + + let project_contents = match fs::read_to_string(&project_file_path) { + Ok(c) => c, + Err(err) => { + log::warn!( + "Failed to read {}: {}", + project_file_path.display(), + err + ); + return ExtractTypesResult::new(); + } + }; + + let project: ProjectFile = match serde_json::from_str(&project_contents) { + Ok(p) => p, + Err(err) => { + log::warn!( + "Invalid JSON in {}: {}", + project_file_path.display(), + err + ); + return ExtractTypesResult::new(); + } + }; + + let tree_path = match project.tree { + Some(tree) => package_path.join(tree.path), + None => { + log::debug!("default.project.json has no tree path"); + return ExtractTypesResult::new(); + } + }; + + let init_lua = tree_path.join("init.lua"); + let init_luau = tree_path.join("init.luau"); + + let init_path = if init_lua.exists() { + init_lua + } else if init_luau.exists() { + init_luau + } else { + log::debug!( + "No init.lua or init.luau found under {}", + tree_path.display() + ); + return ExtractTypesResult::new(); + }; + + let init_contents = match fs::read_to_string(&init_path) { + Ok(c) => c, + Err(err) => { + log::warn!( + "Failed to read {}: {}", + init_path.display(), + err + ); + return ExtractTypesResult::new(); + } + }; + + parse_types(&init_contents) +} \ No newline at end of file diff --git a/src/installation.rs b/src/installation.rs index c9fd4f9d..b710477f 100644 --- a/src/installation.rs +++ b/src/installation.rs @@ -1,8 +1,5 @@ use std::{ - fmt::Display, - io, - path::{Path, PathBuf}, - time::Duration, + collections::BTreeMap, fmt::Display, io, path::{Path, PathBuf}, time::Duration }; use anyhow::{bail, format_err}; @@ -12,6 +9,7 @@ use indicatif::{ProgressBar, ProgressStyle}; use indoc::{formatdoc, indoc}; use crate::{ + extract_types::{extract_types, ExtractTypesResult}, manifest::Realm, package_contents::PackageContents, package_id::PackageId, @@ -31,6 +29,8 @@ pub struct InstallationContext { dev_index_dir: PathBuf, } +type PackageTypeExports = BTreeMap; + impl InstallationContext { /// Create a new `InstallationContext` for the given path. pub fn new( @@ -103,43 +103,14 @@ impl InstallationContext { .build() .unwrap(); - for package_id in resolved_copy.activated { - log::debug!("Installing {}...", package_id); - - let shared_deps = resolved.shared_dependencies.get(&package_id); - let server_deps = resolved.server_dependencies.get(&package_id); - let dev_deps = resolved.dev_dependencies.get(&package_id); - - // We do not need to install the root package, but we should create - // package links for its dependencies. - if package_id == root_package_id { - if let Some(deps) = shared_deps { - self.write_root_package_links(Realm::Shared, deps, &resolved)?; - } - - if let Some(deps) = server_deps { - self.write_root_package_links(Realm::Server, deps, &resolved)?; - } + for package_id in &resolved_copy.activated { + // Shadow because the thread will need to take ownership of this value. + let package_id = package_id.clone(); + if package_id != root_package_id { + log::debug!("Downloading package {}...", package_id); - if let Some(deps) = dev_deps { - self.write_root_package_links(Realm::Dev, deps, &resolved)?; - } - } else { let metadata = resolved.metadata.get(&package_id).unwrap(); let package_realm = metadata.origin_realm; - - if let Some(deps) = shared_deps { - self.write_package_links(&package_id, package_realm, deps, &resolved)?; - } - - if let Some(deps) = server_deps { - self.write_package_links(&package_id, package_realm, deps, &resolved)?; - } - - if let Some(deps) = dev_deps { - self.write_package_links(&package_id, package_realm, deps, &resolved)?; - } - let source_registry = resolved_copy.metadata[&package_id].source_registry.clone(); let source_copy = sources.clone(); let context = self.clone(); @@ -155,7 +126,12 @@ impl InstallationContext { package_id, )); b.inc(1); - context.write_contents(&package_id, &contents, package_realm) + + let write_result = + context.write_contents(&package_id, &contents, package_realm); + write_result.map(|path| { + (package_id, extract_types(&path)) + }) }); handles.push(handle); @@ -163,11 +139,53 @@ impl InstallationContext { } let num_packages = handles.len(); - + let mut types_for_package = PackageTypeExports::new(); for handle in handles { - runtime + let (package_id, exported_types) = runtime .block_on(handle) .expect("Package failed to be installed.")?; + + types_for_package.insert(package_id, exported_types); + } + + for package_id in &resolved_copy.activated { + log::debug!("Installing package {}...", package_id); + + let shared_deps = resolved.shared_dependencies.get(&package_id); + let server_deps = resolved.server_dependencies.get(&package_id); + let dev_deps = resolved.dev_dependencies.get(&package_id); + + // Then 3), run these loops, passing in the registry object. + // We do not need to install the root package, but we should create + // package links for its dependencies. + if *package_id == root_package_id { + if let Some(deps) = shared_deps { + self.write_root_package_links(Realm::Shared, deps, &resolved, &types_for_package)?; + } + + if let Some(deps) = server_deps { + self.write_root_package_links(Realm::Server, deps, &resolved, &types_for_package)?; + } + + if let Some(deps) = dev_deps { + self.write_root_package_links(Realm::Dev, deps, &resolved, &types_for_package)?; + } + } else { + let metadata = resolved.metadata.get(&package_id).unwrap(); + let package_realm = metadata.origin_realm; + + if let Some(deps) = shared_deps { + self.write_package_links(&package_id, package_realm, deps, &resolved, &types_for_package)?; + } + + if let Some(deps) = server_deps { + self.write_package_links(&package_id, package_realm, deps, &resolved, &types_for_package)?; + } + + if let Some(deps) = dev_deps { + self.write_package_links(&package_id, package_realm, deps, &resolved, &types_for_package)?; + } + } } bar.finish_and_clear(); @@ -177,27 +195,53 @@ impl InstallationContext { } /// Contents of a package-to-package link within the same index. - fn link_sibling_same_index(&self, id: &PackageId) -> String { - formatdoc! {r#" - return require(script.Parent.Parent["{full_name}"]["{short_name}"]) - "#, - full_name = package_id_file_name(id), - short_name = id.name().name() + fn link_sibling_same_index(&self, id: &PackageId, exports: &ExtractTypesResult) -> String { + // TODO: Here, pass and write set of types + if exports.is_empty() { + formatdoc! {r#" + return require(script.Parent.Parent["{full_name}"]["{short_name}"]) + "#, + full_name = package_id_file_name(id), + short_name = id.name().name() + } + } else { + formatdoc! {r#" + local MODULE = require(script.Parent.Parent["{full_name}"]["{short_name}"]) + {exports_string} + return MODULE + "#, + full_name = package_id_file_name(id), + short_name = id.name().name(), + exports_string = exports.format_forwarding_statements("MODULE") + } } + } /// Contents of a root-to-package link within the same index. - fn link_root_same_index(&self, id: &PackageId) -> String { - formatdoc! {r#" - return require(script.Parent._Index["{full_name}"]["{short_name}"]) - "#, - full_name = package_id_file_name(id), - short_name = id.name().name() + fn link_root_same_index(&self, id: &PackageId, exports: &ExtractTypesResult) -> String { + if exports.is_empty() { + formatdoc! {r#" + return require(script.Parent._Index["{full_name}"]["{short_name}"]) + "#, + full_name = package_id_file_name(id), + short_name = id.name().name() + } + } else { + formatdoc! {r#" + local MODULE = require(script.Parent._Index["{full_name}"]["{short_name}"]) + {exports_string} + return MODULE + "#, + full_name = package_id_file_name(id), + short_name = id.name().name(), + exports_string = exports.format_forwarding_statements("MODULE") + } } } /// Contents of a link into the shared index from outside the shared index. - fn link_shared_index(&self, id: &PackageId) -> anyhow::Result { + fn link_shared_index(&self, id: &PackageId, exports: &ExtractTypesResult) -> anyhow::Result { let shared_path = self.shared_path.as_ref().ok_or_else(|| { format_err!(indoc! {r#" A server or dev dependency is depending on a shared dependency. @@ -211,19 +255,32 @@ impl InstallationContext { "#}) })?; - let contents = formatdoc! {r#" - return require({packages}._Index["{full_name}"]["{short_name}"]) - "#, - packages = shared_path, - full_name = package_id_file_name(id), - short_name = id.name().name() + let contents = if exports.is_empty() { + formatdoc! {r#" + return require({packages}._Index["{full_name}"]["{short_name}"]) + "#, + packages = shared_path, + full_name = package_id_file_name(id), + short_name = id.name().name() + } + } else { + formatdoc! {r#" + local MODULE = require({packages}._Index["{full_name}"]["{short_name}"]) + {exports_string} + return MODULE + "#, + packages = shared_path, + full_name = package_id_file_name(id), + short_name = id.name().name(), + exports_string = exports.format_forwarding_statements("MODULE") + } }; Ok(contents) } /// Contents of a link into the server index from outside the server index. - fn link_server_index(&self, id: &PackageId) -> anyhow::Result { + fn link_server_index(&self, id: &PackageId, exports: &ExtractTypesResult) -> anyhow::Result { let server_path = self.server_path.as_ref().ok_or_else(|| { format_err!(indoc! {r#" A dev dependency is depending on a server dependency. @@ -237,12 +294,25 @@ impl InstallationContext { "#}) })?; - let contents = formatdoc! {r#" - return require({packages}._Index["{full_name}"]["{short_name}"]) - "#, - packages = server_path, - full_name = package_id_file_name(id), - short_name = id.name().name() + let contents = if exports.is_empty() { + formatdoc! {r#" + return require({packages}._Index["{full_name}"]["{short_name}"]) + "#, + packages = server_path, + full_name = package_id_file_name(id), + short_name = id.name().name() + } + } else { + formatdoc! {r#" + local MODULE = require({packages}._Index["{full_name}"]["{short_name}"]) + {exports_string} + return MODULE + "#, + packages = server_path, + full_name = package_id_file_name(id), + short_name = id.name().name(), + exports_string = exports.format_forwarding_statements("MODULE") + } }; Ok(contents) @@ -253,6 +323,7 @@ impl InstallationContext { root_realm: Realm, dependencies: impl IntoIterator, resolved: &Resolve, + types: &PackageTypeExports ) -> anyhow::Result<()> { log::debug!("Writing root package links"); @@ -268,11 +339,12 @@ impl InstallationContext { for (dep_name, dep_package_id) in dependencies { let dependencies_realm = resolved.metadata.get(dep_package_id).unwrap().origin_realm; let path = base_path.join(format!("{}.lua", dep_name)); + let types_for_dep = types.get(dep_package_id).unwrap(); let contents = match (root_realm, dependencies_realm) { - (source, dest) if source == dest => self.link_root_same_index(dep_package_id), - (_, Realm::Server) => self.link_server_index(dep_package_id)?, - (_, Realm::Shared) => self.link_shared_index(dep_package_id)?, + (source, dest) if source == dest => self.link_root_same_index(dep_package_id, types_for_dep), + (_, Realm::Server) => self.link_server_index(dep_package_id, types_for_dep)?, + (_, Realm::Shared) => self.link_shared_index(dep_package_id, types_for_dep)?, (_, Realm::Dev) => { bail!("A dev dependency cannot be depended upon by a non-dev dependency") } @@ -291,6 +363,7 @@ impl InstallationContext { package_realm: Realm, dependencies: impl IntoIterator, resolved: &Resolve, + types: &PackageTypeExports ) -> anyhow::Result<()> { log::debug!("Writing package links for {}", package_id); @@ -308,11 +381,12 @@ impl InstallationContext { for (dep_name, dep_package_id) in dependencies { let dependencies_realm = resolved.metadata.get(dep_package_id).unwrap().origin_realm; let path = base_path.join(format!("{}.lua", dep_name)); + let types_for_dep = types.get(dep_package_id).unwrap(); let contents = match (package_realm, dependencies_realm) { - (source, dest) if source == dest => self.link_sibling_same_index(dep_package_id), - (_, Realm::Server) => self.link_server_index(dep_package_id)?, - (_, Realm::Shared) => self.link_shared_index(dep_package_id)?, + (source, dest) if source == dest => self.link_sibling_same_index(dep_package_id, types_for_dep), + (_, Realm::Server) => self.link_server_index(dep_package_id, types_for_dep)?, + (_, Realm::Shared) => self.link_shared_index(dep_package_id, types_for_dep)?, (_, Realm::Dev) => { bail!("A dev dependency cannot be depended upon by a non-dev dependency") } @@ -330,7 +404,7 @@ impl InstallationContext { package_id: &PackageId, contents: &PackageContents, realm: Realm, - ) -> anyhow::Result<()> { + ) -> anyhow::Result { let mut path = match realm { Realm::Shared => self.shared_index_dir.clone(), Realm::Server => self.server_index_dir.clone(), @@ -343,7 +417,7 @@ impl InstallationContext { fs::create_dir_all(&path)?; contents.unpack_into_path(&path)?; - Ok(()) + Ok(path) } } diff --git a/src/lib.rs b/src/lib.rs index 1d734aff..efcb2d01 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,5 +12,6 @@ pub mod package_req; pub mod package_source; pub mod resolution; pub mod test_package; +mod extract_types; pub use commands::*; From 4e93f38080bde4922aad659a0375cd6614f0da27 Mon Sep 17 00:00:00 2001 From: Mark Langen Date: Fri, 16 Jan 2026 22:41:42 -0800 Subject: [PATCH 2/2] Add unit tests and one integration test * Add one integration test which install a dependency that has exported types to process. * Add unit tests to extract_types module. * Have to update insta module and deal with some deprecations from that because tests no longer run on a modern toolchain without the update. --- Cargo.lock | 96 +- Cargo.toml | 134 +- src/extract_types.rs | 1239 ++++++++++------- src/resolution.rs | 1002 ++++++------- .../default.project.json | 6 + .../dependency-with-types/src/init.lua | 5 + .../dependency-with-types/wally.toml | 9 + .../biff/minimal-with-types/0.1.0.zip | Bin 0 -> 792 bytes .../index/biff/minimal-with-types | 1 + tests/integration/install.rs | 220 +-- ...ation__install__dependency_with_types.snap | 17 + wally-registry-backend/src/tests/mod.rs | 628 ++++----- 12 files changed, 1829 insertions(+), 1528 deletions(-) create mode 100644 test-projects/dependency-with-types/default.project.json create mode 100644 test-projects/dependency-with-types/src/init.lua create mode 100644 test-projects/dependency-with-types/wally.toml create mode 100644 test-registries/primary-registry/contents/biff/minimal-with-types/0.1.0.zip create mode 100644 test-registries/primary-registry/index/biff/minimal-with-types create mode 100644 tests/integration/snapshots/integration__install__dependency_with_types.snap diff --git a/Cargo.lock b/Cargo.lock index a0b8269f..f31f9abd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,7 +14,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "once_cell", "version_check", ] @@ -292,9 +292,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.51" +version = "1.2.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" +checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" dependencies = [ "find-msvc-tools", "jobserver", @@ -322,9 +322,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" dependencies = [ "iana-time-zone", "js-sys", @@ -817,15 +817,15 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" +checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" [[package]] name = "flate2" -version = "1.1.5" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" dependencies = [ "crc32fast", "miniz_oxide", @@ -1006,9 +1006,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if 1.0.4", "libc", @@ -1073,7 +1073,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap 2.12.1", + "indexmap 2.13.0", "slab", "tokio", "tokio-util", @@ -1389,9 +1389,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -1424,12 +1424,13 @@ checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" [[package]] name = "insta" -version = "1.46.0" +version = "1.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b66886d14d18d420ab5052cbff544fc5d34d0b2cdd35eb5976aaa10a4a472e5" +checksum = "248b42847813a1550dafd15296fd9748c651d0c32194559dbc05d804d54b21e8" dependencies = [ "console", "once_cell", + "serde", "similar", "tempfile", ] @@ -1487,9 +1488,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ "once_cell", "wasm-bindgen", @@ -1523,9 +1524,9 @@ checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" [[package]] name = "libc" -version = "0.2.179" +version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "libgit2-sys" @@ -2251,7 +2252,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] @@ -2325,7 +2326,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "libredox", "thiserror", ] @@ -2454,7 +2455,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if 1.0.4", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted 0.9.0", "windows-sys 0.52.0", @@ -3512,7 +3513,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.12.1", + "indexmap 2.13.0", "serde", "serde_spanned", "toml_datetime", @@ -3725,7 +3726,7 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "serde", ] @@ -3872,9 +3873,9 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ "wit-bindgen", ] @@ -3887,9 +3888,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ "cfg-if 1.0.4", "once_cell", @@ -3900,11 +3901,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" dependencies = [ "cfg-if 1.0.4", + "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -3913,9 +3915,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3923,9 +3925,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ "bumpalo", "proc-macro2", @@ -3936,9 +3938,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ "unicode-ident", ] @@ -3958,9 +3960,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" dependencies = [ "js-sys", "wasm-bindgen", @@ -4344,9 +4346,9 @@ dependencies = [ [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" [[package]] name = "writeable" @@ -4397,18 +4399,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fabae64378cb18147bb18bca364e63bdbe72a0ffe4adf0addfec8aa166b2c56" +checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9c2d862265a8bb4471d87e033e730f536e2a285cc7cb05dbce09a2a97075f90" +checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" dependencies = [ "proc-macro2", "quote", @@ -4491,6 +4493,6 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8" +checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea" diff --git a/Cargo.toml b/Cargo.toml index 73f2af78..cc982aa8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,67 +1,67 @@ -[package] -name = "wally" -description = "Package manager for Roblox" -version = "0.3.2" -license = "MPL-2.0" -authors = ["Lucien Greathouse "] -edition = "2018" - -[workspace] -members = [ - ".", - "wally-registry-backend", -] - -default-members = [ - ".", - "wally-registry-backend", -] - -[lib] -name = "libwally" -path = "src/lib.rs" - -[[bin]] -name = "wally" -path = "src/main.rs" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -anyhow = "1.0.33" -blake3 = "0.3.7" -crossterm = "0.22.1" -dirs = "3.0.1" -env_logger = "0.8.1" -fs-err = "2.5.0" -git2 = "0.16.1" -hex = "0.4.2" -indoc = "1.0.3" -log = "0.4.11" -once_cell = "1.5.2" -opener = "0.5.0" -reqwest = { version = "0.11.20", features = ["blocking", "json"] } -rpassword = "5.0.1" -semver = { version = "0.11.0", features = ["serde"] } -serde = { version = "1.0.116", features = ["derive"] } -serde_json = "1.0.58" -structopt = "0.3.18" -tempfile = "3.1.0" -toml = "0.5.6" -toml_edit = "0.2.0" -url = { version = "2.1.1", features = ["serde"] } -walkdir = "2.3.1" -whoami = "1.5.0" -zip = "0.5.11" -globset = "0.4.8" -ubyte = "0.10.3" -indicatif = "0.17.4" -tokio = "1.28.2" -serial_test = "2.0.0" -time = "=0.3.35" - -[dev-dependencies] -insta = { version = "1.1.0" } - -[features] -vendored-libgit2 = ["git2/vendored-libgit2"] +[package] +name = "wally" +description = "Package manager for Roblox" +version = "0.3.2" +license = "MPL-2.0" +authors = ["Lucien Greathouse "] +edition = "2018" + +[workspace] +members = [ + ".", + "wally-registry-backend", +] + +default-members = [ + ".", + "wally-registry-backend", +] + +[lib] +name = "libwally" +path = "src/lib.rs" + +[[bin]] +name = "wally" +path = "src/main.rs" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.33" +blake3 = "0.3.7" +crossterm = "0.22.1" +dirs = "3.0.1" +env_logger = "0.8.1" +fs-err = "2.5.0" +git2 = "0.16.1" +hex = "0.4.2" +indoc = "1.0.3" +log = "0.4.11" +once_cell = "1.5.2" +opener = "0.5.0" +reqwest = { version = "0.11.20", features = ["blocking", "json"] } +rpassword = "5.0.1" +semver = { version = "0.11.0", features = ["serde"] } +serde = { version = "1.0.116", features = ["derive"] } +serde_json = "1.0.58" +structopt = "0.3.18" +tempfile = "3.1.0" +toml = "0.5.6" +toml_edit = "0.2.0" +url = { version = "2.1.1", features = ["serde"] } +walkdir = "2.3.1" +whoami = "1.5.0" +zip = "0.5.11" +globset = "0.4.8" +ubyte = "0.10.3" +indicatif = "0.17.4" +tokio = { version = "1.28.2", features = ["rt-multi-thread"] } +serial_test = "2.0.0" +time = "=0.3.35" + +[dev-dependencies] +insta = { version = "1.1.0", features = ["yaml"] } + +[features] +vendored-libgit2 = ["git2/vendored-libgit2"] diff --git a/src/extract_types.rs b/src/extract_types.rs index c4967c1f..83004aeb 100644 --- a/src/extract_types.rs +++ b/src/extract_types.rs @@ -1,497 +1,744 @@ - -use std::collections::BTreeSet; -use std::fs; -use std::path::PathBuf; -use serde::Deserialize; -use std::mem::take; - -#[derive(Deserialize)] -struct ProjectFile { - tree: Option, -} - -#[derive(Deserialize)] -struct Tree { - #[serde(rename = "$path")] - path: String, -} - -fn get(code: &str, at: usize) -> char { - if at >= code.len() { - return '\0'; - } - code.as_bytes()[at] as char -} - -fn is_end_of_block(code: &str, at: usize, level: usize) -> bool { - if get(code, at) != ']' { - return false; - } - let mut index = at + 1; - for _ in 0..level { - if get(code, index) != '=' { - return false; - } - index += 1; - } - if get(code, index) != ']' { - return false; - } - true -} - -#[derive(Clone)] -enum LexState { - Code, - TemplateString, // `` - DoubleQuoteString, // "" - SingleQuoteString, // '' - BlockString(usize), // [=[ ]=] - LineComment, // -- - BlockComment(usize), // --[=[ ]=] -} - -fn strip_comments_and_strings(lua_code: &str) -> String { - // Buffer to write out to charater by character - let mut output = String::new(); - let mut index = 0; - let mut state = LexState::Code; - while index < lua_code.len() { - let c = get(lua_code, index); - let peek = get(lua_code, index + 1); - match (state.clone(), c, peek) { - // Checks to enter one of the states to ignore - (LexState::Code, '`', _) => { - state = LexState::TemplateString; - index += 1; - } - (LexState::Code, '"', _) => { - state = LexState::DoubleQuoteString; - index += 1; - } - (LexState::Code, '\'', _) => { - state = LexState::SingleQuoteString; - index += 1; - } - (LexState::Code, '[', '=' | '[') => { - index += 2; - let mut level = if peek == '=' { 1 } else { 0 }; - while get(lua_code, index) == '=' { - level += 1; - index += 1; - } - state = LexState::BlockString(level); - if level > 0 { - assert!(get(lua_code, index) == '['); - index += 1; - } - } - (LexState::Code, '-', '-') => { - index += 2; - if get(lua_code, index) == '[' { - index += 1; - let mut level = 0; - while get(lua_code, index) == '=' { - level += 1; - index += 1; - } - if get(lua_code, index) == '[' { - index += 1; - state = LexState::BlockComment(level); - } else { - state = LexState::LineComment; - } - } else { - state = LexState::LineComment; - } - } - - // Useful contents to not ignore - (LexState::Code, _, _) => { - output.push(c); - index += 1; - } - - // Template string - (LexState::TemplateString, '`', _) => { - state = LexState::Code; - index += 1; - } - (LexState::TemplateString, '\\', '`') => { - index += 2; - } - - // Double quote string - (LexState::DoubleQuoteString, '"', _) => { - state = LexState::Code; - index += 1; - } - (LexState::DoubleQuoteString, '\\', '"') => { - index += 2; - } - - // Single quote string - (LexState::SingleQuoteString, '\'', _) => { - state = LexState::Code; - index += 1; - } - (LexState::SingleQuoteString, '\\', '\'') => { - index += 2; - } - - // Block string - (LexState::BlockString(depth), ']', '=' | ']') => { - if is_end_of_block(lua_code, index, depth) { - state = LexState::Code; - index += depth + 2; - } else { - index += 1; - } - } - - // Block comment - (LexState::BlockComment(depth), ']', '=' | ']') => { - if is_end_of_block(lua_code, index, depth) { - state = LexState::Code; - index += depth + 2; - } else { - index += 1; - } - } - - // Line comment - (LexState::LineComment, '\n', _) => { - state = LexState::Code; - } - - // Other character to ignore - (_, _, _) => { - index += 1; - } - } - } - - output -} - -#[derive(Clone, PartialEq, Debug)] -enum ParseState { - Code, // expect "export" - Export, // expect "type" - Type, // expect type name - StartTypeParamList, // optionally expect '<' - TypeParam, // expect type param name - TypePack, // optionally expect "..." - TypeDefault, // optionally expect '=' and default value - TypeDefaultName, // expect default type name - NextTypeParam, // optionally expect ',' or '>' -} - -#[derive(Clone)] -pub struct TypeParam { - name: String, - is_pack: bool, - default: Option, -} - -impl TypeParam { - fn new() -> Self { - TypeParam { - name: String::new(), - is_pack: false, - default: None, - } - } -} - -impl Default for TypeParam { - fn default() -> Self { - Self::new() - } -} - -pub struct ExportStatement { - name: String, - is_exported: bool, - type_params: Vec, -} - -impl ExportStatement { - fn new() -> Self { - ExportStatement { - name: String::new(), - is_exported: false, - type_params: Vec::new(), - } - } - - pub fn to_forwarding_statement(&self, module_name: &str) -> String { - if self.type_params.len() == 0 { - format!("export type {} = {}.{}", self.name, module_name, self.name) - } else { - let params: Vec = self.type_params.iter().map(|param| { - let pack = if param.is_pack { "..." } else { "" }; - let default = param.default.as_ref().map(|d| format!(" = {}", d)).unwrap_or_default(); - format!("{}{}{}", param.name, pack, default) - }).collect(); - - let param_names: Vec = self.type_params.iter().map(|param| { - let pack = if param.is_pack { "..." } else { "" }; - format!("{}{}", param.name, pack) - }).collect(); - - format!( - "export type {}<{}> = {}.{}<{}>", - self.name, - params.join(", "), - module_name, - self.name, - param_names.join(", ") - ) - } - } -} - -impl Default for ExportStatement { - fn default() -> Self { - Self::new() - } -} - -pub struct ExtractTypesResult { - statements: Vec, -} - -impl ExtractTypesResult { - pub fn new() -> Self { - ExtractTypesResult { - statements: Vec::new(), - } - } - - pub fn format_forwarding_statements(&self, module_name: &str) -> String { - self.statements.iter().map(|stmt| { - stmt.to_forwarding_statement(module_name) - }).collect::>().join("\n") - } - - pub fn is_empty(&self) -> bool { - self.statements.is_empty() - } - - pub fn add_statement(&mut self, statement: ExportStatement) { - if statement.is_exported { - self.statements.push(statement); - } - } -} - -fn parse_types(lua_code: &str) -> ExtractTypesResult { - // First strip any comments / strings which could have extraneous "export type" text in them. - let lua_code = strip_comments_and_strings(lua_code); - - // Now use a permissive parse to find export type statements. - let mut index = 0; - let mut state = ParseState::Code; - let mut current_export_statement = ExportStatement::new(); - let mut current_type_param = TypeParam::new(); - let mut result = ExtractTypesResult::new(); - let mut non_exported_types: BTreeSet = BTreeSet::new(); - while index < lua_code.len() { - let mut c = get(&lua_code, index); - // Skip whitespace - while c.is_ascii_whitespace() { - index += 1; - c = get(&lua_code, index); - } - if index >= lua_code.len() { - break; - } - match (state.clone(), c) { - (ParseState::Code, 'e') => { - if lua_code[index..].starts_with("export") { - state = ParseState::Export; - current_export_statement.is_exported = true; - index += "export".len(); - } else { - index += 1; - } - } - (ParseState::Code, 't') => { - if lua_code[index..].starts_with("type") { - state = ParseState::Type; - current_export_statement.is_exported = false; - index += "type".len(); - } else { - index += 1; - } - } - (ParseState::Export, 't') => { - if lua_code[index..].starts_with("type") { - state = ParseState::Type; - index += "type".len(); - } else { - state = ParseState::Code; - } - } - (ParseState::Type, _) => { - let start = index; - while get(&lua_code, index).is_ascii_alphanumeric() || get(&lua_code, index) == '_' { - index += 1; - } - let type_name = &lua_code[start..index]; - current_export_statement.name = type_name.to_string(); - if !current_export_statement.is_exported { - non_exported_types.insert(type_name.to_string()); - } - state = ParseState::StartTypeParamList; - } - (ParseState::StartTypeParamList, '<') => { - state = ParseState::TypeParam; - index += 1; - } - (ParseState::StartTypeParamList, _) => { - result.add_statement(take(&mut current_export_statement)); - state = ParseState::Code; - } - (ParseState::TypeParam, _) => { - let start = index; - while get(&lua_code, index).is_ascii_alphanumeric() || get(&lua_code, index) == '_' { - index += 1; - } - let param_name = &lua_code[start..index]; - assert!(param_name.len() > 0); - current_type_param.name = param_name.to_string(); - state = ParseState::TypePack; - } - (ParseState::TypePack, '.') => { - if lua_code[index..].starts_with("...") { - current_type_param.is_pack = true; - index += 3; - } - state = ParseState::TypeDefault; - } - (ParseState::TypePack, _) => { - state = ParseState::TypeDefault; - } - (ParseState::TypeDefault, '=') => { - index += 1; - state = ParseState::TypeDefaultName; - } - (ParseState::TypeDefault, _) => { - current_export_statement.type_params.push(take(&mut current_type_param)); - state = ParseState::NextTypeParam; - } - (ParseState::TypeDefaultName, _) => { - let start = index; - while get(&lua_code, index).is_ascii_alphanumeric() || get(&lua_code, index) == '_' { - index += 1; - } - let default_name = &lua_code[start..index]; - assert!(default_name.len() > 0); - current_type_param.default = Some(default_name.to_string()); - current_export_statement.type_params.push(take(&mut current_type_param)); - state = ParseState::NextTypeParam; - } - (ParseState::NextTypeParam, ',') => { - index += 1; - state = ParseState::TypeParam; - } - (ParseState::NextTypeParam, '>') => { - result.add_statement(take(&mut current_export_statement)); - index += 1; - state = ParseState::Code; - } - _ => { - index += 1; - } - } - } - - // Post-process to remove type defaults which weren't exported. - // There's no way to reference these types from outside the module so there's - // no way to re-export them. The library author has to fix this if desired. - for statement in result.statements.iter_mut() { - for param in statement.type_params.iter_mut() { - if let Some(default) = ¶m.default { - if non_exported_types.contains(default) { - param.default = None; - } - } - } - } - - result -} - -pub fn extract_types(package_path: &PathBuf) -> ExtractTypesResult { - log::debug!("Processing types for package at {}", package_path.display()); - - let project_file_path = package_path.join("default.project.json"); - - if !project_file_path.exists() { - log::debug!("No default.project.json found for package at {}", package_path.display()); - return ExtractTypesResult::new(); - } - - let project_contents = match fs::read_to_string(&project_file_path) { - Ok(c) => c, - Err(err) => { - log::warn!( - "Failed to read {}: {}", - project_file_path.display(), - err - ); - return ExtractTypesResult::new(); - } - }; - - let project: ProjectFile = match serde_json::from_str(&project_contents) { - Ok(p) => p, - Err(err) => { - log::warn!( - "Invalid JSON in {}: {}", - project_file_path.display(), - err - ); - return ExtractTypesResult::new(); - } - }; - - let tree_path = match project.tree { - Some(tree) => package_path.join(tree.path), - None => { - log::debug!("default.project.json has no tree path"); - return ExtractTypesResult::new(); - } - }; - - let init_lua = tree_path.join("init.lua"); - let init_luau = tree_path.join("init.luau"); - - let init_path = if init_lua.exists() { - init_lua - } else if init_luau.exists() { - init_luau - } else { - log::debug!( - "No init.lua or init.luau found under {}", - tree_path.display() - ); - return ExtractTypesResult::new(); - }; - - let init_contents = match fs::read_to_string(&init_path) { - Ok(c) => c, - Err(err) => { - log::warn!( - "Failed to read {}: {}", - init_path.display(), - err - ); - return ExtractTypesResult::new(); - } - }; - - parse_types(&init_contents) +use std::collections::BTreeSet; +use std::fs; +use std::path::PathBuf; +use serde::Deserialize; +use std::mem::take; + +#[derive(Deserialize)] +struct ProjectFile { + tree: Option, +} + +#[derive(Deserialize)] +struct Tree { + #[serde(rename = "$path")] + path: String, +} + +fn get(code: &str, at: usize) -> char { + if at >= code.len() { + return '\0'; + } + code.as_bytes()[at] as char +} + +fn is_end_of_block(code: &str, at: usize, level: usize) -> bool { + if get(code, at) != ']' { + return false; + } + let mut index = at + 1; + for _ in 0..level { + if get(code, index) != '=' { + return false; + } + index += 1; + } + if get(code, index) != ']' { + return false; + } + true +} + +#[derive(Clone)] +enum LexState { + Code, + TemplateString, // `` + DoubleQuoteString, // "" + SingleQuoteString, // '' + BlockString(usize), // [=[ ]=] + LineComment, // -- + BlockComment(usize), // --[=[ ]=] +} + +fn strip_comments_and_strings(lua_code: &str) -> String { + // Buffer to write out to charater by character + let mut output = String::new(); + let mut index = 0; + let mut state = LexState::Code; + while index < lua_code.len() { + let c = get(lua_code, index); + let peek = get(lua_code, index + 1); + match (state.clone(), c, peek) { + // Checks to enter one of the states to ignore + (LexState::Code, '`', _) => { + state = LexState::TemplateString; + index += 1; + } + (LexState::Code, '"', _) => { + state = LexState::DoubleQuoteString; + index += 1; + } + (LexState::Code, '\'', _) => { + state = LexState::SingleQuoteString; + index += 1; + } + (LexState::Code, '[', '=' | '[') => { + index += 2; + let mut level = if peek == '=' { 1 } else { 0 }; + while get(lua_code, index) == '=' { + level += 1; + index += 1; + } + state = LexState::BlockString(level); + if level > 0 { + assert!(get(lua_code, index) == '['); + index += 1; + } + } + (LexState::Code, '-', '-') => { + index += 2; + if get(lua_code, index) == '[' { + index += 1; + let mut level = 0; + while get(lua_code, index) == '=' { + level += 1; + index += 1; + } + if get(lua_code, index) == '[' { + index += 1; + state = LexState::BlockComment(level); + } else { + state = LexState::LineComment; + } + } else { + state = LexState::LineComment; + } + } + + // Useful contents to not ignore + (LexState::Code, _, _) => { + output.push(c); + index += 1; + } + + // Template string + (LexState::TemplateString, '`', _) => { + state = LexState::Code; + index += 1; + } + (LexState::TemplateString, '\\', '`') => { + index += 2; + } + + // Double quote string + (LexState::DoubleQuoteString, '"', _) => { + state = LexState::Code; + index += 1; + } + (LexState::DoubleQuoteString, '\\', '"') => { + index += 2; + } + + // Single quote string + (LexState::SingleQuoteString, '\'', _) => { + state = LexState::Code; + index += 1; + } + (LexState::SingleQuoteString, '\\', '\'') => { + index += 2; + } + + // Block string + (LexState::BlockString(depth), ']', '=' | ']') => { + if is_end_of_block(lua_code, index, depth) { + state = LexState::Code; + index += depth + 2; + } else { + index += 1; + } + } + + // Block comment + (LexState::BlockComment(depth), ']', '=' | ']') => { + if is_end_of_block(lua_code, index, depth) { + state = LexState::Code; + index += depth + 2; + } else { + index += 1; + } + } + + // Line comment + (LexState::LineComment, '\n', _) => { + state = LexState::Code; + } + + // Other character to ignore + (_, _, _) => { + index += 1; + } + } + } + + output +} + +#[derive(Clone, PartialEq, Debug)] +enum ParseState { + Code, // expect "export" + Export, // expect "type" + Type, // expect type name + StartTypeParamList, // optionally expect '<' + TypeParam, // expect type param name + TypePack, // optionally expect "..." + TypeDefault, // optionally expect '=' and default value + TypeDefaultName, // expect default type name + NextTypeParam, // optionally expect ',' or '>' +} + +#[derive(Clone)] +pub struct TypeParam { + name: String, + is_pack: bool, + default: Option, +} + +impl TypeParam { + fn new() -> Self { + TypeParam { + name: String::new(), + is_pack: false, + default: None, + } + } +} + +impl Default for TypeParam { + fn default() -> Self { + Self::new() + } +} + +pub struct ExportStatement { + name: String, + is_exported: bool, + type_params: Vec, +} + +impl ExportStatement { + fn new() -> Self { + ExportStatement { + name: String::new(), + is_exported: false, + type_params: Vec::new(), + } + } + + pub fn to_forwarding_statement(&self, module_name: &str) -> String { + if self.type_params.len() == 0 { + format!("export type {} = {}.{}", self.name, module_name, self.name) + } else { + let params: Vec = self.type_params.iter().map(|param| { + let pack = if param.is_pack { "..." } else { "" }; + let default = param.default.as_ref().map(|d| format!(" = {}", d)).unwrap_or_default(); + format!("{}{}{}", param.name, pack, default) + }).collect(); + + let param_names: Vec = self.type_params.iter().map(|param| { + let pack = if param.is_pack { "..." } else { "" }; + format!("{}{}", param.name, pack) + }).collect(); + + format!( + "export type {}<{}> = {}.{}<{}>", + self.name, + params.join(", "), + module_name, + self.name, + param_names.join(", ") + ) + } + } +} + +impl Default for ExportStatement { + fn default() -> Self { + Self::new() + } +} + +pub struct ExtractTypesResult { + statements: Vec, +} + +impl ExtractTypesResult { + pub fn new() -> Self { + ExtractTypesResult { + statements: Vec::new(), + } + } + + pub fn format_forwarding_statements(&self, module_name: &str) -> String { + self.statements.iter().map(|stmt| { + stmt.to_forwarding_statement(module_name) + }).collect::>().join("\n") + } + + pub fn is_empty(&self) -> bool { + self.statements.is_empty() + } + + pub fn add_statement(&mut self, statement: ExportStatement) { + if statement.is_exported { + self.statements.push(statement); + } + } +} + +fn parse_types(lua_code: &str) -> ExtractTypesResult { + // First strip any comments / strings which could have extraneous "export type" text in them. + let lua_code = strip_comments_and_strings(lua_code); + + // Now use a permissive parse to find export type statements. + let mut index = 0; + let mut state = ParseState::Code; + let mut current_export_statement = ExportStatement::new(); + let mut current_type_param = TypeParam::new(); + let mut result = ExtractTypesResult::new(); + let mut non_exported_types: BTreeSet = BTreeSet::new(); + while index < lua_code.len() { + let mut c = get(&lua_code, index); + // Skip whitespace + while c.is_ascii_whitespace() { + index += 1; + c = get(&lua_code, index); + } + if index >= lua_code.len() { + break; + } + match (state.clone(), c) { + (ParseState::Code, 'e') => { + if lua_code[index..].starts_with("export") { + state = ParseState::Export; + current_export_statement.is_exported = true; + index += "export".len(); + } else { + index += 1; + } + } + (ParseState::Code, 't') => { + if lua_code[index..].starts_with("type") { + state = ParseState::Type; + current_export_statement.is_exported = false; + index += "type".len(); + } else { + index += 1; + } + } + (ParseState::Export, 't') => { + if lua_code[index..].starts_with("type") { + state = ParseState::Type; + index += "type".len(); + } else { + state = ParseState::Code; + } + } + (ParseState::Type, _) => { + let start = index; + while get(&lua_code, index).is_ascii_alphanumeric() || get(&lua_code, index) == '_' { + index += 1; + } + let type_name = &lua_code[start..index]; + current_export_statement.name = type_name.to_string(); + if !current_export_statement.is_exported { + non_exported_types.insert(type_name.to_string()); + } + state = ParseState::StartTypeParamList; + } + (ParseState::StartTypeParamList, '<') => { + state = ParseState::TypeParam; + index += 1; + } + (ParseState::StartTypeParamList, _) => { + result.add_statement(take(&mut current_export_statement)); + state = ParseState::Code; + } + (ParseState::TypeParam, _) => { + let start = index; + while get(&lua_code, index).is_ascii_alphanumeric() || get(&lua_code, index) == '_' { + index += 1; + } + let param_name = &lua_code[start..index]; + assert!(param_name.len() > 0); + current_type_param.name = param_name.to_string(); + state = ParseState::TypePack; + } + (ParseState::TypePack, '.') => { + if lua_code[index..].starts_with("...") { + current_type_param.is_pack = true; + index += 3; + } + state = ParseState::TypeDefault; + } + (ParseState::TypePack, _) => { + state = ParseState::TypeDefault; + } + (ParseState::TypeDefault, '=') => { + index += 1; + state = ParseState::TypeDefaultName; + } + (ParseState::TypeDefault, _) => { + current_export_statement.type_params.push(take(&mut current_type_param)); + state = ParseState::NextTypeParam; + } + (ParseState::TypeDefaultName, _) => { + let start = index; + while get(&lua_code, index).is_ascii_alphanumeric() || get(&lua_code, index) == '_' { + index += 1; + } + let default_name = &lua_code[start..index]; + assert!(default_name.len() > 0); + current_type_param.default = Some(default_name.to_string()); + current_export_statement.type_params.push(take(&mut current_type_param)); + state = ParseState::NextTypeParam; + } + (ParseState::NextTypeParam, ',') => { + index += 1; + state = ParseState::TypeParam; + } + (ParseState::NextTypeParam, '>') => { + result.add_statement(take(&mut current_export_statement)); + index += 1; + state = ParseState::Code; + } + _ => { + index += 1; + } + } + } + + // Post-process to remove type defaults which weren't exported. + // There's no way to reference these types from outside the module so there's + // no way to re-export them. The library author has to fix this if desired. + for statement in result.statements.iter_mut() { + for param in statement.type_params.iter_mut() { + if let Some(default) = ¶m.default { + if non_exported_types.contains(default) { + param.default = None; + } + } + } + } + + result +} + +pub fn extract_types(package_path: &PathBuf) -> ExtractTypesResult { + log::debug!("Processing types for package at {}", package_path.display()); + + let project_file_path = package_path.join("default.project.json"); + + if !project_file_path.exists() { + log::debug!("No default.project.json found for package at {}", package_path.display()); + return ExtractTypesResult::new(); + } + + let project_contents = match fs::read_to_string(&project_file_path) { + Ok(c) => c, + Err(err) => { + log::warn!( + "Failed to read {}: {}", + project_file_path.display(), + err + ); + return ExtractTypesResult::new(); + } + }; + + let project: ProjectFile = match serde_json::from_str(&project_contents) { + Ok(p) => p, + Err(err) => { + log::warn!( + "Invalid JSON in {}: {}", + project_file_path.display(), + err + ); + return ExtractTypesResult::new(); + } + }; + + let tree_path = match project.tree { + Some(tree) => package_path.join(tree.path), + None => { + log::debug!("default.project.json has no tree path"); + return ExtractTypesResult::new(); + } + }; + + let init_lua = tree_path.join("init.lua"); + let init_luau = tree_path.join("init.luau"); + + let init_path = if init_lua.exists() { + init_lua + } else if init_luau.exists() { + init_luau + } else { + log::debug!( + "No init.lua or init.luau found under {}", + tree_path.display() + ); + return ExtractTypesResult::new(); + }; + + let init_contents = match fs::read_to_string(&init_path) { + Ok(c) => c, + Err(err) => { + log::warn!( + "Failed to read {}: {}", + init_path.display(), + err + ); + return ExtractTypesResult::new(); + } + }; + + parse_types(&init_contents) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_strip_line_comment() { + let input = "code -- comment\nmore code"; + let expected = "code \nmore code"; + assert_eq!(strip_comments_and_strings(input), expected); + } + + #[test] + fn test_strip_block_comment() { + let input = "code --[[ block comment ]] more"; + let expected = "code more"; + assert_eq!(strip_comments_and_strings(input), expected); + } + + #[test] + fn test_strip_block_comment_with_equals() { + let input = "code --[=[ block comment ]=] more"; + let expected = "code more"; + assert_eq!(strip_comments_and_strings(input), expected); + } + + #[test] + fn test_strip_double_quote_string() { + let input = r#"code "export type Foo" more"#; + let expected = "code more"; + assert_eq!(strip_comments_and_strings(input), expected); + } + + #[test] + fn test_strip_single_quote_string() { + let input = r#"code 'export type Foo' more"#; + let expected = "code more"; + assert_eq!(strip_comments_and_strings(input), expected); + } + + #[test] + fn test_strip_template_string() { + let input = "code `export type Foo` more"; + let expected = "code more"; + assert_eq!(strip_comments_and_strings(input), expected); + } + + #[test] + fn test_strip_block_string() { + let input = "code [[ block string ]] more"; + let expected = "code more"; + assert_eq!(strip_comments_and_strings(input), expected); + } + + #[test] + fn test_strip_block_string_with_equals() { + let input = "code [=[ block string ]=] more"; + let expected = "code more"; + assert_eq!(strip_comments_and_strings(input), expected); + } + + #[test] + fn test_strip_escaped_quotes() { + let input = r#"code "escaped \" quote" more"#; + let expected = "code more"; + assert_eq!(strip_comments_and_strings(input), expected); + } + + #[test] + fn test_parse_simple_export_type() { + let input = "export type Foo = string"; + let result = parse_types(input); + assert_eq!(result.statements.len(), 1); + assert_eq!(result.statements[0].name, "Foo"); + assert!(result.statements[0].is_exported); + assert_eq!(result.statements[0].type_params.len(), 0); + } + + #[test] + fn test_parse_export_type_with_params() { + let input = "export type Foo = Bar"; + let result = parse_types(input); + assert_eq!(result.statements.len(), 1); + assert_eq!(result.statements[0].name, "Foo"); + assert_eq!(result.statements[0].type_params.len(), 2); + assert_eq!(result.statements[0].type_params[0].name, "T"); + assert_eq!(result.statements[0].type_params[1].name, "U"); + assert!(!result.statements[0].type_params[0].is_pack); + assert!(!result.statements[0].type_params[1].is_pack); + } + + #[test] + fn test_parse_export_type_with_parameter_pack() { + let input = "export type Foo = Bar"; + let result = parse_types(input); + assert_eq!(result.statements.len(), 1); + assert_eq!(result.statements[0].type_params.len(), 1); + assert_eq!(result.statements[0].type_params[0].name, "T"); + assert!(result.statements[0].type_params[0].is_pack); + } + + #[test] + fn test_parse_export_type_with_default() { + let input = "export type Foo = Bar"; + let result = parse_types(input); + assert_eq!(result.statements.len(), 1); + assert_eq!(result.statements[0].type_params.len(), 1); + assert_eq!(result.statements[0].type_params[0].name, "T"); + assert_eq!(result.statements[0].type_params[0].default, Some("string".to_string())); + } + + #[test] + fn test_parse_non_exported_type() { + let input = "type Foo = string"; + let result = parse_types(input); + assert_eq!(result.statements.len(), 0); + } + + #[test] + fn test_parse_multiple_types() { + let input = "export type Foo = string\nexport type Bar = number"; + let result = parse_types(input); + assert_eq!(result.statements.len(), 2); + assert_eq!(result.statements[0].name, "Foo"); + assert_eq!(result.statements[1].name, "Bar"); + } + + #[test] + fn test_parse_with_comments() { + let input = "-- comment\nexport type Foo = string -- inline comment"; + let result = parse_types(input); + assert_eq!(result.statements.len(), 1); + assert_eq!(result.statements[0].name, "Foo"); + } + + #[test] + fn test_parse_ignores_type_in_string() { + let input = r#"local x = "export type Fake = string" +export type Real = number"#; + let result = parse_types(input); + assert_eq!(result.statements.len(), 1); + assert_eq!(result.statements[0].name, "Real"); + } + + #[test] + fn test_forwarding_statement_simple() { + let mut stmt = ExportStatement::new(); + stmt.name = "Foo".to_string(); + stmt.is_exported = true; + let forwarding = stmt.to_forwarding_statement("Module"); + assert_eq!(forwarding, "export type Foo = Module.Foo"); + } + + #[test] + fn test_forwarding_statement_with_params() { + let mut stmt = ExportStatement::new(); + stmt.name = "Foo".to_string(); + stmt.is_exported = true; + stmt.type_params.push(TypeParam { + name: "T".to_string(), + is_pack: false, + default: None, + }); + stmt.type_params.push(TypeParam { + name: "U".to_string(), + is_pack: false, + default: Some("string".to_string()), + }); + let forwarding = stmt.to_forwarding_statement("Module"); + assert_eq!(forwarding, "export type Foo = Module.Foo"); + } + + #[test] + fn test_forwarding_statement_with_parameter_pack() { + let mut stmt = ExportStatement::new(); + stmt.name = "Foo".to_string(); + stmt.is_exported = true; + stmt.type_params.push(TypeParam { + name: "T".to_string(), + is_pack: true, + default: None, + }); + let forwarding = stmt.to_forwarding_statement("Module"); + assert_eq!(forwarding, "export type Foo = Module.Foo"); + } + + #[test] + fn test_format_forwarding_statements() { + let mut result = ExtractTypesResult::new(); + let mut stmt1 = ExportStatement::new(); + stmt1.name = "Foo".to_string(); + stmt1.is_exported = true; + let mut stmt2 = ExportStatement::new(); + stmt2.name = "Bar".to_string(); + stmt2.is_exported = true; + result.add_statement(stmt1); + result.add_statement(stmt2); + + let output = result.format_forwarding_statements("Module"); + assert_eq!(output, "export type Foo = Module.Foo\nexport type Bar = Module.Bar"); + } + + #[test] + fn test_remove_non_exported_defaults() { + let input = r#" +type LocalType = string +export type Foo = Bar +"#; + let result = parse_types(input); + assert_eq!(result.statements.len(), 1); + assert_eq!(result.statements[0].type_params[0].default, None); + } + + #[test] + fn test_keep_exported_defaults() { + let input = r#" +export type ExportedType = string +export type Foo = Bar +"#; + let result = parse_types(input); + assert_eq!(result.statements.len(), 2); + assert_eq!(result.statements[1].type_params[0].default, Some("ExportedType".to_string())); + } + + #[test] + fn test_complex_type_params() { + let input = "export type Foo = Bar"; + let result = parse_types(input); + assert_eq!(result.statements.len(), 1); + assert_eq!(result.statements[0].type_params.len(), 4); + + assert_eq!(result.statements[0].type_params[0].name, "T"); + assert!(!result.statements[0].type_params[0].is_pack); + assert_eq!(result.statements[0].type_params[0].default, None); + + assert_eq!(result.statements[0].type_params[1].name, "U"); + assert!(result.statements[0].type_params[1].is_pack); + assert_eq!(result.statements[0].type_params[1].default, None); + + assert_eq!(result.statements[0].type_params[2].name, "V"); + assert!(!result.statements[0].type_params[2].is_pack); + assert_eq!(result.statements[0].type_params[2].default, Some("string".to_string())); + + assert_eq!(result.statements[0].type_params[3].name, "W"); + assert!(result.statements[0].type_params[3].is_pack); + assert_eq!(result.statements[0].type_params[3].default, Some("number".to_string())); + } } \ No newline at end of file diff --git a/src/resolution.rs b/src/resolution.rs index 988b00a8..0d056755 100644 --- a/src/resolution.rs +++ b/src/resolution.rs @@ -1,501 +1,501 @@ -use std::cmp::Ordering; -use std::collections::{BTreeMap, BTreeSet, VecDeque}; - -use anyhow::bail; -use anyhow::format_err; -use semver::Version; -use serde::Serialize; - -use crate::manifest::{Manifest, Realm}; -use crate::package_id::PackageId; -use crate::package_req::PackageReq; -use crate::package_source::{PackageSourceId, PackageSourceMap, PackageSourceProvider}; - -/// A completely resolved graph of packages returned by `resolve`. -/// -/// State here is stored in multiple maps, all keyed by PackageId, to facilitate -/// concurrent mutable access to unrelated information about different packages. -#[derive(Debug, Default, Serialize, Clone)] -pub struct Resolve { - /// Set of all packages that have been chosen to be part of the package - /// graph. - pub activated: BTreeSet, - - /// Metadata stored about each package that does not need to be accessed - /// concurrently to other information. - pub metadata: BTreeMap, - - /// Graph of all dependencies originating from the "shared" dependency realm. - pub shared_dependencies: BTreeMap>, - - /// Graph of all dependencies originating from the "server" dependency realm. - pub server_dependencies: BTreeMap>, - - /// Graph of all dependencies originating from the "dev" dependency realm. - pub dev_dependencies: BTreeMap>, -} - -impl Resolve { - fn activate(&mut self, source: PackageId, dep_name: String, dep_realm: Realm, dep: PackageId) { - self.activated.insert(dep.clone()); - - let dependencies = match dep_realm { - Realm::Shared => self.shared_dependencies.entry(source).or_default(), - Realm::Server => self.server_dependencies.entry(source).or_default(), - Realm::Dev => self.dev_dependencies.entry(source).or_default(), - }; - dependencies.insert(dep_name, dep); - } -} - -/// A single node in the package resolution graph. -/// Origin realm is the "most restrictive" realm the package can still be dependended -/// upon. It is where the package gets placed during install. -/// See [ origin_realm clarification ]. In the resolve function for more info. -#[derive(Debug, Serialize, Clone)] -pub struct ResolvePackageMetadata { - pub realm: Realm, - pub origin_realm: Realm, - pub source_registry: PackageSourceId, -} - -pub fn resolve( - root_manifest: &Manifest, - try_to_use: &BTreeSet, - package_sources: &PackageSourceMap, -) -> anyhow::Result { - let mut resolve = Resolve::default(); - - // Insert root project into graph and activated dependencies, as it'll - // always be present. - resolve.activated.insert(root_manifest.package_id()); - resolve.metadata.insert( - root_manifest.package_id(), - ResolvePackageMetadata { - realm: root_manifest.package.realm, - origin_realm: root_manifest.package.realm, - source_registry: PackageSourceId::DefaultRegistry, - }, - ); - - // Queue of all dependency requests that need to be resolved. - let mut packages_to_visit = VecDeque::new(); - - for (alias, req) in &root_manifest.dependencies { - packages_to_visit.push_back(DependencyRequest { - request_source: root_manifest.package_id(), - request_realm: Realm::Shared, - origin_realm: Realm::Shared, - package_alias: alias.clone(), - package_req: req.clone(), - }); - } - - for (alias, req) in &root_manifest.server_dependencies { - packages_to_visit.push_back(DependencyRequest { - request_source: root_manifest.package_id(), - request_realm: Realm::Server, - origin_realm: Realm::Server, - package_alias: alias.clone(), - package_req: req.clone(), - }); - } - - for (alias, req) in &root_manifest.dev_dependencies { - packages_to_visit.push_back(DependencyRequest { - request_source: root_manifest.package_id(), - request_realm: Realm::Dev, - origin_realm: Realm::Dev, - package_alias: alias.clone(), - package_req: req.clone(), - }); - } - - // Workhorse loop: resolve all dependencies, depth-first. - 'outer: while let Some(dependency_request) = packages_to_visit.pop_front() { - // Locate all already-activated packages that might match this - // dependency request. - let mut matching_activated: Vec<_> = resolve - .activated - .iter() - .filter(|package_id| package_id.name() == dependency_request.package_req.name()) - .cloned() - .collect(); - - // Sort our list of candidates by descending version so that we can pick - // newest candidates first. - matching_activated.sort_by(|a, b| b.version().cmp(a.version())); - - // Check for the highest version already-activated package that matches - // our constraints. - for package_id in &matching_activated { - if dependency_request.package_req.matches_id(package_id) { - let metadata = resolve - .metadata - .get_mut(package_id) - .expect("activated package was missing metadata"); - - // [ origin_realm clarification ] - // We want to set the origin to the most restrictive origin possible. - // For example we want to keep packages in the dev realm unless a dependency - // with a shared/server origin requires it. This way server/shared dependencies - // which only originate from dev dependencies get put into the dev folder even - // if they usually belong to another realm. Likewise we want to keep shared - // dependencies in the server realm unless they are explicitly required as a - // shared dependency. - let realm_match = match (metadata.origin_realm, dependency_request.origin_realm) { - (_, Realm::Shared) => Realm::Shared, - (Realm::Shared, _) => Realm::Shared, - (_, Realm::Server) => Realm::Server, - (Realm::Server, _) => Realm::Server, - (Realm::Dev, Realm::Dev) => Realm::Dev, - }; - - metadata.origin_realm = realm_match; - - resolve.activate( - dependency_request.request_source.clone(), - dependency_request.package_alias.clone(), - realm_match, - package_id.clone(), - ); - - continue 'outer; - } - } - - // Look through all our packages sources in order of priority - let (source_registry, mut candidates) = package_sources - .source_order() - .iter() - .find_map(|source| { - let registry = package_sources.get(source).unwrap(); - - // Pull all of the possible candidate versions of the package we're - // looking for from the highest priority source which has them. - match registry.query(&dependency_request.package_req) { - Ok(manifests) => Some((source, manifests)), - Err(_) => None, - } - }) - .ok_or_else(|| { - format_err!( - "Failed to find a source for {}", - dependency_request.package_req - ) - })?; - - // Sort our candidate packages by descending version, so that we try the - // highest versions first. - // - // Additionally, if there were any packages that were previously used by - // our lockfile (in `try_to_use`), prioritize those first. This - // technique is the one used by Cargo. - candidates.sort_by(|a, b| { - let contains_a = try_to_use.contains(&a.package_id()); - let contains_b = try_to_use.contains(&b.package_id()); - - match (contains_a, contains_b) { - (true, false) => Ordering::Less, - (false, true) => Ordering::Greater, - _ => b.package.version.cmp(&a.package.version), - } - }); - - let filtered_candidates = candidates.iter().filter(|candidate| { - Realm::is_dependency_valid(dependency_request.request_realm, candidate.package.realm) - }); - - let mut conflicting = Vec::new(); - - for candidate in filtered_candidates { - // Conflicts occur if two packages are SemVer compatible. We choose - // to only allow one compatible copy of a given package to prevent - // common user errors. - - let has_conflicting = matching_activated - .iter() - .any(|activated| compatible(&candidate.package.version, activated.version())); - - if has_conflicting { - // This is a matching candidate, but it conflicts with a - // candidate we already selected before. We'll note that this - // happened. If there are no other matching versions that don't - // conflict, we'll report this in an error. - - conflicting.push(candidate.package_id()); - continue; - } - - let candidate_id = PackageId::new( - candidate.package.name.clone(), - candidate.package.version.clone(), - ); - - resolve.activate( - dependency_request.request_source.clone(), - dependency_request.package_alias.to_owned(), - dependency_request.origin_realm, - candidate_id.clone(), - ); - - resolve.metadata.insert( - candidate_id.clone(), - ResolvePackageMetadata { - realm: candidate.package.realm, - origin_realm: dependency_request.origin_realm, - source_registry: source_registry.clone(), - }, - ); - - for (alias, req) in &candidate.dependencies { - packages_to_visit.push_back(DependencyRequest { - request_source: candidate_id.clone(), - request_realm: Realm::Shared, - origin_realm: dependency_request.origin_realm, - package_alias: alias.clone(), - package_req: req.clone(), - }) - } - - for (alias, req) in &candidate.server_dependencies { - packages_to_visit.push_back(DependencyRequest { - request_source: candidate_id.clone(), - request_realm: Realm::Server, - origin_realm: dependency_request.origin_realm, - package_alias: alias.clone(), - package_req: req.clone(), - }) - } - - continue 'outer; - } - - if conflicting.is_empty() { - bail!( - "No packages were found that matched ({req_realm:?}) {req}.\nAre you sure this is \ - a {req_realm:?} dependency?", - req_realm = dependency_request.request_realm, - req = dependency_request.package_req, - ); - } else { - let conflicting_debug: Vec<_> = conflicting - .into_iter() - .map(|id| format!("{:?}", id)) - .collect(); - - bail!( - "All possible candidates for package {req} ({req_realm:?}) conflicted with other \ - packages that were already installed. These packages were previously selected: \ - {conflicting}", - req = dependency_request.package_req, - req_realm = dependency_request.request_realm, - conflicting = conflicting_debug.join(", "), - ); - } - } - - Ok(resolve) -} - -fn compatible(a: &Version, b: &Version) -> bool { - if a == b { - return true; - } - - if a.major == 0 && b.major == 0 { - a.minor == b.minor - } else { - a.major == b.major - } -} - -pub struct DependencyRequest { - request_source: PackageId, - request_realm: Realm, - origin_realm: Realm, - package_alias: String, - package_req: PackageReq, -} - -#[cfg(test)] -mod tests { - use super::*; - - use crate::{ - package_name::PackageName, package_source::InMemoryRegistry, test_package::PackageBuilder, - }; - - fn test_project(registry: InMemoryRegistry, package: PackageBuilder) -> anyhow::Result<()> { - let package_sources = PackageSourceMap::new(Box::new(registry.source())); - let manifest = package.into_manifest(); - let resolve = resolve(&manifest, &Default::default(), &package_sources)?; - insta::assert_yaml_snapshot!(resolve); - Ok(()) - } - - #[test] - fn minimal() -> anyhow::Result<()> { - let registry = InMemoryRegistry::new(); - - let root = PackageBuilder::new("biff/minimal@0.1.0"); - test_project(registry, root) - } - - #[test] - fn one_dependency() -> anyhow::Result<()> { - let registry = InMemoryRegistry::new(); - registry.publish(PackageBuilder::new("biff/minimal@0.1.0")); - registry.publish(PackageBuilder::new("biff/minimal@0.2.0")); - - let root = PackageBuilder::new("biff/one-dependency@0.1.0") - .with_dep("Minimal", "biff/minimal@0.1.0"); - test_project(registry, root) - } - - #[test] - fn transitive_dependency() -> anyhow::Result<()> { - let registry = InMemoryRegistry::new(); - registry.publish(PackageBuilder::new("biff/minimal@0.1.0")); - registry.publish( - PackageBuilder::new("biff/one-dependency@0.1.0") - .with_dep("Minimal", "biff/minimal@0.1.0"), - ); - - let root = PackageBuilder::new("biff/transitive-dependency@0.1.0") - .with_dep("OneDependency", "biff/one-dependency@0.1.0"); - test_project(registry, root) - } - - /// When there are shared dependencies, Wally should select the same - /// dependency. Here, A depends on B and C, which both in turn depend on D. - #[test] - fn unified_dependencies() -> anyhow::Result<()> { - let registry = InMemoryRegistry::new(); - registry.publish(PackageBuilder::new("biff/b@1.0.0").with_dep("D", "biff/d@1.0.0")); - registry.publish(PackageBuilder::new("biff/c@1.0.0").with_dep("D", "biff/d@1.0.0")); - registry.publish(PackageBuilder::new("biff/d@1.0.0")); - - let root = PackageBuilder::new("biff/a@1.0.0") - .with_dep("B", "biff/b@1.0.0") - .with_dep("C", "biff/c@1.0.0"); - - test_project(registry, root) - } - - /// Server dependencies are allowed to depend on shared dependencies. If a - /// shared dependency is only depended on by server dependencies, it should - /// be marked as server-only. - #[test] - fn server_to_shared() -> anyhow::Result<()> { - let registry = InMemoryRegistry::new(); - registry.publish(PackageBuilder::new("biff/shared@1.0.0")); - registry.publish( - PackageBuilder::new("biff/server@1.0.0") - .with_realm(Realm::Server) - .with_dep("Shared", "biff/shared@1.0.0"), - ); - - let root = - PackageBuilder::new("biff/root@1.0.0").with_server_dep("Server", "biff/server@1.0.0"); - - test_project(registry, root) - } - - /// but... if that shared dependency is required by another shared dependency, - /// (while not being also server-only) it's not server-only anymore. - #[test] - fn server_to_shared_and_shared_to_shared() -> anyhow::Result<()> { - let registry = InMemoryRegistry::new(); - registry.publish(PackageBuilder::new("biff/shared@1.0.0")); - registry.publish( - PackageBuilder::new("biff/server@1.0.0") - .with_realm(Realm::Server) - .with_dep("Shared", "biff/shared@1.0.0"), - ); - - let root = PackageBuilder::new("biff/root@1.0.0") - .with_server_dep("Server", "biff/server@1.0.0") - .with_dep("Shared", "biff/shared@1.0.0"); - - test_project(registry, root) - } - - /// Shared dependencies are allowed to depend on server dependencies. Server - /// dependencies should always be marked as server-only. - #[test] - fn shared_to_server() -> anyhow::Result<()> { - let registry = InMemoryRegistry::new(); - registry.publish(PackageBuilder::new("biff/server@1.0.0").with_realm(Realm::Server)); - - let root = - PackageBuilder::new("biff/root@1.0.0").with_server_dep("Server", "biff/server@1.0.0"); - - test_project(registry, root) - } - - #[test] - fn fail_server_in_shared() { - let registry = InMemoryRegistry::new(); - registry.publish(PackageBuilder::new("biff/server@1.0.0").with_realm(Realm::Server)); - - let root = PackageBuilder::new("biff/root@1.0.0").with_dep("Server", "biff/server@1.0.0"); - - let package_sources = PackageSourceMap::new(Box::new(registry.source())); - let err = resolve(root.manifest(), &Default::default(), &package_sources).unwrap_err(); - insta::assert_display_snapshot!(err); - } - - /// Tests the simple one dependency case, except that a new version of the - /// dependency will be published after the initial resolve. By persisting - /// the set of activated packages from the initial install, we signal that - /// the dependency should not be upgraded. - #[test] - fn one_dependency_no_upgrade() -> anyhow::Result<()> { - let registry = InMemoryRegistry::new(); - registry.publish(PackageBuilder::new("biff/minimal@1.0.0")); - - let root = PackageBuilder::new("biff/one-dependency@1.0.0") - .with_dep("Minimal", "biff/minimal@1.0.0"); - - let package_sources = PackageSourceMap::new(Box::new(registry.source())); - - let resolved = resolve(root.manifest(), &Default::default(), &package_sources)?; - insta::assert_yaml_snapshot!("one_dependency_no_upgrade", resolved); - - registry.publish(PackageBuilder::new("biff/minimal@1.1.0")); - let new_resolved = resolve(root.manifest(), &resolved.activated, &package_sources)?; - insta::assert_yaml_snapshot!("one_dependency_no_upgrade", new_resolved); - - Ok(()) - } - - #[test] - fn one_dependency_yes_upgrade() -> anyhow::Result<()> { - let registry = InMemoryRegistry::new(); - registry.publish(PackageBuilder::new("biff/minimal@1.0.0")); - - let root = PackageBuilder::new("biff/one-dependency@1.0.0") - .with_dep("Minimal", "biff/minimal@1.0.0"); - - let package_sources = PackageSourceMap::new(Box::new(registry.source())); - - let resolved = resolve(root.manifest(), &Default::default(), &package_sources)?; - insta::assert_yaml_snapshot!(resolved); - - // We can indicate that we'd like to upgrade a package by just removing - // it from the try_to_use set! - let remove_this: PackageName = "biff/minimal".parse().unwrap(); - let try_to_use = resolved - .activated - .into_iter() - .filter(|id| id.name() != &remove_this) - .collect(); - - registry.publish(PackageBuilder::new("biff/minimal@1.1.0")); - let new_resolved = resolve(root.manifest(), &try_to_use, &package_sources)?; - insta::assert_yaml_snapshot!(new_resolved); - - Ok(()) - } -} +use std::cmp::Ordering; +use std::collections::{BTreeMap, BTreeSet, VecDeque}; + +use anyhow::bail; +use anyhow::format_err; +use semver::Version; +use serde::Serialize; + +use crate::manifest::{Manifest, Realm}; +use crate::package_id::PackageId; +use crate::package_req::PackageReq; +use crate::package_source::{PackageSourceId, PackageSourceMap, PackageSourceProvider}; + +/// A completely resolved graph of packages returned by `resolve`. +/// +/// State here is stored in multiple maps, all keyed by PackageId, to facilitate +/// concurrent mutable access to unrelated information about different packages. +#[derive(Debug, Default, Serialize, Clone)] +pub struct Resolve { + /// Set of all packages that have been chosen to be part of the package + /// graph. + pub activated: BTreeSet, + + /// Metadata stored about each package that does not need to be accessed + /// concurrently to other information. + pub metadata: BTreeMap, + + /// Graph of all dependencies originating from the "shared" dependency realm. + pub shared_dependencies: BTreeMap>, + + /// Graph of all dependencies originating from the "server" dependency realm. + pub server_dependencies: BTreeMap>, + + /// Graph of all dependencies originating from the "dev" dependency realm. + pub dev_dependencies: BTreeMap>, +} + +impl Resolve { + fn activate(&mut self, source: PackageId, dep_name: String, dep_realm: Realm, dep: PackageId) { + self.activated.insert(dep.clone()); + + let dependencies = match dep_realm { + Realm::Shared => self.shared_dependencies.entry(source).or_default(), + Realm::Server => self.server_dependencies.entry(source).or_default(), + Realm::Dev => self.dev_dependencies.entry(source).or_default(), + }; + dependencies.insert(dep_name, dep); + } +} + +/// A single node in the package resolution graph. +/// Origin realm is the "most restrictive" realm the package can still be dependended +/// upon. It is where the package gets placed during install. +/// See [ origin_realm clarification ]. In the resolve function for more info. +#[derive(Debug, Serialize, Clone)] +pub struct ResolvePackageMetadata { + pub realm: Realm, + pub origin_realm: Realm, + pub source_registry: PackageSourceId, +} + +pub fn resolve( + root_manifest: &Manifest, + try_to_use: &BTreeSet, + package_sources: &PackageSourceMap, +) -> anyhow::Result { + let mut resolve = Resolve::default(); + + // Insert root project into graph and activated dependencies, as it'll + // always be present. + resolve.activated.insert(root_manifest.package_id()); + resolve.metadata.insert( + root_manifest.package_id(), + ResolvePackageMetadata { + realm: root_manifest.package.realm, + origin_realm: root_manifest.package.realm, + source_registry: PackageSourceId::DefaultRegistry, + }, + ); + + // Queue of all dependency requests that need to be resolved. + let mut packages_to_visit = VecDeque::new(); + + for (alias, req) in &root_manifest.dependencies { + packages_to_visit.push_back(DependencyRequest { + request_source: root_manifest.package_id(), + request_realm: Realm::Shared, + origin_realm: Realm::Shared, + package_alias: alias.clone(), + package_req: req.clone(), + }); + } + + for (alias, req) in &root_manifest.server_dependencies { + packages_to_visit.push_back(DependencyRequest { + request_source: root_manifest.package_id(), + request_realm: Realm::Server, + origin_realm: Realm::Server, + package_alias: alias.clone(), + package_req: req.clone(), + }); + } + + for (alias, req) in &root_manifest.dev_dependencies { + packages_to_visit.push_back(DependencyRequest { + request_source: root_manifest.package_id(), + request_realm: Realm::Dev, + origin_realm: Realm::Dev, + package_alias: alias.clone(), + package_req: req.clone(), + }); + } + + // Workhorse loop: resolve all dependencies, depth-first. + 'outer: while let Some(dependency_request) = packages_to_visit.pop_front() { + // Locate all already-activated packages that might match this + // dependency request. + let mut matching_activated: Vec<_> = resolve + .activated + .iter() + .filter(|package_id| package_id.name() == dependency_request.package_req.name()) + .cloned() + .collect(); + + // Sort our list of candidates by descending version so that we can pick + // newest candidates first. + matching_activated.sort_by(|a, b| b.version().cmp(a.version())); + + // Check for the highest version already-activated package that matches + // our constraints. + for package_id in &matching_activated { + if dependency_request.package_req.matches_id(package_id) { + let metadata = resolve + .metadata + .get_mut(package_id) + .expect("activated package was missing metadata"); + + // [ origin_realm clarification ] + // We want to set the origin to the most restrictive origin possible. + // For example we want to keep packages in the dev realm unless a dependency + // with a shared/server origin requires it. This way server/shared dependencies + // which only originate from dev dependencies get put into the dev folder even + // if they usually belong to another realm. Likewise we want to keep shared + // dependencies in the server realm unless they are explicitly required as a + // shared dependency. + let realm_match = match (metadata.origin_realm, dependency_request.origin_realm) { + (_, Realm::Shared) => Realm::Shared, + (Realm::Shared, _) => Realm::Shared, + (_, Realm::Server) => Realm::Server, + (Realm::Server, _) => Realm::Server, + (Realm::Dev, Realm::Dev) => Realm::Dev, + }; + + metadata.origin_realm = realm_match; + + resolve.activate( + dependency_request.request_source.clone(), + dependency_request.package_alias.clone(), + realm_match, + package_id.clone(), + ); + + continue 'outer; + } + } + + // Look through all our packages sources in order of priority + let (source_registry, mut candidates) = package_sources + .source_order() + .iter() + .find_map(|source| { + let registry = package_sources.get(source).unwrap(); + + // Pull all of the possible candidate versions of the package we're + // looking for from the highest priority source which has them. + match registry.query(&dependency_request.package_req) { + Ok(manifests) => Some((source, manifests)), + Err(_) => None, + } + }) + .ok_or_else(|| { + format_err!( + "Failed to find a source for {}", + dependency_request.package_req + ) + })?; + + // Sort our candidate packages by descending version, so that we try the + // highest versions first. + // + // Additionally, if there were any packages that were previously used by + // our lockfile (in `try_to_use`), prioritize those first. This + // technique is the one used by Cargo. + candidates.sort_by(|a, b| { + let contains_a = try_to_use.contains(&a.package_id()); + let contains_b = try_to_use.contains(&b.package_id()); + + match (contains_a, contains_b) { + (true, false) => Ordering::Less, + (false, true) => Ordering::Greater, + _ => b.package.version.cmp(&a.package.version), + } + }); + + let filtered_candidates = candidates.iter().filter(|candidate| { + Realm::is_dependency_valid(dependency_request.request_realm, candidate.package.realm) + }); + + let mut conflicting = Vec::new(); + + for candidate in filtered_candidates { + // Conflicts occur if two packages are SemVer compatible. We choose + // to only allow one compatible copy of a given package to prevent + // common user errors. + + let has_conflicting = matching_activated + .iter() + .any(|activated| compatible(&candidate.package.version, activated.version())); + + if has_conflicting { + // This is a matching candidate, but it conflicts with a + // candidate we already selected before. We'll note that this + // happened. If there are no other matching versions that don't + // conflict, we'll report this in an error. + + conflicting.push(candidate.package_id()); + continue; + } + + let candidate_id = PackageId::new( + candidate.package.name.clone(), + candidate.package.version.clone(), + ); + + resolve.activate( + dependency_request.request_source.clone(), + dependency_request.package_alias.to_owned(), + dependency_request.origin_realm, + candidate_id.clone(), + ); + + resolve.metadata.insert( + candidate_id.clone(), + ResolvePackageMetadata { + realm: candidate.package.realm, + origin_realm: dependency_request.origin_realm, + source_registry: source_registry.clone(), + }, + ); + + for (alias, req) in &candidate.dependencies { + packages_to_visit.push_back(DependencyRequest { + request_source: candidate_id.clone(), + request_realm: Realm::Shared, + origin_realm: dependency_request.origin_realm, + package_alias: alias.clone(), + package_req: req.clone(), + }) + } + + for (alias, req) in &candidate.server_dependencies { + packages_to_visit.push_back(DependencyRequest { + request_source: candidate_id.clone(), + request_realm: Realm::Server, + origin_realm: dependency_request.origin_realm, + package_alias: alias.clone(), + package_req: req.clone(), + }) + } + + continue 'outer; + } + + if conflicting.is_empty() { + bail!( + "No packages were found that matched ({req_realm:?}) {req}.\nAre you sure this is \ + a {req_realm:?} dependency?", + req_realm = dependency_request.request_realm, + req = dependency_request.package_req, + ); + } else { + let conflicting_debug: Vec<_> = conflicting + .into_iter() + .map(|id| format!("{:?}", id)) + .collect(); + + bail!( + "All possible candidates for package {req} ({req_realm:?}) conflicted with other \ + packages that were already installed. These packages were previously selected: \ + {conflicting}", + req = dependency_request.package_req, + req_realm = dependency_request.request_realm, + conflicting = conflicting_debug.join(", "), + ); + } + } + + Ok(resolve) +} + +fn compatible(a: &Version, b: &Version) -> bool { + if a == b { + return true; + } + + if a.major == 0 && b.major == 0 { + a.minor == b.minor + } else { + a.major == b.major + } +} + +pub struct DependencyRequest { + request_source: PackageId, + request_realm: Realm, + origin_realm: Realm, + package_alias: String, + package_req: PackageReq, +} + +#[cfg(test)] +mod tests { + use super::*; + + use crate::{ + package_name::PackageName, package_source::InMemoryRegistry, test_package::PackageBuilder, + }; + + fn test_project(test_name: &str, registry: InMemoryRegistry, package: PackageBuilder) -> anyhow::Result<()> { + let package_sources = PackageSourceMap::new(Box::new(registry.source())); + let manifest = package.into_manifest(); + let resolve = resolve(&manifest, &Default::default(), &package_sources)?; + insta::assert_yaml_snapshot!(test_name, resolve); + Ok(()) + } + + #[test] + fn minimal() -> anyhow::Result<()> { + let registry = InMemoryRegistry::new(); + + let root = PackageBuilder::new("biff/minimal@0.1.0"); + test_project("minimal", registry, root) + } + + #[test] + fn one_dependency() -> anyhow::Result<()> { + let registry = InMemoryRegistry::new(); + registry.publish(PackageBuilder::new("biff/minimal@0.1.0")); + registry.publish(PackageBuilder::new("biff/minimal@0.2.0")); + + let root = PackageBuilder::new("biff/one-dependency@0.1.0") + .with_dep("Minimal", "biff/minimal@0.1.0"); + test_project("one_dependency", registry, root) + } + + #[test] + fn transitive_dependency() -> anyhow::Result<()> { + let registry = InMemoryRegistry::new(); + registry.publish(PackageBuilder::new("biff/minimal@0.1.0")); + registry.publish( + PackageBuilder::new("biff/one-dependency@0.1.0") + .with_dep("Minimal", "biff/minimal@0.1.0"), + ); + + let root = PackageBuilder::new("biff/transitive-dependency@0.1.0") + .with_dep("OneDependency", "biff/one-dependency@0.1.0"); + test_project("transitive_dependency", registry, root) + } + + /// When there are shared dependencies, Wally should select the same + /// dependency. Here, A depends on B and C, which both in turn depend on D. + #[test] + fn unified_dependencies() -> anyhow::Result<()> { + let registry = InMemoryRegistry::new(); + registry.publish(PackageBuilder::new("biff/b@1.0.0").with_dep("D", "biff/d@1.0.0")); + registry.publish(PackageBuilder::new("biff/c@1.0.0").with_dep("D", "biff/d@1.0.0")); + registry.publish(PackageBuilder::new("biff/d@1.0.0")); + + let root = PackageBuilder::new("biff/a@1.0.0") + .with_dep("B", "biff/b@1.0.0") + .with_dep("C", "biff/c@1.0.0"); + + test_project("unified_dependencies", registry, root) + } + + /// Server dependencies are allowed to depend on shared dependencies. If a + /// shared dependency is only depended on by server dependencies, it should + /// be marked as server-only. + #[test] + fn server_to_shared() -> anyhow::Result<()> { + let registry = InMemoryRegistry::new(); + registry.publish(PackageBuilder::new("biff/shared@1.0.0")); + registry.publish( + PackageBuilder::new("biff/server@1.0.0") + .with_realm(Realm::Server) + .with_dep("Shared", "biff/shared@1.0.0"), + ); + + let root = + PackageBuilder::new("biff/root@1.0.0").with_server_dep("Server", "biff/server@1.0.0"); + + test_project("server_to_shared", registry, root) + } + + /// but... if that shared dependency is required by another shared dependency, + /// (while not being also server-only) it's not server-only anymore. + #[test] + fn server_to_shared_and_shared_to_shared() -> anyhow::Result<()> { + let registry = InMemoryRegistry::new(); + registry.publish(PackageBuilder::new("biff/shared@1.0.0")); + registry.publish( + PackageBuilder::new("biff/server@1.0.0") + .with_realm(Realm::Server) + .with_dep("Shared", "biff/shared@1.0.0"), + ); + + let root = PackageBuilder::new("biff/root@1.0.0") + .with_server_dep("Server", "biff/server@1.0.0") + .with_dep("Shared", "biff/shared@1.0.0"); + + test_project("server_to_shared_and_shared_to_shared", registry, root) + } + + /// Shared dependencies are allowed to depend on server dependencies. Server + /// dependencies should always be marked as server-only. + #[test] + fn shared_to_server() -> anyhow::Result<()> { + let registry = InMemoryRegistry::new(); + registry.publish(PackageBuilder::new("biff/server@1.0.0").with_realm(Realm::Server)); + + let root = + PackageBuilder::new("biff/root@1.0.0").with_server_dep("Server", "biff/server@1.0.0"); + + test_project("shared_to_server", registry, root) + } + + #[test] + fn fail_server_in_shared() { + let registry = InMemoryRegistry::new(); + registry.publish(PackageBuilder::new("biff/server@1.0.0").with_realm(Realm::Server)); + + let root = PackageBuilder::new("biff/root@1.0.0").with_dep("Server", "biff/server@1.0.0"); + + let package_sources = PackageSourceMap::new(Box::new(registry.source())); + let err = resolve(root.manifest(), &Default::default(), &package_sources).unwrap_err(); + insta::assert_snapshot!(err); + } + + /// Tests the simple one dependency case, except that a new version of the + /// dependency will be published after the initial resolve. By persisting + /// the set of activated packages from the initial install, we signal that + /// the dependency should not be upgraded. + #[test] + fn one_dependency_no_upgrade() -> anyhow::Result<()> { + let registry = InMemoryRegistry::new(); + registry.publish(PackageBuilder::new("biff/minimal@1.0.0")); + + let root = PackageBuilder::new("biff/one-dependency@1.0.0") + .with_dep("Minimal", "biff/minimal@1.0.0"); + + let package_sources = PackageSourceMap::new(Box::new(registry.source())); + + let resolved = resolve(root.manifest(), &Default::default(), &package_sources)?; + insta::assert_yaml_snapshot!("one_dependency_no_upgrade", resolved); + + registry.publish(PackageBuilder::new("biff/minimal@1.1.0")); + let new_resolved = resolve(root.manifest(), &resolved.activated, &package_sources)?; + insta::assert_yaml_snapshot!("one_dependency_no_upgrade", new_resolved); + + Ok(()) + } + + #[test] + fn one_dependency_yes_upgrade() -> anyhow::Result<()> { + let registry = InMemoryRegistry::new(); + registry.publish(PackageBuilder::new("biff/minimal@1.0.0")); + + let root = PackageBuilder::new("biff/one-dependency@1.0.0") + .with_dep("Minimal", "biff/minimal@1.0.0"); + + let package_sources = PackageSourceMap::new(Box::new(registry.source())); + + let resolved = resolve(root.manifest(), &Default::default(), &package_sources)?; + insta::assert_yaml_snapshot!(resolved); + + // We can indicate that we'd like to upgrade a package by just removing + // it from the try_to_use set! + let remove_this: PackageName = "biff/minimal".parse().unwrap(); + let try_to_use = resolved + .activated + .into_iter() + .filter(|id| id.name() != &remove_this) + .collect(); + + registry.publish(PackageBuilder::new("biff/minimal@1.1.0")); + let new_resolved = resolve(root.manifest(), &try_to_use, &package_sources)?; + insta::assert_yaml_snapshot!(new_resolved); + + Ok(()) + } +} diff --git a/test-projects/dependency-with-types/default.project.json b/test-projects/dependency-with-types/default.project.json new file mode 100644 index 00000000..3c8c6813 --- /dev/null +++ b/test-projects/dependency-with-types/default.project.json @@ -0,0 +1,6 @@ +{ + "name": "dependency-with-types", + "tree": { + "$path": "src" + } +} \ No newline at end of file diff --git a/test-projects/dependency-with-types/src/init.lua b/test-projects/dependency-with-types/src/init.lua new file mode 100644 index 00000000..b41ff719 --- /dev/null +++ b/test-projects/dependency-with-types/src/init.lua @@ -0,0 +1,5 @@ +local MinimalWithTypes = require(script.Parent.MinimalWithTypes) + +return function() + print(MinimalWithTypes) +end \ No newline at end of file diff --git a/test-projects/dependency-with-types/wally.toml b/test-projects/dependency-with-types/wally.toml new file mode 100644 index 00000000..3608739f --- /dev/null +++ b/test-projects/dependency-with-types/wally.toml @@ -0,0 +1,9 @@ +[package] +name = "biff/dependency-with-types" +version = "0.1.0" +license = "MIT" +realm = "server" +registry = "test-registries/primary-registry" + +[server-dependencies] +MinimalWithTypes = "biff/minimal-with-types@0.1.0" diff --git a/test-registries/primary-registry/contents/biff/minimal-with-types/0.1.0.zip b/test-registries/primary-registry/contents/biff/minimal-with-types/0.1.0.zip new file mode 100644 index 0000000000000000000000000000000000000000..224f39997f73dae1479f8ae881ed2ba331eb5d96 GIT binary patch literal 792 zcmWIWW@Zs#U|`^2;NNTz^XG~HzblXz0K_2Cl+?7u(wq{#f};Ga)Z`Mqtm6DU)zjWw z2NZZ(9`0Q}Vd3ej#(Qd08XDbPn3syYf0sSY{{EkH{fZNf^!TT$c==ZxP1>Med~|24 z=)9!gp?yAL&sR>9);7Ox6#%ssXbsR>piOYV0%R2zCF{dfa4-mOG>G}$s_mo7$iT3O znSp@^sv`1txwmcu{h}?=)ZPG_y<2JZ5Vn!Z`o5?1rl<0I?d&k_&0rF>FhMd>gAz& z6QlH2ENE??@}+;mbMG#(&2}gH?H)W)ls>k0%e!|xvd$^xo8L+tGt0=^J2&64e7;;! zYu2l%-i%E4;5fw=(<;#5SAf#k;+=~DBFo4i!Eof&srQxbcNk%`o}Atz z5FcR+wupt Result<(), anyhow::Error> { - let source_project = - Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/test-projects",)).join(name); - - let project = TempProject::new(&source_project).unwrap(); - - Args { - global: GlobalOptions { - test_registry: true, - ..Default::default() - }, - subcommand: Subcommand::Install(InstallSubcommand { - project_path: project.path().to_owned(), - locked: true, - }), - } - .run() -} - -fn run_install_test(name: &str) -> TempProject { - let source_project = - Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/test-projects",)).join(name); - - let project = TempProject::new(&source_project).unwrap(); - - let args = Args { - global: GlobalOptions { - test_registry: true, - ..Default::default() - }, - subcommand: Subcommand::Install(InstallSubcommand { - project_path: project.path().to_owned(), - locked: false, - }), - }; - - args.run().unwrap(); - - assert_dir_snapshot!(project.path()); - project -} +use super::temp_project::TempProject; +use libwally::{Args, GlobalOptions, InstallSubcommand, Subcommand}; +use std::path::Path; + +#[test] +fn minimal() { + let project = run_install_test("minimal"); + assert_dir_snapshot!(project.path()); +} + +#[test] +fn dependency_with_types() { + let project = run_install_test("dependency-with-types"); + assert_dir_snapshot!(project.path()); +} + +#[test] +fn one_dependency() { + let project = run_install_test("one-dependency"); + assert_dir_snapshot!(project.path()); +} + +#[test] +fn transitive_dependency() { + let project = run_install_test("transitive-dependency"); + assert_dir_snapshot!(project.path()); +} + +#[test] +fn private_with_public_dependency() { + let project = run_install_test("private-with-public-dependency"); + assert_dir_snapshot!(project.path()); +} + +#[test] +fn dev_dependency() { + let project = run_install_test("dev-dependency"); + assert_dir_snapshot!(project.path()); +} + +#[test] +fn dev_dependency_also_required_as_non_dev() { + let project = run_install_test("dev-dependency-also-required-as-non-dev"); + assert_dir_snapshot!(project.path()); +} + +#[test] +fn cross_realm_dependency() { + let project = run_install_test("cross-realm-dependency"); + assert_dir_snapshot!(project.path()); +} + +#[test] +fn cross_realm_explicit_dependency() { + let project = run_install_test("cross-realm-explicit-dependency"); + assert_dir_snapshot!(project.path()); +} + +#[test] +fn manifest_links() { + let project = run_install_test("manifest-links"); + assert_dir_snapshot!(project.path()); +} + +#[test] +fn locked_pass() { + let result = run_locked_install("diamond-graph/root/latest"); + + assert!(result.is_ok(), "Should pass without any problems"); +} + +#[test] +fn locked_catches_dated_packages() { + let result = run_locked_install("diamond-graph/root/dated"); + assert!(result.is_err(), "Should fail!"); +} + +fn run_locked_install(name: &str) -> Result<(), anyhow::Error> { + let source_project = + Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/test-projects",)).join(name); + + let project = TempProject::new(&source_project).unwrap(); + + Args { + global: GlobalOptions { + test_registry: true, + ..Default::default() + }, + subcommand: Subcommand::Install(InstallSubcommand { + project_path: project.path().to_owned(), + locked: true, + }), + } + .run() +} + +fn run_install_test(name: &str) -> TempProject { + let source_project = + Path::new(concat!(env!("CARGO_MANIFEST_DIR"), "/test-projects",)).join(name); + + let project = TempProject::new(&source_project).unwrap(); + + let args = Args { + global: GlobalOptions { + test_registry: true, + ..Default::default() + }, + subcommand: Subcommand::Install(InstallSubcommand { + project_path: project.path().to_owned(), + locked: false, + }), + }; + + args.run().unwrap(); + + project +} diff --git a/tests/integration/snapshots/integration__install__dependency_with_types.snap b/tests/integration/snapshots/integration__install__dependency_with_types.snap new file mode 100644 index 00000000..52926a50 --- /dev/null +++ b/tests/integration/snapshots/integration__install__dependency_with_types.snap @@ -0,0 +1,17 @@ +--- +source: tests/integration/install.rs +expression: result +--- +ServerPackages: + MinimalWithTypes.lua: "local MODULE = require(script.Parent._Index[\"biff_minimal-with-types@0.1.0\"][\"minimal-with-types\"])\nexport type A = MODULE.A\nexport type B = MODULE.B\nexport type C = MODULE.C\nexport type D = MODULE.D\nexport type E = MODULE.E\nexport type F = MODULE.F\nexport type BadDefaultTypeParam = MODULE.BadDefaultTypeParam\nexport type WithTypeParams = MODULE.WithTypeParams\nexport type WithParamPack = MODULE.WithParamPack\nreturn MODULE\n" + _Index: + biff_minimal-with-types@0.1.0: + minimal-with-types: + default.project.json: "{\n \"name\": \"minimal-with-types\",\n \"tree\": {\n \"$path\": \"src\"\n }\n}" + src: + init.lua: "local _test = ` \\\n test {1337} \\\n \\' \\\nexport type SHOULD_NOT_BE_FORWARDED = number \\\n\texport type SHOULD_NOT_BE_FORWARDED = number \\\n\t--[[ \\\n`;export type A = number\n\nlocal _normalString = \" \\\n\\\" \\\nexport type SHOULD_NOT_BE_FORWARDED = number \\\n\";export type B = number\n\nlocal _longString = [[\nexport type SHOULD_NOT_BE_FORWARDED = number \\\n\texport type SHOULD_NOT_BE_FORWARDED = number \\\n]];export type C = number\n\nlocal _testLongStringEnded = [=[ test ]==]\nexport type SHOULD_NOT_BE_FORWARDED = number\n]=];export type D = number\n\n----[[\n\n--[[]];export type E = number\n\n--[=[\nexport type SHOULD_NOT_BE_FORWARDED = number\n--]]\n\nexport type SHOULD_NOT_BE_FORWARDED = number\n--]=];export type F = number\n\ntype SHOULD_NOT_BE_FORWARDED = number\nexport type BadDefaultTypeParam = number\n\nexport type WithTypeParams = {\n a: T,\n b: U,\n}\n\nexport type WithParamPack = number\n\nreturn {}" +default.project.json: "{\n\t\"name\": \"dependency-with-types\",\n\t\"tree\": {\n\t\t\"$path\": \"src\"\n\t}\n}" +src: + init.lua: "local MinimalWithTypes = require(script.Parent.MinimalWithTypes)\n\nreturn function()\n\tprint(MinimalWithTypes)\nend" +wally.lock: "# This file is automatically @generated by Wally.\n# It is not intended for manual editing.\nregistry = \"test\"\n\n[[package]]\nname = \"biff/dependency-with-types\"\nversion = \"0.1.0\"\ndependencies = [\n\t[\"MinimalWithTypes\", \"biff/minimal-with-types@0.1.0\"],\n]\n\n[[package]]\nname = \"biff/minimal-with-types\"\nversion = \"0.1.0\"\ndependencies = []\n\n" +wally.toml: "[package]\nname = \"biff/dependency-with-types\"\nversion = \"0.1.0\"\nlicense = \"MIT\"\nrealm = \"server\"\nregistry = \"test-registries/primary-registry\"\n\n[server-dependencies]\nMinimalWithTypes = \"biff/minimal-with-types@0.1.0\"\n" diff --git a/wally-registry-backend/src/tests/mod.rs b/wally-registry-backend/src/tests/mod.rs index 7a888878..c94d7b4c 100644 --- a/wally-registry-backend/src/tests/mod.rs +++ b/wally-registry-backend/src/tests/mod.rs @@ -1,314 +1,314 @@ -use std::path::Path; - -use figment::{providers::Serialized, Figment}; -use libwally::test_package::PackageBuilder; -use rocket::{ - http::{Accept, ContentType, Header, Status}, - local::blocking::{Client, LocalResponse}, -}; - -use crate::{auth::AuthMode, config::Config, server, storage::StorageMode}; - -fn init_test_index_remote() -> anyhow::Result { - let temp_dir = tempfile::tempdir()?; - let repo = git2::Repository::init_bare(temp_dir.path())?; - let sig = git2::Signature::now("PackageUser", "PackageUser@localhost")?; - let tree_id = repo.index()?.write_tree()?; - let tree = repo.find_tree(tree_id)?; - - // Setting head is required so clones will clone main instead of master (which doesn't exist) - repo.set_head("refs/heads/main")?; - repo.commit( - Some("refs/heads/main"), - &sig, - &sig, - "Initial commit", - &tree, - &[], - )?; - - Ok(url::Url::from_directory_path(temp_dir.into_path()).unwrap()) -} - -fn add_test_packages(output_dir: &Path) -> anyhow::Result<()> { - let packages_path = Path::new("src/tests/packages"); - - for package in glob::glob("src/tests/packages/**/*.zip")?.filter_map(Result::ok) { - let relative_path = package.strip_prefix(packages_path)?; - let output = output_dir.join(relative_path); - - fs_err::create_dir_all(output.parent().unwrap())?; - fs_err::copy(&package, output)?; - } - - Ok(()) -} - -fn new_client(auth: AuthMode) -> Client { - new_client_with_remote(auth, init_test_index_remote().unwrap()) -} - -fn new_client_with_remote(auth: AuthMode, index_url: url::Url) -> Client { - let package_path = tempfile::tempdir().unwrap().into_path(); - add_test_packages(&package_path).unwrap(); - - let figment = Figment::from(rocket::Config::default()).merge(Serialized::globals(Config { - index_url, - storage: StorageMode::Local { - path: Some(package_path), - }, - auth, - github_token: None, - minimum_wally_version: None, - })); - - Client::tracked(server(figment)).expect("valid rocket instance") -} - -struct Expectation { - status: Status, - content_type: ContentType, -} - -impl Expectation { - fn assert(self, response: LocalResponse<'_>) { - fn get_body(response: LocalResponse<'_>) -> String { - let body = response - .into_string() - .unwrap_or_else(|| format!("")); - - body - } - - let status = response.status(); - - if status != self.status { - panic!( - "Expected status {}, got {}\n{}", - self.status, - status, - get_body(response) - ); - } - - let content_type = response - .content_type() - .unwrap_or_else(|| panic!("response did not have a content type")); - - if content_type != self.content_type { - panic!( - "Expected content type {}, got {}\n{}", - self.content_type, - content_type, - get_body(response), - ); - } - } -} - -#[test] -fn root() { - let client = new_client(AuthMode::Unauthenticated); - let response = client.get("/").dispatch(); - - Expectation { - status: Status::Ok, - content_type: ContentType::JSON, - } - .assert(response); -} - -#[test] -fn read_minimal() { - let client = new_client(AuthMode::Unauthenticated); - let response = client - .get("/v1/package-contents/biff/minimal/0.1.0") - .dispatch(); - - Expectation { - status: Status::Ok, - content_type: ContentType::GZIP, - } - .assert(response); -} - -#[test] -fn read_404() { - let client = new_client(AuthMode::Unauthenticated); - let response = client - .get("/v1/package-contents/biff/doesnt-exist/0.1.0") - .dispatch(); - - Expectation { - status: Status::NotFound, - content_type: ContentType::JSON, - } - .assert(response); -} - -#[test] -fn publish_unauthenticated_401() { - let client = new_client(AuthMode::Unauthenticated); - let response = client.post("/v1/publish").header(Accept::JSON).dispatch(); - - Expectation { - status: Status::Unauthorized, - content_type: ContentType::JSON, - } - .assert(response); -} - -#[test] -fn publish() { - let contents = PackageBuilder::new("biff/hello@1.0.0").contents(); - - let client = new_client(AuthMode::ApiKey(String::from("hello"))); - let response = client - .post("/v1/publish") - .header(Accept::JSON) - .body(contents.data()) - .header(Header::new("Authorization", "Bearer hello")) - .dispatch(); - - Expectation { - status: Status::Ok, - content_type: ContentType::JSON, - } - .assert(response); -} - -#[test] -fn read_write_double_key() { - let client = new_client(AuthMode::DoubleApiKey { - read: None, - write: String::from("A write key"), - }); - - // We can read with no API key - let response = client - .get("/v1/package-contents/biff/minimal/0.1.0") - .dispatch(); - - Expectation { - status: Status::Ok, - content_type: ContentType::GZIP, - } - .assert(response); - - // But we can't write with no API key - let contents = PackageBuilder::new("biff/hello@1.0.0").contents(); - let response = client - .post("/v1/publish") - .header(Accept::JSON) - .body(contents.data()) - .dispatch(); - - Expectation { - status: Status::Unauthorized, - content_type: ContentType::JSON, - } - .assert(response); - - // Unless we use the correct API key - let response = client - .post("/v1/publish") - .header(Accept::JSON) - .body(contents.data()) - .header(Header::new("Authorization", "Bearer A write key")) - .dispatch(); - - Expectation { - status: Status::Ok, - content_type: ContentType::JSON, - } - .assert(response); -} - -#[test] -fn publish_duplicate() { - let contents = PackageBuilder::new("biff/hello@0.1.0").contents(); - let client = new_client(AuthMode::ApiKey(String::from("hello"))); - let send_request = || { - client - .post("/v1/publish") - .header(Accept::JSON) - .body(contents.data()) - .header(Header::new("Authorization", "Bearer hello")) - .dispatch() - }; - - Expectation { - status: Status::Ok, - content_type: ContentType::JSON, - } - .assert(send_request()); - - Expectation { - status: Status::Conflict, - content_type: ContentType::JSON, - } - .assert(send_request()); -} - -#[test] -fn publish_updates_git_remote() { - let remote = init_test_index_remote().unwrap(); - let repo = git2::Repository::open(remote.to_file_path().unwrap()).unwrap(); - let client = new_client_with_remote(AuthMode::ApiKey(String::from("hello")), remote); - - let commit = repo.head().unwrap().peel_to_commit().unwrap(); - assert_eq!(commit.message().unwrap(), "Initial commit"); - - let contents = PackageBuilder::new("biff/hello@0.1.0").contents(); - client - .post("/v1/publish") - .header(Accept::JSON) - .body(contents.data()) - .header(Header::new("Authorization", "Bearer hello")) - .dispatch(); - - let commit = repo.head().unwrap().peel_to_commit().unwrap(); - assert_ne!(commit.message().unwrap(), "Initial commit"); -} - -/// Ensures the package index will update when the remote is modified before a publish request -/// This is to check our update implementation as well as support for multiple api nodes -#[test] -fn publish_then_publish_elsewhere() { - let remote = init_test_index_remote().unwrap(); - let client1 = new_client_with_remote(AuthMode::ApiKey(String::from("hello")), remote.clone()); - let client2 = new_client_with_remote(AuthMode::ApiKey(String::from("hello")), remote); - - let contents = PackageBuilder::new("biff/hello@1.0.0").contents(); - let response = client1 - .post("/v1/publish") - .header(Accept::JSON) - .body(contents.data()) - .header(Header::new("Authorization", "Bearer hello")) - .dispatch(); - - Expectation { - status: Status::Ok, - content_type: ContentType::JSON, - } - .assert(response); - - let contents = PackageBuilder::new("biff/hello@1.0.1").contents(); - let response = client2 - .post("/v1/publish") - .header(Accept::JSON) - .body(contents.data()) - .header(Header::new("Authorization", "Bearer hello")) - .dispatch(); - - Expectation { - status: Status::Ok, - content_type: ContentType::JSON, - } - .assert(response); -} - -// TODO: Implement yanking -#[test] -#[ignore] -fn yank() {} +use std::path::Path; + +use figment::{providers::Serialized, Figment}; +use libwally::test_package::PackageBuilder; +use rocket::{ + http::{Accept, ContentType, Header, Status}, + local::blocking::{Client, LocalResponse}, +}; + +use crate::{auth::AuthMode, config::Config, server, storage::StorageMode}; + +fn init_test_index_remote() -> anyhow::Result { + let temp_dir = tempfile::tempdir()?; + let repo = git2::Repository::init_bare(temp_dir.path())?; + let sig = git2::Signature::now("PackageUser", "PackageUser@localhost")?; + let tree_id = repo.index()?.write_tree()?; + let tree = repo.find_tree(tree_id)?; + + // Setting head is required so clones will clone main instead of master (which doesn't exist) + repo.set_head("refs/heads/main")?; + repo.commit( + Some("refs/heads/main"), + &sig, + &sig, + "Initial commit", + &tree, + &[], + )?; + + Ok(url::Url::from_directory_path(temp_dir.keep()).unwrap()) +} + +fn add_test_packages(output_dir: &Path) -> anyhow::Result<()> { + let packages_path = Path::new("src/tests/packages"); + + for package in glob::glob("src/tests/packages/**/*.zip")?.filter_map(Result::ok) { + let relative_path = package.strip_prefix(packages_path)?; + let output = output_dir.join(relative_path); + + fs_err::create_dir_all(output.parent().unwrap())?; + fs_err::copy(&package, output)?; + } + + Ok(()) +} + +fn new_client(auth: AuthMode) -> Client { + new_client_with_remote(auth, init_test_index_remote().unwrap()) +} + +fn new_client_with_remote(auth: AuthMode, index_url: url::Url) -> Client { + let package_path = tempfile::tempdir().unwrap().keep(); + add_test_packages(&package_path).unwrap(); + + let figment = Figment::from(rocket::Config::default()).merge(Serialized::globals(Config { + index_url, + storage: StorageMode::Local { + path: Some(package_path), + }, + auth, + github_token: None, + minimum_wally_version: None, + })); + + Client::tracked(server(figment)).expect("valid rocket instance") +} + +struct Expectation { + status: Status, + content_type: ContentType, +} + +impl Expectation { + fn assert(self, response: LocalResponse<'_>) { + fn get_body(response: LocalResponse<'_>) -> String { + let body = response + .into_string() + .unwrap_or_else(|| format!("")); + + body + } + + let status = response.status(); + + if status != self.status { + panic!( + "Expected status {}, got {}\n{}", + self.status, + status, + get_body(response) + ); + } + + let content_type = response + .content_type() + .unwrap_or_else(|| panic!("response did not have a content type")); + + if content_type != self.content_type { + panic!( + "Expected content type {}, got {}\n{}", + self.content_type, + content_type, + get_body(response), + ); + } + } +} + +#[test] +fn root() { + let client = new_client(AuthMode::Unauthenticated); + let response = client.get("/").dispatch(); + + Expectation { + status: Status::Ok, + content_type: ContentType::JSON, + } + .assert(response); +} + +#[test] +fn read_minimal() { + let client = new_client(AuthMode::Unauthenticated); + let response = client + .get("/v1/package-contents/biff/minimal/0.1.0") + .dispatch(); + + Expectation { + status: Status::Ok, + content_type: ContentType::GZIP, + } + .assert(response); +} + +#[test] +fn read_404() { + let client = new_client(AuthMode::Unauthenticated); + let response = client + .get("/v1/package-contents/biff/doesnt-exist/0.1.0") + .dispatch(); + + Expectation { + status: Status::NotFound, + content_type: ContentType::JSON, + } + .assert(response); +} + +#[test] +fn publish_unauthenticated_401() { + let client = new_client(AuthMode::Unauthenticated); + let response = client.post("/v1/publish").header(Accept::JSON).dispatch(); + + Expectation { + status: Status::Unauthorized, + content_type: ContentType::JSON, + } + .assert(response); +} + +#[test] +fn publish() { + let contents = PackageBuilder::new("biff/hello@1.0.0").contents(); + + let client = new_client(AuthMode::ApiKey(String::from("hello"))); + let response = client + .post("/v1/publish") + .header(Accept::JSON) + .body(contents.data()) + .header(Header::new("Authorization", "Bearer hello")) + .dispatch(); + + Expectation { + status: Status::Ok, + content_type: ContentType::JSON, + } + .assert(response); +} + +#[test] +fn read_write_double_key() { + let client = new_client(AuthMode::DoubleApiKey { + read: None, + write: String::from("A write key"), + }); + + // We can read with no API key + let response = client + .get("/v1/package-contents/biff/minimal/0.1.0") + .dispatch(); + + Expectation { + status: Status::Ok, + content_type: ContentType::GZIP, + } + .assert(response); + + // But we can't write with no API key + let contents = PackageBuilder::new("biff/hello@1.0.0").contents(); + let response = client + .post("/v1/publish") + .header(Accept::JSON) + .body(contents.data()) + .dispatch(); + + Expectation { + status: Status::Unauthorized, + content_type: ContentType::JSON, + } + .assert(response); + + // Unless we use the correct API key + let response = client + .post("/v1/publish") + .header(Accept::JSON) + .body(contents.data()) + .header(Header::new("Authorization", "Bearer A write key")) + .dispatch(); + + Expectation { + status: Status::Ok, + content_type: ContentType::JSON, + } + .assert(response); +} + +#[test] +fn publish_duplicate() { + let contents = PackageBuilder::new("biff/hello@0.1.0").contents(); + let client = new_client(AuthMode::ApiKey(String::from("hello"))); + let send_request = || { + client + .post("/v1/publish") + .header(Accept::JSON) + .body(contents.data()) + .header(Header::new("Authorization", "Bearer hello")) + .dispatch() + }; + + Expectation { + status: Status::Ok, + content_type: ContentType::JSON, + } + .assert(send_request()); + + Expectation { + status: Status::Conflict, + content_type: ContentType::JSON, + } + .assert(send_request()); +} + +#[test] +fn publish_updates_git_remote() { + let remote = init_test_index_remote().unwrap(); + let repo = git2::Repository::open(remote.to_file_path().unwrap()).unwrap(); + let client = new_client_with_remote(AuthMode::ApiKey(String::from("hello")), remote); + + let commit = repo.head().unwrap().peel_to_commit().unwrap(); + assert_eq!(commit.message().unwrap(), "Initial commit"); + + let contents = PackageBuilder::new("biff/hello@0.1.0").contents(); + client + .post("/v1/publish") + .header(Accept::JSON) + .body(contents.data()) + .header(Header::new("Authorization", "Bearer hello")) + .dispatch(); + + let commit = repo.head().unwrap().peel_to_commit().unwrap(); + assert_ne!(commit.message().unwrap(), "Initial commit"); +} + +/// Ensures the package index will update when the remote is modified before a publish request +/// This is to check our update implementation as well as support for multiple api nodes +#[test] +fn publish_then_publish_elsewhere() { + let remote = init_test_index_remote().unwrap(); + let client1 = new_client_with_remote(AuthMode::ApiKey(String::from("hello")), remote.clone()); + let client2 = new_client_with_remote(AuthMode::ApiKey(String::from("hello")), remote); + + let contents = PackageBuilder::new("biff/hello@1.0.0").contents(); + let response = client1 + .post("/v1/publish") + .header(Accept::JSON) + .body(contents.data()) + .header(Header::new("Authorization", "Bearer hello")) + .dispatch(); + + Expectation { + status: Status::Ok, + content_type: ContentType::JSON, + } + .assert(response); + + let contents = PackageBuilder::new("biff/hello@1.0.1").contents(); + let response = client2 + .post("/v1/publish") + .header(Accept::JSON) + .body(contents.data()) + .header(Header::new("Authorization", "Bearer hello")) + .dispatch(); + + Expectation { + status: Status::Ok, + content_type: ContentType::JSON, + } + .assert(response); +} + +// TODO: Implement yanking +#[test] +#[ignore] +fn yank() {}