Simple tool for automatic file management

ft: allow multiple filters

hauleth.dev 7f9cd43d 46e49d23

verified
+575 -9
Cargo.lock
···
]
[[package]]
+
name = "android-tzdata"
+
version = "0.1.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
+
+
[[package]]
+
name = "android_system_properties"
+
version = "0.1.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+
dependencies = [
+
"libc",
+
]
+
+
[[package]]
+
name = "async-stream"
+
version = "0.3.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51"
+
dependencies = [
+
"async-stream-impl",
+
"futures-core",
+
"pin-project-lite",
+
]
+
+
[[package]]
+
name = "async-stream-impl"
+
version = "0.3.5"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn",
+
]
+
+
[[package]]
+
name = "async-trait"
+
version = "0.1.77"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn",
+
]
+
+
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
+
name = "bumpalo"
+
version = "3.14.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
+
+
[[package]]
name = "bytes"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
+
name = "chrono"
+
version = "0.4.31"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
+
dependencies = [
+
"android-tzdata",
+
"iana-time-zone",
+
"num-traits",
+
"windows-targets 0.48.5",
+
]
+
+
[[package]]
name = "color-eyre"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "core-foundation-sys"
+
version = "0.8.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
+
+
[[package]]
+
name = "erased-serde"
+
version = "0.4.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "55d05712b2d8d88102bc9868020c9e5c7a1f5527c452b9b97450a1d006140ba7"
+
dependencies = [
+
"serde",
+
]
+
+
[[package]]
name = "eyre"
version = "0.6.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "form_urlencoded"
+
version = "1.2.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+
dependencies = [
+
"percent-encoding",
+
]
+
+
[[package]]
+
name = "futures"
+
version = "0.3.30"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
+
dependencies = [
+
"futures-channel",
+
"futures-core",
+
"futures-executor",
+
"futures-io",
+
"futures-sink",
+
"futures-task",
+
"futures-util",
+
]
+
+
[[package]]
+
name = "futures-channel"
+
version = "0.3.30"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
+
dependencies = [
+
"futures-core",
+
"futures-sink",
+
]
+
+
[[package]]
+
name = "futures-core"
+
version = "0.3.30"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
+
+
[[package]]
+
name = "futures-executor"
+
version = "0.3.30"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
+
dependencies = [
+
"futures-core",
+
"futures-task",
+
"futures-util",
+
]
+
+
[[package]]
+
name = "futures-io"
+
version = "0.3.30"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
+
+
[[package]]
+
name = "futures-macro"
+
version = "0.3.30"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn",
+
]
+
+
[[package]]
+
name = "futures-sink"
+
version = "0.3.30"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
+
+
[[package]]
+
name = "futures-task"
+
version = "0.3.30"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
+
+
[[package]]
+
name = "futures-util"
+
version = "0.3.30"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
+
dependencies = [
+
"futures-channel",
+
"futures-core",
+
"futures-io",
+
"futures-macro",
+
"futures-sink",
+
"futures-task",
+
"memchr",
+
"pin-project-lite",
+
"pin-utils",
+
"slab",
+
]
+
+
[[package]]
name = "gimli"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
[[package]]
+
name = "iana-time-zone"
+
version = "0.1.59"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539"
+
dependencies = [
+
"android_system_properties",
+
"core-foundation-sys",
+
"iana-time-zone-haiku",
+
"js-sys",
+
"wasm-bindgen",
+
"windows-core",
+
]
+
+
[[package]]
+
name = "iana-time-zone-haiku"
+
version = "0.1.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+
dependencies = [
+
"cc",
+
]
+
+
[[package]]
+
name = "idna"
+
version = "0.5.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6"
+
dependencies = [
+
"unicode-bidi",
+
"unicode-normalization",
+
]
+
+
[[package]]
name = "indenter"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
[[package]]
+
name = "inventory"
+
version = "0.3.14"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c8573b2b1fb643a372c73b23f4da5f888677feef3305146d68a539250a9bccc7"
+
+
[[package]]
name = "itoa"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
+
name = "js-sys"
+
version = "0.3.67"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1"
+
dependencies = [
+
"wasm-bindgen",
+
]
+
+
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "log"
+
version = "0.4.20"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
+
+
[[package]]
+
name = "malloc_buf"
+
version = "0.0.6"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
+
dependencies = [
+
"libc",
+
]
+
+
[[package]]
name = "memchr"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "num-traits"
+
version = "0.2.17"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
+
dependencies = [
+
"autocfg",
+
]
+
+
[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "objc"
+
version = "0.2.7"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
+
dependencies = [
+
"malloc_buf",
+
]
+
+
[[package]]
name = "object"
version = "0.32.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
"libc",
"redox_syscall",
"smallvec",
-
"windows-targets",
+
"windows-targets 0.48.5",
]
[[package]]
+
name = "percent-encoding"
+
version = "2.3.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+
+
[[package]]
name = "pin-project-lite"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58"
+
+
[[package]]
+
name = "pin-utils"
+
version = "0.1.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "proc-macro2"
···
name = "ptsd"
version = "0.1.0"
dependencies = [
+
"async-stream",
+
"async-trait",
"color-eyre",
+
"futures",
+
"libc",
"regex",
"serde",
"serde_json",
"tokio",
+
"tokio-stream",
+
"trash",
+
"typetag",
"wildmatch",
]
···
]
[[package]]
+
name = "slab"
+
version = "0.4.9"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
+
dependencies = [
+
"autocfg",
+
]
+
+
[[package]]
name = "smallvec"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "tinyvec"
+
version = "1.6.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+
dependencies = [
+
"tinyvec_macros",
+
]
+
+
[[package]]
+
name = "tinyvec_macros"
+
version = "0.1.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+
[[package]]
name = "tokio"
version = "1.35.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "tokio-stream"
+
version = "0.1.14"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842"
+
dependencies = [
+
"futures-core",
+
"pin-project-lite",
+
"tokio",
+
]
+
+
[[package]]
name = "tracing"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
]
[[package]]
+
name = "trash"
+
version = "3.2.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6e7b1a28f9550f43ac27987f2144d7798520c6dee6a7eb1dedfe3131e3c257e3"
+
dependencies = [
+
"chrono",
+
"libc",
+
"log",
+
"objc",
+
"once_cell",
+
"scopeguard",
+
"url",
+
"windows",
+
]
+
+
[[package]]
+
name = "typetag"
+
version = "0.2.15"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c43148481c7b66502c48f35b8eef38b6ccdc7a9f04bd4cc294226d901ccc9bc7"
+
dependencies = [
+
"erased-serde",
+
"inventory",
+
"once_cell",
+
"serde",
+
"typetag-impl",
+
]
+
+
[[package]]
+
name = "typetag-impl"
+
version = "0.2.15"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "291db8a81af4840c10d636e047cac67664e343be44e24dfdbd1492df9a5d3390"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn",
+
]
+
+
[[package]]
+
name = "unicode-bidi"
+
version = "0.3.14"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416"
+
+
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
+
name = "unicode-normalization"
+
version = "0.1.22"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+
dependencies = [
+
"tinyvec",
+
]
+
+
[[package]]
+
name = "url"
+
version = "2.5.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
+
dependencies = [
+
"form_urlencoded",
+
"idna",
+
"percent-encoding",
+
]
+
+
[[package]]
name = "valuable"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
···
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
+
name = "wasm-bindgen"
+
version = "0.2.90"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406"
+
dependencies = [
+
"cfg-if",
+
"wasm-bindgen-macro",
+
]
+
+
[[package]]
+
name = "wasm-bindgen-backend"
+
version = "0.2.90"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd"
+
dependencies = [
+
"bumpalo",
+
"log",
+
"once_cell",
+
"proc-macro2",
+
"quote",
+
"syn",
+
"wasm-bindgen-shared",
+
]
+
+
[[package]]
+
name = "wasm-bindgen-macro"
+
version = "0.2.90"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999"
+
dependencies = [
+
"quote",
+
"wasm-bindgen-macro-support",
+
]
+
+
[[package]]
+
name = "wasm-bindgen-macro-support"
+
version = "0.2.90"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7"
+
dependencies = [
+
"proc-macro2",
+
"quote",
+
"syn",
+
"wasm-bindgen-backend",
+
"wasm-bindgen-shared",
+
]
+
+
[[package]]
+
name = "wasm-bindgen-shared"
+
version = "0.2.90"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b"
+
+
[[package]]
name = "wildmatch"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "495ec47bf3c1345005f40724f0269362c8556cbc43aed0526ed44cae1d35fceb"
[[package]]
+
name = "windows"
+
version = "0.44.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b"
+
dependencies = [
+
"windows-targets 0.42.2",
+
]
+
+
[[package]]
+
name = "windows-core"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
+
dependencies = [
+
"windows-targets 0.52.0",
+
]
+
+
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
-
"windows-targets",
+
"windows-targets 0.48.5",
+
]
+
+
[[package]]
+
name = "windows-targets"
+
version = "0.42.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
+
dependencies = [
+
"windows_aarch64_gnullvm 0.42.2",
+
"windows_aarch64_msvc 0.42.2",
+
"windows_i686_gnu 0.42.2",
+
"windows_i686_msvc 0.42.2",
+
"windows_x86_64_gnu 0.42.2",
+
"windows_x86_64_gnullvm 0.42.2",
+
"windows_x86_64_msvc 0.42.2",
]
[[package]]
···
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
-
"windows_aarch64_gnullvm",
-
"windows_aarch64_msvc",
-
"windows_i686_gnu",
-
"windows_i686_msvc",
-
"windows_x86_64_gnu",
-
"windows_x86_64_gnullvm",
-
"windows_x86_64_msvc",
+
"windows_aarch64_gnullvm 0.48.5",
+
"windows_aarch64_msvc 0.48.5",
+
"windows_i686_gnu 0.48.5",
+
"windows_i686_msvc 0.48.5",
+
"windows_x86_64_gnu 0.48.5",
+
"windows_x86_64_gnullvm 0.48.5",
+
"windows_x86_64_msvc 0.48.5",
]
[[package]]
+
name = "windows-targets"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
+
dependencies = [
+
"windows_aarch64_gnullvm 0.52.0",
+
"windows_aarch64_msvc 0.52.0",
+
"windows_i686_gnu 0.52.0",
+
"windows_i686_msvc 0.52.0",
+
"windows_x86_64_gnu 0.52.0",
+
"windows_x86_64_gnullvm 0.52.0",
+
"windows_x86_64_msvc 0.52.0",
+
]
+
+
[[package]]
+
name = "windows_aarch64_gnullvm"
+
version = "0.42.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
+
+
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
+
name = "windows_aarch64_gnullvm"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
+
+
[[package]]
+
name = "windows_aarch64_msvc"
+
version = "0.42.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
+
+
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
+
+
[[package]]
+
name = "windows_aarch64_msvc"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
+
+
[[package]]
+
name = "windows_i686_gnu"
+
version = "0.42.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
[[package]]
name = "windows_i686_gnu"
···
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
+
name = "windows_i686_gnu"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
+
+
[[package]]
+
name = "windows_i686_msvc"
+
version = "0.42.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
+
+
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
+
+
[[package]]
+
name = "windows_i686_msvc"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
+
+
[[package]]
+
name = "windows_x86_64_gnu"
+
version = "0.42.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
+
+
[[package]]
+
name = "windows_x86_64_gnu"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
+
+
[[package]]
+
name = "windows_x86_64_gnullvm"
+
version = "0.42.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
[[package]]
name = "windows_x86_64_gnullvm"
···
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
+
name = "windows_x86_64_gnullvm"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
+
+
[[package]]
+
name = "windows_x86_64_msvc"
+
version = "0.42.2"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
+
+
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
+
+
[[package]]
+
name = "windows_x86_64_msvc"
+
version = "0.52.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
+7
Cargo.toml
···
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+
async-stream = "0.3.5"
+
async-trait = "0.1.77"
color-eyre = "0.6.2"
+
futures = "0.3.30"
+
libc = "0.2.152"
regex = "1.10.2"
serde = { version = "1.0.195", features = ["derive"] }
serde_json = "1.0.111"
tokio = { version = "1.35.1", default-features = false, features = ["rt-multi-thread", "fs", "io-std", "io-util", "macros", "process", "parking_lot", "mio"] }
+
tokio-stream = { version = "0.1.14", features = ["fs"] }
+
trash = "3.2.0"
+
typetag = "0.2.15"
wildmatch = "2.3.0"
+9 -2
flake.nix
···
devenv.shells.default = {
languages.rust = {
-
enable = true;
-
channel = "nightly";
+
enable = true;
};
+
+
packages =
+
[]
+
++ pkgs.lib.lists.optionals pkgs.stdenv.isDarwin (with pkgs.darwin.apple_sdk; [
+
frameworks.Foundation
+
pkgs.libiconv
+
pkgs.darwin.libobjc
+
]);
};
};
};
+91
src/filters.rs
···
+
use std::path::Path;
+
+
use async_trait::async_trait;
+
use serde::Deserialize;
+
use tokio::fs;
+
+
use crate::pattern::Pattern;
+
+
#[typetag::deserialize(tag = "type")]
+
#[async_trait]
+
pub trait Filter: std::fmt::Debug {
+
async fn matches(&self, path: &Path) -> bool;
+
}
+
+
#[derive(Debug, Deserialize)]
+
pub struct Name(Pattern);
+
+
#[typetag::deserialize(name = "name")]
+
#[async_trait]
+
impl Filter for Name {
+
async fn matches(&self, path: &Path) -> bool {
+
self.0.matches(path)
+
}
+
}
+
+
#[derive(Debug, Deserialize)]
+
pub struct Size {
+
size: u64,
+
#[serde(with = "Ordering")]
+
ordering: std::cmp::Ordering,
+
}
+
+
#[derive(Deserialize)]
+
#[serde(remote = "std::cmp::Ordering")]
+
enum Ordering {
+
Less,
+
Equal,
+
Greater,
+
}
+
+
#[typetag::deserialize(name = "size")]
+
#[async_trait]
+
impl Filter for Size {
+
async fn matches(&self, path: &Path) -> bool {
+
with_metadata(path, |metadata| {
+
let len = metadata.len();
+
+
self.size.cmp(&len) == self.ordering
+
})
+
.await
+
}
+
}
+
+
#[derive(Debug, Deserialize)]
+
pub enum FileType {
+
Dir,
+
File,
+
Symlink,
+
}
+
+
#[typetag::deserialize(name = "file_type")]
+
#[async_trait]
+
impl Filter for FileType {
+
async fn matches(&self, path: &Path) -> bool {
+
use FileType::*;
+
+
with_metadata(path, |metadata| {
+
let ft = metadata.file_type();
+
+
match *self {
+
Dir => ft.is_dir(),
+
File => ft.is_file(),
+
Symlink => ft.is_symlink(),
+
}
+
})
+
.await
+
}
+
}
+
+
async fn with_metadata<F>(path: &Path, fun: F) -> bool
+
where
+
F: FnOnce(std::fs::Metadata) -> bool,
+
{
+
fs::metadata(path).await.map(fun).unwrap_or(false)
+
}
+
+
#[derive(Debug, Deserialize)]
+
pub enum Magic {
+
Mime(String),
+
Bytes(Box<[u8]>),
+
}
+34 -98
src/job.rs
···
use color_eyre::eyre::Result;
-
use std::fmt;
use std::path::{Path, PathBuf};
use tokio::fs;
use tokio::process::Command;
+
use tokio_stream::wrappers::ReadDirStream;
-
use serde::{de, Deserialize};
-
use wildmatch::WildMatch;
+
use futures::prelude::*;
+
+
use serde::Deserialize;
+
+
use crate::filters::Filter;
/// Definition of the job files
#[derive(Debug, Deserialize)]
pub struct Job {
-
pattern: Pattern,
+
filters: Vec<Box<dyn Filter>>,
location: PathBuf,
actions: Vec<Action>,
}
impl Job {
-
pub async fn run(&self) -> Result<()> {
+
pub async fn run(&self) -> Result<impl tokio_stream::Stream<Item = (Action, PathBuf)> + '_> {
let loc = normalise_path(&self.location);
-
let mut dir = fs::read_dir(&loc).await?;
+
let dir = ReadDirStream::new(fs::read_dir(&loc).await?);
-
while let Some(entry) = dir.next_entry().await? {
-
if self.pattern.matches(entry.file_name().as_ref()) {
-
self.execute_actions(&loc, entry.path().as_ref()).await;
+
Ok(async_stream::stream! {
+
for await entry in dir {
+
let entry = entry.unwrap();
+
if self.matches_filters(&entry.path()).await {
+
for action in &self.actions {
+
yield (action.clone(), entry.path())
+
}
+
}
}
-
}
-
-
Ok(())
-
}
-
-
async fn execute_actions(&self, loc: &Path, path: &Path) {
-
for action in &self.actions {
-
action.execute(loc, path).await;
-
}
+
})
}
-
}
-
/// Patterns that can be matched against files
-
#[derive(Debug, Deserialize)]
-
pub enum Pattern {
-
#[serde(deserialize_with = "deserialize_wildcard")]
-
Wildcard(WildMatch),
-
#[serde(deserialize_with = "deserialize_regex")]
-
Regex(regex::Regex),
-
Exact(Box<Path>),
-
}
-
-
impl Pattern {
-
pub fn matches(&self, path: &Path) -> bool {
-
match *self {
-
Self::Wildcard(ref pattern) => pattern.matches(path.to_str().unwrap()),
-
Self::Regex(ref pattern) => pattern.is_match(path.to_str().unwrap()),
-
Self::Exact(ref pattern) => **pattern == *path,
-
}
+
async fn matches_filters(&self, path: &Path) -> bool {
+
stream::iter(&self.filters).all(|f| f.matches(path)).await
}
}
/// Actions available for file
-
#[derive(Debug, Deserialize)]
+
#[derive(Clone, Debug, Deserialize)]
#[serde(untagged)]
pub enum Action {
/// Run given script with 1st argument. It will be ran in parent directory for given file
···
Move { move_to: Box<Path> },
/// Print message and do nothing
Echo { message: String },
+
/// Move to trash
+
Trash,
}
impl Action {
-
pub async fn execute(&self, dir: &Path, source: &Path) {
-
match *self {
+
pub async fn execute(self, source: PathBuf) {
+
match self {
Action::Script { ref script } => {
Command::new(script.as_ref())
-
.arg(source)
-
.current_dir(dir)
+
.arg(&source)
+
.current_dir(source.parent().unwrap())
.spawn()
.expect("Couldnt spawn process")
.wait()
···
.expect("Child exited abnormally");
}
-
Action::Move { move_to: ref dest_dir } => {
+
Action::Move {
+
move_to: ref dest_dir,
+
} => {
let dest = normalise_path(dest_dir).join(source.file_name().unwrap());
-
if let Err(err) = std::fs::rename(source, &dest) {
-
if err.kind() == std::io::ErrorKind::CrossesDevices {
+
if let Err(err) = fs::rename(&source, &dest).await {
+
if err.raw_os_error() == Some(libc::EXDEV) {
panic!("X dev");
} else {
panic!("Cannot move {source:?} -> {dest:?}: {err:?}");
···
}
Action::Echo { ref message } => println!("{source:?} - {message}"),
+
+
Action::Trash => trash::delete(source).unwrap(),
}
}
}
···
Err(_) => path.to_owned(),
}
}
-
-
struct RegexVisitor;
-
-
impl<'de> de::Visitor<'de> for RegexVisitor {
-
type Value = regex::Regex;
-
-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-
write!(formatter, "expected regex string")
-
}
-
-
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
-
where
-
E: de::Error,
-
{
-
match regex::Regex::new(s) {
-
Ok(regex) => Ok(regex),
-
Err(regex::Error::Syntax(ref desc)) => {
-
Err(E::invalid_value(de::Unexpected::Str(s), &desc.as_str()))
-
}
-
Err(_) => unreachable!(),
-
}
-
}
-
}
-
-
fn deserialize_regex<'de, D>(des: D) -> Result<regex::Regex, D::Error>
-
where
-
D: serde::Deserializer<'de>,
-
{
-
des.deserialize_str(RegexVisitor)
-
}
-
-
struct WildcardVisitor;
-
-
impl<'de> de::Visitor<'de> for WildcardVisitor {
-
type Value = WildMatch;
-
-
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
-
write!(formatter, "expected regex string")
-
}
-
-
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
-
where
-
E: de::Error,
-
{
-
Ok(WildMatch::new(s))
-
}
-
}
-
-
fn deserialize_wildcard<'de, D>(des: D) -> Result<WildMatch, D::Error>
-
where
-
D: serde::Deserializer<'de>,
-
{
-
des.deserialize_str(WildcardVisitor)
-
}
+23 -15
src/main.rs
···
-
#![feature(io_error_more)]
-
use color_eyre::eyre::Result;
+
use tokio_stream::iter;
+
use futures::StreamExt;
+
mod filters;
mod job;
+
mod pattern;
-
const data: &str = r#"
-
{
-
"pattern": {"Wildcard": "*.dmg"},
-
"location": "~/Downloads",
-
"actions": [
-
{"message": "move to ~/Documents/Gitara/"}
-
]
-
}"#;
+
const DATA: &str = r#"
+
[
+
{
+
"filters": [
+
{"type": "name", "Wildcard": "*.dmg"}
+
],
+
"location": "~/Downloads",
+
"actions": [
+
{"message": "move to ~/Documents/Gitara/"}
+
]
+
}
+
]"#;
#[tokio::main]
async fn main() -> Result<()> {
-
println!("{data}");
-
let j: job::Job = serde_json::from_str(data).unwrap();
+
let jobs: Vec<job::Job> = serde_json::from_str(DATA).unwrap();
-
j.run().await?;
-
-
println!("{j:?}");
+
iter(&jobs)
+
.then(|job| job.run())
+
.map(|result| result.unwrap())
+
.flatten()
+
.for_each_concurrent(None, |(action, path)| action.execute(path))
+
.await;
Ok(())
}
+79
src/pattern.rs
···
+
use std::fmt;
+
use std::path::Path;
+
+
use serde::{de, Deserialize};
+
use wildmatch::WildMatch;
+
+
/// Patterns that can be matched against files
+
#[derive(Debug, Deserialize)]
+
pub enum Pattern {
+
#[serde(deserialize_with = "deserialize_wildcard")]
+
Wildcard(WildMatch),
+
#[serde(deserialize_with = "deserialize_regex")]
+
Regex(regex::Regex),
+
Exact(Box<Path>),
+
}
+
+
impl Pattern {
+
pub fn matches(&self, path: &Path) -> bool {
+
match *self {
+
Self::Wildcard(ref pattern) => pattern.matches(path.to_str().unwrap()),
+
Self::Regex(ref pattern) => pattern.is_match(path.to_str().unwrap()),
+
Self::Exact(ref pattern) => **pattern == *path,
+
}
+
}
+
}
+
+
struct RegexVisitor;
+
+
impl<'de> de::Visitor<'de> for RegexVisitor {
+
type Value = regex::Regex;
+
+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+
write!(formatter, "expected regex string")
+
}
+
+
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
+
where
+
E: de::Error,
+
{
+
match regex::Regex::new(s) {
+
Ok(regex) => Ok(regex),
+
Err(regex::Error::Syntax(ref desc)) => {
+
Err(E::invalid_value(de::Unexpected::Str(s), &desc.as_str()))
+
}
+
Err(_) => unreachable!(),
+
}
+
}
+
}
+
+
fn deserialize_regex<'de, D>(des: D) -> Result<regex::Regex, D::Error>
+
where
+
D: serde::Deserializer<'de>,
+
{
+
des.deserialize_str(RegexVisitor)
+
}
+
+
struct WildcardVisitor;
+
+
impl<'de> de::Visitor<'de> for WildcardVisitor {
+
type Value = WildMatch;
+
+
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+
write!(formatter, "expected regex string")
+
}
+
+
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
+
where
+
E: de::Error,
+
{
+
Ok(WildMatch::new(s))
+
}
+
}
+
+
fn deserialize_wildcard<'de, D>(des: D) -> Result<WildMatch, D::Error>
+
where
+
D: serde::Deserializer<'de>,
+
{
+
des.deserialize_str(WildcardVisitor)
+
}