From ec178fdb52403b568a6586aebd306e590e654da0 Mon Sep 17 00:00:00 2001 From: sxyazi Date: Sun, 5 Apr 2026 14:05:42 +0800 Subject: [PATCH] refactor: unify progress representation and add cleanup state (#3853) --- Cargo.lock | 692 +++++++++++++++---------- Cargo.toml | 8 +- yazi-actor/src/lives/task.rs | 3 +- yazi-fs/src/sorter.rs | 4 +- yazi-scheduler/Cargo.toml | 1 + yazi-scheduler/src/cleanup.rs | 11 + yazi-scheduler/src/fetch/progress.rs | 16 +- yazi-scheduler/src/file/out.rs | 22 +- yazi-scheduler/src/file/progress.rs | 224 +++----- yazi-scheduler/src/lib.rs | 2 +- yazi-scheduler/src/macros.rs | 27 + yazi-scheduler/src/plugin/progress.rs | 16 +- yazi-scheduler/src/preload/out.rs | 4 +- yazi-scheduler/src/preload/progress.rs | 18 +- yazi-scheduler/src/process/progress.rs | 44 +- yazi-scheduler/src/progress.rs | 210 +++----- yazi-scheduler/src/size/progress.rs | 16 +- yazi-scheduler/src/summary.rs | 2 +- yazi-scheduler/src/worker.rs | 4 +- 19 files changed, 663 insertions(+), 661 deletions(-) create mode 100644 yazi-scheduler/src/cleanup.rs diff --git a/Cargo.lock b/Cargo.lock index 97cbf293..acf8cea5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -27,6 +27,16 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "aead" +version = "0.6.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b657e772794c6b04730ea897b66a058ccd866c16d1967da05eeeecec39043fe" +dependencies = [ + "crypto-common 0.2.1", + "inout 0.2.2", +] + [[package]] name = "aes" version = "0.8.4" @@ -34,7 +44,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", + "cpufeatures 0.2.17", +] + +[[package]] +name = "aes" +version = "0.9.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04097e08a47d9ad181c2e1f4a5fabc9ae06ce8839a333ba9a949bcb0d31fd2a3" +dependencies = [ + "cipher 0.5.1", + "cpubits", "cpufeatures 0.2.17", ] @@ -44,11 +65,25 @@ version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ - "aead", - "aes", - "cipher", - "ctr", - "ghash", + "aead 0.5.2", + "aes 0.8.4", + "cipher 0.4.4", + "ctr 0.9.2", + "ghash 0.5.1", + "subtle", +] + +[[package]] +name = "aes-gcm" +version = "0.11.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22c0c90bbe8d4f77c3ca9ddabe41a1f8382d6fc1f7cea89459d0f320371f972" +dependencies = [ + "aead 0.6.0-rc.10", + "aes 0.9.0-rc.4", + "cipher 0.5.1", + "ctr 0.10.0-rc.4", + "ghash 0.6.0", "subtle", ] @@ -171,9 +206,9 @@ checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] name = "arc-swap" -version = "1.9.0" +version = "1.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a07d1f37ff60921c83bdfc7407723bdefe89b44b98a9b772f225c8f9d67141a6" +checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" dependencies = [ "rustversion", ] @@ -298,12 +333,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - [[package]] name = "base16ct" version = "1.0.0" @@ -329,7 +358,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2" dependencies = [ "blowfish", - "pbkdf2", + "pbkdf2 0.12.2", "sha2 0.10.9", ] @@ -433,7 +462,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" dependencies = [ - "hybrid-array 0.4.10", + "hybrid-array", ] [[package]] @@ -445,6 +474,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "block-padding" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710f1dd022ef4e93f8a438b4ba958de7f64308434fa6a87104481645cc30068b" +dependencies = [ + "hybrid-array", +] + [[package]] name = "blowfish" version = "0.9.1" @@ -452,7 +490,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" dependencies = [ "byteorder", - "cipher", + "cipher 0.4.4", ] [[package]] @@ -536,14 +574,23 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" dependencies = [ - "cipher", + "cipher 0.4.4", +] + +[[package]] +name = "cbc" +version = "0.2.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab1412b9ae2463ede01f1e591412dfbcfeacecf40e8c4c3e0655814c19065c38" +dependencies = [ + "cipher 0.5.1", ] [[package]] name = "cc" -version = "1.2.58" +version = "1.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" +checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" dependencies = [ "find-msvc-tools", "jobserver", @@ -570,10 +617,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", "cpufeatures 0.2.17", ] +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.0", +] + [[package]] name = "chrono" version = "0.4.44" @@ -595,7 +653,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common 0.1.7", - "inout", + "inout 0.1.4", +] + +[[package]] +name = "cipher" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" +dependencies = [ + "block-buffer 0.12.0", + "crypto-common 0.2.1", + "inout 0.2.2", ] [[package]] @@ -678,9 +747,9 @@ dependencies = [ [[package]] name = "cmov" -version = "0.5.0-pre.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5417da527aa9bf6a1e10a781231effd1edd3ee82f27d5f8529ac9b279babce96" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" [[package]] name = "color_quant" @@ -766,6 +835,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "cpubits" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -883,26 +958,18 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array 0.14.7", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-bigint" -version = "0.7.0-rc.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37387ceb32048ff590f2cbd24d8b05fffe63c3f69a5cfa089d4f722ca4385a19" +checksum = "42a0d26b245348befa0c121944541476763dcc46ede886c88f9d12e1697d27c3" dependencies = [ + "cpubits", "ctutils", + "getrandom 0.4.2", + "hybrid-array", "num-traits", - "rand_core 0.10.0-rc-3", + "rand_core 0.10.0", "serdect", + "subtle", "zeroize", ] @@ -922,18 +989,20 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" dependencies = [ - "hybrid-array 0.4.10", + "getrandom 0.4.2", + "hybrid-array", + "rand_core 0.10.0", ] [[package]] name = "crypto-primes" -version = "0.7.0-pre.6" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79c98a281f9441200b24e3151407a629bfbe720399186e50516da939195e482" +checksum = "21f41f23de7d24cdbda7f0c4d9c0351f99a4ceb258ef30e5c1927af8987ffe5a" dependencies = [ - "crypto-bigint 0.7.0-rc.18", + "crypto-bigint", "libm", - "rand_core 0.10.0-rc-3", + "rand_core 0.10.0", ] [[package]] @@ -952,28 +1021,38 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher", + "cipher 0.4.4", +] + +[[package]] +name = "ctr" +version = "0.10.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee683dd898fbd052617b4514bc31f98bc32081a83b69ec46adef3b1ef4ae36f" +dependencies = [ + "cipher 0.5.1", ] [[package]] name = "ctutils" -version = "0.3.2" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758e5ed90be3c8abff7f9a6f37ab7f6d8c59c2210d448b81f3f508134aec84e4" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" dependencies = [ "cmov", + "subtle", ] [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0-pre.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "335f1947f241137a14106b6f5acc5918a5ede29c9d71d3f2cb1678d5075d9fc3" dependencies = [ "cfg-if", "cpufeatures 0.2.17", "curve25519-dalek-derive", - "digest 0.10.7", + "digest 0.11.2", "fiat-crypto", "rustc_version", "subtle", @@ -1103,17 +1182,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5729f5117e208430e437df2f4843f5e5952997175992d1414f94c57d61e270b4" -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid 0.9.6", - "pem-rfc7468 0.7.0", - "zeroize", -] - [[package]] name = "der" version = "0.8.0" @@ -1209,6 +1277,7 @@ dependencies = [ "block-buffer 0.12.0", "const-oid 0.10.2", "crypto-common 0.2.1", + "ctutils", ] [[package]] @@ -1249,39 +1318,41 @@ checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0-rc.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "91bbdd377139884fafcad8dc43a760a3e1e681aa26db910257fa6535b70e1829" dependencies = [ - "der 0.7.10", - "digest 0.10.7", + "der", + "digest 0.11.2", "elliptic-curve", "rfc6979", - "signature 2.2.0", - "spki 0.7.3", + "signature", + "spki", + "zeroize", ] [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "c6e914c7c52decb085cea910552e24c63ac019e3ab8bf001ff736da9a9d9d890" dependencies = [ - "pkcs8 0.10.2", - "signature 2.2.0", + "pkcs8", + "signature", ] [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "3.0.0-pre.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "053618a4c3d3bc24f188aa660ae75a46eeab74ef07fb415c61431e5e7cd4749b" dependencies = [ "curve25519-dalek", "ed25519", - "rand_core 0.6.4", + "rand_core 0.10.0", "serde", - "sha2 0.10.9", + "sha2 0.11.0", + "signature", "subtle", "zeroize", ] @@ -1294,20 +1365,22 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.0-rc.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "e84043d573efd4ac9d2d125817979a379204bf7e328b25a4a30487e8d100e618" dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.5", - "digest 0.10.7", - "ff", - "generic-array 0.14.7", - "group", + "base16ct", + "crypto-bigint", + "crypto-common 0.2.1", + "digest 0.11.2", "hkdf", - "pem-rfc7468 0.7.0", - "pkcs8 0.10.2", - "rand_core 0.6.4", + "hybrid-array", + "once_cell", + "pem-rfc7468 1.0.0", + "pkcs8", + "rand_core 0.10.0", + "rustcrypto-ff", + "rustcrypto-group", "sec1", "subtle", "zeroize", @@ -1473,21 +1546,11 @@ dependencies = [ "thiserror 1.0.69", ] -[[package]] -name = "ff" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "filedescriptor" @@ -1657,7 +1720,6 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", - "zeroize", ] [[package]] @@ -1705,6 +1767,7 @@ dependencies = [ "cfg-if", "libc", "r-efi 6.0.0", + "rand_core 0.10.0", "wasip2", "wasip3", ] @@ -1716,7 +1779,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", - "polyval", + "polyval 0.6.2", +] + +[[package]] +name = "ghash" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eecf2d5dc9b66b732b97707a0210906b1d30523eb773193ab777c0c84b3e8d5" +dependencies = [ + "polyval 0.7.1", ] [[package]] @@ -1748,17 +1820,6 @@ dependencies = [ "regex-syntax", ] -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "half" version = "2.7.1" @@ -1824,11 +1885,11 @@ checksum = "e712f64ec3850b98572bffac52e2c6f282b29fe6c5fa6d42334b30be438d95c1" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ - "hmac", + "hmac 0.13.0", ] [[package]] @@ -1841,12 +1902,12 @@ dependencies = [ ] [[package]] -name = "hybrid-array" -version = "0.2.3" +name = "hmac" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d35805454dc9f8662a98d6d61886ffe26bd465f5960e0e55345c70d5c0d2a9" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "typenum", + "digest 0.11.2", ] [[package]] @@ -1855,7 +1916,10 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" dependencies = [ + "ctutils", + "subtle", "typenum", + "zeroize", ] [[package]] @@ -1991,10 +2055,20 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ - "block-padding", + "block-padding 0.3.3", "generic-array 0.14.7", ] +[[package]] +name = "inout" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" +dependencies = [ + "block-padding 0.4.2", + "hybrid-array", +] + [[package]] name = "instability" version = "0.3.12" @@ -2010,35 +2084,45 @@ dependencies = [ [[package]] name = "internal-russh-forked-ssh-key" -version = "0.6.16+upstream-0.6.7" +version = "0.6.18+upstream-0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe44f2bbd99fcb302e246e2d6bcf51aeda346d02a365f80296a07a8c711b6da6" +checksum = "25f8a978272e3cbdf4768f7363eb1c8e1e6ba63c52a3ed05e29e222da4aec7cb" dependencies = [ "argon2", "bcrypt-pbkdf", - "digest 0.11.2", + "crypto-bigint", "ecdsa", "ed25519-dalek", "hex", - "hmac", + "hmac 0.13.0", "num-bigint-dig", "p256", "p384", "p521", - "rand_core 0.6.4", + "rand_core 0.10.0", "rsa", "sec1", - "sha1 0.10.6", "sha1 0.11.0", - "sha2 0.10.9", - "signature 2.2.0", - "signature 3.0.0-rc.6", + "sha2 0.11.0", + "signature", "ssh-cipher", "ssh-encoding", "subtle", "zeroize", ] +[[package]] +name = "internal-russh-num-bigint" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae8e22120c32fb4d19ec55fba35015f57095cd95a2e3b732e44457f5915b2ee8" +dependencies = [ + "num-integer", + "num-traits", + "rand 0.10.0", + "rand_core 0.10.0", +] + [[package]] name = "interpolate_name" version = "0.2.4" @@ -2106,21 +2190,22 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.6" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +checksum = "9e24a010dd405bd7ed803e5253182815b41bf2e6a80cc3bfc066658e03a198aa" dependencies = [ - "cpufeatures 0.2.17", + "cfg-if", + "cpufeatures 0.3.0", ] [[package]] name = "kem" -version = "0.3.0-pre.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b8645470337db67b01a7f966decf7d0bafedbae74147d33e641c67a91df239f" +checksum = "01737161ba802849cfd486b5bd209d38ba4943494c249a8126005170c7621edd" dependencies = [ - "rand_core 0.6.4", - "zeroize", + "crypto-common 0.2.1", + "rand_core 0.10.0", ] [[package]] @@ -2365,13 +2450,14 @@ dependencies = [ [[package]] name = "ml-kem" -version = "0.2.3" +version = "0.3.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de49b3df74c35498c0232031bb7e85f9389f913e2796169c8ab47a53993a18f" +checksum = "04437cb1a66c0b78740927b76cc61f218344b9f6ef3dd430e283274a718ef0e9" dependencies = [ - "hybrid-array 0.2.3", + "hybrid-array", "kem", - "rand_core 0.6.4", + "module-lattice", + "rand_core 0.10.0", "sha3", ] @@ -2426,6 +2512,17 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "module-lattice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "164eb3faeaecbd14b0b2a917c1b4d0c035097a9c559b0bed85c2cdd032bc8faa" +dependencies = [ + "ctutils", + "hybrid-array", + "num-traits", +] + [[package]] name = "moxcms" version = "0.8.1" @@ -2536,7 +2633,6 @@ checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ "num-integer", "num-traits", - "rand 0.8.5", ] [[package]] @@ -2749,40 +2845,43 @@ dependencies = [ [[package]] name = "p256" -version = "0.13.2" +version = "0.14.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +checksum = "44f0a10fe314869359cb2901342b045f4e5a962ef9febc006f03d2a8c848fe4c" dependencies = [ "ecdsa", "elliptic-curve", + "primefield", "primeorder", - "sha2 0.10.9", + "sha2 0.11.0", ] [[package]] name = "p384" -version = "0.13.1" +version = "0.14.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +checksum = "b079e66810c55ab3d6ba424e056dc4aefcdb8046c8c3f3816142edbdd7af7721" dependencies = [ "ecdsa", "elliptic-curve", + "fiat-crypto", + "primefield", "primeorder", - "sha2 0.10.9", + "sha2 0.11.0", ] [[package]] name = "p521" -version = "0.13.3" +version = "0.14.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" +checksum = "9eecc34c4c6e6596d5271fecf90ac4f16593fa198e77282214d0c22736aa9266" dependencies = [ - "base16ct 0.2.0", + "base16ct", "ecdsa", "elliptic-curve", + "primefield", "primeorder", - "rand_core 0.6.4", - "sha2 0.10.9", + "sha2 0.11.0", ] [[package]] @@ -2887,7 +2986,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" dependencies = [ "digest 0.10.7", - "hmac", + "hmac 0.12.1", +] + +[[package]] +name = "pbkdf2" +version = "0.13.0-rc.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f24f3eb2f4471b1730d59e4b730b747939960a8c7eb0c33c5a9076f2d3dddea" +dependencies = [ + "digest 0.11.2", + "hmac 0.13.0", ] [[package]] @@ -3021,35 +3130,25 @@ version = "0.8.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "986d2e952779af96ea048f160fd9194e1751b4faea78bcf3ceb456efe008088e" dependencies = [ - "der 0.8.0", - "spki 0.8.0-rc.4", + "der", + "spki", ] [[package]] name = "pkcs5" -version = "0.7.1" +version = "0.8.0-rc.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" +checksum = "c5a777c6e26664bc9504b3ce3f6133f8f20d9071f130a4f9fcbd3186959d8dd6" dependencies = [ - "aes", - "cbc", - "der 0.7.10", - "pbkdf2", + "aes 0.9.0-rc.4", + "aes-gcm 0.11.0-rc.3", + "cbc 0.2.0-rc.4", + "der", + "pbkdf2 0.13.0-rc.10", + "rand_core 0.10.0", "scrypt", - "sha2 0.10.9", - "spki 0.7.3", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.10", - "pkcs5", - "rand_core 0.6.4", - "spki 0.7.3", + "sha2 0.11.0", + "spki", ] [[package]] @@ -3058,8 +3157,10 @@ version = "0.11.0-rc.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12922b6296c06eb741b02d7b5161e3aaa22864af38dfa025a1a3ba3f68c84577" dependencies = [ - "der 0.8.0", - "spki 0.8.0-rc.4", + "der", + "pkcs5", + "rand_core 0.10.0", + "spki", ] [[package]] @@ -3102,7 +3203,7 @@ checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures 0.2.17", "opaque-debug", - "universal-hash", + "universal-hash 0.5.1", ] [[package]] @@ -3114,7 +3215,18 @@ dependencies = [ "cfg-if", "cpufeatures 0.2.17", "opaque-debug", - "universal-hash", + "universal-hash 0.5.1", +] + +[[package]] +name = "polyval" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfc63250416fea14f5749b90725916a6c903f599d51cb635aa7a52bfd03eede" +dependencies = [ + "cpubits", + "cpufeatures 0.3.0", + "universal-hash 0.6.1", ] [[package]] @@ -3149,10 +3261,24 @@ dependencies = [ ] [[package]] -name = "primeorder" -version = "0.13.6" +name = "primefield" +version = "0.14.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +checksum = "c6543f5eec854fbf74ba5ef651fbdc9408919b47c3e1526623687135c16d12e9" +dependencies = [ + "crypto-bigint", + "crypto-common 0.2.1", + "rand_core 0.10.0", + "rustcrypto-ff", + "subtle", + "zeroize", +] + +[[package]] +name = "primeorder" +version = "0.14.0-rc.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "569d9ad6ef822bb0322c7e7d84e5e286244050bd5246cac4c013535ae91c2c90" dependencies = [ "elliptic-curve", ] @@ -3302,6 +3428,17 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" +dependencies = [ + "chacha20 0.10.0", + "getrandom 0.4.2", + "rand_core 0.10.0", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -3343,9 +3480,9 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.10.0-rc-3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66ee92bc15280519ef199a274fe0cafff4245d31bc39aaa31c011ad56cb1f05" +checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" [[package]] name = "ratatui" @@ -3588,11 +3725,11 @@ checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.5.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "23a3127ee32baec36af75b4107082d9bd823501ec14a4e016be4b6b37faa74ae" dependencies = [ - "hmac", + "hmac 0.13.0", "subtle", ] @@ -3618,40 +3755,42 @@ dependencies = [ [[package]] name = "rsa" -version = "0.10.0-rc.12" +version = "0.10.0-rc.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a2b1eacbc34fbaf77f6f1db1385518446008d49b9f9f59dc9d1340fce4ca9e" +checksum = "87ed3e93fc7e473e464b9726f4759659e72bc8665e4b8ea227547024f416d905" dependencies = [ "const-oid 0.10.2", - "crypto-bigint 0.7.0-rc.18", + "crypto-bigint", "crypto-primes", "digest 0.11.2", "pkcs1", - "pkcs8 0.11.0-rc.11", - "rand_core 0.10.0-rc-3", + "pkcs8", + "rand_core 0.10.0", "sha2 0.11.0", - "signature 3.0.0-rc.6", - "spki 0.8.0-rc.4", + "signature", + "spki", "zeroize", ] [[package]] name = "russh" -version = "0.59.0" +version = "0.60.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cb8a9835664462e2fae27bbe22deb66482fe1566ce3ea73a6b72261ca774ceb" +checksum = "3b530252dc3ff163b73a7e48c97b925450d2ca53edcb466a46ad0a231e45f998" dependencies = [ - "aes", + "aes 0.8.4", "bitflags 2.11.0", - "block-padding", + "block-padding 0.3.3", "byteorder", "bytes", - "cbc", - "ctr", + "cbc 0.1.2", + "cipher 0.5.1", + "crypto-bigint", + "ctr 0.9.2", "curve25519-dalek", "data-encoding", "delegate", - "der 0.7.10", + "der", "digest 0.10.7", "ecdsa", "ed25519-dalek", @@ -3661,23 +3800,25 @@ dependencies = [ "generic-array 1.3.5", "getrandom 0.2.17", "hex-literal", - "hmac", - "inout", + "hmac 0.12.1", + "inout 0.1.4", "internal-russh-forked-ssh-key", + "internal-russh-num-bigint", "log", "md5", "ml-kem", - "num-bigint", + "module-lattice", "p256", "p384", "p521", "pageant", - "pbkdf2", + "pbkdf2 0.12.2", "pkcs1", "pkcs5", - "pkcs8 0.10.2", - "rand 0.9.2", - "rand_core 0.10.0-rc-3", + "pkcs8", + "polyval 0.7.1", + "rand 0.10.0", + "rand_core 0.10.0", "ring", "rsa", "russh-cryptovec", @@ -3685,13 +3826,14 @@ dependencies = [ "sec1", "sha1 0.10.6", "sha2 0.10.9", - "signature 2.2.0", - "spki 0.7.3", + "signature", + "spki", "ssh-encoding", "subtle", "thiserror 2.0.18", "tokio", "typenum", + "universal-hash 0.6.1", "zeroize", ] @@ -3740,6 +3882,27 @@ dependencies = [ "semver", ] +[[package]] +name = "rustcrypto-ff" +version = "0.14.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd2a8adb347447693cd2ba0d218c4b66c62da9b0a5672b17b981e4291ec65ff6" +dependencies = [ + "rand_core 0.10.0", + "subtle", +] + +[[package]] +name = "rustcrypto-group" +version = "0.14.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "369f9b61aa45933c062c9f6b5c3c50ab710687eca83dd3802653b140b43f85ed" +dependencies = [ + "rand_core 0.10.0", + "rustcrypto-ff", + "subtle", +] + [[package]] name = "rustix" version = "0.38.44" @@ -3789,11 +3952,12 @@ dependencies = [ [[package]] name = "salsa20" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +checksum = "2f874456e72520ff1375a06c588eaf074b0f01f9e9e1aada45bd9b7954a6e42c" dependencies = [ - "cipher", + "cfg-if", + "cipher 0.5.1", ] [[package]] @@ -3837,34 +4001,35 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "scrypt" -version = "0.11.0" +version = "0.12.0-rc.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" +checksum = "e03ed5b54ed5fcc8e016cd94301416bc2c01c05c87a6742b97468337c8804598" dependencies = [ - "pbkdf2", + "cfg-if", + "pbkdf2 0.13.0-rc.10", "salsa20", - "sha2 0.10.9", + "sha2 0.11.0", ] [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ - "base16ct 0.2.0", - "der 0.7.10", - "generic-array 0.14.7", - "pkcs8 0.10.2", + "base16ct", + "ctutils", + "der", + "hybrid-array", "subtle", "zeroize", ] [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" @@ -3965,7 +4130,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9af4a3e75ebd5599b30d4de5768e00b5095d518a79fefc3ecbaf77e665d1ec06" dependencies = [ - "base16ct 1.0.0", + "base16ct", "serde", ] @@ -4015,11 +4180,11 @@ dependencies = [ [[package]] name = "sha3" -version = "0.10.8" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +checksum = "be176f1a57ce4e3d31c1a166222d9768de5954f811601fb7ca06fc8203905ce1" dependencies = [ - "digest 0.10.7", + "digest 0.11.2", "keccak", ] @@ -4050,9 +4215,9 @@ dependencies = [ [[package]] name = "signal-hook" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b57709da74f9ff9f4a27dce9526eec25ca8407c45a7887243b031a58935fb8e" +checksum = "b2a0c28ca5908dbdbcd52e6fdaa00358ab88637f8ab33e1f188dd510eb44b53d" dependencies = [ "libc", "signal-hook-registry", @@ -4087,28 +4252,18 @@ checksum = "e513e435a8898a0002270f29d0a708b7879708fb5c4d00e46983ca2d2d378cf0" dependencies = [ "futures-core", "libc", - "signal-hook 0.4.3", + "signal-hook 0.4.4", "tokio", ] [[package]] name = "signature" -version = "2.2.0" +version = "3.0.0-rc.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "signature" -version = "3.0.0-rc.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a96996ccff7dfa16f052bd995b4cecc72af22c35138738dc029f0ead6608d" +checksum = "7f1880df446116126965eeec169136b2e0251dba37c6223bcc819569550edea3" dependencies = [ "digest 0.11.2", - "rand_core 0.10.0-rc-3", + "rand_core 0.10.0", ] [[package]] @@ -4168,22 +4323,12 @@ checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" [[package]] name = "spki" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", - "der 0.7.10", -] - -[[package]] -name = "spki" -version = "0.8.0-rc.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8baeff88f34ed0691978ec34440140e1572b68c7dd4a495fd14a3dc1944daa80" -dependencies = [ - "base64ct", - "der 0.8.0", + "der", ] [[package]] @@ -4192,12 +4337,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" dependencies = [ - "aes", - "aes-gcm", - "cbc", - "chacha20", - "cipher", - "ctr", + "aes 0.8.4", + "aes-gcm 0.10.3", + "cbc 0.1.2", + "chacha20 0.9.1", + "cipher 0.4.4", + "ctr 0.9.2", "poly1305", "ssh-encoding", "subtle", @@ -4522,9 +4667,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.50.0" +version = "1.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" dependencies = [ "bytes", "libc", @@ -4539,9 +4684,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -4780,6 +4925,16 @@ dependencies = [ "subtle", ] +[[package]] +name = "universal-hash" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" +dependencies = [ + "crypto-common 0.2.1", + "ctutils", +] + [[package]] name = "untrusted" version = "0.9.0" @@ -5910,7 +6065,7 @@ dependencies = [ "objc2", "parking_lot", "percent-encoding", - "rand 0.9.2", + "rand 0.10.0", "regex", "scopeguard", "serde", @@ -6058,6 +6213,7 @@ dependencies = [ "ordered-float 5.3.0", "parking_lot", "serde", + "strum 0.28.0", "tokio", "tokio-util", "tracing", diff --git a/Cargo.toml b/Cargo.toml index b8221aa1..d5b697fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,7 +37,7 @@ debug = false [workspace.dependencies] ansi-to-tui = "8.0.1" anyhow = "1.0.102" -arc-swap = "1.9.0" +arc-swap = "1.9.1" base64 = "0.22.1" bitflags = { version = "2.11.0", features = [ "serde" ] } chrono = "0.4.44" @@ -60,10 +60,10 @@ ordered-float = { version = "5.3.0", features = [ "serde" ] } parking_lot = "0.12.5" paste = "1.0.15" percent-encoding = "2.3.2" -rand = { version = "0.9.2", default-features = false, features = [ "os_rng", "small_rng", "std" ] } +rand = { version = "0.10.0", default-features = false, features = [ "std", "sys_rng" ] } ratatui = { version = "0.30.0", features = [ "serde", "unstable-rendered-line-info", "unstable-widget-ref" ] } regex = "1.12.3" -russh = { version = "0.59.0", default-features = false, features = [ "ring", "rsa" ] } +russh = { version = "0.60.0", default-features = false, features = [ "ring", "rsa" ] } scopeguard = "1.2.0" serde = { version = "1.0.228", features = [ "derive" ] } serde_json = "1.0.149" @@ -71,7 +71,7 @@ serde_with = "3.18.0" strum = { version = "0.28.0", features = [ "derive" ] } syntect = { version = "5.3.0", default-features = false, features = [ "parsing", "plist-load", "regex-onig" ] } thiserror = "2.0.18" -tokio = { version = "1.50.0", features = [ "full" ] } +tokio = { version = "1.51.0", features = [ "full" ] } tokio-stream = "0.1.18" tokio-util = "0.7.18" toml = { version = "1.1.2" } diff --git a/yazi-actor/src/lives/task.rs b/yazi-actor/src/lives/task.rs index 7d63b7b5..e7e85905 100644 --- a/yazi-actor/src/lives/task.rs +++ b/yazi-actor/src/lives/task.rs @@ -2,6 +2,7 @@ use std::ops::Deref; use mlua::{AnyUserData, LuaSerdeExt, UserData, UserDataFields, Value}; use yazi_binding::{SER_OPT, cached_field}; +use yazi_scheduler::Progress; use super::{Lives, PtrCell}; @@ -29,8 +30,8 @@ impl UserData for TaskSnap { cached_field!(fields, name, |lua, me| lua.create_string(&me.name)); cached_field!(fields, prog, |lua, me| lua.to_value_with(&me.prog, SER_OPT)); - fields.add_field_method_get("cooked", |_, me| Ok(me.prog.cooked())); fields.add_field_method_get("running", |_, me| Ok(me.prog.running())); + fields.add_field_method_get("cooked", |_, me| Ok(me.prog.cooked())); fields.add_field_method_get("success", |_, me| Ok(me.prog.success())); fields.add_field_method_get("failed", |_, me| Ok(me.prog.failed())); fields.add_field_method_get("percent", |_, me| Ok(me.prog.percent())); diff --git a/yazi-fs/src/sorter.rs b/yazi-fs/src/sorter.rs index af21f4d3..9ef44d8b 100644 --- a/yazi-fs/src/sorter.rs +++ b/yazi-fs/src/sorter.rs @@ -1,7 +1,7 @@ use std::cmp::Ordering; use hashbrown::HashMap; -use rand::{RngCore, SeedableRng, rngs::SmallRng}; +use rand::{Rng, make_rng, rngs::SmallRng}; use yazi_shared::{natsort, path::PathBufDyn, translit::Transliterator, url::UrlLike}; use crate::{File, SortBy, SortFallback}; @@ -72,7 +72,7 @@ impl FilesSorter { self.fallback(a, b, self.cmp(aa.unwrap_or(a.len), bb.unwrap_or(b.len))) }), SortBy::Random => { - let mut rng = SmallRng::from_os_rng(); + let mut rng = make_rng::(); items.sort_unstable_by(|a, b| { promote!(a, b); self.cmp(rng.next_u64(), rng.next_u64()) diff --git a/yazi-scheduler/Cargo.toml b/yazi-scheduler/Cargo.toml index 6b44d23b..70806031 100644 --- a/yazi-scheduler/Cargo.toml +++ b/yazi-scheduler/Cargo.toml @@ -33,6 +33,7 @@ mlua = { workspace = true } ordered-float = { workspace = true } parking_lot = { workspace = true } serde = { workspace = true } +strum = { workspace = true } tokio = { workspace = true } tokio-util = { workspace = true } tracing = { workspace = true } diff --git a/yazi-scheduler/src/cleanup.rs b/yazi-scheduler/src/cleanup.rs new file mode 100644 index 00000000..0778aa1c --- /dev/null +++ b/yazi-scheduler/src/cleanup.rs @@ -0,0 +1,11 @@ +use serde::Serialize; +use strum::EnumIs; + +#[derive(Clone, Copy, Debug, Default, EnumIs, Eq, PartialEq, Serialize)] +#[serde(rename_all = "kebab-case")] +pub enum CleanupState { + #[default] + Pending, + Success, + Failed, +} diff --git a/yazi-scheduler/src/fetch/progress.rs b/yazi-scheduler/src/fetch/progress.rs index f63c1b28..6fa25ab5 100644 --- a/yazi-scheduler/src/fetch/progress.rs +++ b/yazi-scheduler/src/fetch/progress.rs @@ -1,6 +1,6 @@ use serde::Serialize; -use crate::TaskSummary; +use crate::{Progress, TaskSummary}; #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize)] pub struct FetchProg { @@ -18,16 +18,10 @@ impl From for TaskSummary { } } -impl FetchProg { - pub fn cooked(self) -> bool { self.state == Some(true) } +impl Progress for FetchProg { + fn running(self) -> bool { self.state.is_none() } - pub fn running(self) -> bool { self.state.is_none() } + fn cooked(self) -> bool { self.state == Some(true) } - pub fn success(self) -> bool { self.cooked() } - - pub fn failed(self) -> bool { self.state == Some(false) } - - pub fn cleaned(self) -> Option { None } - - pub fn percent(self) -> Option { None } + fn failed(self) -> bool { self.state == Some(false) } } diff --git a/yazi-scheduler/src/file/out.rs b/yazi-scheduler/src/file/out.rs index fb452b3c..d6a34994 100644 --- a/yazi-scheduler/src/file/out.rs +++ b/yazi-scheduler/src/file/out.rs @@ -1,6 +1,6 @@ use std::io; -use crate::{Task, TaskProg}; +use crate::{CleanupState, Task, TaskProg}; // --- Copy #[derive(Debug)] @@ -41,7 +41,7 @@ impl FileOutCopy { task.log(reason); } Self::Clean => { - prog.cleaned = Some(true); + prog.cleaned = CleanupState::Success; } } } @@ -120,10 +120,10 @@ impl FileOutCut { task.log(reason); } Self::Clean(Ok(())) => { - prog.cleaned = Some(true); + prog.cleaned = CleanupState::Success; } Self::Clean(Err(reason)) => { - prog.cleaned = Some(false); + prog.cleaned = CleanupState::Failed; task.log(format!("Failed cleaning up cut file: {reason:?}")); } } @@ -188,7 +188,7 @@ impl FileOutLink { task.log(reason); } Self::Clean => { - prog.cleaned = Some(true); + prog.cleaned = CleanupState::Success; } } } else if let TaskProg::FileCopy(prog) = &mut task.prog { @@ -255,7 +255,7 @@ impl FileOutHardlink { task.log(reason); } Self::Clean => { - prog.cleaned = Some(true); + prog.cleaned = CleanupState::Success; } } } @@ -316,10 +316,10 @@ impl FileOutDelete { task.log(reason); } Self::Clean(Ok(())) => { - prog.cleaned = Some(true); + prog.cleaned = CleanupState::Success; } Self::Clean(Err(reason)) => { - prog.cleaned = Some(false); + prog.cleaned = CleanupState::Failed; task.log(format!("Failed cleaning up deleted file: {reason:?}")); } } @@ -377,7 +377,7 @@ impl FileOutTrash { task.log(reason); } Self::Clean => { - prog.cleaned = Some(true); + prog.cleaned = CleanupState::Success; } } } @@ -418,7 +418,7 @@ impl FileOutDownload { task.log(reason); } Self::Clean => { - prog.cleaned = Some(true); + prog.cleaned = CleanupState::Success; } } } @@ -493,7 +493,7 @@ impl FileOutUpload { task.log(reason); } Self::Clean => { - prog.cleaned = Some(true); + prog.cleaned = CleanupState::Success; } } } diff --git a/yazi-scheduler/src/file/progress.rs b/yazi-scheduler/src/file/progress.rs index 2c1f5e8d..1d24b9f3 100644 --- a/yazi-scheduler/src/file/progress.rs +++ b/yazi-scheduler/src/file/progress.rs @@ -1,6 +1,6 @@ use serde::Serialize; -use crate::TaskSummary; +use crate::{CleanupState, Progress, TaskSummary}; // --- Copy #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize)] @@ -11,7 +11,7 @@ pub struct FileProgCopy { pub total_bytes: u64, pub processed_bytes: u64, pub collected: Option, - pub cleaned: Option, + pub cleaned: CleanupState, } impl From for TaskSummary { @@ -25,33 +25,21 @@ impl From for TaskSummary { } } -impl FileProgCopy { - pub fn cooked(self) -> bool { - self.collected == Some(true) && self.success_files == self.total_files +impl Progress for FileProgCopy { + fn running(self) -> bool { + self.cooking_or_cleaning( + self.collected.is_none() || self.success_files + self.failed_files != self.total_files, + ) } - pub fn running(self) -> bool { - self.collected.is_none() - || self.success_files + self.failed_files != self.total_files - || (self.cleaned.is_none() && self.cooked()) - } + fn cooked(self) -> bool { self.collected == Some(true) && self.success_files == self.total_files } - pub fn success(self) -> bool { self.cleaned == Some(true) && self.cooked() } + fn failed(self) -> bool { self.cleaned.is_failed() || self.collected == Some(false) } - pub fn failed(self) -> bool { self.cleaned == Some(false) || self.collected == Some(false) } + fn cleaned(self) -> Option { Some(self.cleaned) } - pub fn cleaned(self) -> Option { self.cleaned } - - pub fn percent(self) -> Option { - Some(if self.success() { - 100.0 - } else if self.failed() { - 0.0 - } else if self.total_bytes != 0 { - 99.99f32.min(self.processed_bytes as f32 / self.total_bytes as f32 * 100.0) - } else { - 99.99 - }) + fn percent(self) -> Option { + Some(self.byte_percent(self.processed_bytes, self.total_bytes)) } } @@ -64,7 +52,7 @@ pub struct FileProgCut { pub total_bytes: u64, pub processed_bytes: u64, pub collected: Option, - pub cleaned: Option, + pub cleaned: CleanupState, } impl From for TaskSummary { @@ -78,33 +66,21 @@ impl From for TaskSummary { } } -impl FileProgCut { - pub fn cooked(self) -> bool { - self.collected == Some(true) && self.success_files == self.total_files +impl Progress for FileProgCut { + fn running(self) -> bool { + self.cooking_or_cleaning( + self.collected.is_none() || self.success_files + self.failed_files != self.total_files, + ) } - pub fn running(self) -> bool { - self.collected.is_none() - || self.success_files + self.failed_files != self.total_files - || (self.cleaned.is_none() && self.cooked()) - } + fn cooked(self) -> bool { self.collected == Some(true) && self.success_files == self.total_files } - pub fn success(self) -> bool { self.cleaned == Some(true) && self.cooked() } + fn failed(self) -> bool { self.cleaned.is_failed() || self.collected == Some(false) } - pub fn failed(self) -> bool { self.cleaned == Some(false) || self.collected == Some(false) } + fn cleaned(self) -> Option { Some(self.cleaned) } - pub fn cleaned(self) -> Option { self.cleaned } - - pub fn percent(self) -> Option { - Some(if self.success() { - 100.0 - } else if self.failed() { - 0.0 - } else if self.total_bytes != 0 { - 99.99f32.min(self.processed_bytes as f32 / self.total_bytes as f32 * 100.0) - } else { - 99.99 - }) + fn percent(self) -> Option { + Some(self.byte_percent(self.processed_bytes, self.total_bytes)) } } @@ -112,7 +88,7 @@ impl FileProgCut { #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize)] pub struct FileProgLink { pub state: Option, - pub cleaned: Option, + pub cleaned: CleanupState, } impl From for TaskSummary { @@ -126,18 +102,14 @@ impl From for TaskSummary { } } -impl FileProgLink { - pub fn cooked(self) -> bool { self.state == Some(true) } +impl Progress for FileProgLink { + fn running(self) -> bool { self.cooking_or_cleaning(self.state.is_none()) } - pub fn running(self) -> bool { self.state.is_none() || (self.cleaned.is_none() && self.cooked()) } + fn cooked(self) -> bool { self.state == Some(true) } - pub fn success(self) -> bool { self.cleaned == Some(true) && self.cooked() } + fn failed(self) -> bool { self.cleaned.is_failed() || self.state == Some(false) } - pub fn failed(self) -> bool { self.cleaned == Some(false) || self.state == Some(false) } - - pub fn cleaned(self) -> Option { self.cleaned } - - pub fn percent(self) -> Option { None } + fn cleaned(self) -> Option { Some(self.cleaned) } } // --- Hardlink @@ -147,7 +119,7 @@ pub struct FileProgHardlink { pub success: u32, pub failed: u32, pub collected: Option, - pub cleaned: Option, + pub cleaned: CleanupState, } impl From for TaskSummary { @@ -161,22 +133,16 @@ impl From for TaskSummary { } } -impl FileProgHardlink { - pub fn cooked(self) -> bool { self.collected == Some(true) && self.success == self.total } - - pub fn running(self) -> bool { - self.collected.is_none() - || self.success + self.failed != self.total - || (self.cleaned.is_none() && self.cooked()) +impl Progress for FileProgHardlink { + fn running(self) -> bool { + self.cooking_or_cleaning(self.collected.is_none() || self.success + self.failed != self.total) } - pub fn success(self) -> bool { self.cleaned == Some(true) && self.cooked() } + fn cooked(self) -> bool { self.collected == Some(true) && self.success == self.total } - pub fn failed(self) -> bool { self.cleaned == Some(false) || self.collected == Some(false) } + fn failed(self) -> bool { self.cleaned.is_failed() || self.collected == Some(false) } - pub fn cleaned(self) -> Option { self.cleaned } - - pub fn percent(self) -> Option { None } + fn cleaned(self) -> Option { Some(self.cleaned) } } // --- Delete @@ -188,7 +154,7 @@ pub struct FileProgDelete { pub total_bytes: u64, pub processed_bytes: u64, pub collected: Option, - pub cleaned: Option, + pub cleaned: CleanupState, } impl From for TaskSummary { @@ -202,33 +168,21 @@ impl From for TaskSummary { } } -impl FileProgDelete { - pub fn cooked(self) -> bool { - self.collected == Some(true) && self.success_files == self.total_files +impl Progress for FileProgDelete { + fn running(self) -> bool { + self.cooking_or_cleaning( + self.collected.is_none() || self.success_files + self.failed_files != self.total_files, + ) } - pub fn running(self) -> bool { - self.collected.is_none() - || self.success_files + self.failed_files != self.total_files - || (self.cleaned.is_none() && self.cooked()) - } + fn cooked(self) -> bool { self.collected == Some(true) && self.success_files == self.total_files } - pub fn success(self) -> bool { self.cleaned == Some(true) && self.cooked() } + fn failed(self) -> bool { self.cleaned.is_failed() || self.collected == Some(false) } - pub fn failed(self) -> bool { self.cleaned == Some(false) || self.collected == Some(false) } + fn cleaned(self) -> Option { Some(self.cleaned) } - pub fn cleaned(self) -> Option { self.cleaned } - - pub fn percent(self) -> Option { - Some(if self.success() { - 100.0 - } else if self.failed() { - 0.0 - } else if self.total_bytes != 0 { - 99.99f32.min(self.processed_bytes as f32 / self.total_bytes as f32 * 100.0) - } else { - 99.99 - }) + fn percent(self) -> Option { + Some(self.byte_percent(self.processed_bytes, self.total_bytes)) } } @@ -236,7 +190,7 @@ impl FileProgDelete { #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize)] pub struct FileProgTrash { pub state: Option, - pub cleaned: Option, + pub cleaned: CleanupState, } impl From for TaskSummary { @@ -250,18 +204,14 @@ impl From for TaskSummary { } } -impl FileProgTrash { - pub fn cooked(self) -> bool { self.state == Some(true) } +impl Progress for FileProgTrash { + fn running(self) -> bool { self.cooking_or_cleaning(self.state.is_none()) } - pub fn running(self) -> bool { self.state.is_none() || (self.cleaned.is_none() && self.cooked()) } + fn cooked(self) -> bool { self.state == Some(true) } - pub fn success(self) -> bool { self.cleaned == Some(true) && self.cooked() } + fn failed(self) -> bool { self.cleaned.is_failed() || self.state == Some(false) } - pub fn failed(self) -> bool { self.cleaned == Some(false) || self.state == Some(false) } - - pub fn cleaned(self) -> Option { self.cleaned } - - pub fn percent(self) -> Option { None } + fn cleaned(self) -> Option { Some(self.cleaned) } } // --- Download @@ -273,7 +223,7 @@ pub struct FileProgDownload { pub total_bytes: u64, pub processed_bytes: u64, pub collected: Option, - pub cleaned: Option, + pub cleaned: CleanupState, } impl From for TaskSummary { @@ -287,33 +237,21 @@ impl From for TaskSummary { } } -impl FileProgDownload { - pub fn cooked(self) -> bool { - self.collected == Some(true) && self.success_files == self.total_files +impl Progress for FileProgDownload { + fn running(self) -> bool { + self.cooking_or_cleaning( + self.collected.is_none() || self.success_files + self.failed_files != self.total_files, + ) } - pub fn running(self) -> bool { - self.collected.is_none() - || self.success_files + self.failed_files != self.total_files - || (self.cleaned.is_none() && self.cooked()) - } + fn cooked(self) -> bool { self.collected == Some(true) && self.success_files == self.total_files } - pub fn success(self) -> bool { self.cleaned == Some(true) && self.cooked() } + fn failed(self) -> bool { self.cleaned.is_failed() || self.collected == Some(false) } - pub fn failed(self) -> bool { self.cleaned == Some(false) || self.collected == Some(false) } + fn cleaned(self) -> Option { Some(self.cleaned) } - pub fn cleaned(self) -> Option { self.cleaned } - - pub fn percent(self) -> Option { - Some(if self.success() { - 100.0 - } else if self.failed() { - 0.0 - } else if self.total_bytes != 0 { - 99.99f32.min(self.processed_bytes as f32 / self.total_bytes as f32 * 100.0) - } else { - 99.99 - }) + fn percent(self) -> Option { + Some(self.byte_percent(self.processed_bytes, self.total_bytes)) } } @@ -326,7 +264,7 @@ pub struct FileProgUpload { pub total_bytes: u64, pub processed_bytes: u64, pub collected: Option, - pub cleaned: Option, + pub cleaned: CleanupState, } impl From for TaskSummary { @@ -340,32 +278,20 @@ impl From for TaskSummary { } } -impl FileProgUpload { - pub fn cooked(self) -> bool { - self.collected == Some(true) && self.success_files == self.total_files +impl Progress for FileProgUpload { + fn running(self) -> bool { + self.cooking_or_cleaning( + self.collected.is_none() || self.success_files + self.failed_files != self.total_files, + ) } - pub fn running(self) -> bool { - self.collected.is_none() - || self.success_files + self.failed_files != self.total_files - || (self.cleaned.is_none() && self.cooked()) - } + fn cooked(self) -> bool { self.collected == Some(true) && self.success_files == self.total_files } - pub fn success(self) -> bool { self.cleaned == Some(true) && self.cooked() } + fn failed(self) -> bool { self.cleaned.is_failed() || self.collected == Some(false) } - pub fn failed(self) -> bool { self.cleaned == Some(false) || self.collected == Some(false) } + fn cleaned(self) -> Option { Some(self.cleaned) } - pub fn cleaned(self) -> Option { self.cleaned } - - pub fn percent(self) -> Option { - Some(if self.success() { - 100.0 - } else if self.failed() { - 0.0 - } else if self.total_bytes != 0 { - 99.99f32.min(self.processed_bytes as f32 / self.total_bytes as f32 * 100.0) - } else { - 99.99 - }) + fn percent(self) -> Option { + Some(self.byte_percent(self.processed_bytes, self.total_bytes)) } } diff --git a/yazi-scheduler/src/lib.rs b/yazi-scheduler/src/lib.rs index 9ea9dfc7..8dd69f54 100644 --- a/yazi-scheduler/src/lib.rs +++ b/yazi-scheduler/src/lib.rs @@ -2,7 +2,7 @@ mod macros; yazi_macro::mod_pub!(fetch file hook plugin preload process size); -yazi_macro::mod_flat!(behavior ongoing op out progress proxy scheduler snap summary task worker); +yazi_macro::mod_flat!(behavior cleanup ongoing op out progress proxy scheduler snap summary task worker); const LOW: u8 = yazi_config::Priority::Low as u8; const NORMAL: u8 = yazi_config::Priority::Normal as u8; diff --git a/yazi-scheduler/src/macros.rs b/yazi-scheduler/src/macros.rs index 826b4b0a..ef43cd05 100644 --- a/yazi-scheduler/src/macros.rs +++ b/yazi-scheduler/src/macros.rs @@ -45,3 +45,30 @@ macro_rules! impl_from_prog { )* }; } + +#[macro_export] +macro_rules! dispatch_progress { + ($value:expr, $method:ident) => { + match $value { + // File + $crate::TaskProg::FileCopy(p) => $crate::Progress::$method(p), + $crate::TaskProg::FileCut(p) => $crate::Progress::$method(p), + $crate::TaskProg::FileLink(p) => $crate::Progress::$method(p), + $crate::TaskProg::FileHardlink(p) => $crate::Progress::$method(p), + $crate::TaskProg::FileDelete(p) => $crate::Progress::$method(p), + $crate::TaskProg::FileTrash(p) => $crate::Progress::$method(p), + $crate::TaskProg::FileDownload(p) => $crate::Progress::$method(p), + $crate::TaskProg::FileUpload(p) => $crate::Progress::$method(p), + // Plugin + $crate::TaskProg::PluginEntry(p) => $crate::Progress::$method(p), + // Prework + $crate::TaskProg::Fetch(p) => $crate::Progress::$method(p), + $crate::TaskProg::Preload(p) => $crate::Progress::$method(p), + $crate::TaskProg::Size(p) => $crate::Progress::$method(p), + // Process + $crate::TaskProg::ProcessBlock(p) => $crate::Progress::$method(p), + $crate::TaskProg::ProcessOrphan(p) => $crate::Progress::$method(p), + $crate::TaskProg::ProcessBg(p) => $crate::Progress::$method(p), + } + }; +} diff --git a/yazi-scheduler/src/plugin/progress.rs b/yazi-scheduler/src/plugin/progress.rs index a2f1d71c..2fba592e 100644 --- a/yazi-scheduler/src/plugin/progress.rs +++ b/yazi-scheduler/src/plugin/progress.rs @@ -1,6 +1,6 @@ use serde::Serialize; -use crate::TaskSummary; +use crate::{Progress, TaskSummary}; // --- Entry #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize)] @@ -19,16 +19,10 @@ impl From for TaskSummary { } } -impl PluginProgEntry { - pub fn cooked(self) -> bool { self.state == Some(true) } +impl Progress for PluginProgEntry { + fn running(self) -> bool { self.state.is_none() } - pub fn running(self) -> bool { self.state.is_none() } + fn cooked(self) -> bool { self.state == Some(true) } - pub fn success(self) -> bool { self.cooked() } - - pub fn failed(self) -> bool { self.state == Some(false) } - - pub fn cleaned(self) -> Option { None } - - pub fn percent(self) -> Option { None } + fn failed(self) -> bool { self.state == Some(false) } } diff --git a/yazi-scheduler/src/preload/out.rs b/yazi-scheduler/src/preload/out.rs index 9cef4d44..c15068c4 100644 --- a/yazi-scheduler/src/preload/out.rs +++ b/yazi-scheduler/src/preload/out.rs @@ -1,6 +1,6 @@ use yazi_runner::preloader::PreloadError; -use crate::{Task, TaskProg}; +use crate::{CleanupState, Task, TaskProg}; #[derive(Debug)] pub(crate) enum PreloadOut { @@ -25,7 +25,7 @@ impl PreloadOut { task.log(reason); } Self::Clean => { - prog.cleaned = Some(true); + prog.cleaned = CleanupState::Success; } } } diff --git a/yazi-scheduler/src/preload/progress.rs b/yazi-scheduler/src/preload/progress.rs index e28c8969..4c505fc8 100644 --- a/yazi-scheduler/src/preload/progress.rs +++ b/yazi-scheduler/src/preload/progress.rs @@ -1,11 +1,11 @@ use serde::Serialize; -use crate::TaskSummary; +use crate::{CleanupState, Progress, TaskSummary}; #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize)] pub struct PreloadProg { pub state: Option, - pub cleaned: Option, + pub cleaned: CleanupState, } impl From for TaskSummary { @@ -19,16 +19,12 @@ impl From for TaskSummary { } } -impl PreloadProg { - pub fn cooked(self) -> bool { self.state == Some(true) } +impl Progress for PreloadProg { + fn running(self) -> bool { self.cooking_or_cleaning(self.state.is_none()) } - pub fn running(self) -> bool { self.state.is_none() || (self.cleaned.is_none() && self.cooked()) } + fn cooked(self) -> bool { self.state == Some(true) } - pub fn success(self) -> bool { self.cleaned == Some(true) && self.cooked() } + fn failed(self) -> bool { self.cleaned.is_failed() || self.state == Some(false) } - pub fn failed(self) -> bool { self.cleaned == Some(false) || self.state == Some(false) } - - pub fn cleaned(self) -> Option { self.cleaned } - - pub fn percent(self) -> Option { None } + fn cleaned(self) -> Option { Some(self.cleaned) } } diff --git a/yazi-scheduler/src/process/progress.rs b/yazi-scheduler/src/process/progress.rs index 69c8357e..91bdef0c 100644 --- a/yazi-scheduler/src/process/progress.rs +++ b/yazi-scheduler/src/process/progress.rs @@ -1,6 +1,6 @@ use serde::Serialize; -use crate::TaskSummary; +use crate::{Progress, TaskSummary}; // --- Block #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize)] @@ -19,18 +19,12 @@ impl From for TaskSummary { } } -impl ProcessProgBlock { - pub fn cooked(self) -> bool { self.state == Some(true) } +impl Progress for ProcessProgBlock { + fn running(self) -> bool { self.state.is_none() } - pub fn running(self) -> bool { self.state.is_none() } + fn cooked(self) -> bool { self.state == Some(true) } - pub fn success(self) -> bool { self.cooked() } - - pub fn failed(self) -> bool { self.state == Some(false) } - - pub fn cleaned(self) -> Option { None } - - pub fn percent(self) -> Option { None } + fn failed(self) -> bool { self.state == Some(false) } } // --- Orphan @@ -50,18 +44,12 @@ impl From for TaskSummary { } } -impl ProcessProgOrphan { - pub fn cooked(self) -> bool { self.state == Some(true) } +impl Progress for ProcessProgOrphan { + fn running(self) -> bool { self.state.is_none() } - pub fn running(self) -> bool { self.state.is_none() } + fn cooked(self) -> bool { self.state == Some(true) } - pub fn success(self) -> bool { self.cooked() } - - pub fn failed(self) -> bool { self.state == Some(false) } - - pub fn cleaned(self) -> Option { None } - - pub fn percent(self) -> Option { None } + fn failed(self) -> bool { self.state == Some(false) } } // --- Bg @@ -81,16 +69,10 @@ impl From for TaskSummary { } } -impl ProcessProgBg { - pub fn cooked(self) -> bool { self.state == Some(true) } +impl Progress for ProcessProgBg { + fn running(self) -> bool { self.state.is_none() } - pub fn running(self) -> bool { self.state.is_none() } + fn cooked(self) -> bool { self.state == Some(true) } - pub fn success(self) -> bool { self.cooked() } - - pub fn failed(self) -> bool { self.state == Some(false) } - - pub fn cleaned(self) -> Option { None } - - pub fn percent(self) -> Option { None } + fn failed(self) -> bool { self.state == Some(false) } } diff --git a/yazi-scheduler/src/progress.rs b/yazi-scheduler/src/progress.rs index 3546e18b..8cd02c34 100644 --- a/yazi-scheduler/src/progress.rs +++ b/yazi-scheduler/src/progress.rs @@ -1,7 +1,57 @@ use serde::Serialize; -use crate::{TaskSummary, fetch::FetchProg, file::{FileProgCopy, FileProgCut, FileProgDelete, FileProgDownload, FileProgHardlink, FileProgLink, FileProgTrash, FileProgUpload}, impl_from_prog, plugin::PluginProgEntry, preload::PreloadProg, process::{ProcessProgBg, ProcessProgBlock, ProcessProgOrphan}, size::SizeProg}; +use crate::{CleanupState, TaskSummary, dispatch_progress, fetch::FetchProg, file::{FileProgCopy, FileProgCut, FileProgDelete, FileProgDownload, FileProgHardlink, FileProgLink, FileProgTrash, FileProgUpload}, impl_from_prog, plugin::PluginProgEntry, preload::PreloadProg, process::{ProcessProgBg, ProcessProgBlock, ProcessProgOrphan}, size::SizeProg}; +pub trait Progress: Copy { + // Whether the task is still cooking or cleaning. + fn running(self) -> bool; + + // Whether the task succeeded, regardless cleanup. + // For tasks without a cleanup, this is the same as `success()`. + fn cooked(self) -> bool; + + // Whether the task fully succeeded, including cleanup if applicable. + fn success(self) -> bool { + match self.cleaned() { + None | Some(CleanupState::Success) => self.cooked(), + Some(CleanupState::Pending | CleanupState::Failed) => false, + } + } + + // Whether the task fully failed. + // + // For tasks with a collect phase, e.g. gathering files to copy: + // collect failed, or cleanup failed if applicable, regardless main work. + // For tasks without a collect phase: + // main work failed, or cleanup failed if applicable. + fn failed(self) -> bool; + + // Cleanup state if the task has a cleanup phase, otherwise `None`. + fn cleaned(self) -> Option { None } + + // Optional percentage for UI display. + fn percent(self) -> Option { None } + + // Helper for tasks that are still cooking or cleaning. + fn cooking_or_cleaning(self, cooking: bool) -> bool { + cooking || (self.cooked() && self.cleaned() == Some(CleanupState::Pending)) + } + + // Helper for byte-based progress calculations used by file transfer tasks. + fn byte_percent(self, processed_bytes: u64, total_bytes: u64) -> f32 { + if self.success() { + 100.0 + } else if self.failed() { + 0.0 + } else if total_bytes != 0 { + 99.99f32.min(processed_bytes as f32 / total_bytes as f32 * 100.0) + } else { + 99.99 + } + } +} + +// --- TaskProg #[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)] #[serde(tag = "kind")] pub enum TaskProg { @@ -69,151 +119,21 @@ impl From for TaskSummary { } } +impl Progress for TaskProg { + fn running(self) -> bool { dispatch_progress!(self, running) } + + fn cooked(self) -> bool { dispatch_progress!(self, cooked) } + + fn success(self) -> bool { dispatch_progress!(self, success) } + + fn failed(self) -> bool { dispatch_progress!(self, failed) } + + fn cleaned(self) -> Option { dispatch_progress!(self, cleaned) } + + fn percent(self) -> Option { dispatch_progress!(self, percent) } +} + impl TaskProg { - pub fn cooked(self) -> bool { - match self { - // File - Self::FileCopy(p) => p.cooked(), - Self::FileCut(p) => p.cooked(), - Self::FileLink(p) => p.cooked(), - Self::FileHardlink(p) => p.cooked(), - Self::FileDelete(p) => p.cooked(), - Self::FileTrash(p) => p.cooked(), - Self::FileDownload(p) => p.cooked(), - Self::FileUpload(p) => p.cooked(), - // Plugin - Self::PluginEntry(p) => p.cooked(), - // Prework - Self::Fetch(p) => p.cooked(), - Self::Preload(p) => p.cooked(), - Self::Size(p) => p.cooked(), - // Process - Self::ProcessBlock(p) => p.cooked(), - Self::ProcessOrphan(p) => p.cooked(), - Self::ProcessBg(p) => p.cooked(), - } - } - - pub fn running(self) -> bool { - match self { - // File - Self::FileCopy(p) => p.running(), - Self::FileCut(p) => p.running(), - Self::FileLink(p) => p.running(), - Self::FileHardlink(p) => p.running(), - Self::FileDelete(p) => p.running(), - Self::FileTrash(p) => p.running(), - Self::FileDownload(p) => p.running(), - Self::FileUpload(p) => p.running(), - // Plugin - Self::PluginEntry(p) => p.running(), - // Prework - Self::Fetch(p) => p.running(), - Self::Preload(p) => p.running(), - Self::Size(p) => p.running(), - // Process - Self::ProcessBlock(p) => p.running(), - Self::ProcessOrphan(p) => p.running(), - Self::ProcessBg(p) => p.running(), - } - } - - pub fn success(self) -> bool { - match self { - // File - Self::FileCopy(p) => p.success(), - Self::FileCut(p) => p.success(), - Self::FileLink(p) => p.success(), - Self::FileHardlink(p) => p.success(), - Self::FileDelete(p) => p.success(), - Self::FileTrash(p) => p.success(), - Self::FileDownload(p) => p.success(), - Self::FileUpload(p) => p.success(), - // Plugin - Self::PluginEntry(p) => p.success(), - // Prework - Self::Fetch(p) => p.success(), - Self::Preload(p) => p.success(), - Self::Size(p) => p.success(), - // Process - Self::ProcessBlock(p) => p.success(), - Self::ProcessOrphan(p) => p.success(), - Self::ProcessBg(p) => p.success(), - } - } - - pub fn failed(self) -> bool { - match self { - // File - Self::FileCopy(p) => p.failed(), - Self::FileCut(p) => p.failed(), - Self::FileLink(p) => p.failed(), - Self::FileHardlink(p) => p.failed(), - Self::FileDelete(p) => p.failed(), - Self::FileTrash(p) => p.failed(), - Self::FileDownload(p) => p.failed(), - Self::FileUpload(p) => p.failed(), - // Plugin - Self::PluginEntry(p) => p.failed(), - // Prework - Self::Fetch(p) => p.failed(), - Self::Preload(p) => p.failed(), - Self::Size(p) => p.failed(), - // Process - Self::ProcessBlock(p) => p.failed(), - Self::ProcessOrphan(p) => p.failed(), - Self::ProcessBg(p) => p.failed(), - } - } - - pub fn cleaned(self) -> Option { - match self { - // File - Self::FileCopy(p) => p.cleaned(), - Self::FileCut(p) => p.cleaned(), - Self::FileLink(p) => p.cleaned(), - Self::FileHardlink(p) => p.cleaned(), - Self::FileDelete(p) => p.cleaned(), - Self::FileTrash(p) => p.cleaned(), - Self::FileDownload(p) => p.cleaned(), - Self::FileUpload(p) => p.cleaned(), - // Plugin - Self::PluginEntry(p) => p.cleaned(), - // Prework - Self::Fetch(p) => p.cleaned(), - Self::Preload(p) => p.cleaned(), - Self::Size(p) => p.cleaned(), - // Process - Self::ProcessBlock(p) => p.cleaned(), - Self::ProcessOrphan(p) => p.cleaned(), - Self::ProcessBg(p) => p.cleaned(), - } - } - - pub fn percent(self) -> Option { - match self { - // File - Self::FileCopy(p) => p.percent(), - Self::FileCut(p) => p.percent(), - Self::FileLink(p) => p.percent(), - Self::FileHardlink(p) => p.percent(), - Self::FileDelete(p) => p.percent(), - Self::FileTrash(p) => p.percent(), - Self::FileDownload(p) => p.percent(), - Self::FileUpload(p) => p.percent(), - // Plugin - Self::PluginEntry(p) => p.percent(), - // Prework - Self::Fetch(p) => p.percent(), - Self::Preload(p) => p.percent(), - Self::Size(p) => p.percent(), - // Process - Self::ProcessBlock(p) => p.percent(), - Self::ProcessOrphan(p) => p.percent(), - Self::ProcessBg(p) => p.percent(), - } - } - pub(crate) fn is_user(self) -> bool { match self { // File diff --git a/yazi-scheduler/src/size/progress.rs b/yazi-scheduler/src/size/progress.rs index a4ba42f0..d199f6d2 100644 --- a/yazi-scheduler/src/size/progress.rs +++ b/yazi-scheduler/src/size/progress.rs @@ -1,6 +1,6 @@ use serde::Serialize; -use crate::TaskSummary; +use crate::{Progress, TaskSummary}; #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize)] pub struct SizeProg { @@ -18,16 +18,10 @@ impl From for TaskSummary { } } -impl SizeProg { - pub fn cooked(self) -> bool { self.done } +impl Progress for SizeProg { + fn running(self) -> bool { !self.done } - pub fn running(self) -> bool { !self.done } + fn cooked(self) -> bool { self.done } - pub fn success(self) -> bool { self.cooked() } - - pub fn failed(self) -> bool { false } - - pub fn cleaned(self) -> Option { None } - - pub fn percent(self) -> Option { None } + fn failed(self) -> bool { false } } diff --git a/yazi-scheduler/src/summary.rs b/yazi-scheduler/src/summary.rs index 703b293f..4e0134c6 100644 --- a/yazi-scheduler/src/summary.rs +++ b/yazi-scheduler/src/summary.rs @@ -1,7 +1,7 @@ use ordered_float::OrderedFloat; use serde::Serialize; -use crate::Ongoing; +use crate::{Ongoing, Progress}; #[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize)] pub struct TaskSummary { diff --git a/yazi-scheduler/src/worker.rs b/yazi-scheduler/src/worker.rs index b0679164..ff89ebe5 100644 --- a/yazi-scheduler/src/worker.rs +++ b/yazi-scheduler/src/worker.rs @@ -4,7 +4,7 @@ use parking_lot::Mutex; use tokio::{select, sync::mpsc, task::JoinHandle}; use yazi_config::YAZI; -use crate::{LOW, Ongoing, TaskOp, TaskOps, TaskOut, fetch::{Fetch, FetchIn}, file::{File, FileIn}, hook::{Hook, HookIn}, plugin::{Plugin, PluginIn}, preload::{Preload, PreloadIn}, process::{Process, ProcessIn}, size::{Size, SizeIn}}; +use crate::{CleanupState, LOW, Ongoing, Progress, TaskOp, TaskOps, TaskOut, fetch::{Fetch, FetchIn}, file::{File, FileIn}, hook::{Hook, HookIn}, plugin::{Plugin, PluginIn}, preload::{Preload, PreloadIn}, process::{Process, ProcessIn}, size::{Size, SizeIn}}; #[derive(Clone)] pub struct Worker { @@ -282,7 +282,7 @@ impl Worker { op.out.reduce(task); if !task.prog.cooked() && task.done.completed() != Some(false) { continue; // Not cooked yet, also not canceled - } else if task.prog.cleaned() == Some(false) { + } else if task.prog.cleaned() == Some(CleanupState::Failed) { continue; // Failed to clean up } else if let Some(hook) = task.hook.take() { me.hook.submit(hook, LOW);