diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9ccb8a8..829427f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -35,14 +35,6 @@ jobs: --all-targets \ --no-deps \ --workspace \ - -- \ - -D warnings \ - -D rustdoc::broken_intra_doc_links \ - -W clippy::explicit_iter_loop \ - -W clippy::explicit_into_iter_loop \ - -W clippy::semicolon_if_nothing_returned \ - -W clippy::doc_markdown \ - -W clippy::manual_let_else test: name: test rust files diff --git a/.gitignore b/.gitignore index 1492cc9..16215cb 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ result # editors .idea/ .vscode/ + +# Everyone their own +tmp/ diff --git a/Cargo.lock b/Cargo.lock index 23778e5..bd358fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "adler2" @@ -8,17 +8,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" -[[package]] -name = "ahash" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" -dependencies = [ - "getrandom", - "once_cell", - "version_check", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -28,26 +17,11 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "allocator-api2" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "android-tzdata" @@ -72,9 +46,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -87,44 +61,39 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell", + "windows-sys 0.59.0", ] -[[package]] -name = "anyhow" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" - [[package]] name = "arrayvec" version = "0.7.6" @@ -152,143 +121,57 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.79", + "syn", ] [[package]] name = "bit-set" -version = "0.5.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ "bit-vec", ] [[package]] name = "bit-vec" -version = "0.6.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[package]] -name = "borsh" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" -dependencies = [ - "borsh-derive", - "cfg_aliases", -] - -[[package]] -name = "borsh-derive" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" -dependencies = [ - "once_cell", - "proc-macro-crate", - "proc-macro2", - "quote", - "syn 2.0.79", - "syn_derive", -] - -[[package]] -name = "brotli" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19483b140a7ac7174d34b5a581b406c64f84da5409d3e09cf4fff604f9270e67" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "4.0.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] -name = "byte-unit" -version = "5.1.4" +name = "bstr" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ac19bdf0b2665407c39d82dbc937e951e7e2001609f0fb32edd0af45a2d63e" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ - "rust_decimal", + "memchr", "serde", - "utf8-width", -] - -[[package]] -name = "bytecheck" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" -dependencies = [ - "bytecheck_derive", - "ptr_meta", - "simdutf8", -] - -[[package]] -name = "bytecheck_derive" -version = "0.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", ] [[package]] -name = "byteorder" -version = "1.5.0" +name = "bumpalo" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] name = "bytes" -version = "1.7.2" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "bytesize" -version = "1.3.0" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc" +checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" [[package]] name = "cast" @@ -298,9 +181,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.1.30" +version = "1.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0" dependencies = [ "shlex", ] @@ -328,16 +211,16 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "pure-rust-locales", "serde", - "windows-targets 0.52.6", + "windows-link", ] [[package]] @@ -389,9 +272,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.20" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97f376d85a664d5837dbae44bf546e6477a679ff6610010f17276f686d867e8" +checksum = "eccb054f56cbd38340b380d4a8e69ef1f02f1af43db2f0cc817a4774d80ae071" dependencies = [ "clap_builder", "clap_derive", @@ -399,9 +282,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.20" +version = "4.5.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19bc80abd44e4bed93ca373a0704ccbd1b710dc5749406201bb018272808dc54" +checksum = "efd9466fac8543255d3b1fcad4762c5e116ffe808c8a3043d4263cd4fd4862a2" dependencies = [ "anstream", "anstyle", @@ -413,42 +296,42 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.18" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.79", + "syn", ] [[package]] name = "clap_lex" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1462739cb27611015575c0c11df5df7601141071f07518d56fcc1be504cbec97" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "const_format" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.33" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" dependencies = [ "proc-macro2", "quote", @@ -508,9 +391,9 @@ dependencies = [ [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -527,9 +410,25 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crossterm" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags", + "crossterm_winapi", + "mio", + "parking_lot", + "rustix 0.38.44", + "signal-hook", + "signal-hook-mio", + "winapi", +] [[package]] name = "crossterm_winapi" @@ -542,15 +441,15 @@ dependencies = [ [[package]] name = "crunchy" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -578,9 +477,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "env_logger" @@ -597,15 +496,15 @@ 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 = "erased-serde" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e2389d65ab4fab27dc2a5de7b191e1f6617d1f1c8855c0dc569c94a4cbb18d" +checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" dependencies = [ "serde", "typeid", @@ -613,30 +512,36 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.9" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "fancy-regex" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2" +checksum = "6e24cb5a94bcae1e5408b0effca5cd7172ea3c5755049c5f3af4cd283a165298" dependencies = [ "bit-set", "regex-automata", "regex-syntax", ] +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "flate2" -version = "1.0.34" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", "miniz_oxide", @@ -644,57 +549,110 @@ dependencies = [ [[package]] name = "foldhash" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81ec6369c545a7d40e4589b5597581fa1c441fe1cce96dd1de43159910a36a2" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] -name = "funty" -version = "2.0.0" +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-macro", + "futures-task", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] [[package]] name = "getrandom" -version = "0.2.15" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", "libc", - "wasi", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] -name = "half" -version = "2.4.1" +name = "globset" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5" dependencies = [ - "cfg-if", - "crunchy", + "aho-corasick", + "bstr", + "log", + "regex-automata", + "regex-syntax", ] [[package]] -name = "hashbrown" -version = "0.12.3" +name = "half" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ - "ahash", + "cfg-if", + "crunchy", ] [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" dependencies = [ "allocator-api2", "equivalent", @@ -709,9 +667,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" +checksum = "fbd780fe5cc30f81464441920d82ac8740e2e46b29a6fad543ddd075229ce37e" [[package]] name = "hex" @@ -721,22 +679,23 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "humantime" -version = "2.1.0" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core 0.61.0", ] [[package]] @@ -748,31 +707,50 @@ dependencies = [ "cc", ] +[[package]] +name = "ignore" +version = "0.4.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + [[package]] name = "indexmap" -version = "2.6.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown", ] [[package]] name = "inventory" -version = "0.3.15" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" +checksum = "ab08d7cd2c5897f2c949e5383ea7c7db03fb19130ffcfbf7eda795137ae3cb83" +dependencies = [ + "rustversion", +] [[package]] name = "is-terminal" -version = "0.4.13" +version = "0.4.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "261f68e344040fbd0edea105bef17c66edf46f984ddb1115b775ce31be948f4b" +checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -783,9 +761,9 @@ checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" [[package]] name = "is_debug" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06d198e9919d9822d5f7083ba8530e04de87841eaf21ead9af8f2304efd57c89" +checksum = "1fe266d2e243c931d8190177f20bf7f24eed45e96f39e87dc49a27b32d12d407" [[package]] name = "is_terminal_polyfill" @@ -813,36 +791,31 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - [[package]] name = "libc" -version = "0.2.159" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -871,15 +844,31 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "lock_api" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] [[package]] name = "log" -version = "0.4.22" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "lru" @@ -887,7 +876,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.0", + "hashbrown", ] [[package]] @@ -916,9 +905,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miette" -version = "7.2.0" +version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4edc8853320c2a0dab800fbda86253c8938f6ea88510dc92c5f1ed20e794afc1" +checksum = "5f98efec8807c63c752b5bd61f862c165c115b0a35685bdcfd9238c7aeb592b7" dependencies = [ "cfg-if", "miette-derive", @@ -928,19 +917,18 @@ dependencies = [ "supports-unicode", "terminal_size", "textwrap", - "thiserror", "unicode-width 0.1.14", ] [[package]] name = "miette-derive" -version = "7.2.0" +version = "7.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf09caffaac8068c346b6df2a7fc27a177fd20b39421a39ce0a211bde679a6c" +checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn", ] [[package]] @@ -951,13 +939,25 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.0" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", ] +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + [[package]] name = "nix" version = "0.29.0" @@ -1000,9 +1000,9 @@ dependencies = [ [[package]] name = "nu-cmd-lang" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27055f050baefe46ec1ee7311c0cba27ec8700e18c6ab00f68a745f957da9f3f" +checksum = "e66adfeda88f8e27bcb25d068d9e6e8b3a94c2bf988a9c30e8e3b2045867aefe" dependencies = [ "itertools 0.13.0", "nu-engine", @@ -1014,42 +1014,41 @@ dependencies = [ [[package]] name = "nu-derive-value" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733a3c36228f10968e82d5aacfc0269b050b5fdf359d1b9f34f3b3464f954f18" +checksum = "5fd0d8e358b6440d01fe4e617f180aea826bade72efb54f5dc1c22e0e8038b6f" dependencies = [ "heck", - "proc-macro-error", + "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.79", + "syn", ] [[package]] name = "nu-engine" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebb70da462cbfe52635826d2c3e73c9d381e181f39e3e19887b57252bd92d7b1" +checksum = "0c2b01483e3d09460375f0c0da7a83b6dc26fb319ca09c55d0665087b2d587c7" dependencies = [ "log", "nu-glob", "nu-path", "nu-protocol", "nu-utils", - "terminal_size", ] [[package]] name = "nu-glob" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfe8f781a5bbc1d81c6ae9deb4406042c044f6e3d7157f6132a4d7802689f1c" +checksum = "202ce25889336061efea24e69d4e0de7147c15fd9892cdd70533500d47db8364" [[package]] name = "nu-parser" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd6b22646adbb8fff8949935ce86240a149f28d7f094d23f981145b404e25e94" +checksum = "cb0591ef4d4989c1930863d9d17d8fd2d70b03ec2d9caeca067e9626e05c49d9" dependencies = [ "bytesize", "chrono", @@ -1058,28 +1057,28 @@ dependencies = [ "nu-engine", "nu-path", "nu-protocol", + "nu-utils", "serde_json", ] [[package]] name = "nu-path" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a94dd32424ad75d665ad40add544dd3c35e66cbd147db18a6c0c7ac31ad48a6d" +checksum = "41c68c7c06898a5c4c9f10038da63759661cb8ac8f301ce7d159173a595c8258" dependencies = [ "dirs", "omnipath", "pwd", + "ref-cast", ] [[package]] name = "nu-protocol" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d113bafbe48178fdddaace7a2e783be73d66a71c2b732dd052c195eb8780e24" +checksum = "ab657b1947f1fad3c5052cb210fa311744736a4800a966ae21c4bc63de7c60ab" dependencies = [ - "brotli", - "byte-unit", "bytes", "chrono", "chrono-humanize", @@ -1090,26 +1089,31 @@ dependencies = [ "indexmap", "log", "lru", + "memchr", "miette", "nix", "nu-derive-value", + "nu-glob", "nu-path", "nu-system", "nu-utils", "num-format", "os_pipe", - "rmp-serde", "serde", - "thiserror", + "serde_json", + "strum", + "strum_macros", + "thiserror 2.0.12", "typetag", + "web-time", "windows-sys 0.48.0", ] [[package]] name = "nu-system" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbcabdb319f6126b1662181fdd4f30ddb1750e5a47378e1f757ac9cb3167eca3" +checksum = "f47094aaab4f1e3a86c3960400d82a50fcabde907f964ae095963ec95669577a" dependencies = [ "chrono", "itertools 0.13.0", @@ -1119,24 +1123,27 @@ dependencies = [ "mach2", "nix", "ntapi", - "once_cell", "procfs", "sysinfo", - "windows 0.54.0", + "web-time", + "windows 0.56.0", ] [[package]] name = "nu-utils" -version = "0.99.0" +version = "0.104.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e0dfcc946f4ee4d158d1db7bfa2a8aec2a35dba97af63bfbc3e61e771893797" +checksum = "327999b774d78b301a6b68c33d312a1a8047c59fb8971b6552ebf823251f1481" dependencies = [ + "crossterm", "crossterm_winapi", + "fancy-regex", "log", "lscolors", "nix", "num-format", "serde", + "serde_json", "strip-ansi-escapes", "sys-locale", "unicase", @@ -1146,14 +1153,20 @@ dependencies = [ name = "nufmt" version = "0.1.0" dependencies = [ - "anyhow", "clap", "criterion", "env_logger", + "ignore", "log", + "nu-ansi-term", "nu-cmd-lang", "nu-parser", "nu-protocol", + "nuon", + "rayon", + "rstest", + "tempfile", + "thiserror 2.0.12", ] [[package]] @@ -1190,6 +1203,18 @@ dependencies = [ "libc", ] +[[package]] +name = "nuon" +version = "0.104.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ad155fee37ed58420483d38c40cd9bea88160e281e1d04c1592525c8f8da9a5" +dependencies = [ + "nu-engine", + "nu-parser", + "nu-protocol", + "nu-utils", +] + [[package]] name = "omnipath" version = "0.1.6" @@ -1198,15 +1223,15 @@ checksum = "80adb31078122c880307e9cdfd4e3361e6545c319f9b9dcafcb03acd3b51a575" [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "oorandom" -version = "11.1.4" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "option-ext" @@ -1226,15 +1251,44 @@ dependencies = [ [[package]] name = "owo-colors" -version = "4.1.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" +checksum = "1036865bb9422d3300cf723f657c2851d0e9ab12567854b1f4eba3d77decf564" [[package]] -name = "paste" -version = "1.0.15" +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "plotters" @@ -1270,102 +1324,71 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - [[package]] name = "proc-macro-crate" -version = "3.2.0" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ "toml_edit", ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ - "proc-macro-error-attr", "proc-macro2", "quote", - "version_check", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "proc-macro-error2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ + "proc-macro-error-attr2", "proc-macro2", "quote", - "version_check", + "syn", ] [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "procfs" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "731e0d9356b0c25f16f33b5be79b1c57b562f141ebfcdb0ad8ac2c13a24293b4" +checksum = "cc5b72d8145275d844d4b5f6d4e1eef00c8cd889edb6035c21675d1bb1f45c9f" dependencies = [ "bitflags", "chrono", "flate2", "hex", - "lazy_static", "procfs-core", - "rustix", + "rustix 0.38.44", ] [[package]] name = "procfs-core" -version = "0.16.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3554923a69f4ce04c4a754260c338f505ce22642d3830e049a399fc2059a29" +checksum = "239df02d8349b06fc07398a3a1697b06418223b1c7725085e801e7c0fc6a12ec" dependencies = [ "bitflags", "chrono", "hex", ] -[[package]] -name = "ptr_meta" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "pure-rust-locales" version = "0.8.1" @@ -1379,90 +1402,89 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c71c0c79b9701efe4e1e4b563b2016dd4ee789eb99badcb09d61ac4b92e4a2" dependencies = [ "libc", - "thiserror", + "thiserror 1.0.69", ] [[package]] name = "quote" -version = "1.0.37" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] -name = "radium" -version = "0.7.0" +name = "r-efi" +version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" [[package]] -name = "rand" -version = "0.8.5" +name = "rayon" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ - "libc", - "rand_chacha", - "rand_core", + "either", + "rayon-core", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "rayon-core" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "ppv-lite86", - "rand_core", + "crossbeam-deque", + "crossbeam-utils", ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "redox_syscall" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "d2f103c6d277498fbceb16e84d317e2a400f160f46904d5f5410848c829511a3" dependencies = [ - "getrandom", + "bitflags", ] [[package]] -name = "rayon" -version = "1.10.0" +name = "redox_users" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "either", - "rayon-core", + "getrandom 0.2.16", + "libredox", + "thiserror 1.0.69", ] [[package]] -name = "rayon-core" -version = "1.12.1" +name = "ref-cast" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" dependencies = [ - "crossbeam-deque", - "crossbeam-utils", + "ref-cast-impl", ] [[package]] -name = "redox_users" -version = "0.4.6" +name = "ref-cast-impl" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" dependencies = [ - "getrandom", - "libredox", - "thiserror", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1472,9 +1494,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1488,105 +1510,93 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] -name = "rend" -version = "0.4.2" +name = "relative-path" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" -dependencies = [ - "bytecheck", -] +checksum = "ba39f3699c378cd8970968dcbff9c43159ea4cfbd88d43c00b22f2ef10a435d2" [[package]] -name = "rkyv" -version = "0.7.45" +name = "rstest" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +checksum = "6fc39292f8613e913f7df8fa892b8944ceb47c247b78e1b1ae2f09e019be789d" dependencies = [ - "bitvec", - "bytecheck", - "bytes", - "hashbrown 0.12.3", - "ptr_meta", - "rend", - "rkyv_derive", - "seahash", - "tinyvec", - "uuid", + "futures-timer", + "futures-util", + "rstest_macros", + "rustc_version", ] [[package]] -name = "rkyv_derive" -version = "0.7.45" +name = "rstest_macros" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +checksum = "1f168d99749d307be9de54d23fd226628d99768225ef08f6ffb52e0182a27746" dependencies = [ + "cfg-if", + "glob", + "proc-macro-crate", "proc-macro2", "quote", - "syn 1.0.109", + "regex", + "relative-path", + "rustc_version", + "syn", + "unicode-ident", ] [[package]] -name = "rmp" -version = "0.8.14" +name = "rustc-hash" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" -dependencies = [ - "byteorder", - "num-traits", - "paste", -] +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] -name = "rmp-serde" -version = "1.3.0" +name = "rustc_version" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "byteorder", - "rmp", - "serde", + "semver", ] [[package]] -name = "rust_decimal" -version = "1.36.0" +name = "rustix" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "arrayvec", - "borsh", - "bytes", - "num-traits", - "rand", - "rkyv", - "serde", - "serde_json", + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", ] -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustix" -version = "0.38.37" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys", - "windows-sys 0.52.0", + "linux-raw-sys 0.9.4", + "windows-sys 0.59.0", ] +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -1598,36 +1608,42 @@ dependencies = [ ] [[package]] -name = "seahash" -version = "4.1.0" +name = "scopeguard" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn", ] [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -1637,13 +1653,14 @@ dependencies = [ [[package]] name = "shadow-rs" -version = "0.35.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2311e39772c00391875f40e34d43efef247b23930143a70ca5fbec9505937420" +checksum = "6d5625ed609cf66d7e505e7d487aca815626dc4ebb6c0dd07637ca61a44651a6" dependencies = [ "const_format", "is_debug", "time", + "tzdb", ] [[package]] @@ -1653,22 +1670,55 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] -name = "simdutf8" -version = "0.1.5" +name = "signal-hook" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] [[package]] -name = "smawk" -version = "0.3.2" +name = "signal-hook-mio" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "strip-ansi-escapes" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ff8ef943b384c414f54aefa961dd2bd853add74ec75e7ac74cf91dba62bcfa" +checksum = "2a8f8038e7e7969abb3f1b7c2a811225e9296da208539e0f79c5251d6cac0025" dependencies = [ "vte", ] @@ -1679,20 +1729,39 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + [[package]] name = "supports-color" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8775305acf21c96926c900ad056abeef436701108518cf890020387236ac5a77" +checksum = "c64fc7232dd8d2e4ac5ce4ef302b1d81e0b80d055b9d77c7c4f51f6aa4c867d6" dependencies = [ "is_ci", ] [[package]] name = "supports-hyperlinks" -version = "3.0.0" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c0a1e5168041f5f3ff68ff7d95dcb9c8749df29f6e7e89ada40dd4c9de404ee" +checksum = "804f44ed3c63152de6a9f90acbea1a110441de43006ea51bcce8f436196a288b" [[package]] name = "supports-unicode" @@ -1702,67 +1771,50 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.79" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] -[[package]] -name = "syn_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" -dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.79", -] - [[package]] name = "sys-locale" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e801cf239ecd6ccd71f03d270d67dd53d13e90aab208bf4b8fe4ad957ea949b0" +checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4" dependencies = [ "libc", ] [[package]] name = "sysinfo" -version = "0.30.13" +version = "0.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a5b4ddaee55fb2bea2bf0e5000747e5f5c0de765e5a5ff87f4cd106439f4bb3" +checksum = "4fc858248ea01b66f19d8e8a6d55f41deaf91e9d495246fd01368d99935c6c01" dependencies = [ - "cfg-if", "core-foundation-sys", "libc", + "memchr", "ntapi", - "once_cell", "rayon", - "windows 0.52.0", + "windows 0.57.0", ] [[package]] -name = "tap" -version = "1.0.1" +name = "tempfile" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" +dependencies = [ + "fastrand", + "getrandom 0.3.2", + "once_cell", + "rustix 1.0.7", + "windows-sys 0.59.0", +] [[package]] name = "termcolor" @@ -1775,50 +1827,69 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.3.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +checksum = "45c6481c4829e4cc63825e62c49186a34538b7b2750b73b266581ffb612fb5ed" dependencies = [ - "rustix", - "windows-sys 0.48.0", + "rustix 1.0.7", + "windows-sys 0.59.0", ] [[package]] name = "textwrap" -version = "0.16.1" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" dependencies = [ - "smawk", "unicode-linebreak", - "unicode-width 0.1.14", + "unicode-width 0.2.0", ] [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] name = "time" -version = "0.3.36" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -1833,15 +1904,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -1857,32 +1928,17 @@ dependencies = [ "serde_json", ] -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "toml_datetime" -version = "0.6.8" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" [[package]] name = "toml_edit" -version = "0.22.22" +version = "0.22.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" dependencies = [ "indexmap", "toml_datetime", @@ -1891,15 +1947,15 @@ dependencies = [ [[package]] name = "typeid" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e13db2e0ccd5e14a544e8a246ba2312cd25223f616442d7f2cb0e3db614236e" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typetag" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba3b6e86ffe0054b2c44f2d86407388b933b16cb0a70eea3929420db1d9bbe" +checksum = "73f22b40dd7bfe8c14230cf9702081366421890435b2d625fa92b4acc4c3de6f" dependencies = [ "erased-serde", "inventory", @@ -1910,29 +1966,52 @@ dependencies = [ [[package]] name = "typetag-impl" -version = "0.2.18" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70b20a22c42c8f1cd23ce5e34f165d4d37038f5b663ad20fb6adbdf029172483" +checksum = "35f5380909ffc31b4de4f4bdf96b877175a016aa2ca98cee39fcfd8c4d53d952" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn", ] [[package]] -name = "unicase" -version = "2.7.0" +name = "tz-rs" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +checksum = "e1450bf2b99397e72070e7935c89facaa80092ac812502200375f1f7d33c71a1" + +[[package]] +name = "tzdb" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0be2ea5956f295449f47c0b825c5e109022ff1a6a53bb4f77682a87c2341fbf5" +dependencies = [ + "iana-time-zone", + "tz-rs", + "tzdb_data", +] + +[[package]] +name = "tzdb_data" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c4c81d75033770e40fbd3643ce7472a1a9fd301f90b7139038228daf8af03ec" dependencies = [ - "version_check", + "tz-rs", ] +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + [[package]] name = "unicode-ident" -version = "1.0.13" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-linebreak" @@ -1958,48 +2037,19 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" -[[package]] -name = "utf8-width" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" - [[package]] name = "utf8parse" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" -[[package]] -name = "uuid" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "vte" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197" -dependencies = [ - "utf8parse", - "vte_generate_state_changes", -] - -[[package]] -name = "vte_generate_state_changes" -version = "0.1.2" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" +checksum = "231fdcd7ef3037e8330d8e17e61011a2c244126acc0a982f4040ac3f9f0bc077" dependencies = [ - "proc-macro2", - "quote", + "memchr", ] [[package]] @@ -2018,37 +2068,46 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.79", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2056,28 +2115,41 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.79", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.95" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" -version = "0.3.72" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -2116,43 +2188,133 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.52.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" dependencies = [ - "windows-core 0.52.0", + "windows-core 0.56.0", "windows-targets 0.52.6", ] [[package]] name = "windows" -version = "0.54.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9252e5725dbed82865af151df558e754e4a3c2c30818359eb17465f1346a1b49" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" dependencies = [ - "windows-core 0.54.0", + "windows-core 0.57.0", "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.52.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" dependencies = [ + "windows-implement 0.56.0", + "windows-interface 0.56.0", + "windows-result 0.1.2", "windows-targets 0.52.6", ] [[package]] name = "windows-core" -version = "0.54.0" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12661b9c89351d684a50a8a643ce5f608e20243b9fb84687800163429f161d65" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" dependencies = [ - "windows-result", + "windows-implement 0.57.0", + "windows-interface 0.57.0", + "windows-result 0.1.2", "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.61.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +dependencies = [ + "windows-implement 0.60.0", + "windows-interface 0.59.1", + "windows-link", + "windows-result 0.3.2", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.56.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" + [[package]] name = "windows-result" version = "0.1.2" @@ -2162,6 +2324,24 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-result" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -2312,39 +2492,18 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.20" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3" dependencies = [ "memchr", ] [[package]] -name = "wyz" -version = "0.5.1" +name = "wit-bindgen-rt" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "tap", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.79", + "bitflags", ] diff --git a/Cargo.toml b/Cargo.toml index f9ea128..0d13171 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,16 +14,22 @@ categories = ["command-line-utilities"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0.71" clap = { version = "4.3.0", optional = true, features = ["unicode", "derive"] } env_logger = "0.10.0" +ignore = "0.4" log = "0.4.17" -nu-cmd-lang = "0.99.0" -nu-parser = "0.99.0" -nu-protocol = "0.99.0" +nu-ansi-term = "0.50.1" +nu-cmd-lang = "0.104.0" +nu-parser = "0.104.0" +nu-protocol = "0.104.0" +nuon = "0.104.0" +rayon = "1.10" +thiserror = "2" [dev-dependencies] criterion = "0.5.1" +rstest = "0.25" +tempfile = "3" [features] default = ["bin"] diff --git a/README.md b/README.md index 488b0cc..e8a3a79 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ [discord-url]: https://discord.gg/NtAbbGn [ci-badge]: https://github.com/nushell/nufmt/actions/workflows/main.yml/badge.svg [ci-url]: https://github.com/nushell/nufmt/actions/workflows/main.yml -[nushell-badge]: https://img.shields.io/badge/nushell-v0.103.0-green +[nushell-badge]: https://img.shields.io/badge/nushell-v0.104.0-green [nushell-url]: https://crates.io/crates/nu @@ -60,6 +60,7 @@ nufmt my-file1.nu my-file2.nu my-file3.nu ### Options +- `--dry-run` if you just want to check files without formatting them. It cannot be combined with stdin. - `-s` or `--stdin` formats from `stdin`, returns to `stdout` as a String. It cannot be used combined with `files`. - `-c` or `--config` pass the config file path. Sample: @@ -73,10 +74,17 @@ nufmt my-file1.nu my-file2.nu my-file3.nu ```text nufmt --stdin --config my-stdin-config.json ``` - - `-h` or `--help` show help and exit - `-v` or `--version` prints the version and exit +### Exit codes + +``nufmt`` exits with the following status codes: +- **0**: if ``nufmt`` terminates successfully, regardless of whether files or stdin were formatted. +- **1** (only used in check mode): ``nufmt`` terminates successfully and at least one file would be formatted if check mode was off. +- **2**: ``nufmt`` terminates abnormally due to invalid configuration, invalid CLI options, or an internal error. + + ## Contributing We have a [contribution guide](docs/CONTRIBUTING.md). If you still have doubts, you can mention @`AucaCoyan` who is active on this repo. diff --git a/benches/file-format-bench.rs b/benches/file-format-bench.rs index c2e7765..6751bda 100644 --- a/benches/file-format-bench.rs +++ b/benches/file-format-bench.rs @@ -1,10 +1,16 @@ use criterion::{criterion_group, criterion_main, Criterion}; -use nu_formatter::{config::Config, format_single_file}; +use nu_formatter::{config::Config, format_single_file, Mode}; use std::path::PathBuf; fn criterion_benchmark(c: &mut Criterion) { c.bench_function("Format massive nu", |b| { - b.iter(|| format_single_file(&PathBuf::from("./benches/example.nu"), &Config::default())); + b.iter(|| { + format_single_file( + PathBuf::from("./benches/example.nu"), + &Config::default(), + &Mode::Normal, + ) + }); }); } diff --git a/scripts/update-nushell-version b/scripts/update-nushell-version index 11dc8c2..acf3d19 100755 --- a/scripts/update-nushell-version +++ b/scripts/update-nushell-version @@ -10,10 +10,14 @@ def main [ | str replace 'https://img.shields.io/badge/nushell-v\d+\.\d+\.\d+-green' $"https://img.shields.io/badge/nushell-v($version)-green" | save --force README.md + log info "updating the `nu-cmd-lang` dependency" + cargo add $"nu-cmd-lang@($version)" log info "updating the `nu-parser` dependency" cargo add $"nu-parser@($version)" log info "updating the `nu-protocol` dependency" cargo add $"nu-protocol@($version)" + log info "updating the `nuon` dependency" + cargo add $"nuon@($version)" log warning "do not forget to commit and push this :wink:" } diff --git a/src/config.rs b/src/config.rs index 09c311e..b4cb598 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,18 +1,25 @@ //! Keeps all the options, tweaks and dials of the configuration. -#[derive(Debug)] +use std::convert::TryFrom; + +use crate::config_error::ConfigError; +use nu_protocol::Value; + +#[derive(Debug, Clone, PartialEq, Eq)] pub struct Config { - pub tab_spaces: usize, - pub max_width: usize, + pub indent: usize, + pub line_length: usize, pub margin: usize, + pub excludes: Vec, } impl Default for Config { fn default() -> Self { Config { - tab_spaces: 4, - max_width: 80, + indent: 4, + line_length: 80, margin: 1, + excludes: vec![], } } } @@ -20,9 +27,96 @@ impl Default for Config { impl Config { pub fn new(tab_spaces: usize, max_width: usize, margin: usize) -> Self { Config { - tab_spaces, - max_width, + indent: tab_spaces, + line_length: max_width, margin, + excludes: vec![], + } + } +} + +impl TryFrom for Config { + type Error = ConfigError; + + fn try_from(value: Value) -> Result { + let mut config = Config::default(); + match value { + Value::Nothing { .. } => (), + Value::Record { val: record, .. } => { + for (key, value) in record.iter() { + match key.as_str() { + "indent" => { + let indent = parse_value_to_usize(key, value)?; + config.indent = indent; + } + "line_length" => { + let line_length = parse_value_to_usize(key, value)?; + config.line_length = line_length; + } + "margin" => { + let margin = parse_value_to_usize(key, value)?; + config.margin = margin; + } + "exclude" => { + let excludes = parse_excludes(value)?; + config.excludes = excludes; + } + unknown => return Err(ConfigError::UnknownOption(unknown.to_string())), + } + } + } + _ => { + return Err(ConfigError::InvalidFormat); + } + }; + Ok(config) + } +} + +fn parse_value_to_usize(key: &str, value: &Value) -> Result { + match value { + Value::Int { val, .. } => { + if *val <= 0 { + return Err(ConfigError::InvalidOptionValue( + key.to_string(), + format!("{}", val), + "a positive number", + )); + } + Ok(*val as usize) + } + other => Err(ConfigError::InvalidOptionType( + key.to_string(), + other.get_type().to_string(), + "number", + )), + } +} + +fn parse_excludes(value: &Value) -> Result, ConfigError> { + match value { + Value::List { vals, .. } => { + let mut excludes = vec![]; + for val in vals { + match val { + Value::String { val, .. } => { + excludes.push(val.clone()); + } + other => { + return Err(ConfigError::InvalidOptionType( + "excludes".to_string(), + other.get_type().to_string(), + "list", + )); + } + } + } + Ok(excludes) } + other => Err(ConfigError::InvalidOptionType( + "excludes".to_string(), + other.get_type().to_string(), + "list", + )), } } diff --git a/src/config_error.rs b/src/config_error.rs new file mode 100644 index 0000000..8b0d5e6 --- /dev/null +++ b/src/config_error.rs @@ -0,0 +1,35 @@ +use thiserror::Error; + +#[derive(Clone, Debug, Error, PartialEq, Eq)] +pub enum ConfigError { + #[error("Failed read the configuration file: {0}")] + IOError(String), + #[error("The configuration is not a valid nuon record")] + InvalidFormat, + #[error("Found unknown configuration option: {0}")] + UnknownOption(String), + #[error("Found invalid type for option '{0}': got {1}, expected {2}")] + InvalidOptionType(String, String, &'static str), + #[error("Found invalid value for option '{0}': got {1}, expected {2}")] + InvalidOptionValue(String, String, &'static str), + #[error("Found an invalid exclude pattern")] + InvalidExcludePattern, +} + +impl From for ConfigError { + fn from(value: std::io::Error) -> Self { + ConfigError::IOError(value.to_string()) + } +} + +impl From for ConfigError { + fn from(_value: nu_protocol::ShellError) -> Self { + ConfigError::InvalidFormat + } +} + +impl From for ConfigError { + fn from(_value: ignore::Error) -> Self { + ConfigError::InvalidExcludePattern + } +} diff --git a/src/format_error.rs b/src/format_error.rs new file mode 100644 index 0000000..1c28bf9 --- /dev/null +++ b/src/format_error.rs @@ -0,0 +1,7 @@ +use thiserror::Error; + +#[derive(Clone, Debug, Error, PartialEq, Eq)] +pub enum FormatError { + #[error("found invalid Nushell syntax")] + GarbageFound, +} diff --git a/src/formatting.rs b/src/formatting.rs index 52298d4..84397d2 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -2,7 +2,8 @@ //! //! It has functions to format slice of bytes and some help functions to separate concerns while doing the job. use crate::config::Config; -use log::{error, info, trace}; +use crate::format_error::FormatError; +use log::{debug, trace}; use nu_parser::{flatten_block, parse, FlatShape}; use nu_protocol::{ ast::Block, @@ -32,7 +33,7 @@ fn get_engine_state() -> EngineState { /// format an array of bytes /// /// Reading the file gives you a list of bytes -pub(crate) fn format_inner(contents: &[u8], _config: &Config) -> Vec { +pub(crate) fn format_inner(contents: &[u8], _config: &Config) -> Result, FormatError> { let engine_state = get_engine_state(); let decls_sorted: Vec<(Vec, nu_protocol::Id)> = engine_state.get_decls_sorted(false); @@ -44,8 +45,8 @@ pub(crate) fn format_inner(contents: &[u8], _config: &Config) -> Vec { if !block_has_pipelines(&parsed_block) { trace!("block has no pipelines!"); - info!("File has no code to format."); - return contents.to_vec(); + debug!("File has no code to format."); + return Ok(contents.to_vec()); } let flat = flatten_block(&working_set, &parsed_block); @@ -122,9 +123,8 @@ pub(crate) fn format_inner(contents: &[u8], _config: &Config) -> Vec { out.extend(b" "); } FlatShape::Garbage => { - error!("found garbage 😢 {content}"); - out.extend(bytes); - out = insert_newline(out); + debug!("found garbage 😢 {content}"); + return Err(FormatError::GarbageFound); } _ => out.extend(bytes), @@ -147,7 +147,7 @@ pub(crate) fn format_inner(contents: &[u8], _config: &Config) -> Vec { start = span.end + 1; } - out + Ok(out) } /// insert a newline at the end of a buffer diff --git a/src/lib.rs b/src/lib.rs index 8d5649e..5f4353f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,39 +2,89 @@ //! //! It does not do anything more than that, which makes it so fast. use config::Config; +use format_error::FormatError; use formatting::{add_newline_at_end_of_file, format_inner}; -use log::{debug, trace}; +use log::debug; use std::fs::File; use std::io::Write; use std::path::PathBuf; pub mod config; +pub mod config_error; +pub mod format_error; mod formatting; -/// format a Nushell file inplace -pub fn format_single_file(file: &PathBuf, config: &Config) { - let contents = std::fs::read(file) - .unwrap_or_else(|_| panic!("something went wrong reading the file {}", file.display())); +/// Possible modes the formatter can run on +#[derive(Debug, Clone, Default, PartialEq, Eq)] +pub enum Mode { + #[default] + Normal, + DryRun, +} + +/// The possible outcome of formatting a file +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum FileDiagnostic { + /// File was left unchanged, as it is already correctly formatted + AlreadyFormatted, + /// File was formatted successfully + Reformatted, + /// An error occurred while trying to access or write to the file + Failure(String), +} - let formatted_bytes = add_newline_at_end_of_file(format_inner(&contents, config)); +/// format a Nushell file in place. Do not write in dry-run mode. +pub fn format_single_file( + file: PathBuf, + config: &Config, + mode: &Mode, +) -> (PathBuf, FileDiagnostic) { + let contents = match std::fs::read(&file) { + Ok(content) => content, + Err(err) => { + return (file, FileDiagnostic::Failure(err.to_string())); + } + }; + + let formatted_bytes = add_newline_at_end_of_file(match format_inner(&contents, config) { + Ok(bytes) => bytes, + Err(err) => { + return (file, FileDiagnostic::Failure(err.to_string())); + } + }); if formatted_bytes == contents { debug!("File is already formatted correctly."); + return (file, FileDiagnostic::AlreadyFormatted); } - let mut writer = File::create(file).unwrap(); - let file_bytes = formatted_bytes.as_slice(); - writer - .write_all(file_bytes) - .expect("something went wrong writing"); - trace!("written"); + match mode { + Mode::DryRun => { + debug!("File not formatted because running in dry run, but would be reformatted in normal mode."); + } + Mode::Normal => { + let mut writer = match File::create(&file) { + Ok(file) => file, + Err(err) => { + return (file, FileDiagnostic::Failure(err.to_string())); + } + }; + let file_bytes = formatted_bytes.as_slice(); + if let Err(err) = writer.write_all(file_bytes) { + return (file, FileDiagnostic::Failure(err.to_string())); + } + debug!("File formatted."); + } + }; + (file, FileDiagnostic::Reformatted) } /// format a string of Nushell code -pub fn format_string(input_string: &String, config: &Config) -> String { +pub fn format_string(input_string: &String, config: &Config) -> Result { let contents = input_string.as_bytes(); - let formatted_bytes = format_inner(contents, config); - String::from_utf8(formatted_bytes).unwrap() + let formatted_bytes = format_inner(contents, config)?; + Ok(String::from_utf8(formatted_bytes) + .expect("Formatted string could not be converted to a UTF-8 string")) } #[cfg(test)] @@ -45,10 +95,13 @@ mod test { /// 1. formatting the input gives the expected result /// 2. formatting the output of `nufmt` a second time does not change the content fn run_test(input: &str, expected: &str) { - let formatted = format_string(&input.to_string(), &Config::default()); + let formatted = format_string(&input.to_string(), &Config::default()).unwrap(); assert_eq!(expected.to_string(), formatted); - assert_eq!(formatted, format_string(&formatted, &Config::default())); + assert_eq!( + formatted, + format_string(&formatted, &Config::default()).unwrap() + ); } #[test] diff --git a/src/main.rs b/src/main.rs index a3de0f2..1ca5488 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,46 +1,87 @@ #![doc = include_str!("../README.md")] +#![deny(warnings, rustdoc::broken_intra_doc_links)] +#![warn( + clippy::explicit_iter_loop, + clippy::explicit_into_iter_loop, + clippy::semicolon_if_nothing_returned, + clippy::doc_markdown, + clippy::manual_let_else +)] use clap::Parser; -use log::{error, info, trace}; +use ignore::{overrides::OverrideBuilder, DirEntry, WalkBuilder}; +use log::{info, trace}; +use nu_ansi_term::{Color, Style}; use nu_formatter::config::Config; +use nu_formatter::config_error::ConfigError; +use nu_formatter::FileDiagnostic; +use nu_formatter::Mode; +use rayon::iter::{IntoParallelIterator, ParallelIterator}; +use std::convert::TryFrom; use std::{ - fs, io::{self, Write}, path::{Path, PathBuf}, }; +const DEFAULT_CONFIG_FILE: &str = "nufmt.nuon"; + +/// The possible exit codes +#[derive(Debug, Clone, PartialEq, Eq)] enum ExitCode { + /// nufmt terminates successfully, regardless of whether files or stdin were formatted. Success, + /// only used in check mode: nufmt terminates successfully and at least one file would be formatted if check mode was off. + CheckFailed, + /// nufmt terminates abnormally due to invalid configuration, invalid CLI options, or an internal error. Failure, } +impl ExitCode { + /// Return the exit code to use. + /// If check mode is off: return 2 if at least one file could not be formatted, 0 otherwise (regardless of whether any files were formatted). + /// If check mode is on: return 1 if some files would be formatted if check mode was off, 0 otherwise. + fn code(&self) -> i32 { + match self { + ExitCode::Success => 0, + ExitCode::CheckFailed => 1, + ExitCode::Failure => 2, + } + } +} + /// the CLI signature of the `nufmt` executable. #[derive(Parser)] #[command(author, version, about)] struct Cli { #[arg( - required_unless_present("stdin"), - help = "one of more Nushell files you want to format" + value_name = "FILES", + default_value = ".", + conflicts_with("stdin"), + help = "One of more Nushell files or directories to format" )] files: Vec, #[arg( - short, long, + conflicts_with = "stdin", + help = "Avoid writing any formatted files back; instead, exit with a non-zero status code if any files would have been modified, and zero otherwise" + )] + dry_run: bool, + + #[arg( + long, + conflicts_with = "dry_run", conflicts_with = "files", - help = "a string of Nushell directly given to the formatter" + help = "A string of Nushell directly given to the formatter" )] stdin: bool, - #[arg(short, long, help = "the configuration file")] + #[arg(short, long, help = "nufmt configuration file")] config: Option, } fn exit_with_code(exit_code: ExitCode) { - let code = match exit_code { - ExitCode::Success => 0, - ExitCode::Failure => 1, - }; + let code = exit_code.code(); trace!("exit code: {code}"); // NOTE: this immediately terminates the process without doing any cleanup, @@ -56,95 +97,335 @@ fn main() { trace!("recieved cli.stdin: {:?}", cli.stdin); trace!("recieved cli.config: {:?}", cli.config); - let cli_config = match cli.config { + let config_file = cli.config.or(find_in_parent_dirs(DEFAULT_CONFIG_FILE)); + let config = match config_file { None => Config::default(), - Some(input_cli) => { - todo!( - "cannot read from {:?} Reading a config from file not implemented!", - input_cli - ) - } + Some(cli_config) => match read_config(&cli_config) { + Ok(config) => config, + Err(err) => { + eprintln!("{}: {}", Color::LightRed.paint("error"), &err); + return exit_with_code(ExitCode::Failure); + } + }, }; - let exit_code = match cli.files[..] { - [] if cli.stdin => { - let stdin_input = io::stdin().lines().map(|x| x.unwrap()).collect(); - format_string(Some(stdin_input), &cli_config) - } - _ => format_files(cli.files, &cli_config), + let exit_code = if cli.stdin { + let stdin_input = io::stdin().lines().map(|x| x.unwrap()).collect(); + format_string(stdin_input, &config) + } else { + let (target_files, invalid_files) = match discover_nu_files(cli.files, &config.excludes) { + Ok(files) => files, + Err(err) => { + eprintln!("{}: {}", Color::LightRed.paint("error"), err); + return exit_with_code(ExitCode::Failure); + } + }; + let mode = if cli.dry_run { + Mode::DryRun + } else { + Mode::default() + }; + let mut results = handle_invalid_file(invalid_files); + results.extend(format_files(target_files, &config, &mode)); + display_diagnostic_and_compute_exit_code(&results, cli.dry_run) }; - std::io::stdout().flush().unwrap(); + std::io::stdout() + .flush() + .expect("Unexpected error occurred when flushing stdout"); exit_with_code(exit_code); } +fn read_config(path: &PathBuf) -> Result { + let content = std::fs::read_to_string(path)?; + let content_nuon = nuon::from_nuon(&content, None)?; + Config::try_from(content_nuon) +} + /// format a string passed via stdin and output it directly to stdout -fn format_string(string: Option, options: &Config) -> ExitCode { - let output = nu_formatter::format_string(&string.unwrap(), options); - println!("{output}"); +fn format_string(string: String, options: &Config) -> ExitCode { + match nu_formatter::format_string(&string, options) { + Ok(output) => { + println!("{output}"); + ExitCode::Success + } + Err(err) => { + eprintln!( + "{}: {}", + Color::LightRed.paint("Could not format stdin"), + err + ); + ExitCode::Failure + } + } +} - ExitCode::Success +fn handle_invalid_file(files: Vec) -> Vec<(PathBuf, FileDiagnostic)> { + let mut results: Vec<(PathBuf, FileDiagnostic)> = vec![]; + for file in files { + results.push(( + file, + FileDiagnostic::Failure("cannot find the file specified".to_string()), + )); + } + results } -/// format a list of files, possibly one, and modify them inplace -fn format_files(files: Vec, options: &Config) -> ExitCode { - for file in &files { - if !file.exists() { - error!("Error: {} not found!", file.to_str().unwrap()); - return ExitCode::Failure; - } else if file.is_dir() { - for path in recurse_files(file).unwrap() { - if is_file_extension(&path, ".nu") { - info!("formatting file: {:?}", &path); - nu_formatter::format_single_file(&path, options); - } else { - info!("not nu file: skipping"); - } +/// format a list of files, possibly one, and modify them in place +/// if check mode is on, only check the files but do not modify them in place +fn format_files( + files: Vec, + options: &Config, + mode: &Mode, +) -> Vec<(PathBuf, FileDiagnostic)> { + files + .into_par_iter() + .map(|file| { + info!("formatting file: {:?}", &file); + nu_formatter::format_single_file(file, options, mode) + }) + .collect() +} + +/// Display results and return the appropriate exit code after formatting in check mode +fn display_diagnostic_and_compute_exit_code( + results: &[(PathBuf, FileDiagnostic)], + check_mode: bool, +) -> ExitCode { + let mut already_formatted: usize = 0; + let mut reformatted_or_would_reformat: usize = 0; + let mut failures: usize = 0; + let mut at_least_one_failure = false; + let mut warning_messages: Vec = vec![]; + + let file_failed_msg = if check_mode { + "Failed to check" + } else { + "Failed to format" + }; + + for (file, result) in results { + match result { + FileDiagnostic::AlreadyFormatted => already_formatted += 1, + FileDiagnostic::Reformatted => { + reformatted_or_would_reformat += 1; + if check_mode { + warning_messages.push(format!( + "Would reformat: {}", + Style::new().bold().paint(make_relative(file)) + )); + }; + } + FileDiagnostic::Failure(reason) => { + failures += 1; + eprintln!( + "{}: {} {}: {}", + Color::LightRed.paint("error"), + Style::new().bold().paint(file_failed_msg), + Style::new().bold().paint(make_relative(file)), + &reason + ); + at_least_one_failure = true; } - // Files only - } else { - info!("formatting file: {:?}", file); - nu_formatter::format_single_file(file, options); } } - ExitCode::Success -} + for msg in warning_messages { + println!("{}", msg); + } -fn recurse_files(path: impl AsRef) -> std::io::Result> { - let mut buf = vec![]; - let entries = fs::read_dir(path)?; + if already_formatted + reformatted_or_would_reformat + failures == 0 { + print!( + "{}: no Nushell files found under the given path(s)", + Color::LightYellow.paint("warning"), + ); + return ExitCode::Success; + } - for entry in entries { - let entry = entry?; - let meta = entry.metadata()?; + if reformatted_or_would_reformat > 0 { + let msg = if check_mode { + "would be reformatted" + } else { + "were formatted" + }; + println!( + "{} file{} {}", + reformatted_or_would_reformat, + if reformatted_or_would_reformat == 1 { + "" + } else { + "s" + }, + msg, + ); + } + if already_formatted > 0 { + println!( + "{} file{} already formatted", + already_formatted, + if already_formatted == 1 { "" } else { "s" } + ); + }; + if at_least_one_failure { + ExitCode::Failure + } else if check_mode && reformatted_or_would_reformat > 0 { + ExitCode::CheckFailed + } else { + ExitCode::Success + } +} - if meta.is_dir() { - let mut subdir = recurse_files(entry.path())?; - buf.append(&mut subdir); - } +/// Return the different files to analyze, taking only files with .nu extension and discarding files excluded in the config +/// and the invalid paths provided +fn discover_nu_files( + paths: Vec, + excludes: &Vec, +) -> Result<(Vec, Vec), ConfigError> { + let mut valid_paths: Vec = vec![]; + let mut invalid_paths: Vec = vec![]; - if meta.is_file() { - buf.push(entry.path()); + for path in paths { + if path.exists() { + valid_paths.push(path); + } else { + invalid_paths.push(path); } } - Ok(buf) + let mut overrides = OverrideBuilder::new("."); + for pattern in excludes { + overrides.add(&format!("!{}", pattern))?; + } + let overrides = overrides.build()?; + + let nu_files = valid_paths + .iter() + .flat_map(|path| { + WalkBuilder::new(path) + .overrides(overrides.clone()) + .build() + .filter_map(Result::ok) + .filter(is_nu_file) + .map(|path| path.into_path()) + .collect::>() + }) + .collect(); + + Ok((nu_files, invalid_paths)) } -/// Get the file extension -fn is_file_extension(file: &Path, extension: &str) -> bool { - String::from(file.to_str().unwrap()).ends_with(extension) +/// Return whether a `DirEntry` is a .nu file or not +fn is_nu_file(entry: &DirEntry) -> bool { + entry.file_type().map(|ft| ft.is_file()).unwrap_or(false) + && entry.path().extension().is_some_and(|ext| ext == "nu") +} + +fn make_relative(path: &Path) -> String { + let current = std::env::current_dir().unwrap_or(PathBuf::from(".")); + path.strip_prefix(¤t) + .unwrap_or(path) + .display() + .to_string() + .replace("\\", "/") + .trim_start_matches("./") + .to_string() +} + +/// Search for `filename` in current or any parent directories. +/// If `start_dir` is not provided, the current directory is used +fn find_in_parent_dirs(filename: &str) -> Option { + let start_dir = std::env::current_dir().unwrap_or(PathBuf::from(".")); + + let mut dir = Some(start_dir.as_path()); + while let Some(current) = dir { + let candidate = current.join(filename); + if candidate.exists() { + return Some(candidate); + } + dir = current.parent(); + } + None } #[cfg(test)] mod tests { use super::*; + use rstest::rstest; + use std::fs; + use tempfile::tempdir; #[test] fn clap_cli_construction() { use clap::CommandFactory; Cli::command().debug_assert(); } + + #[test] + fn read_valid_config_empty() { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + fs::write(&config_file, "").unwrap(); + + let config = read_config(&config_file).expect("Config should be valid"); + assert_eq!(config, Config::default()); + } + + #[rstest] + #[case(r#"{line_length: 120, exclude: ["a*nu", "b*.nu"]}"#)] + fn read_valid_config(#[case] config_content: &str) { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + fs::write(&config_file, config_content).unwrap(); + + let config = read_config(&config_file).expect("Config should be valid"); + assert_eq!(config.line_length, 120_usize); + assert_eq!(config.excludes.len(), 2_usize); + } + + #[rstest] + #[case(r#"some string"#)] + #[case(r#"{unknown: 1}"#)] + #[case(r#"{line_length: -1}"#)] + #[case(r#"{line_length: "120"}"#)] + #[case(r#"{exclude: "a*nu"}"#)] + #[case(r#"{exclude: ["a*nu", 1]}"#)] + fn read_invalid_config(#[case] config_content: &str) { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + fs::write(&config_file, config_content).unwrap(); + + let config = read_config(&config_file); + assert!(config.is_err()); + } + + #[rstest] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::AlreadyFormatted),], false, ExitCode::Success)] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::AlreadyFormatted),], true, ExitCode::Success)] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::Reformatted),], false, ExitCode::Success)] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::Reformatted),], true, ExitCode::CheckFailed)] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::Reformatted), + (PathBuf::from("c.nu"), FileDiagnostic::Failure("some error".to_string())),], false, ExitCode::Failure)] + #[case(vec![ + (PathBuf::from("a.nu"), FileDiagnostic::AlreadyFormatted), + (PathBuf::from("b.nu"), FileDiagnostic::Reformatted), + (PathBuf::from("c.nu"), FileDiagnostic::Failure("some error".to_string())),], true, ExitCode::Failure)] + fn exit_code( + #[case] results: Vec<(PathBuf, FileDiagnostic)>, + #[case] check_mode: bool, + #[case] expected: ExitCode, + ) { + let exit_code = display_diagnostic_and_compute_exit_code(&results, check_mode); + assert_eq!(exit_code, expected); + } } diff --git a/tests/main.rs b/tests/main.rs new file mode 100644 index 0000000..c19811d --- /dev/null +++ b/tests/main.rs @@ -0,0 +1,138 @@ +use std::{fs, process::Command}; +use tempfile::tempdir; + +const INVALID: &str = "# beginning of script comment + +let one = 1 +"; +const VALID: &str = "# beginning of script comment +let one = 1 +"; + +#[test] +fn failure_with_invalid_config() { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + fs::write(&config_file, r#"{unknown: 1}"#).unwrap(); + + let output = Command::new("target/debug/nufmt") + .arg("--config") + .arg(config_file.to_str().unwrap()) + .arg(dir.path().to_str().unwrap()) + .output() + .unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + + assert!(stderr.contains("error")); + assert_eq!(output.status.code(), Some(2)); +} + +#[test] +fn failure_with_invalid_config_file() { + let output = Command::new("target/debug/nufmt") + .arg("--config") + .arg("path/that/does/not/exist/nufmt.nuon") + .output() + .unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + + assert!(stderr.contains("error")); + assert_eq!(output.status.code(), Some(2)); +} + +#[test] +fn failure_with_invalid_file_to_format() { + let output = Command::new("target/debug/nufmt") + .arg("path/that/does/not/exist/a.nu") + .output() + .unwrap(); + let stderr = String::from_utf8_lossy(&output.stderr); + + assert!(stderr.contains("error")); + assert_eq!(output.status.code(), Some(2)); +} + +#[test] +fn warning_when_no_files_are_detected() { + let dir = tempdir().unwrap(); + + let output = Command::new("target/debug/nufmt") + .arg("--dry-run") + .arg(dir.path().to_str().unwrap()) + .output() + .unwrap(); + let stdout = String::from_utf8_lossy(&output.stdout); + + assert!(stdout.contains("warning")); + assert_eq!(output.status.code(), Some(0)); +} + +#[test] +fn warning_is_displayed_when_no_files_are_detected_with_excluded_files() { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + let file_a = dir.path().join("a.nu"); + fs::write(&config_file, r#"{exclude: ["a*"]}"#).unwrap(); + fs::write(&file_a, INVALID).unwrap(); + + let output = Command::new("target/debug/nufmt") + .arg("--config") + .arg(config_file.to_str().unwrap()) + .arg("--dry-run") + .arg(dir.path().to_str().unwrap()) + .output() + .unwrap(); + let stdout = String::from_utf8_lossy(&output.stdout); + + assert!(stdout.contains("warning")); + assert_eq!(output.status.code(), Some(0)); +} + +#[test] +fn files_are_reformatted() { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + let file_a = dir.path().join("a.nu"); + let file_b = dir.path().join("b.nu"); + fs::write(&config_file, r#"{exclude: ["a*"]}"#).unwrap(); + fs::write(&file_a, INVALID).unwrap(); + fs::write(&file_b, INVALID).unwrap(); + + let output = Command::new("target/debug/nufmt") + .arg("--config") + .arg(config_file.to_str().unwrap()) + .arg(dir.path().to_str().unwrap()) + .output() + .unwrap(); + + assert_eq!(output.status.code(), Some(0)); + let file_a_content = fs::read_to_string(file_a).unwrap(); + let file_b_content = fs::read_to_string(file_b).unwrap(); + assert_eq!(file_a_content.as_str(), INVALID); + assert_eq!(file_b_content.as_str(), VALID); +} + +#[test] +fn files_are_checked() { + let dir = tempdir().unwrap(); + let config_file = dir.path().join("nufmt.nuon"); + let file_a = dir.path().join("a.nu"); + let file_b = dir.path().join("b.nu"); + fs::write(&config_file, r#"{exclude: ["a*"]}"#).unwrap(); + fs::write(&file_a, INVALID).unwrap(); + fs::write(&file_b, INVALID).unwrap(); + + let output = Command::new("target/debug/nufmt") + .arg("--config") + .arg(config_file.to_str().unwrap()) + .arg("--dry-run") + .arg(dir.path().to_str().unwrap()) + .output() + .unwrap(); + + assert_eq!(output.status.code(), Some(1)); + let file_a_content = fs::read_to_string(file_a).unwrap(); + let file_b_content = fs::read_to_string(file_b).unwrap(); + assert_eq!(file_a_content.as_str(), INVALID); + assert_eq!(file_b_content.as_str(), INVALID); +}