diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 891de39..d6bc597 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,7 @@ on: pull_request: branches: [ "main" ] workflow_call: + workflow_dispatch: env: CARGO_TERM_COLOR: always @@ -28,7 +29,9 @@ jobs: steps: - uses: actions/checkout@v3 - name: Run tests - run: cargo test --release --verbose + run: | + cargo build --bin normalizer --features=cli --release + cargo test --release perfomance: name: ⚑ Performance & πŸ“ˆ Coverage needs: diff --git a/Cargo.lock b/Cargo.lock index 8842707..6bc88a1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,91 +1,95 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "ahash" -version = "0.8.3" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom", + "getrandom 0.3.3", "once_cell", "version_check", + "zerocopy", ] [[package]] name = "aho-corasick" -version = "1.0.5" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c378d78423fdad8089616f827526ee33c19f2fddbd5de1629152c9593ba4783" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anstream" -version = "0.5.0" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.2" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15c4c2c83f81532e5845a733998b6971faca23490340a418e9b72a3ec9de12ea" +checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.1" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "2.1.0" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", - "windows-sys 0.48.0", + "once_cell_polyfill", + "windows-sys 0.60.2", ] [[package]] name = "assert_cmd" -version = "2.0.12" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88903cb14723e4d4003335bb7f8a14f27691649105346a0f0957466c096adfe6" +checksum = "2bd389a4b2970a01282ee455294913c0a43724daedcd1a24c3eb0ec1c1320b66" dependencies = [ "anstyle", "bstr", "doc-comment", + "libc", "predicates", "predicates-core", "predicates-tree", @@ -98,16 +102,16 @@ version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "hermit-abi 0.1.19", + "hermit-abi", "libc", "winapi", ] [[package]] name = "autocfg" -version = "1.1.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "bitflags" @@ -117,15 +121,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.0" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" [[package]] name = "bstr" -version = "1.6.2" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" dependencies = [ "memchr", "regex-automata", @@ -134,42 +138,42 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.13.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "cached" -version = "0.46.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cead8ece0da6b744b2ad8ef9c58a4cdc7ef2921e60a6ddfb9eaaa86839b5fc5" +checksum = "801927ee168e17809ab8901d9f01f700cd7d8d6a6527997fee44e4b0327a253c" dependencies = [ "ahash", "cached_proc_macro", "cached_proc_macro_types", "hashbrown", - "instant", "once_cell", "thiserror", + "web-time", ] [[package]] name = "cached_proc_macro" -version = "0.18.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8245dd5f576a41c3b76247b54c15b0e43139ceeb4f732033e15be7c005176" +checksum = "9225bdcf4e4a9a4c08bf16607908eb2fbf746828d5e0b5e019726dbf6571f201" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "cached_proc_macro_types" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a4f925191b4367301851c6d99b09890311d74b0d43f274c0b34c86d308a3663" +checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" [[package]] name = "cast" @@ -177,20 +181,11 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" -[[package]] -name = "cc" -version = "1.0.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" -dependencies = [ - "libc", -] - [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] name = "chardet" @@ -211,15 +206,15 @@ dependencies = [ [[package]] name = "charset-normalizer-rs" -version = "1.0.6" +version = "1.1.0" dependencies = [ "ahash", "assert_cmd", - "bitflags 2.4.0", + "bitflags 2.9.4", "cached", "chardet", "chardetng", - "clap 4.4.2", + "clap 4.5.47", "counter", "criterion", "dialoguer", @@ -246,14 +241,14 @@ checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "bitflags 1.3.2", "textwrap", - "unicode-width", + "unicode-width 0.1.14", ] [[package]] name = "clap" -version = "4.4.2" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" +checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" dependencies = [ "clap_builder", "clap_derive", @@ -261,9 +256,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.2" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" dependencies = [ "anstream", "anstyle", @@ -273,46 +268,46 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.4.2" +version = "4.5.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" +checksum = "bbfd7eae0b0f1a6e63d4b13c9c478de77c2eb546fba158ad50b4203dc24b9f9c" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.31", + "syn", ] [[package]] name = "clap_lex" -version = "0.5.1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "console" -version = "0.15.7" +version = "0.15.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" dependencies = [ "encode_unicode", - "lazy_static", "libc", - "unicode-width", - "windows-sys 0.45.0", + "once_cell", + "unicode-width 0.2.1", + "windows-sys 0.59.0", ] [[package]] name = "counter" -version = "0.5.7" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d458e66999348f56fd3ffcfbb7f7951542075ca8359687c703de6500c1ddccd" +checksum = "337a5b3c62043f6a4f5331bdb467a7f7a2099dce8522bcded6d4ebda1214fa4c" dependencies = [ "num-traits", ] @@ -353,54 +348,36 @@ dependencies = [ "itertools", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" -version = "0.8.3" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ - "cfg-if", "crossbeam-epoch", "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "autocfg", - "cfg-if", "crossbeam-utils", - "memoffset", - "scopeguard", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if", -] +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "csv" -version = "1.2.2" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626ae34994d3d8d668f4269922248239db4ae42d538b14c398b74a52208e8086" +checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf" dependencies = [ "csv-core", "itoa", @@ -410,18 +387,18 @@ dependencies = [ [[package]] name = "csv-core" -version = "0.1.10" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90" +checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d" dependencies = [ "memchr", ] [[package]] name = "darling" -version = "0.14.4" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ "darling_core", "darling_macro", @@ -429,27 +406,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.14.4" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 1.0.109", + "syn", ] [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -472,13 +449,13 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn", ] [[package]] @@ -489,15 +466,15 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "either" -version = "1.9.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "encode_unicode" -version = "0.3.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" [[package]] name = "encoding" @@ -565,58 +542,63 @@ checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] [[package]] -name = "env_logger" -version = "0.10.0" +name = "env_filter" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" dependencies = [ - "humantime", - "is-terminal", "log", "regex", - "termcolor", ] [[package]] -name = "errno" -version = "0.3.3" +name = "env_logger" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" +checksum = "13c863f0904021b108aa8b2f55046443e6b1ebde8fd4a15c399893aae4fa069f" dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", + "anstream", + "anstyle", + "env_filter", + "jiff", + "log", ] [[package]] -name = "errno-dragonfly" -version = "0.1.2" +name = "equivalent" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ - "cc", "libc", + "windows-sys 0.61.0", ] [[package]] name = "fastrand" -version = "2.0.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "float-cmp" -version = "0.9.0" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" +checksum = "b09cf3155332e944990140d967ff5eceb70df778b34f77d8075db46e4704e6d8" dependencies = [ "num-traits", ] @@ -628,46 +610,56 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "getopts" -version = "0.2.21" +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "getrandom" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ - "unicode-width", + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", ] [[package]] name = "getrandom" -version = "0.2.10" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", - "wasi", + "r-efi", + "wasi 0.14.7+wasi-0.2.4", ] [[package]] name = "half" -version = "1.8.2" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" +checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" [[package]] name = "hashbrown" -version = "0.14.0" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "ahash", "allocator-api2", + "equivalent", + "foldhash", ] [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -678,23 +670,11 @@ dependencies = [ "libc", ] -[[package]] -name = "hermit-abi" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" - -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "icu_collections" -version = "1.3.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3907b2246e8dd5a29ead8a965e7c0c8a90e9b928e614a4279257d45c5e553e91" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ "displaydoc", "yoke", @@ -704,9 +684,9 @@ dependencies = [ [[package]] name = "icu_locid" -version = "1.3.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f284eb342dc49d3e9d9f3b188489d76b5d22dfb1d1a5e0d1941811253bac625c" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ "displaydoc", "litemap", @@ -717,9 +697,9 @@ dependencies = [ [[package]] name = "icu_locid_transform" -version = "1.3.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6551daf80882d8e68eee186cc19e132d8bde1b1f059a79b93384a5ca0e8fc5e7" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ "displaydoc", "icu_locid", @@ -731,15 +711,15 @@ dependencies = [ [[package]] name = "icu_locid_transform_data" -version = "1.3.2" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a741eba5431f75eb2f1f9022d3cffabcadda6771e54fb4e77c8ba8653e4da44" +checksum = "7515e6d781098bf9f7205ab3fc7e9709d34554ae0b21ddbcb5febfa4bc7df11d" [[package]] name = "icu_normalizer" -version = "1.3.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "080fc33a720d50a7342b0c58df010fbcfb842d6f78ef81555f8b1ac6bba57d3c" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ "displaydoc", "icu_collections", @@ -755,15 +735,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "1.3.2" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f8d22f74066c2e6442db2a9aa14950278e86719e811e304e48bae03094b369d" +checksum = "c5e8338228bdc8ab83303f16b797e177953730f601a96c25d10cb3ab0daa0cb7" [[package]] name = "icu_properties" -version = "1.3.2" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3477ae70f8ca8dc08ff7574b5398ed0a2f2e4e6b66bdff2558a92ed67e262be1" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" dependencies = [ "displaydoc", "icu_collections", @@ -776,15 +756,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "1.3.2" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c8bb3b67a8347e94d580434369e5c7ee89999b9309d04b7cfc88dfaa0f31b59" +checksum = "85fb8799753b75aee8d2a21d7c14d9f38921b54b3dbda10f5a3c7a7b82dba5e2" [[package]] name = "icu_provider" -version = "1.3.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68acdef80034b5e35d8524e9817479d389a4f9774f3f0cbe1bf3884d80fd5934" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" dependencies = [ "displaydoc", "icu_locid", @@ -799,13 +779,13 @@ dependencies = [ [[package]] name = "icu_provider_macros" -version = "1.3.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2060258edfcfe32ca7058849bf0f146cb5c59aadbedf480333c0d0002f97bc99" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn", ] [[package]] @@ -815,24 +795,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "instant" -version = "0.1.12" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "is-terminal" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" -dependencies = [ - "hermit-abi 0.3.2", - "rustix", - "windows-sys 0.48.0", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -845,63 +811,79 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.9" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "jiff" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "js-sys" -version = "0.3.64" +version = "0.3.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +checksum = "852f13bec5eba4ba9afbeb93fd7c13fe56147f055939ae21c43a29a0ecb2702e" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.147" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "linux-raw-sys" -version = "0.4.7" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" -version = "0.7.1" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a1a2647d5b7134127971a6de0d533c49de2159167e7f259c427195f87168a1" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] name = "log" -version = "0.4.20" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" [[package]] name = "memchr" -version = "2.6.3" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" - -[[package]] -name = "memoffset" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "normalize-line-endings" @@ -911,58 +893,54 @@ checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] -name = "num_cpus" -version = "1.16.0" +name = "once_cell" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.2", - "libc", -] +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] -name = "once_cell" -version = "1.18.0" +name = "once_cell_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "oorandom" -version = "11.1.3" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "ordered-float" -version = "3.9.1" +version = "3.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a54938017eacd63036332b4ae5c8a49fc8c0c1d6d629893057e4f13609edd06" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" dependencies = [ "num-traits", ] [[package]] name = "phf" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" dependencies = [ "phf_shared", ] [[package]] name = "phf_codegen" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" dependencies = [ "phf_generator", "phf_shared", @@ -970,9 +948,9 @@ dependencies = [ [[package]] name = "phf_generator" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", "rand", @@ -980,18 +958,18 @@ dependencies = [ [[package]] name = "phf_shared" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ "siphasher", ] [[package]] name = "plotters" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" dependencies = [ "num-traits", "plotters-backend", @@ -1002,35 +980,52 @@ dependencies = [ [[package]] name = "plotters-backend" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" [[package]] name = "plotters-svg" -version = "0.3.5" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" dependencies = [ "plotters-backend", ] +[[package]] +name = "portable-atomic" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] [[package]] name = "predicates" -version = "3.0.3" +version = "3.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09963355b9f467184c04017ced4a2ba2d75cbcb4e7462690d388233253d4b1a9" +checksum = "a5d19ee57562043d37e82899fade9a22ebab7be9cef5026b07fda9cdd4293573" dependencies = [ "anstyle", "difflib", "float-cmp", - "itertools", "normalize-line-endings", "predicates-core", "regex", @@ -1038,15 +1033,15 @@ dependencies = [ [[package]] name = "predicates-core" -version = "1.0.6" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" +checksum = "727e462b119fe9c93fd0eb1429a5f7647394014cf3c04ab2c0350eeb09095ffa" [[package]] name = "predicates-tree" -version = "1.0.9" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +checksum = "72dd2d6d381dfb73a193c7fca536518d7caee39fc8503f74e7dc0be0531b425c" dependencies = [ "predicates-core", "termtree", @@ -1054,22 +1049,28 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.33" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "rand" version = "0.8.5" @@ -1097,14 +1098,14 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.16", ] [[package]] name = "rayon" -version = "1.7.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -1112,30 +1113,19 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", -] - -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags 1.3.2", ] [[package]] name = "regex" -version = "1.9.5" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ "aho-corasick", "memchr", @@ -1145,9 +1135,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.8" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" dependencies = [ "aho-corasick", "memchr", @@ -1156,28 +1146,34 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] name = "rustix" -version = "0.38.12" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdf14a7a466ce88b5eac3da815b53aefc208ce7e74d1c263aabb04d88c4abeb1" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.4.0", + "bitflags 2.9.4", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.61.0", ] +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + [[package]] name = "ryu" -version = "1.0.15" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "same-file" @@ -1188,18 +1184,13 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "serde" -version = "1.0.188" +version = "1.0.225" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d" dependencies = [ + "serde_core", "serde_derive", ] @@ -1213,26 +1204,37 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_core" +version = "1.0.225" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.188" +version = "1.0.225" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn", ] [[package]] name = "serde_json" -version = "1.0.107" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ "itoa", + "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -1243,15 +1245,15 @@ checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" [[package]] name = "siphasher" -version = "0.3.11" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" [[package]] name = "smallvec" -version = "1.11.1" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "stable_deref_trait" @@ -1261,26 +1263,15 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - -[[package]] -name = "syn" -version = "1.0.109" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.31" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -1289,43 +1280,33 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.0" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "285ba80e733fac80aa4270fbcdf83772a79b80aa35c97075320abfee4a915b06" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", - "unicode-xid", + "syn", ] [[package]] name = "tempfile" -version = "3.8.0" +version = "3.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53" dependencies = [ - "cfg-if", "fastrand", - "redox_syscall", + "getrandom 0.3.3", + "once_cell", "rustix", - "windows-sys 0.48.0", -] - -[[package]] -name = "termcolor" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" -dependencies = [ - "winapi-util", + "windows-sys 0.61.0", ] [[package]] name = "termtree" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" +checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683" [[package]] name = "textwrap" @@ -1333,50 +1314,34 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" dependencies = [ - "unicode-width", + "unicode-width 0.1.14", ] [[package]] name = "thiserror" -version = "1.0.49" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4" +checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.49" +version = "2.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" +checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn", ] -[[package]] -name = "time" -version = "0.3.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" -dependencies = [ - "serde", - "time-core", -] - -[[package]] -name = "time-core" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" - [[package]] name = "tinystr" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0e245e80bdc9b4e5356fc45a72184abbc3861992603f515270e9340f5a219" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ "displaydoc", "zerovec", @@ -1394,27 +1359,27 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.11" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" +checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" [[package]] name = "unicode-width" -version = "0.1.10" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] -name = "unicode-xid" -version = "0.2.4" +name = "unicode-width" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" [[package]] name = "unicode_names2" -version = "1.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b2c0942619ae1797f999a0ce7efc6c09592ad30e68e16cdbfdcd48a98c3579" +checksum = "d189085656ca1203291e965444e7f6a2723fbdd1dd9f34f8482e79bafd8338a0" dependencies = [ "phf", "unicode_names2_generator", @@ -1422,55 +1387,52 @@ dependencies = [ [[package]] name = "unicode_names2_generator" -version = "1.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d0d66ab60be9799a70f8eb227ea43da7dcc47561dd9102cbadacfe0930113f7" +checksum = "1262662dc96937c71115228ce2e1d30f41db71a7a45d3459e98783ef94052214" dependencies = [ - "getopts", - "log", "phf_codegen", "rand", - "time", ] [[package]] name = "utf16_iter" -version = "1.0.4" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52df8b7fb78e7910d776fccf2e42ceaf3604d55e8e7eb2dbd183cb1441d8a692" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" [[package]] name = "utf8_iter" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a8922555b9500e3d865caed19330172cd67cbf82203f1a3311d8c305cc9f33" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wait-timeout" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" dependencies = [ "libc", ] [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -1478,40 +1440,60 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] [[package]] name = "wasm-bindgen" -version = "0.2.87" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +checksum = "ab10a69fbd0a177f5f649ad4d8d3305499c42bab9aef2f7ff592d0ec8f833819" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.87" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +checksum = "0bb702423545a6007bbc368fde243ba47ca275e549c8a28617f56f6ba53b1d1c" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.31", + "syn", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.87" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +checksum = "fc65f4f411d91494355917b605e1480033152658d71f722a90647f56a70c88a0" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1519,28 +1501,41 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.87" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +checksum = "ffc003a991398a8ee604a401e194b6b3a39677b3173d6e74495eb51b82e99a32" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.87" +version = "0.2.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" +checksum = "293c37f4efa430ca14db3721dfbe48d8c33308096bd44d80ebaa775ab71ba1cf" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" -version = "0.3.64" +version = "0.3.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbe734895e869dc429d78c4b433f8d17d95f8d05317440b4fad5ab2d33e596dc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -1564,11 +1559,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "winapi", + "windows-sys 0.61.0", ] [[package]] @@ -1577,137 +1572,179 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.42.2", + "windows-targets 0.53.3", ] [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" dependencies = [ - "windows-targets 0.48.5", + "windows-link 0.2.0", ] [[package]] name = "windows-targets" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.53.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", + "windows-link 0.1.3", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" [[package]] name = "windows_aarch64_msvc" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" [[package]] name = "windows_i686_gnu" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" [[package]] name = "windows_i686_msvc" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" [[package]] name = "windows_x86_64_gnu" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" [[package]] name = "windows_x86_64_msvc" -version = "0.42.2" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "write16" @@ -1717,15 +1754,15 @@ checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" [[package]] name = "writeable" -version = "0.5.3" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0af0c3d13faebf8dda0b5256fa7096a2d5ccb662f7b9f54a40fe201077ab1c2" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "yoke" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e38c508604d6bbbd292dadb3c02559aa7fff6b654a078a36217cad871636e4" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ "serde", "stable_deref_trait", @@ -1735,48 +1772,68 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.2" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5e19fb6ed40002bab5403ffa37e53e0e56f914a4450c8765f533018db1db35f" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn", "synstructure", ] +[[package]] +name = "zerocopy" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zerofrom" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655b0814c5c0b19ade497851070c640773304939a6c0fd5f5fb43da0696d05b7" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.3" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6a647510471d372f2e6c2e6b7219e44d8c574d24fdc11c610a61455782f18c3" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn", "synstructure", ] [[package]] name = "zeroize" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zerovec" -version = "0.10.0" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1194130c5b155bf8ae50ab16c86ab758cd695cf9ad176d2f870b744cbdbb572e" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" dependencies = [ "yoke", "zerofrom", @@ -1785,11 +1842,11 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.0" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acabf549809064225ff8878baedc4ce3732ac3b07e7c7ce6e5c2ccdbc485c324" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.31", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml index 39bbf89..a99f506 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "charset-normalizer-rs" -version = "1.0.6" +version = "1.1.0" authors = ["Nikolay Yarovoy "] edition = "2021" description = "Truly universal encoding detector in pure Rust - port of Python version" @@ -20,25 +20,25 @@ exclude = [ [dependencies] ahash = "0.8.3" -bitflags = "2.4.0" -cached = "0.46.0" +bitflags = "2.9.0" +cached = "0.56.0" chardet = { version = "0.2.4", optional = true } chardetng = { version = "0.1.17", optional = true } -clap = { version = "4.4.2", features = ["derive"] } -counter = "0.5.7" -dialoguer = "0.10.4" +clap = { version = "4.4.2", features = ["derive"], optional = true} +counter = "0.7.0" +dialoguer = { version = "0.10.4", optional = true } encoding = "0.2.33" -env_logger = "0.10.0" +env_logger = { version = "0.11.0", optional = true } icu_normalizer = "1.3.2" icu_properties = "1.3.2" log = "0.4.20" -once_cell = "1.18.0" +once_cell = "1.21.0" ordered-float = "3.9.1" regex = "1.9.3" serde = { version = "1.0.188", features = ["derive"] } serde_json = "1.0.107" -strsim = "0.10.0" -unicode_names2 = "1.1.0" +strsim = "0.11.0" +unicode_names2 = "2.0.0" [dev-dependencies] assert_cmd = "2.0.12" @@ -54,7 +54,8 @@ name = "large_datasets" harness = false [features] -performance = ["chardet", "chardetng"] +cli = ["clap", "dialoguer", "env_logger"] +performance = ["chardet", "chardetng", "cli"] [[bin]] name = "performance" @@ -64,6 +65,7 @@ required-features = ["performance"] [[bin]] name = "normalizer" path = "src/normalizer.rs" +required-features = ["cli"] [profile.release] opt-level = 3 diff --git a/src/cd.rs b/src/cd.rs index 7808596..d60ae27 100644 --- a/src/cd.rs +++ b/src/cd.rs @@ -93,7 +93,8 @@ pub(crate) fn alphabet_languages( characters: &[char], ignore_non_latin: bool, ) -> Vec<&'static Language> { - let mut languages: Vec<(&Language, f32)> = Vec::with_capacity(*LANGUAGE_SUPPORTED_COUNT); + let mut languages: Vec<(&Language, OrderedFloat)> = + Vec::with_capacity(*LANGUAGE_SUPPORTED_COUNT); let source_characters_set: HashSet = characters.iter().copied().collect(); let source_has_accents = source_characters_set .iter() @@ -114,11 +115,11 @@ pub(crate) fn alphabet_languages( let ratio: f32 = intersection.len() as f32 / language_characters_set.len() as f32; if ratio >= 0.2 { - languages.push((language, ratio)); + languages.push((language, OrderedFloat(ratio))); } } // reverse sort - languages.sort_unstable_by(|&a, &b| b.1.partial_cmp(&a.1).unwrap()); + languages.sort_unstable_by(|&a, &b| b.1.cmp(&a.1)); languages.iter().map(|&lang| lang.0).collect() } @@ -158,7 +159,7 @@ pub(crate) fn characters_popularity_compare( // We shall NOT return more than one "English" in CoherenceMatches because it is an alternative // of "English" (the same for Japan language). This function only keeps the best match. pub(crate) fn filter_alt_coherence_matches(results: &CoherenceMatches) -> CoherenceMatches { - let mut index: HashMap<&Language, f32> = HashMap::with_capacity(results.len()); + let mut index: HashMap<&Language, OrderedFloat> = HashMap::with_capacity(results.len()); for result in results { let score = index.entry(result.language).or_default(); *score = result.score.max(*score); @@ -171,8 +172,9 @@ pub(crate) fn filter_alt_coherence_matches(results: &CoherenceMatches) -> Cohere // This function merge results previously given by the function coherence_ratio. // The return type is the same as coherence_ratio. -pub(crate) fn merge_coherence_ratios(results: &Vec) -> CoherenceMatches { - let mut index: HashMap<&Language, Vec> = HashMap::with_capacity(results.len()); +pub(crate) fn merge_coherence_ratios(results: &[CoherenceMatches]) -> CoherenceMatches { + let mut index: HashMap<&Language, Vec>> = + HashMap::with_capacity(results.len()); results .iter() .flatten() @@ -182,11 +184,11 @@ pub(crate) fn merge_coherence_ratios(results: &Vec) -> Coheren .iter() .map(|(&lang, scores)| CoherenceMatch { language: lang, - score: scores.iter().sum::() / (scores.len() as f32), + score: scores.iter().sum::>() / (scores.len() as f32), }) .collect(); - merge.sort_unstable_by(|a, b| b.score.partial_cmp(&a.score).unwrap()); + merge.sort_unstable_by(|a, b| b.score.cmp(&a.score)); merge } @@ -238,7 +240,7 @@ pub(crate) fn coherence_ratio( results.push(CoherenceMatch { language, - score: ratio, + score: OrderedFloat(ratio), }); if sufficient_match_count >= 3 { @@ -247,6 +249,6 @@ pub(crate) fn coherence_ratio( } } results = filter_alt_coherence_matches(&results); - results.sort_unstable_by(|a, b| b.score.partial_cmp(&a.score).unwrap()); + results.sort_unstable_by(|a, b| b.score.cmp(&a.score)); Ok(results) } diff --git a/src/consts.rs b/src/consts.rs index 6d56a65..4a1fd7e 100644 --- a/src/consts.rs +++ b/src/consts.rs @@ -8,10 +8,10 @@ pub static TOO_BIG_SEQUENCE: usize = 1_000_000; // 10E6 pub(crate) static MAX_PROCESSED_BYTES: usize = 500_000; pub(crate) static TOO_SMALL_SEQUENCE: usize = 32; pub(crate) static UTF8_MAXIMAL_ALLOCATION: usize = 1_112_064; -pub(crate) static COMMON_SAFE_ASCII_CHARACTERS: &'static str = "<>=:/&;{}[],|\"-"; +pub(crate) static COMMON_SAFE_ASCII_CHARACTERS: &str = "<>=:/&;{}[],|\"-"; // Contain for each eligible encoding a list of/item bytes SIG/BOM -pub(crate) static ENCODING_MARKS: Lazy> = Lazy::new(|| { +pub(crate) static ENCODING_MARKS: Lazy> = Lazy::new(|| { HashMap::from_iter([ ("utf-8", b"\xef\xbb\xbf".as_slice()), ("gb18030", b"\x84\x31\x95\x33".as_slice()), @@ -20,7 +20,7 @@ pub(crate) static ENCODING_MARKS: Lazy> = L ]) }); -pub(crate) static UNICODE_RANGES_COMBINED: Lazy<[(&'static str, RangeInclusive); 279]> = +pub(crate) static UNICODE_RANGES_COMBINED: Lazy<[(&str, RangeInclusive); 279]> = Lazy::new(|| { [ ("Control character", 0..=31), diff --git a/src/entity.rs b/src/entity.rs index 252c41d..8c67b5c 100644 --- a/src/entity.rs +++ b/src/entity.rs @@ -3,17 +3,14 @@ use crate::cd::{encoding_languages, mb_encoding_languages}; use crate::consts::{IANA_SUPPORTED_ALIASES, TOO_BIG_SEQUENCE}; use crate::utils::{decode, iana_name, is_multi_byte_encoding, range_scan}; -use clap::Parser; use encoding::DecoderTrap; use ordered_float::OrderedFloat; -use serde::Serialize; +use std::borrow::Cow; use std::cmp::Ordering; use std::fmt; use std::fmt::{Debug, Display, Formatter}; use std::hash::Hash; use std::ops::Index; -use std::path::PathBuf; -use std::time::Duration; ///////////////////////////////////////////////////////////////////////////////////// // Languages @@ -73,12 +70,12 @@ impl Display for Language { ///////////////////////////////////////////////////////////////////////////////////// #[derive(Debug, PartialEq, Clone)] -pub struct CoherenceMatch { +pub(crate) struct CoherenceMatch { pub language: &'static Language, - pub score: f32, + pub score: OrderedFloat, } -pub type CoherenceMatches = Vec; +pub(crate) type CoherenceMatches = Vec; ///////////////////////////////////////////////////////////////////////////////////// // CharsetMatch @@ -86,10 +83,10 @@ pub type CoherenceMatches = Vec; #[derive(Clone)] pub struct CharsetMatch { - payload: Vec, + payload: Cow<'static, [u8]>, encoding: String, - mean_mess_ratio: f32, + mean_mess_ratio: OrderedFloat, coherence_matches: CoherenceMatches, has_sig_or_bom: bool, @@ -113,9 +110,9 @@ impl Debug for CharsetMatch { impl Default for CharsetMatch { fn default() -> Self { CharsetMatch { - payload: vec![], + payload: Cow::Borrowed(&[]), encoding: "utf-8".to_string(), - mean_mess_ratio: 0.0, + mean_mess_ratio: OrderedFloat(0.0), coherence_matches: vec![], has_sig_or_bom: false, submatch: vec![], @@ -130,33 +127,41 @@ impl PartialEq for CharsetMatch { } } -impl PartialOrd for CharsetMatch { - fn partial_cmp(&self, other: &Self) -> Option { +impl Eq for CharsetMatch {} + +impl Ord for CharsetMatch { + fn cmp(&self, other: &Self) -> Ordering { let mess_difference = (self.mean_mess_ratio - other.mean_mess_ratio).abs(); - let coherence_a = self.coherence(); - let coherence_b = other.coherence(); + let coherence_a = OrderedFloat(self.coherence()); + let coherence_b = OrderedFloat(other.coherence()); let coherence_difference = (coherence_a - coherence_b).abs(); // Below 1% difference --> Use Coherence if mess_difference < 0.01 { if coherence_difference > 0.02 { - return coherence_b.partial_cmp(&coherence_a); + return coherence_b.cmp(&coherence_a); } - let multibyte_usage_a = self.multi_byte_usage(); - let multibyte_usage_b = other.multi_byte_usage(); + let multibyte_usage_a = OrderedFloat(self.multi_byte_usage()); + let multibyte_usage_b = OrderedFloat(other.multi_byte_usage()); let multibyte_usage_delta = (multibyte_usage_a - multibyte_usage_b).abs(); if multibyte_usage_delta > f32::EPSILON { - return multibyte_usage_b.partial_cmp(&multibyte_usage_a); + return multibyte_usage_b.cmp(&multibyte_usage_a); } } - self.mean_mess_ratio.partial_cmp(&other.mean_mess_ratio) + self.mean_mess_ratio.cmp(&other.mean_mess_ratio) + } +} + +impl PartialOrd for CharsetMatch { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) } } impl CharsetMatch { // Init function - pub fn new( - payload: &[u8], + pub(crate) fn new( + payload: Cow<'static, [u8]>, encoding: &str, mean_mess_ratio: f32, has_sig_or_bom: bool, @@ -164,14 +169,14 @@ impl CharsetMatch { decoded_payload: Option<&str>, ) -> Self { CharsetMatch { - payload: Vec::from(payload), + payload: payload.clone(), encoding: String::from(encoding), - mean_mess_ratio, + mean_mess_ratio: OrderedFloat(mean_mess_ratio), coherence_matches: coherence_matches.clone(), has_sig_or_bom, submatch: vec![], decoded_payload: decoded_payload.map(String::from).or_else(|| { - decode(payload, encoding, DecoderTrap::Strict, false, true) + decode(&payload, encoding, DecoderTrap::Strict, false, true) .ok() .map(|res| res.strip_prefix('\u{feff}').unwrap_or(&res).to_string()) }), @@ -179,7 +184,7 @@ impl CharsetMatch { } // Add submatch - pub fn add_submatch(&mut self, submatch: &CharsetMatch) { + pub(crate) fn add_submatch(&mut self, submatch: &CharsetMatch) { self.submatch.push(submatch.clone()); //self.decoded_payload = None; } @@ -199,7 +204,7 @@ impl CharsetMatch { &self.encoding } pub fn chaos(&self) -> f32 { - self.mean_mess_ratio + self.mean_mess_ratio.0 } // Most probable language found in decoded sequence. If none were detected or inferred, the property will return // Language::Unknown @@ -245,7 +250,7 @@ impl CharsetMatch { 1.0 - (decoded_chars / payload_len) } // Original untouched bytes - pub fn raw(&self) -> &Vec { + pub fn raw(&self) -> &[u8] { &self.payload } // Return chaos in percents with rounding @@ -260,7 +265,7 @@ impl CharsetMatch { pub fn coherence(&self) -> f32 { self.coherence_matches .first() - .map(|lang| lang.score) + .map(|lang| lang.score.0) .unwrap_or_default() } @@ -347,15 +352,15 @@ impl CharsetMatches { } // Resort items by relevancy (for internal use) fn resort(items: &mut [CharsetMatch]) { - items.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap()); + items.sort_unstable(); } // iterator - pub fn iter_mut(&mut self) -> CharsetMatchesIterMut { + pub fn iter_mut(&mut self) -> CharsetMatchesIterMut<'_> { CharsetMatchesIterMut { items: self.items.iter_mut(), } } - pub fn iter(&self) -> CharsetMatchesIter { + pub fn iter(&self) -> CharsetMatchesIter<'_> { CharsetMatchesIter { items: self.items.iter(), } @@ -427,92 +432,3 @@ impl Default for NormalizerSettings { } } } - -///////////////////////////////////////////////////////////////////////////////////// -// Performance binary application -///////////////////////////////////////////////////////////////////////////////////// - -#[derive(Parser, Debug)] -#[command(name = "Performance check for charset-normalizer-rs vs chardet vs chardetng")] -#[command(author, version, about, long_about = None)] -pub struct PerformanceArgs { - /// Apply artificial size increase to challenge the detection mechanism further - #[arg(short, long, default_value_t = 1)] - pub size_increase: u8, -} - -// Struct to save result of each test in performance app -pub struct PerformanceResult { - /// Performance test duration - pub duration: Duration, - /// Is result accurate? - pub correct: bool, -} - -///////////////////////////////////////////////////////////////////////////////////// -// Normalizer CLI application -///////////////////////////////////////////////////////////////////////////////////// - -#[derive(Parser, Debug)] -#[command( - name = "The Real First Universal Charset Detector. Discover originating encoding used on text file. Normalize text to unicode." -)] -#[command(author, version, about, long_about = None)] -pub struct CLINormalizerArgs { - /// File(s) to be analysed - #[arg(required = true, action = clap::ArgAction::Append)] - pub files: Vec, - - /// Display complementary information about file if any. Stdout will contain logs about the detection process. - #[arg(short = 'v', long = "verbose", default_value_t = false)] - pub verbose: bool, - - /// Output complementary possibilities if any. Top-level JSON WILL be a list. - #[arg(short = 'a', long = "with-alternative", default_value_t = false)] - pub alternatives: bool, - - /// Permit to normalize input file. If not set, program does not write anything. - #[arg(short, long, default_value_t = false)] - pub normalize: bool, - - /// Only output the charset detected to STDOUT. Disabling JSON output. - #[arg(short, long, default_value_t = false)] - pub minimal: bool, - - /// Replace file when trying to normalize it instead of creating a new one. - #[arg(short, long, default_value_t = false)] - pub replace: bool, - - /// Replace file without asking if you are sure, use this flag with caution. - #[arg(short, long, default_value_t = false)] - pub force: bool, - - /// Define a custom maximum amount of chaos allowed in decoded content. 0. <= chaos <= 1. - #[arg(short, long, default_value_t = 0.2)] - pub threshold: f32, -} - -#[derive(Default, Debug, Serialize)] -pub struct CLINormalizerResult { - /// Path to analysed file - pub path: PathBuf, - /// Guessed encoding - pub encoding: Option, - /// Possible aliases of guessed encoding - pub encoding_aliases: Vec, - /// Alternative possible encodings - pub alternative_encodings: Vec, - /// Most probably language - pub language: String, - /// Found alphabets - pub alphabets: Vec, - /// Does it has SIG or BOM mark? - pub has_sig_or_bom: bool, - /// Chaos (mess) level - pub chaos: String, - /// Coherence (language detection) level - pub coherence: String, - /// Path to decoded data - pub unicode_path: Option, - pub is_preferred: bool, -} diff --git a/src/lib.rs b/src/lib.rs index 2eb99e5..5fa3a7c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -30,7 +30,7 @@ //! use charset_normalizer_rs::from_bytes; //! //! fn test_from_bytes() { -//! let result = from_bytes(&vec![0x84, 0x31, 0x95, 0x33], None); +//! let result = from_bytes(&vec![0x84, 0x31, 0x95, 0x33], None).unwrap(); //! let best_guess = result.get_best(); //! assert_eq!( //! best_guess.unwrap().encoding(), @@ -140,6 +140,7 @@ use crate::utils::{ }; use encoding::DecoderTrap; use log::{debug, trace}; +use std::borrow::Cow; use std::collections::VecDeque; use std::fs::File; use std::io::Read; @@ -155,31 +156,38 @@ mod md; mod tests; pub mod utils; -// Given a raw bytes sequence, return the best possibles charset usable to render str objects. -// If there is no results, it is a strong indicator that the source is binary/not text. -// By default, the process will extract 5 blocks of 512o each to assess the mess and coherence of a given sequence. -// And will give up a particular code page after 20% of measured mess. Those criteria are customizable at will. -// -// The preemptive behavior DOES NOT replace the traditional detection workflow, it prioritize a particular code page -// but never take it for granted. Can improve the performance. -// -// You may want to focus your attention to some code page or/and not others, use cp_isolation and cp_exclusion for that -// purpose. -// -// This function will strip the SIG in the payload/sequence every time except on UTF-16, UTF-32. -// By default the library does not setup any handler other than the NullHandler, if you choose to set the 'explain' -// toggle to True it will alter the logger configuration to add a StreamHandler that is suitable for debugging. -// Custom logging format and handler can be set manually. -pub fn from_bytes(bytes: &[u8], settings: Option) -> CharsetMatches { +/// Given a raw bytes sequence, return the best possibles charset usable to render str objects. +/// If there is no results, it is a strong indicator that the source is binary/not text. +/// By default, the process will extract 5 blocks of 512o each to assess the mess and coherence of a given sequence. +/// And will give up a particular code page after 20% of measured mess. Those criteria are customizable at will. +/// +/// The preemptive behavior DOES NOT replace the traditional detection workflow, it prioritize a particular code page +/// but never take it for granted. Can improve the performance. +/// +/// You may want to focus your attention to some code page or/and not others, use cp_isolation and cp_exclusion for that +/// purpose. +/// +/// This function will strip the SIG in the payload/sequence every time except on UTF-16, UTF-32. +/// By default the library does not setup any handler other than the NullHandler, if you choose to set the 'explain' +/// toggle to True it will alter the logger configuration to add a StreamHandler that is suitable for debugging. +/// Custom logging format and handler can be set manually. +pub fn from_bytes( + bytes: &[u8], + settings: Option, +) -> Result { // init settings with default values if it's None and recheck include_encodings and // exclude_encodings settings let mut settings = settings.unwrap_or_default(); if !settings.include_encodings.is_empty() { - settings.include_encodings = settings - .include_encodings - .iter() - .map(|e| iana_name(e).unwrap().to_string()) - .collect(); + let mut normalized = vec![]; + for enc in &settings.include_encodings { + normalized.push( + iana_name(enc) + .ok_or_else(|| format!("included {enc} is not a valid encoding name"))? + .to_string(), + ); + } + settings.include_encodings = normalized; trace!( "include_encodings is set. Use this flag for debugging purpose. \ Limited list of encoding allowed : {}.", @@ -187,11 +195,15 @@ pub fn from_bytes(bytes: &[u8], settings: Option) -> Charset ); } if !settings.exclude_encodings.is_empty() { - settings.exclude_encodings = settings - .exclude_encodings - .iter() - .map(|e| iana_name(e).unwrap().to_string()) - .collect(); + let mut normalized = vec![]; + for enc in &settings.exclude_encodings { + normalized.push( + iana_name(enc) + .ok_or_else(|| format!("excluded encoding {enc} is not a valid encoding name"))? + .to_string(), + ); + } + settings.exclude_encodings = normalized; trace!( "exclude_encodings is set. Use this flag for debugging purpose. \ Limited list of encoding allowed : {}.", @@ -203,7 +215,7 @@ pub fn from_bytes(bytes: &[u8], settings: Option) -> Charset let bytes_length = bytes.len(); if bytes_length == 0 { debug!("Encoding detection on empty bytes, assuming utf_8 intention."); - return CharsetMatches::from_single(CharsetMatch::default()); + return Ok(CharsetMatches::from_single(CharsetMatch::default())); } // check min length @@ -274,7 +286,7 @@ pub fn from_bytes(bytes: &[u8], settings: Option) -> Charset let mut iana_encodings: VecDeque<&str> = VecDeque::from(IANA_SUPPORTED.clone()); for pe in prioritized_encodings.iter().rev() { if let Some(index) = iana_encodings.iter().position(|x| x == pe) { - let value = iana_encodings.remove(index).unwrap(); + let value = iana_encodings.remove(index).expect("index found above"); iana_encodings.push_front(value); } } @@ -287,6 +299,8 @@ pub fn from_bytes(bytes: &[u8], settings: Option) -> Charset let mut fallback_specified: Option = None; let mut results: CharsetMatches = CharsetMatches::default(); + let bytes: Cow<'static, [u8]> = Cow::Owned(bytes.to_vec()); + // Iterate and probe our encodings 'iana_encodings_loop: for encoding_iana in iana_encodings { if (!settings.include_encodings.is_empty() @@ -314,7 +328,9 @@ pub fn from_bytes(bytes: &[u8], settings: Option) -> Charset // fast pre-check let start_idx = match bom_or_sig_available { - true => sig_payload.unwrap().len(), + true => sig_payload + .ok_or_else(|| "sig_payload cannot not be None".to_string())? + .len(), false => 0, }; let end_idx = match is_too_large_sequence && !is_multi_byte_decoder { @@ -415,12 +431,12 @@ pub fn from_bytes(bytes: &[u8], settings: Option) -> Charset lazy_str_hard_failure = true; break 'chunks_loop; } - let decoded_chunk = decoded_chunk_result.unwrap(); + let decoded_chunk = decoded_chunk_result?; // MD ratios calc md_chunks.push(decoded_chunk.clone()); md_ratios.push(mess_ratio(decoded_chunk, Some(settings.threshold))); - if md_ratios.last().unwrap() >= &settings.threshold { + if md_ratios.last().expect("never empty") >= &settings.threshold { early_stop_count += 1; } if early_stop_count >= max_chunk_gave_up { @@ -443,7 +459,7 @@ pub fn from_bytes(bytes: &[u8], settings: Option) -> Charset "LazyStr Loading: After final lookup, code page {} does not fit \ given bytes sequence at ALL. {}", encoding_iana, - decoded_chunk_result.unwrap_err().to_string(), + decoded_chunk_result.unwrap_err() ); tested_but_hard_failure.push(encoding_iana); continue 'iana_encodings_loop; @@ -471,7 +487,7 @@ pub fn from_bytes(bytes: &[u8], settings: Option) -> Charset && prioritized_encodings.contains(&encoding_iana) { let fallback_entry = Some(CharsetMatch::new( - bytes, + bytes.clone(), encoding_iana, f32::from(settings.threshold), false, @@ -520,7 +536,7 @@ pub fn from_bytes(bytes: &[u8], settings: Option) -> Charset // process results results.append(CharsetMatch::new( - bytes, + bytes.clone(), encoding_iana, mean_mess_ratio, bom_or_sig_available, @@ -535,9 +551,12 @@ pub fn from_bytes(bytes: &[u8], settings: Option) -> Charset "Encoding detection: {} is most likely the one.", encoding_iana ); - return CharsetMatches::from_single( - results.get_by_encoding(encoding_iana).unwrap().clone(), - ); + return Ok(CharsetMatches::from_single( + results + .get_by_encoding(encoding_iana) + .ok_or_else(|| format!("{encoding_iana} entry not present"))? + .clone(), + )); } } @@ -570,16 +589,19 @@ pub fn from_bytes(bytes: &[u8], settings: Option) -> Charset debug!( "Encoding detection: Found {} as plausible (best-candidate) for content. \ With {} alternatives.", - results.get_best().unwrap().encoding(), + results + .get_best() + .expect("not empty checked above") + .encoding(), results.len() - 1, ); } - results + Ok(results) } -// Same thing than the function from_bytes but with one extra step. -// Opening and reading given file path in binary mode. -// Can return Error. +/// Same thing than the function from_bytes but with one extra step. +/// Opening and reading given file path in binary mode. +/// Can return Error. pub fn from_path( path: &Path, settings: Option, @@ -593,5 +615,5 @@ pub fn from_path( .map_err(|e| format!("Error reading from file: {e}"))?; // calculate - Ok(from_bytes(&buffer, settings)) + from_bytes(&buffer, settings) } diff --git a/src/md/structs.rs b/src/md/structs.rs index ea6a3fa..e6e0a90 100644 --- a/src/md/structs.rs +++ b/src/md/structs.rs @@ -65,7 +65,7 @@ impl MessDetectorChar { } #[cached( - type = "UnboundCache", + ty = "UnboundCache", create = "{ UnboundCache::with_capacity(UTF8_MAXIMAL_ALLOCATION) }", convert = r#"{ character }"# )] diff --git a/src/normalizer.rs b/src/normalizer.rs index 9806487..dcdbd7c 100644 --- a/src/normalizer.rs +++ b/src/normalizer.rs @@ -1,13 +1,83 @@ -use charset_normalizer_rs::entity::{CLINormalizerArgs, CLINormalizerResult, NormalizerSettings}; +use charset_normalizer_rs::entity::NormalizerSettings; use charset_normalizer_rs::from_path; use clap::Parser; use dialoguer::Confirm; use env_logger::Env; use ordered_float::OrderedFloat; +use serde::Serialize; use std::fs::File; use std::io::Write; +use std::path::PathBuf; use std::{fs, process}; +///////////////////////////////////////////////////////////////////////////////////// +// Normalizer CLI application +///////////////////////////////////////////////////////////////////////////////////// + +#[derive(Parser, Debug)] +#[command( + name = "The Real First Universal Charset Detector. Discover originating encoding used on text file. Normalize text to unicode." +)] +#[command(author, version, about, long_about = None)] +struct CLINormalizerArgs { + /// File(s) to be analysed + #[arg(required = true, action = clap::ArgAction::Append)] + pub files: Vec, + + /// Display complementary information about file if any. Stdout will contain logs about the detection process. + #[arg(short = 'v', long = "verbose", default_value_t = false)] + pub verbose: bool, + + /// Output complementary possibilities if any. Top-level JSON WILL be a list. + #[arg(short = 'a', long = "with-alternative", default_value_t = false)] + pub alternatives: bool, + + /// Permit to normalize input file. If not set, program does not write anything. + #[arg(short, long, default_value_t = false)] + pub normalize: bool, + + /// Only output the charset detected to STDOUT. Disabling JSON output. + #[arg(short, long, default_value_t = false)] + pub minimal: bool, + + /// Replace file when trying to normalize it instead of creating a new one. + #[arg(short, long, default_value_t = false)] + pub replace: bool, + + /// Replace file without asking if you are sure, use this flag with caution. + #[arg(short, long, default_value_t = false)] + pub force: bool, + + /// Define a custom maximum amount of chaos allowed in decoded content. 0. <= chaos <= 1. + #[arg(short, long, default_value_t = 0.2)] + pub threshold: f32, +} + +#[derive(Default, Debug, Serialize)] +struct CLINormalizerResult { + /// Path to analysed file + pub path: PathBuf, + /// Guessed encoding + pub encoding: Option, + /// Possible aliases of guessed encoding + pub encoding_aliases: Vec, + /// Alternative possible encodings + pub alternative_encodings: Vec, + /// Most probably language + pub language: String, + /// Found alphabets + pub alphabets: Vec, + /// Does it has SIG or BOM mark? + pub has_sig_or_bom: bool, + /// Chaos (mess) level + pub chaos: String, + /// Coherence (language detection) level + pub coherence: String, + /// Path to decoded data + pub unicode_path: Option, + pub is_preferred: bool, +} + fn normalizer(args: &CLINormalizerArgs) -> Result { match (args.replace, args.normalize, args.force, args.threshold) { (true, false, _, _) => return Err("Use --replace in addition to --normalize only.".into()), diff --git a/src/performance.rs b/src/performance.rs index 6dd8ac5..f0335b9 100644 --- a/src/performance.rs +++ b/src/performance.rs @@ -1,6 +1,5 @@ use chardetng::EncodingDetector; use charset_normalizer_rs::consts::CHARDET_CORRESPONDENCE; -use charset_normalizer_rs::entity::{PerformanceArgs, PerformanceResult}; use charset_normalizer_rs::from_bytes; use charset_normalizer_rs::utils::get_large_test_datasets; use clap::Parser; @@ -13,6 +12,27 @@ use std::io::Read; use std::process; use std::time::{Duration, Instant}; +///////////////////////////////////////////////////////////////////////////////////// +// Performance binary application +///////////////////////////////////////////////////////////////////////////////////// + +#[derive(Parser, Debug)] +#[command(name = "Performance check for charset-normalizer-rs vs chardet vs chardetng")] +#[command(author, version, about, long_about = None)] +struct PerformanceArgs { + /// Apply artificial size increase to challenge the detection mechanism further + #[arg(short, long, default_value_t = 1)] + pub size_increase: u8, +} + +// Struct to save result of each test in performance app +struct PerformanceResult { + /// Performance test duration + pub duration: Duration, + /// Is result accurate? + pub correct: bool, +} + // Check result fn check_result( correct_encodings: &Vec, @@ -97,7 +117,7 @@ fn performance_compare(args: &PerformanceArgs) -> i32 { tested_functions.insert( "A) charset-normalizer-rs", Box::new(|bytes: &Vec| { - if let Some(gb) = from_bytes(bytes, None).get_best() { + if let Some(gb) = from_bytes(bytes, None).unwrap().get_best() { gb.encoding().to_string() } else { String::from("None") diff --git a/src/tests/cd.rs b/src/tests/cd.rs index 1719e49..57d58c5 100644 --- a/src/tests/cd.rs +++ b/src/tests/cd.rs @@ -1,5 +1,6 @@ use crate::cd::*; use crate::entity::{CoherenceMatch, CoherenceMatches, Language}; +use ordered_float::OrderedFloat; #[test] fn test_encoding_unicode_range() { @@ -104,16 +105,16 @@ fn test_filter_alt_coherence_matches() { let input: CoherenceMatches = vec![ CoherenceMatch { language: &Language::English, - score: 7.77, + score: OrderedFloat(7.77), }, CoherenceMatch { language: &Language::English, - score: 4.44, + score: OrderedFloat(4.44), }, ]; let expected_output: CoherenceMatches = vec![CoherenceMatch { language: &Language::English, - score: 7.77, + score: OrderedFloat(7.77), }]; assert_eq!(filter_alt_coherence_matches(&input), expected_output); } @@ -124,45 +125,45 @@ fn test_merge_coherence_ratios() { vec![ CoherenceMatch { language: &Language::English, - score: 7.77, + score: OrderedFloat(7.77), }, CoherenceMatch { language: &Language::English, - score: 4.44, + score: OrderedFloat(4.44), }, ], vec![ CoherenceMatch { language: &Language::Ukrainian, - score: 5.0, + score: OrderedFloat(5.0), }, CoherenceMatch { language: &Language::Ukrainian, - score: 10.0, + score: OrderedFloat(10.0), }, ], vec![CoherenceMatch { language: &Language::Bulgarian, - score: 12.0, + score: OrderedFloat(12.0), }], ]; let mut expected_output: CoherenceMatches = vec![ CoherenceMatch { language: &Language::English, - score: 6.105, + score: OrderedFloat(6.105), }, CoherenceMatch { language: &Language::Ukrainian, - score: 7.5, + score: OrderedFloat(7.5), }, CoherenceMatch { language: &Language::Bulgarian, - score: 12.0, + score: OrderedFloat(12.0), }, ]; let mut output = merge_coherence_ratios(&input); - output.sort_unstable_by(|a, b| a.score.partial_cmp(&b.score).unwrap()); - expected_output.sort_unstable_by(|a, b| a.score.partial_cmp(&b.score).unwrap()); + output.sort_unstable_by(|a, b| a.score.cmp(&b.score)); + expected_output.sort_unstable_by(|a, b| a.score.cmp(&b.score)); assert_eq!(output, expected_output); } diff --git a/src/tests/detection_base.rs b/src/tests/detection_base.rs index f0e139b..b0b1544 100644 --- a/src/tests/detection_base.rs +++ b/src/tests/detection_base.rs @@ -6,7 +6,7 @@ use encoding::EncoderTrap; #[test] fn test_empty() { let bytes: Vec = b"".to_vec(); - let result = from_bytes(&bytes, None); + let result = from_bytes(&bytes, None).unwrap(); let best_guess = result.get_best(); assert!( @@ -31,7 +31,7 @@ fn test_empty_but_with_bom_or_sig() { ]; for (input, expected_encoding) in tests { - let result = from_bytes(&input, None); + let result = from_bytes(&input, None).unwrap(); let best_guess = result.get_best(); assert!( best_guess.is_some(), @@ -97,7 +97,7 @@ fn test_content_with_bom_or_sig() { ]; for (input, expected_encoding) in tests { - let result = from_bytes(&input, None); + let result = from_bytes(&input, None).unwrap(); let best_guess = result.get_best(); assert!( best_guess.is_some(), @@ -129,7 +129,7 @@ fn test_obviously_ascii_content() { ]; for input in tests { - let result = from_bytes(input, None); + let result = from_bytes(input, None).unwrap(); let best_guess = result.get_best(); assert!( best_guess.is_some(), @@ -161,7 +161,7 @@ fn test_obviously_utf8_content() { ]; for input in tests { - let result = from_bytes(input.as_bytes(), None); + let result = from_bytes(input.as_bytes(), None).unwrap(); let best_guess = result.get_best(); assert!( best_guess.is_some(), @@ -180,7 +180,7 @@ fn test_obviously_utf8_content() { #[test] fn test_unicode_ranges_property() { let text = "πŸ˜€ Hello World! How affairs are going? πŸ˜€"; - let result = from_bytes(text.as_bytes(), None); + let result = from_bytes(text.as_bytes(), None).unwrap(); let best_guess = result.get_best(); let ur = best_guess.unwrap().unicode_ranges(); assert!(ur.contains(&"Basic Latin".to_string())); @@ -192,7 +192,7 @@ fn test_mb_cutting_chk() { let payload = b"\xbf\xaa\xbb\xe7\xc0\xfb \xbf\xb9\xbc\xf6 \xbf\xac\xb1\xb8\xc0\xda\xb5\xe9\xc0\xba \xba\xb9\xc0\xbd\xbc\xad\xb3\xaa ".repeat(128); let mut settings = NormalizerSettings::default(); settings.include_encodings.push(String::from("euc-kr")); - let result = from_bytes(payload.as_slice(), Some(settings)); + let result = from_bytes(payload.as_slice(), Some(settings)).unwrap(); let best_guess = result.get_best().unwrap(); assert_eq!(result.len(), 1); assert_eq!(best_guess.encoding(), "euc-kr"); diff --git a/src/tests/detection_edge_case.rs b/src/tests/detection_edge_case.rs index 8110481..a2bab77 100644 --- a/src/tests/detection_edge_case.rs +++ b/src/tests/detection_edge_case.rs @@ -5,7 +5,7 @@ fn test_undefined_unicode_ranges() { let tests = [b"\xef\xbb\xbf\xf0\x9f\xa9\xb3".as_slice()]; for input in tests { - let result = from_bytes(input, None); + let result = from_bytes(input, None).unwrap(); let best_guess = result.get_best(); assert!( best_guess.is_some(), diff --git a/src/tests/detection_large_payload.rs b/src/tests/detection_large_payload.rs index 6f0c7f0..8292c40 100644 --- a/src/tests/detection_large_payload.rs +++ b/src/tests/detection_large_payload.rs @@ -6,7 +6,7 @@ fn test_large_payload_utf8_sig_basic_entry() { let mut payload = b"\xef\xbb\xbf".as_slice().to_vec(); payload.extend(b"0".repeat(TOO_BIG_SEQUENCE + 1).as_slice().to_vec()); - let result = from_bytes(&payload, None); + let result = from_bytes(&payload, None).unwrap(); let best_guess = result.get_best(); assert!( best_guess.is_some(), @@ -29,7 +29,7 @@ fn test_large_payload_utf8_sig_basic_entry() { fn test_large_payload_ascii_sig_basic_entry() { let payload = b"0".repeat(TOO_BIG_SEQUENCE + 1).as_slice().to_vec(); - let result = from_bytes(&payload, None); + let result = from_bytes(&payload, None).unwrap(); let best_guess = result.get_best(); assert!( best_guess.is_some(), @@ -59,7 +59,7 @@ fn test_misleading_large_sequence() { .to_vec(); payload.extend("ζˆ‘ζ²‘ζœ‰εŸ‹ζ€¨οΌŒη£‹η £ηš„εͺζ˜―δΈ€δΊ›ζ—Άι—΄γ€‚ η£‹η £ηš„εͺζ˜―δΈ€δΊ›ζ—Άι—΄γ€‚".as_bytes()); - let result = from_bytes(&payload, None); + let result = from_bytes(&payload, None).unwrap(); assert!(!result.is_empty(), "No results"); let best_guess = result.get_best(); assert!(best_guess.is_some(), "Best guess is exists"); diff --git a/src/tests/entity.rs b/src/tests/entity.rs index 2a67d1d..589ac62 100644 --- a/src/tests/entity.rs +++ b/src/tests/entity.rs @@ -1,4 +1,5 @@ use crate::entity::{CharsetMatch, CharsetMatches, CoherenceMatch, Language}; +use ordered_float::OrderedFloat; #[test] fn test_charset_matches() { @@ -7,18 +8,18 @@ fn test_charset_matches() { /////////////////////////////////////////////////////////////////////////////////////////// let mut c_matches = CharsetMatches::new(Some(vec![CharsetMatch::new( - &[0xD0, 0xA2, 0xD0, 0xB5, 0xD1, 0x81, 0xD1, 0x82], + (&[0xD0, 0xA2, 0xD0, 0xB5, 0xD1, 0x81, 0xD1, 0x82]).into(), "utf-8", 0.01, false, &vec![ CoherenceMatch { language: &Language::Russian, - score: 0.99, + score: OrderedFloat(0.99), }, CoherenceMatch { language: &Language::Ukrainian, - score: 0.8, + score: OrderedFloat(0.8), }, ], None, @@ -27,18 +28,18 @@ fn test_charset_matches() { // append new CharsetMatch c_matches.append(CharsetMatch::new( - &[0xD0, 0xA2, 0xD0, 0xB5, 0xD1, 0x81, 0xD1, 0x82], + (&[0xD0, 0xA2, 0xD0, 0xB5, 0xD1, 0x81, 0xD1, 0x82]).into(), "utf-16le", 0.011, false, &vec![ CoherenceMatch { language: &Language::Russian, - score: 0.95, + score: OrderedFloat(0.95), }, CoherenceMatch { language: &Language::Kazakh, - score: 0.7, + score: OrderedFloat(0.7), }, ], None, @@ -85,18 +86,18 @@ fn test_charset_matches() { assert_eq!( c_matches[1], CharsetMatch::new( - &[0xD0, 0xA2, 0xD0, 0xB5, 0xD1, 0x81, 0xD1, 0x82], + (&[0xD0, 0xA2, 0xD0, 0xB5, 0xD1, 0x81, 0xD1, 0x82]).into(), "utf-16le", 0.044, true, &vec!( CoherenceMatch { language: &Language::Russian, - score: 0.1, + score: OrderedFloat(0.1), }, CoherenceMatch { language: &Language::Kazakh, - score: 0.5, + score: OrderedFloat(0.5), }, ), None, diff --git a/src/utils.rs b/src/utils.rs index eb605d9..6f25107 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -14,7 +14,7 @@ use icu_normalizer::DecomposingNormalizer; use unicode_names2::name; use std::borrow::Cow; -use std::fs; +#[cfg(any(test, feature = "performance"))] use std::path::{Path, PathBuf}; // Utils module @@ -32,8 +32,10 @@ pub(crate) fn in_range(range: Option<&str>, ranges_partial: &[&str]) -> bool { #[inline] pub(crate) fn in_description(character: char, patterns: &[&str]) -> bool { - name(character) - .is_some_and(|ucd_name| patterns.iter().any(|&s| ucd_name.to_string().contains(s))) + name(character).is_some_and(|ucd_name| { + let ucd_name = ucd_name.to_string(); + patterns.iter().any(|&s| ucd_name.contains(s)) + }) } pub(crate) fn is_accentuated(character: char) -> bool { @@ -345,13 +347,13 @@ pub(crate) fn is_suspiciously_successive_range( [range_a, range_b] .iter() .any(|x| x.contains("Punctuation") || x.contains("Forms")), // has_punct_or_forms - [range_a, range_b].iter().any(|&x| x == "Basic Latin"), // is_any_basic_latin + [range_a, range_b].contains(&"Basic Latin"), // is_any_basic_latin ) { (true, true, _, _, _, _) // both are japanese | (true, _, true, _, _, _) | (_, true, true, _, _, _) //either is japanese and either contains CJK | (_, _, true, true, _, _) // either has both CJK and Hanguls - | (_, _, true, _, true, _) // either has chinese and dedicated punctuation and separators - | (_, _, _, true, _, true) // either has hangul and basic latin + | (_, _, true, _, true, _) // either has chinese and dedicated punctuation and separators + | (_, _, _, true, _, true) // either has hangul and basic latin => return false, _ => {} // All other combinations } @@ -380,11 +382,12 @@ pub(super) fn is_invalid_chunk( } // Get large datasets +#[cfg(any(test, feature = "performance"))] fn collect_large_sets(dir: &Path) -> Vec { let mut files = Vec::new(); if dir.is_dir() { - for entry in fs::read_dir(dir).unwrap() { + for entry in std::fs::read_dir(dir).unwrap() { let path = entry.unwrap().path(); if path.is_dir() { @@ -401,10 +404,11 @@ fn collect_large_sets(dir: &Path) -> Vec { } // Get large datasets +#[cfg(any(test, feature = "performance"))] pub fn get_large_test_datasets() -> Result)>, String> { let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("src/tests/data/largesets/"); - match fs::metadata(&path) { + match std::fs::metadata(&path) { Ok(metadata) if metadata.is_dir() => Ok(collect_large_sets(&path) .iter() .filter_map(|set| {