Allocation decrease (#1156)
This commit is contained in:
parent
739e2a9860
commit
219f9f058b
243
Cargo.lock
generated
243
Cargo.lock
generated
|
@ -113,9 +113,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.4"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44"
|
||||
checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
|
@ -133,30 +133,30 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87"
|
|||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.2"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140"
|
||||
checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.0"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||
checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648"
|
||||
dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.1"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628"
|
||||
checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -324,7 +324,7 @@ dependencies = [
|
|||
"futures-lite 2.1.0",
|
||||
"parking",
|
||||
"polling 3.3.1",
|
||||
"rustix 0.38.26",
|
||||
"rustix 0.38.28",
|
||||
"slab",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
|
@ -363,7 +363,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"event-listener 3.1.0",
|
||||
"futures-lite 1.13.0",
|
||||
"rustix 0.38.26",
|
||||
"rustix 0.38.28",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
|
@ -390,7 +390,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"rustix 0.38.26",
|
||||
"rustix 0.38.28",
|
||||
"signal-hook-registry",
|
||||
"slab",
|
||||
"windows-sys 0.48.0",
|
||||
|
@ -439,15 +439,6 @@ dependencies = [
|
|||
"syn 2.0.39",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-polyfill"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atomic-waker"
|
||||
version = "1.1.2"
|
||||
|
@ -724,7 +715,7 @@ dependencies = [
|
|||
"bitflags 2.4.1",
|
||||
"log",
|
||||
"polling 3.3.1",
|
||||
"rustix 0.38.26",
|
||||
"rustix 0.38.28",
|
||||
"slab",
|
||||
"thiserror",
|
||||
]
|
||||
|
@ -736,7 +727,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02"
|
||||
dependencies = [
|
||||
"calloop",
|
||||
"rustix 0.38.26",
|
||||
"rustix 0.38.28",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
]
|
||||
|
@ -854,9 +845,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.4.10"
|
||||
version = "4.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272"
|
||||
checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
@ -864,9 +855,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.4.9"
|
||||
version = "4.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1"
|
||||
checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
@ -1096,6 +1087,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core2"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "countme"
|
||||
version = "3.0.1"
|
||||
|
@ -1343,6 +1343,12 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dary_heap"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7762d17f1241643615821a8455a0b2c3e803784b058693d990b11f2dce25a0ca"
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.5.3"
|
||||
|
@ -1803,14 +1809,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.22"
|
||||
version = "0.2.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0"
|
||||
checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall 0.3.5",
|
||||
"windows-sys 0.48.0",
|
||||
"redox_syscall 0.4.1",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2258,9 +2264,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "gio"
|
||||
version = "0.18.3"
|
||||
version = "0.18.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47d809baf02bdf1b5ef4ad3bf60dd9d4977149db4612b7bbb58e56aef168193b"
|
||||
checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
|
@ -2301,9 +2307,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "glib"
|
||||
version = "0.18.3"
|
||||
version = "0.18.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58cf801b6f7829fa76db37449ab67c9c98a2b1bf21076d9113225621e61a0fa6"
|
||||
checksum = "951bbd7fdc5c044ede9f05170f05a3ae9479239c3afdfe2d22d537a3add15c4e"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"futures-channel",
|
||||
|
@ -2605,6 +2611,15 @@ version = "0.12.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.3"
|
||||
|
@ -3111,15 +3126,6 @@ dependencies = [
|
|||
"cfb",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inflate"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inout"
|
||||
version = "0.1.3"
|
||||
|
@ -3249,9 +3255,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
|
@ -3384,6 +3390,30 @@ version = "0.2.150"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
|
||||
|
||||
[[package]]
|
||||
name = "libflate"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f7d5654ae1795afc7ff76f4365c2c8791b0feb18e8996a96adad8ffd7c3b2bf"
|
||||
dependencies = [
|
||||
"adler32",
|
||||
"core2",
|
||||
"crc32fast",
|
||||
"dary_heap",
|
||||
"libflate_lz77",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libflate_lz77"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be5f52fb8c451576ec6b79d3f4deb327398bc05bbdbd99021a6e77a4c855d524"
|
||||
dependencies = [
|
||||
"core2",
|
||||
"hashbrown 0.13.2",
|
||||
"rle-decode-fast",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libheif-rs"
|
||||
version = "0.18.0"
|
||||
|
@ -3553,9 +3583,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "lofty"
|
||||
version = "0.16.1"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c18ba58211b3c3557970755d7afc3a7438c2d4557bcd684470b2195c0ae66e53"
|
||||
checksum = "e9d514acc39ec2bee7392e451db35e5f5eb06ab26e1cae83746c3017e8c95099"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"byteorder",
|
||||
|
@ -3955,9 +3985,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "objc-sys"
|
||||
version = "0.3.1"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99e1d07c6eab1ce8b6382b8e3c7246fe117ff3f8b34be065f5ebace6749fe845"
|
||||
checksum = "c7c71324e4180d0899963fc83d9d241ac39e699609fc1025a850aadac8257459"
|
||||
|
||||
[[package]]
|
||||
name = "objc2"
|
||||
|
@ -4004,12 +4034,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.18.0"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
dependencies = [
|
||||
"atomic-polyfill",
|
||||
"critical-section",
|
||||
"portable-atomic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4158,9 +4188,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pdf"
|
||||
version = "0.8.1"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e375ec076445f61d4dbc4636e9e788f841d279c65d6fea8a3875caddd4f2dd82"
|
||||
checksum = "3afc7e745846405d572daba57a429f30a198d955602aff8a1a9e437c2abfcaa2"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"bitflags 1.3.2",
|
||||
|
@ -4169,10 +4199,11 @@ dependencies = [
|
|||
"deflate",
|
||||
"fax",
|
||||
"globalcache",
|
||||
"inflate",
|
||||
"indexmap 2.1.0",
|
||||
"istring",
|
||||
"itertools 0.10.5",
|
||||
"jpeg-decoder",
|
||||
"libflate",
|
||||
"log",
|
||||
"md5",
|
||||
"once_cell",
|
||||
|
@ -4185,9 +4216,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pdf_derive"
|
||||
version = "0.1.22"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f4007262775d0798de87b15cbc64cf1aed5f7ee87eec847e297b69d8ed4b4f8"
|
||||
checksum = "1038b9cb38dec35eeee9f23eacfb2480087982f9b7e9221efa8034eea9ca2360"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -4305,7 +4336,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"concurrent-queue",
|
||||
"pin-project-lite",
|
||||
"rustix 0.38.26",
|
||||
"rustix 0.38.28",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
@ -4318,9 +4349,9 @@ checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2"
|
|||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.5.1"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3bccab0e7fd7cc19f820a1c8c91720af652d0c88dc9664dd72aef2614f04af3b"
|
||||
checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
]
|
||||
|
@ -4650,9 +4681,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.6"
|
||||
version = "0.17.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "684d5e6e18f669ccebf64a92236bb7db9a34f07be010e3627368182027180866"
|
||||
checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"getrandom",
|
||||
|
@ -4663,13 +4694,19 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "rowan"
|
||||
version = "0.15.13"
|
||||
name = "rle-decode-fast"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "906057e449592587bf6724f00155bf82a6752c868d78a8fb3aa41f4e6357cfe8"
|
||||
checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422"
|
||||
|
||||
[[package]]
|
||||
name = "rowan"
|
||||
version = "0.15.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49"
|
||||
dependencies = [
|
||||
"countme",
|
||||
"hashbrown 0.12.3",
|
||||
"hashbrown 0.14.3",
|
||||
"memoffset 0.9.0",
|
||||
"rustc-hash",
|
||||
"text-size",
|
||||
|
@ -4698,9 +4735,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rust-embed"
|
||||
version = "8.0.0"
|
||||
version = "8.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1e7d90385b59f0a6bf3d3b757f3ca4ece2048265d70db20a2016043d4509a40"
|
||||
checksum = "810294a8a4a0853d4118e3b94bb079905f2107c7fe979d8f0faae98765eb6378"
|
||||
dependencies = [
|
||||
"rust-embed-impl",
|
||||
"rust-embed-utils",
|
||||
|
@ -4709,9 +4746,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rust-embed-impl"
|
||||
version = "8.0.0"
|
||||
version = "8.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c3d8c6fd84090ae348e63a84336b112b5c3918b3bf0493a581f7bd8ee623c29"
|
||||
checksum = "bfc144a1273124a67b8c1d7cd19f5695d1878b31569c0512f6086f0f4676604e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -4722,9 +4759,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rust-embed-utils"
|
||||
version = "8.0.0"
|
||||
version = "8.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "873feff8cb7bf86fdf0a71bb21c95159f4e4a37dd7a4bd1855a940909b583ada"
|
||||
checksum = "816ccd4875431253d6bb54b804bcff4369cbde9bae33defde25fdf6c2ef91d40"
|
||||
dependencies = [
|
||||
"sha2",
|
||||
"walkdir",
|
||||
|
@ -4808,9 +4845,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.26"
|
||||
version = "0.38.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9470c4bf8246c8daf25f9598dca807fb6510347b1e1cfa55749113850c79d88a"
|
||||
checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
|
||||
dependencies = [
|
||||
"bitflags 2.4.1",
|
||||
"errno",
|
||||
|
@ -4821,9 +4858,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.21.9"
|
||||
version = "0.21.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9"
|
||||
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
|
||||
dependencies = [
|
||||
"log",
|
||||
"ring",
|
||||
|
@ -4891,9 +4928,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.15"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
|
||||
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
|
@ -5211,7 +5248,7 @@ dependencies = [
|
|||
"libc",
|
||||
"log",
|
||||
"memmap2 0.9.0",
|
||||
"rustix 0.38.26",
|
||||
"rustix 0.38.28",
|
||||
"thiserror",
|
||||
"wayland-backend",
|
||||
"wayland-client",
|
||||
|
@ -5295,7 +5332,7 @@ dependencies = [
|
|||
"objc",
|
||||
"raw-window-handle 0.5.2",
|
||||
"redox_syscall 0.4.1",
|
||||
"rustix 0.38.26",
|
||||
"rustix 0.38.28",
|
||||
"tiny-xlib",
|
||||
"wasm-bindgen",
|
||||
"wayland-backend",
|
||||
|
@ -5659,7 +5696,7 @@ dependencies = [
|
|||
"cfg-if",
|
||||
"fastrand 2.0.1",
|
||||
"redox_syscall 0.4.1",
|
||||
"rustix 0.38.26",
|
||||
"rustix 0.38.28",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
|
@ -5752,9 +5789,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tiny-skia"
|
||||
version = "0.11.2"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b72a92a05db376db09fe6d50b7948d106011761c05a6a45e23e17ee9b556222"
|
||||
checksum = "b6a067b809476893fce6a254cf285850ff69c847e6cfbade6a20b655b6c7e80d"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
|
@ -5767,9 +5804,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tiny-skia-path"
|
||||
version = "0.11.2"
|
||||
version = "0.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ac3865b9708fc7e1961a65c3a4fa55e984272f33092d3c859929f887fceb647"
|
||||
checksum = "5de35e8a90052baaaf61f171680ac2f8e925a1e43ea9d2e3a00514772250e541"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"bytemuck",
|
||||
|
@ -6039,18 +6076,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "unic-langid"
|
||||
version = "0.9.1"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "398f9ad7239db44fd0f80fe068d12ff22d78354080332a5077dc6f52f14dcf2f"
|
||||
checksum = "887622f8e7b723780c5e64b04dcc0c9b8f426ada7cca6790cd3ea3bf0f08037a"
|
||||
dependencies = [
|
||||
"unic-langid-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-langid-impl"
|
||||
version = "0.9.1"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e35bfd2f2b8796545b55d7d3fd3e89a0613f68a0d1c8bc28cb7ff96b411a35ff"
|
||||
checksum = "5adeb847e35eed4efbffd9fb2e4d078b91ece56e4d6a3c0d2df55b3a1dac07d5"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"tinystr",
|
||||
|
@ -6067,9 +6104,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "unicode-bidi"
|
||||
version = "0.3.13"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460"
|
||||
checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-bidi-mirroring"
|
||||
|
@ -6581,7 +6618,7 @@ dependencies = [
|
|||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix 0.38.26",
|
||||
"rustix 0.38.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -6878,7 +6915,7 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
"raw-window-handle 0.5.2",
|
||||
"redox_syscall 0.3.5",
|
||||
"rustix 0.38.26",
|
||||
"rustix 0.38.28",
|
||||
"sctk-adwaita",
|
||||
"smithay-client-toolkit",
|
||||
"smol_str",
|
||||
|
@ -6899,9 +6936,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.19"
|
||||
version = "0.5.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b"
|
||||
checksum = "b67b5f0a4e7a27a64c651977932b9dc5667ca7fc31ac44b03ed37a0cf42fdfff"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -6963,9 +7000,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.0.1"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4686009f71ff3e5c4dbcf1a282d0a44db3f021ba69350cd42086b3e5f1c6985"
|
||||
checksum = "fbc6ab6ec1907d1a901cdbcd2bd4cb9e7d64ce5c9739cbb97d3c391acd8c7fae"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
@ -7120,18 +7157,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.28"
|
||||
version = "0.7.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d6f15f7ade05d2a4935e34a457b936c23dc70a05cc1d97133dc99e7a3fe0f0e"
|
||||
checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.28"
|
||||
version = "0.7.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbbad221e3f78500350ecbd7dfa4e63ef945c05f4c61cb7f4d3f84cd0bba649b"
|
||||
checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
|
|
@ -316,17 +316,18 @@ fn collect_all_files_and_dirs(dir: &str) -> std::io::Result<CollectedFiles> {
|
|||
let rd = fs::read_dir(folder)?;
|
||||
for entry in rd {
|
||||
let entry = entry?;
|
||||
let path = entry.path();
|
||||
let file_type = entry.file_type()?;
|
||||
let path_str = entry.path().to_string_lossy().to_string();
|
||||
|
||||
if path.is_dir() {
|
||||
folders.insert(path.to_string_lossy().to_string());
|
||||
folders_to_check.push(path.to_string_lossy().to_string());
|
||||
} else if path.is_symlink() {
|
||||
symlinks.insert(path.to_string_lossy().to_string());
|
||||
} else if path.is_file() {
|
||||
files.insert(path.to_string_lossy().to_string());
|
||||
if file_type.is_dir() {
|
||||
folders.insert(path_str.clone());
|
||||
folders_to_check.push(path_str);
|
||||
} else if file_type.is_symlink() {
|
||||
symlinks.insert(path_str);
|
||||
} else if file_type.is_file() {
|
||||
files.insert(path_str);
|
||||
} else {
|
||||
panic!("Unknown type of file {:?}", path);
|
||||
panic!("Unknown type of file {path_str:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,14 @@ homepage = "https://github.com/qarmin/czkawka"
|
|||
repository = "https://github.com/qarmin/czkawka"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.3", features = ["derive"] }
|
||||
clap = { version = "4.4", features = ["derive"] }
|
||||
|
||||
# For enum types
|
||||
image_hasher = "1.2"
|
||||
|
||||
log = "0.4.20"
|
||||
handsome_logger = "0.8"
|
||||
fun_time = { version = "0.3.1", features = ["log"] }
|
||||
fun_time = { version = "0.3", features = ["log"] }
|
||||
czkawka_core = { path = "../czkawka_core", version = "6.1.0", features = [] }
|
||||
|
||||
[features]
|
||||
|
|
|
@ -8,7 +8,7 @@ description = "Core of Czkawka app"
|
|||
license = "MIT"
|
||||
homepage = "https://github.com/qarmin/czkawka"
|
||||
repository = "https://github.com/qarmin/czkawka"
|
||||
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
humansize = "2.1"
|
||||
|
@ -26,12 +26,12 @@ hamming = "0.1"
|
|||
|
||||
# Needed by same music
|
||||
bitflags = "2.4"
|
||||
lofty = "0.16"
|
||||
lofty = "0.17"
|
||||
|
||||
# Needed by broken files
|
||||
zip = { version = "0.6", features = ["aes-crypto", "bzip2", "deflate", "time"], default-features = false }
|
||||
audio_checker = "0.1"
|
||||
pdf = "0.8"
|
||||
pdf = "0.9"
|
||||
|
||||
# Needed by audio similarity feature
|
||||
rusty-chromaprint = "0.1"
|
||||
|
@ -56,8 +56,8 @@ serde_json = "1.0"
|
|||
# Language
|
||||
i18n-embed = { version = "0.14", features = ["fluent-system", "desktop-requester"] }
|
||||
i18n-embed-fl = "0.7"
|
||||
rust-embed = { version = "8.0", features = ["debug-embed"] }
|
||||
once_cell = "1.18"
|
||||
rust-embed = { version = "8.1", features = ["debug-embed"] }
|
||||
once_cell = "1.19"
|
||||
|
||||
# Raw image files
|
||||
rawloader = "0.37"
|
||||
|
@ -77,12 +77,14 @@ anyhow = { version = "1.0" }
|
|||
state = "0.6"
|
||||
|
||||
os_info = { version = "3", default-features = false }
|
||||
rustc_version = "0.4"
|
||||
log = "0.4.20"
|
||||
handsome_logger = "0.8"
|
||||
fun_time = { version = "0.3.1", features = ["log"] }
|
||||
fun_time = { version = "0.3", features = ["log"] }
|
||||
|
||||
[build-dependencies]
|
||||
rustc_version = "0.4"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
heif = ["dep:libheif-rs", "dep:libheif-sys"]
|
||||
libraw = ["dep:libraw-rs"]
|
||||
libraw = ["dep:libraw-rs"]
|
||||
|
|
18
czkawka_core/build.rs
Normal file
18
czkawka_core/build.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
fn main() {
|
||||
let rust_version = match rustc_version::version_meta() {
|
||||
Ok(meta) => {
|
||||
let rust_v = meta.semver.to_string();
|
||||
let rust_date = meta.commit_date.unwrap_or_default();
|
||||
format!("{rust_v} ({rust_date})")
|
||||
}
|
||||
Err(_) => "<unknown>".to_string(),
|
||||
};
|
||||
println!("cargo:rustc-env=RUST_VERSION_INTERNAL={rust_version}");
|
||||
|
||||
// Find if app is build with cranelift
|
||||
if let Ok(codegen) = std::env::var("CARGO_PROFILE_RELEASE_CODEGEN_UNITS") {
|
||||
if codegen == "1" {
|
||||
println!("cargo:rustc-env=USING_CRANELIFT=1");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -231,9 +231,7 @@ impl BadExtensions {
|
|||
|
||||
true
|
||||
}
|
||||
DirTraversalResult::SuccessFolders { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
DirTraversalResult::Stopped => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::collections::BTreeMap;
|
|||
use std::fs;
|
||||
use std::fs::DirEntry;
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -106,14 +106,13 @@ impl BigFile {
|
|||
check_folder_children(
|
||||
&mut dir_result,
|
||||
&mut warnings,
|
||||
¤t_folder,
|
||||
&entry_data,
|
||||
self.common_data.recursive_search,
|
||||
&self.common_data.directories,
|
||||
&self.common_data.excluded_items,
|
||||
);
|
||||
} else if file_type.is_file() {
|
||||
self.collect_file_entry(&atomic_counter, &entry_data, &mut fe_result, &mut warnings, ¤t_folder);
|
||||
self.collect_file_entry(&atomic_counter, &entry_data, &mut fe_result, &mut warnings);
|
||||
}
|
||||
}
|
||||
(dir_result, warnings, fe_result)
|
||||
|
@ -142,20 +141,13 @@ impl BigFile {
|
|||
true
|
||||
}
|
||||
|
||||
pub fn collect_file_entry(
|
||||
&self,
|
||||
atomic_counter: &Arc<AtomicUsize>,
|
||||
entry_data: &DirEntry,
|
||||
fe_result: &mut Vec<(u64, FileEntry)>,
|
||||
warnings: &mut Vec<String>,
|
||||
current_folder: &Path,
|
||||
) {
|
||||
pub fn collect_file_entry(&self, atomic_counter: &Arc<AtomicUsize>, entry_data: &DirEntry, fe_result: &mut Vec<(u64, FileEntry)>, warnings: &mut Vec<String>) {
|
||||
atomic_counter.fetch_add(1, Ordering::Relaxed);
|
||||
if !self.common_data.allowed_extensions.check_if_entry_ends_with_extension(entry_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
let current_file_name = current_folder.join(entry_data.file_name());
|
||||
let current_file_name = entry_data.path();
|
||||
if self.common_data.excluded_items.is_excluded(¤t_file_name) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -144,14 +144,13 @@ impl BrokenFiles {
|
|||
check_folder_children(
|
||||
&mut dir_result,
|
||||
&mut warnings,
|
||||
¤t_folder,
|
||||
&entry_data,
|
||||
self.common_data.recursive_search,
|
||||
&self.common_data.directories,
|
||||
&self.common_data.excluded_items,
|
||||
);
|
||||
} else if file_type.is_file() {
|
||||
if let Some(file_entry) = self.get_file_entry(&atomic_counter, &entry_data, &mut warnings, ¤t_folder) {
|
||||
if let Some(file_entry) = self.get_file_entry(&atomic_counter, &entry_data, &mut warnings) {
|
||||
fe_result.push((file_entry.path.to_string_lossy().to_string(), file_entry));
|
||||
}
|
||||
}
|
||||
|
@ -178,7 +177,7 @@ impl BrokenFiles {
|
|||
true
|
||||
}
|
||||
|
||||
fn get_file_entry(&self, atomic_counter: &Arc<AtomicUsize>, entry_data: &DirEntry, warnings: &mut Vec<String>, current_folder: &Path) -> Option<FileEntry> {
|
||||
fn get_file_entry(&self, atomic_counter: &Arc<AtomicUsize>, entry_data: &DirEntry, warnings: &mut Vec<String>) -> Option<FileEntry> {
|
||||
atomic_counter.fetch_add(1, Ordering::Relaxed);
|
||||
if !self.common_data.allowed_extensions.check_if_entry_ends_with_extension(entry_data) {
|
||||
return None;
|
||||
|
@ -191,7 +190,7 @@ impl BrokenFiles {
|
|||
return None;
|
||||
}
|
||||
|
||||
let current_file_name = current_folder.join(entry_data.file_name());
|
||||
let current_file_name = entry_data.path();
|
||||
if self.common_data.excluded_items.is_excluded(¤t_file_name) {
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -75,10 +75,7 @@ pub fn get_available_threads() -> usize {
|
|||
}
|
||||
|
||||
pub fn print_version_mode() {
|
||||
let rust_version = match rustc_version::version_meta() {
|
||||
Ok(meta) => meta.semver.to_string(),
|
||||
Err(_) => "<unknown>".to_string(),
|
||||
};
|
||||
let rust_version = env!("RUST_VERSION_INTERNAL");
|
||||
let debug_release = if cfg!(debug_assertions) { "debug" } else { "release" };
|
||||
|
||||
let processors = get_available_threads();
|
||||
|
@ -94,6 +91,10 @@ pub fn print_version_mode() {
|
|||
if cfg!(debug_assertions) {
|
||||
warn!("You are running debug version of app which is a lot of slower than release version.");
|
||||
}
|
||||
|
||||
if option_env!("USING_CRANELIFT").is_some() {
|
||||
warn!("You are running app with cranelift which is intended only for fast compilation, not runtime performance.");
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_default_number_of_threads() {
|
||||
|
@ -173,7 +174,11 @@ pub fn remove_folder_if_contains_only_empty_folders(path: impl AsRef<Path>) -> b
|
|||
let Some(entry) = entries_to_check.pop() else {
|
||||
break;
|
||||
};
|
||||
if !entry.path().is_dir() {
|
||||
let Some(file_type) = entry.file_type().ok() else {
|
||||
return false;
|
||||
};
|
||||
|
||||
if !file_type.is_dir() {
|
||||
return false;
|
||||
}
|
||||
let Ok(internal_read_dir) = entry.path().read_dir() else {
|
||||
|
@ -421,7 +426,6 @@ pub fn normalize_windows_path(path_to_change: impl AsRef<Path>) -> PathBuf {
|
|||
pub fn check_folder_children(
|
||||
dir_result: &mut Vec<PathBuf>,
|
||||
warnings: &mut Vec<String>,
|
||||
current_folder: &Path,
|
||||
entry_data: &DirEntry,
|
||||
recursive_search: bool,
|
||||
directories: &Directories,
|
||||
|
@ -431,25 +435,25 @@ pub fn check_folder_children(
|
|||
return;
|
||||
}
|
||||
|
||||
let next_folder = current_folder.join(entry_data.file_name());
|
||||
if directories.is_excluded(&next_folder) {
|
||||
let next_item = entry_data.path();
|
||||
if directories.is_excluded(&next_item) {
|
||||
return;
|
||||
}
|
||||
|
||||
if excluded_items.is_excluded(&next_folder) {
|
||||
if excluded_items.is_excluded(&next_item) {
|
||||
return;
|
||||
}
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
if directories.exclude_other_filesystems() {
|
||||
match directories.is_on_other_filesystems(&next_folder) {
|
||||
match directories.is_on_other_filesystems(&next_item) {
|
||||
Ok(true) => return,
|
||||
Err(e) => warnings.push(e),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
dir_result.push(next_folder);
|
||||
dir_result.push(next_item);
|
||||
}
|
||||
|
||||
// Here we assume, that internal Vec<> have at least 1 object
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs;
|
||||
use std::fs::{DirEntry, FileType, Metadata, ReadDir};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
@ -95,31 +95,8 @@ pub enum ErrorType {
|
|||
NonExistentFile,
|
||||
}
|
||||
|
||||
// Empty folders
|
||||
|
||||
/// Enum with values which show if folder is empty.
|
||||
/// In function "`optimize_folders`" automatically "Maybe" is changed to "Yes", so it is not necessary to put it here
|
||||
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
||||
pub(crate) enum FolderEmptiness {
|
||||
No,
|
||||
Maybe,
|
||||
}
|
||||
|
||||
/// Struct assigned to each checked folder with parent path(used to ignore parent if children are not empty) and flag which shows if folder is empty
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FolderEntry {
|
||||
pub path: PathBuf,
|
||||
pub(crate) parent_path: Option<String>,
|
||||
// Usable only when finding
|
||||
pub(crate) is_empty: FolderEmptiness,
|
||||
pub modified_date: u64,
|
||||
}
|
||||
|
||||
// Collection mode (files / empty folders)
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
pub enum Collect {
|
||||
EmptyFolders,
|
||||
InvalidSymlinks,
|
||||
Files,
|
||||
}
|
||||
|
@ -315,10 +292,6 @@ pub enum DirTraversalResult<T: Ord + PartialOrd> {
|
|||
warnings: Vec<String>,
|
||||
grouped_file_entries: BTreeMap<T, Vec<FileEntry>>,
|
||||
},
|
||||
SuccessFolders {
|
||||
warnings: Vec<String>,
|
||||
folder_entries: HashMap<String, FolderEntry>, // Path, FolderEntry
|
||||
},
|
||||
Stopped,
|
||||
}
|
||||
|
||||
|
@ -345,22 +318,7 @@ where
|
|||
|
||||
let mut all_warnings = vec![];
|
||||
let mut grouped_file_entries: BTreeMap<T, Vec<FileEntry>> = BTreeMap::new();
|
||||
let mut folder_entries: HashMap<String, FolderEntry> = HashMap::new();
|
||||
|
||||
// Add root folders into result (only for empty folder collection)
|
||||
if self.collect == Collect::EmptyFolders {
|
||||
for dir in &self.root_dirs {
|
||||
folder_entries.insert(
|
||||
dir.to_string_lossy().to_string(),
|
||||
FolderEntry {
|
||||
path: dir.clone(),
|
||||
parent_path: None,
|
||||
is_empty: FolderEmptiness::Maybe,
|
||||
modified_date: 0,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
// Add root folders for finding
|
||||
let mut folders_to_check: Vec<PathBuf> = self.root_dirs.clone();
|
||||
|
||||
|
@ -391,19 +349,14 @@ where
|
|||
let mut dir_result = vec![];
|
||||
let mut warnings = vec![];
|
||||
let mut fe_result = vec![];
|
||||
let mut set_as_not_empty_folder_list = vec![];
|
||||
let mut folder_entries_list = vec![];
|
||||
|
||||
let Some(read_dir) = common_read_dir(¤t_folder, &mut warnings) else {
|
||||
if collect == Collect::EmptyFolders {
|
||||
set_as_not_empty_folder_list.push(current_folder);
|
||||
}
|
||||
return (dir_result, warnings, fe_result, set_as_not_empty_folder_list, folder_entries_list);
|
||||
return (dir_result, warnings, fe_result);
|
||||
};
|
||||
|
||||
let mut counter = 0;
|
||||
// Check every sub folder/file/link etc.
|
||||
'dir: for entry in read_dir {
|
||||
for entry in read_dir {
|
||||
let Some(entry_data) = common_get_entry_data(&entry, &mut warnings, ¤t_folder) else {
|
||||
continue;
|
||||
};
|
||||
|
@ -411,20 +364,7 @@ where
|
|||
|
||||
match (entry_type(file_type), collect) {
|
||||
(EntryType::Dir, Collect::Files | Collect::InvalidSymlinks) => {
|
||||
process_dir_in_file_symlink_mode(recursive_search, ¤t_folder, entry_data, &directories, &mut dir_result, &mut warnings, &excluded_items);
|
||||
}
|
||||
(EntryType::Dir, Collect::EmptyFolders) => {
|
||||
counter += 1;
|
||||
process_dir_in_dir_mode(
|
||||
¤t_folder,
|
||||
entry_data,
|
||||
&directories,
|
||||
&mut dir_result,
|
||||
&mut warnings,
|
||||
&excluded_items,
|
||||
&mut set_as_not_empty_folder_list,
|
||||
&mut folder_entries_list,
|
||||
);
|
||||
process_dir_in_file_symlink_mode(recursive_search, entry_data, &directories, &mut dir_result, &mut warnings, &excluded_items);
|
||||
}
|
||||
(EntryType::File, Collect::Files) => {
|
||||
counter += 1;
|
||||
|
@ -433,39 +373,18 @@ where
|
|||
&mut warnings,
|
||||
&mut fe_result,
|
||||
&allowed_extensions,
|
||||
¤t_folder,
|
||||
&directories,
|
||||
&excluded_items,
|
||||
minimal_file_size,
|
||||
maximal_file_size,
|
||||
);
|
||||
}
|
||||
(EntryType::File | EntryType::Symlink, Collect::EmptyFolders) => {
|
||||
#[cfg(target_family = "unix")]
|
||||
if directories.exclude_other_filesystems() {
|
||||
match directories.is_on_other_filesystems(¤t_folder) {
|
||||
Ok(true) => continue 'dir,
|
||||
Err(e) => warnings.push(e.to_string()),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
set_as_not_empty_folder_list.push(current_folder.clone());
|
||||
}
|
||||
(EntryType::File, Collect::InvalidSymlinks) => {
|
||||
counter += 1;
|
||||
}
|
||||
(EntryType::Symlink, Collect::InvalidSymlinks) => {
|
||||
counter += 1;
|
||||
process_symlink_in_symlink_mode(
|
||||
entry_data,
|
||||
&mut warnings,
|
||||
&mut fe_result,
|
||||
&allowed_extensions,
|
||||
¤t_folder,
|
||||
&directories,
|
||||
&excluded_items,
|
||||
);
|
||||
process_symlink_in_symlink_mode(entry_data, &mut warnings, &mut fe_result, &allowed_extensions, &directories, &excluded_items);
|
||||
}
|
||||
(EntryType::Symlink, Collect::Files) | (EntryType::Other, _) => {
|
||||
// nothing to do
|
||||
|
@ -476,47 +395,33 @@ where
|
|||
// Increase counter in batch, because usually it may be slow to add multiple times atomic value
|
||||
atomic_counter.fetch_add(counter, Ordering::Relaxed);
|
||||
}
|
||||
(dir_result, warnings, fe_result, set_as_not_empty_folder_list, folder_entries_list)
|
||||
(dir_result, warnings, fe_result)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let required_size = segments.iter().map(|(segment, _, _, _, _)| segment.len()).sum::<usize>();
|
||||
let required_size = segments.iter().map(|(segment, _, _)| segment.len()).sum::<usize>();
|
||||
folders_to_check = Vec::with_capacity(required_size);
|
||||
|
||||
// Process collected data
|
||||
for (segment, warnings, fe_result, set_as_not_empty_folder_list, fe_list) in segments {
|
||||
for (segment, warnings, fe_result) in segments {
|
||||
folders_to_check.extend(segment);
|
||||
all_warnings.extend(warnings);
|
||||
for fe in fe_result {
|
||||
let key = (self.group_by)(&fe);
|
||||
grouped_file_entries.entry(key).or_default().push(fe);
|
||||
}
|
||||
for current_folder in &set_as_not_empty_folder_list {
|
||||
set_as_not_empty_folder(&mut folder_entries, current_folder);
|
||||
}
|
||||
for (path, entry) in fe_list {
|
||||
folder_entries.insert(path.to_string_lossy().to_string(), entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
send_info_and_wait_for_ending_all_threads(&progress_thread_run, progress_thread_handle);
|
||||
|
||||
debug!(
|
||||
"Collected {} files, {} folders",
|
||||
grouped_file_entries.values().map(Vec::len).sum::<usize>(),
|
||||
folder_entries.len()
|
||||
);
|
||||
debug!("Collected {} files", grouped_file_entries.values().map(Vec::len).sum::<usize>());
|
||||
|
||||
match collect {
|
||||
Collect::Files | Collect::InvalidSymlinks => DirTraversalResult::SuccessFiles {
|
||||
grouped_file_entries,
|
||||
warnings: all_warnings,
|
||||
},
|
||||
Collect::EmptyFolders => DirTraversalResult::SuccessFolders {
|
||||
folder_entries,
|
||||
warnings: all_warnings,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -526,7 +431,6 @@ fn process_file_in_file_mode(
|
|||
warnings: &mut Vec<String>,
|
||||
fe_result: &mut Vec<FileEntry>,
|
||||
allowed_extensions: &Extensions,
|
||||
current_folder: &Path,
|
||||
directories: &Directories,
|
||||
excluded_items: &ExcludedItems,
|
||||
minimal_file_size: u64,
|
||||
|
@ -536,7 +440,7 @@ fn process_file_in_file_mode(
|
|||
return;
|
||||
}
|
||||
|
||||
let current_file_name = current_folder.join(entry_data.file_name());
|
||||
let current_file_name = entry_data.path();
|
||||
if excluded_items.is_excluded(¤t_file_name) {
|
||||
return;
|
||||
}
|
||||
|
@ -550,7 +454,7 @@ fn process_file_in_file_mode(
|
|||
}
|
||||
}
|
||||
|
||||
let Some(metadata) = common_get_metadata_dir(entry_data, warnings, current_folder) else {
|
||||
let Some(metadata) = common_get_metadata_dir(entry_data, warnings, ¤t_file_name) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -568,51 +472,8 @@ fn process_file_in_file_mode(
|
|||
}
|
||||
}
|
||||
|
||||
fn process_dir_in_dir_mode(
|
||||
current_folder: &Path,
|
||||
entry_data: &DirEntry,
|
||||
directories: &Directories,
|
||||
dir_result: &mut Vec<PathBuf>,
|
||||
warnings: &mut Vec<String>,
|
||||
excluded_items: &ExcludedItems,
|
||||
set_as_not_empty_folder_list: &mut Vec<PathBuf>,
|
||||
folder_entries_list: &mut Vec<(PathBuf, FolderEntry)>,
|
||||
) {
|
||||
let next_folder = current_folder.join(entry_data.file_name());
|
||||
if excluded_items.is_excluded(&next_folder) || directories.is_excluded(&next_folder) {
|
||||
set_as_not_empty_folder_list.push(current_folder.to_path_buf());
|
||||
return;
|
||||
}
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
if directories.exclude_other_filesystems() {
|
||||
match directories.is_on_other_filesystems(&next_folder) {
|
||||
Ok(true) => return,
|
||||
Err(e) => warnings.push(e),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
let Some(metadata) = common_get_metadata_dir(entry_data, warnings, current_folder) else {
|
||||
set_as_not_empty_folder_list.push(current_folder.to_path_buf());
|
||||
return;
|
||||
};
|
||||
|
||||
dir_result.push(next_folder.clone());
|
||||
folder_entries_list.push((
|
||||
next_folder.clone(),
|
||||
FolderEntry {
|
||||
path: next_folder,
|
||||
parent_path: Some(current_folder.to_string_lossy().to_string()),
|
||||
is_empty: FolderEmptiness::Maybe,
|
||||
modified_date: get_modified_time(&metadata, warnings, current_folder, true),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
fn process_dir_in_file_symlink_mode(
|
||||
recursive_search: bool,
|
||||
current_folder: &Path,
|
||||
entry_data: &DirEntry,
|
||||
directories: &Directories,
|
||||
dir_result: &mut Vec<PathBuf>,
|
||||
|
@ -623,25 +484,25 @@ fn process_dir_in_file_symlink_mode(
|
|||
return;
|
||||
}
|
||||
|
||||
let next_folder = current_folder.join(entry_data.file_name());
|
||||
if directories.is_excluded(&next_folder) {
|
||||
let dir_path = entry_data.path();
|
||||
if directories.is_excluded(&dir_path) {
|
||||
return;
|
||||
}
|
||||
|
||||
if excluded_items.is_excluded(&next_folder) {
|
||||
if excluded_items.is_excluded(&dir_path) {
|
||||
return;
|
||||
}
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
if directories.exclude_other_filesystems() {
|
||||
match directories.is_on_other_filesystems(&next_folder) {
|
||||
match directories.is_on_other_filesystems(&dir_path) {
|
||||
Ok(true) => return,
|
||||
Err(e) => warnings.push(e),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
dir_result.push(next_folder);
|
||||
dir_result.push(dir_path);
|
||||
}
|
||||
|
||||
fn process_symlink_in_symlink_mode(
|
||||
|
@ -649,7 +510,6 @@ fn process_symlink_in_symlink_mode(
|
|||
warnings: &mut Vec<String>,
|
||||
fe_result: &mut Vec<FileEntry>,
|
||||
allowed_extensions: &Extensions,
|
||||
current_folder: &Path,
|
||||
directories: &Directories,
|
||||
excluded_items: &ExcludedItems,
|
||||
) {
|
||||
|
@ -657,21 +517,21 @@ fn process_symlink_in_symlink_mode(
|
|||
return;
|
||||
}
|
||||
|
||||
let current_file_name = current_folder.join(entry_data.file_name());
|
||||
let current_file_name = entry_data.path();
|
||||
if excluded_items.is_excluded(¤t_file_name) {
|
||||
return;
|
||||
}
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
if directories.exclude_other_filesystems() {
|
||||
match directories.is_on_other_filesystems(current_folder) {
|
||||
match directories.is_on_other_filesystems(¤t_file_name) {
|
||||
Ok(true) => return,
|
||||
Err(e) => warnings.push(e),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
let Some(metadata) = common_get_metadata_dir(entry_data, warnings, current_folder) else {
|
||||
let Some(metadata) = common_get_metadata_dir(entry_data, warnings, ¤t_file_name) else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -826,20 +686,3 @@ pub fn get_lowercase_name(entry_data: &DirEntry, warnings: &mut Vec<String>) ->
|
|||
.to_lowercase();
|
||||
Some(name)
|
||||
}
|
||||
|
||||
fn set_as_not_empty_folder(folder_entries: &mut HashMap<String, FolderEntry>, current_folder: &Path) {
|
||||
let mut d = folder_entries.get_mut(current_folder.to_string_lossy().as_ref()).unwrap();
|
||||
// Loop to recursively set as non empty this and all his parent folders
|
||||
loop {
|
||||
d.is_empty = FolderEmptiness::No;
|
||||
if d.parent_path.is_some() {
|
||||
let cf = d.parent_path.clone().unwrap();
|
||||
d = folder_entries.get_mut(&cf).unwrap();
|
||||
if d.is_empty == FolderEmptiness::No {
|
||||
break; // Already set as non empty, so one of child already set it to non empty
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -204,9 +204,6 @@ impl DuplicateFinder {
|
|||
|
||||
true
|
||||
}
|
||||
DirTraversalResult::SuccessFolders { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
DirTraversalResult::Stopped => false,
|
||||
}
|
||||
}
|
||||
|
@ -280,9 +277,7 @@ impl DuplicateFinder {
|
|||
|
||||
true
|
||||
}
|
||||
DirTraversalResult::SuccessFolders { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
DirTraversalResult::Stopped => false,
|
||||
}
|
||||
}
|
||||
|
@ -356,9 +351,7 @@ impl DuplicateFinder {
|
|||
|
||||
true
|
||||
}
|
||||
DirTraversalResult::SuccessFolders { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
DirTraversalResult::Stopped => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,9 +77,7 @@ impl EmptyFiles {
|
|||
|
||||
true
|
||||
}
|
||||
DirTraversalResult::SuccessFolders { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
DirTraversalResult::Stopped => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,22 +1,45 @@
|
|||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
use std::fs::DirEntry;
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
use crate::common::{check_if_stop_received, prepare_thread_handler_common, send_info_and_wait_for_ending_all_threads};
|
||||
use crossbeam_channel::{Receiver, Sender};
|
||||
use fun_time::fun_time;
|
||||
use log::debug;
|
||||
use rayon::prelude::*;
|
||||
|
||||
use crate::common_dir_traversal::{Collect, DirTraversalBuilder, DirTraversalResult, FolderEmptiness, FolderEntry, ProgressData, ToolType};
|
||||
use crate::common_dir_traversal::{common_get_entry_data, common_get_metadata_dir, common_read_dir, get_modified_time, CheckingMethod, ProgressData, ToolType};
|
||||
use crate::common_directory::Directories;
|
||||
use crate::common_items::ExcludedItems;
|
||||
use crate::common_tool::{CommonData, CommonToolData, DeleteMethod};
|
||||
use crate::common_traits::{DebugPrint, PrintResults};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct FolderEntry {
|
||||
pub path: PathBuf,
|
||||
pub(crate) parent_path: Option<String>,
|
||||
// Usable only when finding
|
||||
pub(crate) is_empty: FolderEmptiness,
|
||||
pub modified_date: u64,
|
||||
}
|
||||
|
||||
pub struct EmptyFolder {
|
||||
common_data: CommonToolData,
|
||||
information: Info,
|
||||
empty_folder_list: HashMap<String, FolderEntry>, // Path, FolderEntry
|
||||
}
|
||||
|
||||
/// Enum with values which show if folder is empty.
|
||||
/// In function "`optimize_folders`" automatically "Maybe" is changed to "Yes", so it is not necessary to put it here
|
||||
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
|
||||
pub(crate) enum FolderEmptiness {
|
||||
No,
|
||||
Maybe,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Info {
|
||||
pub number_of_empty_folders: usize,
|
||||
|
@ -73,36 +96,172 @@ impl EmptyFolder {
|
|||
|
||||
#[fun_time(message = "check_for_empty_folders", level = "debug")]
|
||||
fn check_for_empty_folders(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&Sender<ProgressData>>) -> bool {
|
||||
let result = DirTraversalBuilder::new()
|
||||
.root_dirs(self.common_data.directories.included_directories.clone())
|
||||
.group_by(|_fe| ())
|
||||
.stop_receiver(stop_receiver)
|
||||
.progress_sender(progress_sender)
|
||||
.directories(self.common_data.directories.clone())
|
||||
.excluded_items(self.common_data.excluded_items.clone())
|
||||
.collect(Collect::EmptyFolders)
|
||||
.max_stage(0)
|
||||
.tool_type(self.common_data.tool_type)
|
||||
.build()
|
||||
.run();
|
||||
let mut folders_to_check: Vec<PathBuf> = self.common_data.directories.included_directories.clone();
|
||||
|
||||
match result {
|
||||
DirTraversalResult::SuccessFiles { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
DirTraversalResult::SuccessFolders { folder_entries, warnings } => {
|
||||
for (name, folder_entry) in folder_entries {
|
||||
if folder_entry.is_empty != FolderEmptiness::No {
|
||||
self.empty_folder_list.insert(name, folder_entry);
|
||||
}
|
||||
}
|
||||
let (progress_thread_handle, progress_thread_run, atomic_counter, _check_was_stopped) =
|
||||
prepare_thread_handler_common(progress_sender, 0, 0, 0, CheckingMethod::None, self.common_data.tool_type);
|
||||
|
||||
self.common_data.text_messages.warnings.extend(warnings);
|
||||
debug!("Found {} empty folders.", self.empty_folder_list.len());
|
||||
true
|
||||
}
|
||||
DirTraversalResult::Stopped => false,
|
||||
let excluded_items = self.common_data.excluded_items.clone();
|
||||
let directories = self.common_data.directories.clone();
|
||||
|
||||
let mut folder_entries: HashMap<String, FolderEntry> = HashMap::new();
|
||||
let mut non_empty_folders: Vec<String> = vec![];
|
||||
|
||||
for dir in &folders_to_check {
|
||||
folder_entries.insert(
|
||||
dir.to_string_lossy().to_string(),
|
||||
FolderEntry {
|
||||
path: dir.clone(),
|
||||
parent_path: None,
|
||||
is_empty: FolderEmptiness::Maybe,
|
||||
modified_date: 0,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
while !folders_to_check.is_empty() {
|
||||
if check_if_stop_received(stop_receiver) {
|
||||
send_info_and_wait_for_ending_all_threads(&progress_thread_run, progress_thread_handle);
|
||||
return false;
|
||||
}
|
||||
|
||||
let segments: Vec<_> = folders_to_check
|
||||
.into_par_iter()
|
||||
.map(|current_folder| {
|
||||
let mut dir_result = vec![];
|
||||
let mut warnings = vec![];
|
||||
let mut set_as_not_empty_folder_list = vec![];
|
||||
let mut folder_entries_list = vec![];
|
||||
|
||||
let Some(read_dir) = common_read_dir(¤t_folder, &mut warnings) else {
|
||||
set_as_not_empty_folder_list.push(current_folder.to_string_lossy().to_string());
|
||||
return (dir_result, warnings, set_as_not_empty_folder_list, folder_entries_list);
|
||||
};
|
||||
|
||||
let mut counter = 0;
|
||||
// Check every sub folder/file/link etc.
|
||||
for entry in read_dir {
|
||||
let Some(entry_data) = common_get_entry_data(&entry, &mut warnings, ¤t_folder) else {
|
||||
continue;
|
||||
};
|
||||
let Ok(file_type) = entry_data.file_type() else { continue };
|
||||
|
||||
if file_type.is_dir() {
|
||||
counter += 1;
|
||||
Self::process_dir_in_dir_mode(
|
||||
¤t_folder,
|
||||
entry_data,
|
||||
&directories,
|
||||
&mut dir_result,
|
||||
&mut warnings,
|
||||
&excluded_items,
|
||||
&mut set_as_not_empty_folder_list,
|
||||
&mut folder_entries_list,
|
||||
);
|
||||
} else {
|
||||
set_as_not_empty_folder_list.push(current_folder.to_string_lossy().to_string());
|
||||
}
|
||||
}
|
||||
if counter > 0 {
|
||||
// Increase counter in batch, because usually it may be slow to add multiple times atomic value
|
||||
atomic_counter.fetch_add(counter, Ordering::Relaxed);
|
||||
}
|
||||
(dir_result, warnings, set_as_not_empty_folder_list, folder_entries_list)
|
||||
})
|
||||
.collect();
|
||||
|
||||
let required_size = segments.iter().map(|(segment, _, _, _)| segment.len()).sum::<usize>();
|
||||
folders_to_check = Vec::with_capacity(required_size);
|
||||
|
||||
// Process collected data
|
||||
for (segment, warnings, set_as_not_empty_folder_list, fe_list) in segments {
|
||||
folders_to_check.extend(segment);
|
||||
self.common_data.text_messages.warnings.extend(warnings);
|
||||
non_empty_folders.extend(set_as_not_empty_folder_list);
|
||||
for (path, entry) in fe_list {
|
||||
folder_entries.insert(path, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Start to
|
||||
for current_folder in non_empty_folders.into_iter().rev() {
|
||||
Self::set_as_not_empty_folder(&mut folder_entries, ¤t_folder);
|
||||
}
|
||||
|
||||
for (name, folder_entry) in folder_entries {
|
||||
if folder_entry.is_empty != FolderEmptiness::No {
|
||||
self.empty_folder_list.insert(name, folder_entry);
|
||||
}
|
||||
}
|
||||
|
||||
debug!("Found {} empty folders.", self.empty_folder_list.len());
|
||||
send_info_and_wait_for_ending_all_threads(&progress_thread_run, progress_thread_handle);
|
||||
true
|
||||
}
|
||||
|
||||
pub(crate) fn set_as_not_empty_folder(folder_entries: &mut HashMap<String, FolderEntry>, current_folder: &str) {
|
||||
let mut d = folder_entries.get_mut(current_folder).unwrap();
|
||||
if d.is_empty == FolderEmptiness::No {
|
||||
return; // Already set as non empty by one of his child
|
||||
}
|
||||
|
||||
// Loop to recursively set as non empty this and all his parent folders
|
||||
loop {
|
||||
d.is_empty = FolderEmptiness::No;
|
||||
if d.parent_path.is_some() {
|
||||
let cf = d.parent_path.clone().unwrap();
|
||||
d = folder_entries.get_mut(&cf).unwrap();
|
||||
if d.is_empty == FolderEmptiness::No {
|
||||
break; // Already set as non empty, so one of child already set it to non empty
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn process_dir_in_dir_mode(
|
||||
current_folder: &Path,
|
||||
entry_data: &DirEntry,
|
||||
directories: &Directories,
|
||||
dir_result: &mut Vec<PathBuf>,
|
||||
warnings: &mut Vec<String>,
|
||||
excluded_items: &ExcludedItems,
|
||||
set_as_not_empty_folder_list: &mut Vec<String>,
|
||||
folder_entries_list: &mut Vec<(String, FolderEntry)>,
|
||||
) {
|
||||
let parent_folder_str = current_folder.to_string_lossy().to_string();
|
||||
let next_folder = entry_data.path();
|
||||
if excluded_items.is_excluded(&next_folder) || directories.is_excluded(&next_folder) {
|
||||
set_as_not_empty_folder_list.push(parent_folder_str);
|
||||
return;
|
||||
}
|
||||
|
||||
#[cfg(target_family = "unix")]
|
||||
if directories.exclude_other_filesystems() {
|
||||
match directories.is_on_other_filesystems(&next_folder) {
|
||||
Ok(true) => return,
|
||||
Err(e) => warnings.push(e),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
let Some(metadata) = common_get_metadata_dir(entry_data, warnings, &next_folder) else {
|
||||
set_as_not_empty_folder_list.push(parent_folder_str);
|
||||
return;
|
||||
};
|
||||
|
||||
dir_result.push(next_folder.clone());
|
||||
folder_entries_list.push((
|
||||
next_folder.to_string_lossy().to_string(),
|
||||
FolderEntry {
|
||||
path: next_folder,
|
||||
parent_path: Some(parent_folder_str),
|
||||
is_empty: FolderEmptiness::Maybe,
|
||||
modified_date: get_modified_time(&metadata, warnings, current_folder, true),
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
#[fun_time(message = "delete_files", level = "debug")]
|
||||
|
|
|
@ -64,7 +64,6 @@ impl InvalidSymlinks {
|
|||
debug!("Found {} invalid symlinks.", self.information.number_of_invalid_symlinks);
|
||||
true
|
||||
}
|
||||
DirTraversalResult::SuccessFolders { .. } => unreachable!(),
|
||||
DirTraversalResult::Stopped => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,9 +219,7 @@ impl SameMusic {
|
|||
debug!("check_files - Found {} music files.", self.music_to_check.len());
|
||||
true
|
||||
}
|
||||
DirTraversalResult::SuccessFolders { .. } => {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
DirTraversalResult::Stopped => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,7 +198,6 @@ impl SimilarImages {
|
|||
check_folder_children(
|
||||
&mut dir_result,
|
||||
&mut warnings,
|
||||
¤t_folder,
|
||||
&entry_data,
|
||||
self.common_data.recursive_search,
|
||||
&self.common_data.directories,
|
||||
|
@ -206,7 +205,7 @@ impl SimilarImages {
|
|||
);
|
||||
} else if file_type.is_file() {
|
||||
atomic_counter.fetch_add(1, Ordering::Relaxed);
|
||||
self.add_file_entry(¤t_folder, &entry_data, &mut fe_result, &mut warnings);
|
||||
self.add_file_entry(&entry_data, &mut fe_result, &mut warnings);
|
||||
}
|
||||
}
|
||||
(dir_result, warnings, fe_result)
|
||||
|
@ -233,12 +232,12 @@ impl SimilarImages {
|
|||
true
|
||||
}
|
||||
|
||||
fn add_file_entry(&self, current_folder: &Path, entry_data: &DirEntry, fe_result: &mut Vec<(String, FileEntry)>, warnings: &mut Vec<String>) {
|
||||
fn add_file_entry(&self, entry_data: &DirEntry, fe_result: &mut Vec<(String, FileEntry)>, warnings: &mut Vec<String>) {
|
||||
if !self.common_data.allowed_extensions.check_if_entry_ends_with_extension(entry_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
let current_file_name = current_folder.join(entry_data.file_name());
|
||||
let current_file_name = entry_data.path();
|
||||
if self.common_data.excluded_items.is_excluded(¤t_file_name) {
|
||||
return;
|
||||
}
|
||||
|
@ -249,16 +248,17 @@ impl SimilarImages {
|
|||
|
||||
// Checking files
|
||||
if (self.common_data.minimal_file_size..=self.common_data.maximal_file_size).contains(&metadata.len()) {
|
||||
let path_str = current_file_name.to_string_lossy().to_string();
|
||||
let fe: FileEntry = FileEntry {
|
||||
path: current_file_name.clone(),
|
||||
size: metadata.len(),
|
||||
dimensions: String::new(),
|
||||
modified_date: get_modified_time(&metadata, warnings, ¤t_file_name, false),
|
||||
path: current_file_name,
|
||||
hash: Vec::new(),
|
||||
similarity: 0,
|
||||
};
|
||||
|
||||
fe_result.push((current_file_name.to_string_lossy().to_string(), fe));
|
||||
fe_result.push((path_str, fe));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -174,7 +174,6 @@ impl SimilarVideos {
|
|||
check_folder_children(
|
||||
&mut dir_result,
|
||||
&mut warnings,
|
||||
¤t_folder,
|
||||
&entry_data,
|
||||
self.common_data.recursive_search,
|
||||
&self.common_data.directories,
|
||||
|
@ -182,7 +181,7 @@ impl SimilarVideos {
|
|||
);
|
||||
} else if file_type.is_file() {
|
||||
atomic_counter.fetch_add(1, Ordering::Relaxed);
|
||||
self.add_video_file_entry(&entry_data, &mut fe_result, &mut warnings, ¤t_folder);
|
||||
self.add_video_file_entry(&entry_data, &mut fe_result, &mut warnings);
|
||||
}
|
||||
}
|
||||
(dir_result, warnings, fe_result)
|
||||
|
@ -207,12 +206,12 @@ impl SimilarVideos {
|
|||
true
|
||||
}
|
||||
|
||||
fn add_video_file_entry(&self, entry_data: &DirEntry, fe_result: &mut Vec<(String, FileEntry)>, warnings: &mut Vec<String>, current_folder: &Path) {
|
||||
fn add_video_file_entry(&self, entry_data: &DirEntry, fe_result: &mut Vec<(String, FileEntry)>, warnings: &mut Vec<String>) {
|
||||
if !self.common_data.allowed_extensions.check_if_entry_ends_with_extension(entry_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
let current_file_name = current_folder.join(entry_data.file_name());
|
||||
let current_file_name = entry_data.path();
|
||||
if self.common_data.excluded_items.is_excluded(¤t_file_name) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::fs;
|
|||
use std::fs::DirEntry;
|
||||
use std::io::prelude::*;
|
||||
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
use std::sync::Arc;
|
||||
|
||||
|
@ -106,14 +106,13 @@ impl Temporary {
|
|||
check_folder_children(
|
||||
&mut dir_result,
|
||||
&mut warnings,
|
||||
¤t_folder,
|
||||
&entry_data,
|
||||
self.common_data.recursive_search,
|
||||
&self.common_data.directories,
|
||||
&self.common_data.excluded_items,
|
||||
);
|
||||
} else if file_type.is_file() {
|
||||
if let Some(file_entry) = self.get_file_entry(&atomic_counter, &entry_data, &mut warnings, ¤t_folder) {
|
||||
if let Some(file_entry) = self.get_file_entry(&atomic_counter, &entry_data, &mut warnings) {
|
||||
fe_result.push(file_entry);
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +139,7 @@ impl Temporary {
|
|||
|
||||
true
|
||||
}
|
||||
pub fn get_file_entry(&self, atomic_counter: &Arc<AtomicUsize>, entry_data: &DirEntry, warnings: &mut Vec<String>, current_folder: &Path) -> Option<FileEntry> {
|
||||
pub fn get_file_entry(&self, atomic_counter: &Arc<AtomicUsize>, entry_data: &DirEntry, warnings: &mut Vec<String>) -> Option<FileEntry> {
|
||||
atomic_counter.fetch_add(1, Ordering::Relaxed);
|
||||
|
||||
let file_name_lowercase = get_lowercase_name(entry_data, warnings)?;
|
||||
|
@ -148,7 +147,7 @@ impl Temporary {
|
|||
if !TEMP_EXTENSIONS.iter().any(|f| file_name_lowercase.ends_with(f)) {
|
||||
return None;
|
||||
}
|
||||
let current_file_name = current_folder.join(entry_data.file_name());
|
||||
let current_file_name = entry_data.path();
|
||||
if self.common_data.excluded_items.is_excluded(¤t_file_name) {
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -29,13 +29,13 @@ open = "5.0"
|
|||
image = "0.24"
|
||||
|
||||
# To be able to use custom select
|
||||
regex = "1.9"
|
||||
regex = "1.10"
|
||||
|
||||
# To get image_hasher types
|
||||
image_hasher = "1.2"
|
||||
|
||||
# Move files to trash
|
||||
trash = "3.0"
|
||||
trash = "3.1"
|
||||
|
||||
# For moving files(why std::fs doesn't have such features?)
|
||||
fs_extra = "1.3"
|
||||
|
@ -43,12 +43,12 @@ fs_extra = "1.3"
|
|||
# Language
|
||||
i18n-embed = { version = "0.14", features = ["fluent-system", "desktop-requester"] }
|
||||
i18n-embed-fl = "0.7"
|
||||
rust-embed = { version = "8.0", features = ["debug-embed"] }
|
||||
once_cell = "1.18"
|
||||
rust-embed = { version = "8.1", features = ["debug-embed"] }
|
||||
once_cell = "1.19"
|
||||
|
||||
log = "0.4.20"
|
||||
handsome_logger = "0.8"
|
||||
fun_time = { version = "0.3.1", features = ["log"] }
|
||||
fun_time = { version = "0.3", features = ["log"] }
|
||||
|
||||
czkawka_core = { path = "../czkawka_core", version = "6.1.0", features = [] }
|
||||
gtk4 = { version = "0.7", default-features = false, features = ["v4_6"] }
|
||||
|
|
|
@ -1325,13 +1325,13 @@ fn computer_duplicate_finder(
|
|||
}
|
||||
}
|
||||
|
||||
fn vector_sort_unstable_entry_by_path(vector: &Vec<FileEntry>) -> Vec<FileEntry> {
|
||||
fn vector_sort_unstable_entry_by_path(vector: &[FileEntry]) -> Vec<FileEntry> {
|
||||
if vector.len() >= 2 {
|
||||
let mut vector = vector.clone();
|
||||
let mut vector = vector.to_owned();
|
||||
vector.sort_unstable_by(|a, b| split_path_compare(a.path.as_path(), b.path.as_path()));
|
||||
vector
|
||||
} else {
|
||||
vector.clone()
|
||||
vector.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,6 +83,8 @@ fn build_ui(application: &Application, arguments: &[OsString]) {
|
|||
let gui_data: GuiData = GuiData::new_with_application(application);
|
||||
|
||||
// Used for getting data from thread
|
||||
// TODO - deprecation happened without any example, so not sure how new code should look like
|
||||
#[allow(deprecated)]
|
||||
let (glib_stop_sender, glib_stop_receiver) = glib::MainContext::channel(Priority::default());
|
||||
|
||||
// Futures progress report
|
||||
|
|
|
@ -257,7 +257,7 @@ impl LoadSaveStruct {
|
|||
};
|
||||
return Some((config_file_handler, config_file));
|
||||
}
|
||||
if !config_file.exists() || !config_file.is_file() {
|
||||
if !config_file.is_file() {
|
||||
if manual_execution {
|
||||
// Don't show errors when there is no configuration file when starting app
|
||||
add_text_to_text_view(
|
||||
|
|
|
@ -40,8 +40,8 @@ rayon = "1.8.0"
|
|||
# Translations
|
||||
i18n-embed = { version = "0.14", features = ["fluent-system", "desktop-requester"] }
|
||||
i18n-embed-fl = "0.7"
|
||||
rust-embed = { version = "8.0", features = ["debug-embed"] }
|
||||
once_cell = "1.18"
|
||||
rust-embed = { version = "8.1", features = ["debug-embed"] }
|
||||
once_cell = "1.19"
|
||||
|
||||
[build-dependencies]
|
||||
slint-build = "1.3"
|
||||
|
|
|
@ -3,11 +3,12 @@ use crate::{CurrentTab, GuiState, MainListModel, MainWindow, ProgressToSend};
|
|||
use chrono::NaiveDateTime;
|
||||
use crossbeam_channel::{Receiver, Sender};
|
||||
use czkawka_core::common::{split_path, split_path_compare, DEFAULT_THREAD_SIZE};
|
||||
use czkawka_core::common_dir_traversal::{FileEntry, FolderEntry, ProgressData};
|
||||
use czkawka_core::common_dir_traversal::{FileEntry, ProgressData};
|
||||
use czkawka_core::common_tool::CommonData;
|
||||
use czkawka_core::common_traits::ResultEntry;
|
||||
use czkawka_core::empty_files::EmptyFiles;
|
||||
use czkawka_core::empty_folder::EmptyFolder;
|
||||
use czkawka_core::empty_folder::FolderEntry;
|
||||
use czkawka_core::similar_images;
|
||||
use czkawka_core::similar_images::SimilarImages;
|
||||
use humansize::{format_size, BINARY};
|
||||
|
|
|
@ -31,6 +31,8 @@ mod set_initial_gui_info;
|
|||
mod settings;
|
||||
|
||||
use crossbeam_channel::{unbounded, Receiver, Sender};
|
||||
use slint::VecModel;
|
||||
use std::rc::Rc;
|
||||
// use std::rc::Rc;
|
||||
|
||||
use crate::connect_delete::connect_delete_button;
|
||||
|
@ -60,6 +62,10 @@ fn main() {
|
|||
|
||||
// to_remove_debug(&app);
|
||||
|
||||
// Slint files may already contains data in models, so clear them before starting - todo,
|
||||
// check if non zeroed models are useful
|
||||
zeroing_all_models(&app);
|
||||
|
||||
set_initial_gui_infos(&app);
|
||||
|
||||
create_default_settings_files();
|
||||
|
@ -80,6 +86,12 @@ fn main() {
|
|||
save_all_settings_to_file(&app);
|
||||
}
|
||||
|
||||
pub fn zeroing_all_models(app: &MainWindow) {
|
||||
app.set_empty_folder_model(Rc::new(VecModel::default()).into());
|
||||
app.set_empty_files_model(Rc::new(VecModel::default()).into());
|
||||
app.set_similar_images_model(Rc::new(VecModel::default()).into());
|
||||
}
|
||||
|
||||
// // TODO remove this after debugging - or leave commented
|
||||
// pub fn to_remove_debug(app: &MainWindow) {
|
||||
// app.set_empty_folder_model(to_remove_create_without_header("@@").into());
|
||||
|
|
Loading…
Reference in a new issue