mirror of
https://github.com/edu4rdshl/Strata.git
synced 2026-07-17 23:24:46 +00:00
deps+fix: upgrade zbus 5 / rusqlite 0.40 / dirs 6; daemon hardening
Dependency major upgrades (zbus 4->5, rusqlite 0.31->0.40, dirs 5->6) and the migration + hardening that came with the review: - zbus 5: SignalContext -> SignalEmitter, signal_context() -> signal_emitter(). - Single-instance D-Bus name: request with DoNotQueue instead of ReplaceExisting|AllowReplacement. If the name is already owned the daemon now exits instead of running without owning it (zbus 5 returns InQueue as Ok) or stealing the name and orphaning the running instance (zbus does not terminate a replaced owner). The extension already skips spawning when the name is owned, so replacement was never needed. - Stop swallowing real SQLite errors: upsert_item's dedup SELECT and get_thumbnail/get_raw_item now use .optional().context()? so a missing row is Ok(None) and a genuine error propagates instead of masquerading as not-found. - clippy pedantic/nursery cleanup: uninlined format args, redundant mime clone, pass ObjectId/Connection by reference where not consumed, match->if/is_ok, doc backticks; #[allow] with rationale for the intentional lints (significant_drop_tightening on the single-writer lock, unused_async on zbus interface methods). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
e2972de37a
commit
aa56cac958
7 changed files with 196 additions and 492 deletions
499
strata-daemon/Cargo.lock
generated
499
strata-daemon/Cargo.lock
generated
|
|
@ -8,18 +8,6 @@ version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ahash"
|
|
||||||
version = "0.8.12"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"once_cell",
|
|
||||||
"version_check",
|
|
||||||
"zerocopy",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "1.1.4"
|
version = "1.1.4"
|
||||||
|
|
@ -85,17 +73,6 @@ dependencies = [
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "async-fs"
|
|
||||||
version = "2.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5"
|
|
||||||
dependencies = [
|
|
||||||
"async-lock",
|
|
||||||
"blocking",
|
|
||||||
"futures-lite",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-io"
|
name = "async-io"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
|
|
@ -111,7 +88,7 @@ dependencies = [
|
||||||
"polling",
|
"polling",
|
||||||
"rustix",
|
"rustix",
|
||||||
"slab",
|
"slab",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -169,7 +146,7 @@ dependencies = [
|
||||||
"rustix",
|
"rustix",
|
||||||
"signal-hook-registry",
|
"signal-hook-registry",
|
||||||
"slab",
|
"slab",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -218,16 +195,7 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"constant_time_eq",
|
"constant_time_eq",
|
||||||
"cpufeatures 0.3.0",
|
"cpufeatures",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "block-buffer"
|
|
||||||
version = "0.10.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
|
||||||
dependencies = [
|
|
||||||
"generic-array",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -283,12 +251,6 @@ version = "1.0.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cfg_aliases"
|
|
||||||
version = "0.2.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "color_quant"
|
name = "color_quant"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
|
@ -310,15 +272,6 @@ version = "0.4.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b"
|
checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "cpufeatures"
|
|
||||||
version = "0.2.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|
@ -349,45 +302,25 @@ version = "0.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "crypto-common"
|
|
||||||
version = "0.1.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
|
|
||||||
dependencies = [
|
|
||||||
"generic-array",
|
|
||||||
"typenum",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "digest"
|
|
||||||
version = "0.10.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
|
||||||
dependencies = [
|
|
||||||
"block-buffer",
|
|
||||||
"crypto-common",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "5.0.1"
|
version = "6.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dirs-sys",
|
"dirs-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs-sys"
|
name = "dirs-sys"
|
||||||
version = "0.4.1"
|
version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"option-ext",
|
"option-ext",
|
||||||
"redox_users",
|
"redox_users",
|
||||||
"windows-sys 0.48.0",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -436,7 +369,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -521,6 +454,12 @@ version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "foldhash"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.32"
|
version = "0.3.32"
|
||||||
|
|
@ -546,12 +485,6 @@ dependencies = [
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "futures-sink"
|
|
||||||
version = "0.3.32"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.32"
|
version = "0.3.32"
|
||||||
|
|
@ -565,24 +498,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
|
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-io",
|
|
||||||
"futures-sink",
|
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"memchr",
|
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"slab",
|
"slab",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "generic-array"
|
|
||||||
version = "0.14.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
|
||||||
dependencies = [
|
|
||||||
"typenum",
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.17"
|
version = "0.2.17"
|
||||||
|
|
@ -628,22 +548,22 @@ dependencies = [
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "hashbrown"
|
|
||||||
version = "0.14.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
|
||||||
dependencies = [
|
|
||||||
"ahash",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashbrown"
|
name = "hashbrown"
|
||||||
version = "0.15.5"
|
version = "0.15.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"foldhash",
|
"foldhash 0.1.5",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.16.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
||||||
|
dependencies = [
|
||||||
|
"foldhash 0.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -654,11 +574,11 @@ checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hashlink"
|
name = "hashlink"
|
||||||
version = "0.9.1"
|
version = "0.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af"
|
checksum = "ea0b22561a9c04a7cb1a302c013e0259cd3b4bb619f145b32f72b8b4bcbed230"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hashbrown 0.14.5",
|
"hashbrown 0.16.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -773,9 +693,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libsqlite3-sys"
|
name = "libsqlite3-sys"
|
||||||
version = "0.28.0"
|
version = "0.38.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f"
|
checksum = "a76001fb4daed01e5f2b518aac0b4dc592e7c734da63dbffcf0c64fa612a8d0c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"pkg-config",
|
"pkg-config",
|
||||||
|
|
@ -845,7 +765,7 @@ checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -858,19 +778,6 @@ dependencies = [
|
||||||
"pxfm",
|
"pxfm",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "nix"
|
|
||||||
version = "0.29.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46"
|
|
||||||
dependencies = [
|
|
||||||
"bitflags",
|
|
||||||
"cfg-if",
|
|
||||||
"cfg_aliases",
|
|
||||||
"libc",
|
|
||||||
"memoffset",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nom"
|
name = "nom"
|
||||||
version = "8.0.0"
|
version = "8.0.0"
|
||||||
|
|
@ -886,7 +793,7 @@ version = "0.50.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -927,7 +834,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
|
checksum = "7d8fae84b431384b68627d0f9b3b1245fcf9f46f6c0e3dc902e9dce64edd1967"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1017,16 +924,7 @@ dependencies = [
|
||||||
"hermit-abi",
|
"hermit-abi",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ppv-lite86"
|
|
||||||
version = "0.2.21"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
|
||||||
dependencies = [
|
|
||||||
"zerocopy",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1093,36 +991,6 @@ version = "6.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand"
|
|
||||||
version = "0.8.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"rand_chacha",
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_chacha"
|
|
||||||
version = "0.3.1"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
|
||||||
dependencies = [
|
|
||||||
"ppv-lite86",
|
|
||||||
"rand_core",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rand_core"
|
|
||||||
version = "0.6.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
|
||||||
dependencies = [
|
|
||||||
"getrandom 0.2.17",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_syscall"
|
name = "redox_syscall"
|
||||||
version = "0.5.18"
|
version = "0.5.18"
|
||||||
|
|
@ -1134,13 +1002,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "redox_users"
|
name = "redox_users"
|
||||||
version = "0.4.6"
|
version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
|
checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.2.17",
|
"getrandom 0.2.17",
|
||||||
"libredox",
|
"libredox",
|
||||||
"thiserror 1.0.69",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1161,10 +1029,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rusqlite"
|
name = "rsqlite-vfs"
|
||||||
version = "0.31.0"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae"
|
checksum = "c51c9ae4df8a7fba42103df5c621fa3c37eccf3a3c650879e90fc48b11cc192c"
|
||||||
|
dependencies = [
|
||||||
|
"hashbrown 0.16.1",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rusqlite"
|
||||||
|
version = "0.40.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1b3492ea85308705c3a5cc24fb9b9cf77273d30590349070db42991202b214c4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"fallible-iterator",
|
"fallible-iterator",
|
||||||
|
|
@ -1172,6 +1050,7 @@ dependencies = [
|
||||||
"hashlink",
|
"hashlink",
|
||||||
"libsqlite3-sys",
|
"libsqlite3-sys",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
"sqlite-wasm-rs",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1184,7 +1063,7 @@ dependencies = [
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1259,17 +1138,6 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "sha1"
|
|
||||||
version = "0.10.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
|
|
||||||
dependencies = [
|
|
||||||
"cfg-if",
|
|
||||||
"cpufeatures 0.2.17",
|
|
||||||
"digest",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sharded-slab"
|
name = "sharded-slab"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
|
|
@ -1320,14 +1188,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
|
checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "static_assertions"
|
name = "sqlite-wasm-rs"
|
||||||
version = "1.1.0"
|
version = "0.5.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
checksum = "dc3efc0da82635d7e1ced0053bbbfa8c7ab9645d0bf36ceb4f7127bb85315d75"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"js-sys",
|
||||||
|
"rsqlite-vfs",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strata-daemon"
|
name = "strata-daemon"
|
||||||
|
|
@ -1372,16 +1246,7 @@ dependencies = [
|
||||||
"getrandom 0.4.2",
|
"getrandom 0.4.2",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror"
|
|
||||||
version = "1.0.69"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
|
||||||
dependencies = [
|
|
||||||
"thiserror-impl 1.0.69",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1390,18 +1255,7 @@ version = "2.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl 2.0.18",
|
"thiserror-impl",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "thiserror-impl"
|
|
||||||
version = "1.0.69"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
|
||||||
dependencies = [
|
|
||||||
"proc-macro2",
|
|
||||||
"quote",
|
|
||||||
"syn",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1453,7 +1307,7 @@ dependencies = [
|
||||||
"socket2",
|
"socket2",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1569,12 +1423,6 @@ dependencies = [
|
||||||
"petgraph",
|
"petgraph",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "typenum"
|
|
||||||
version = "1.20.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "uds_windows"
|
name = "uds_windows"
|
||||||
version = "1.2.1"
|
version = "1.2.1"
|
||||||
|
|
@ -1583,7 +1431,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memoffset",
|
"memoffset",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"windows-sys 0.61.2",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
@ -1606,6 +1454,7 @@ checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.4.2",
|
"getrandom 0.4.2",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
"serde_core",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -1621,12 +1470,6 @@ version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "version_check"
|
|
||||||
version = "0.9.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasi"
|
name = "wasi"
|
||||||
version = "0.11.1+wasi-snapshot-preview1"
|
version = "0.11.1+wasi-snapshot-preview1"
|
||||||
|
|
@ -1812,33 +1655,6 @@ version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.48.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets 0.48.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.52.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets 0.52.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-sys"
|
|
||||||
version = "0.59.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
|
||||||
dependencies = [
|
|
||||||
"windows-targets 0.52.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.61.2"
|
version = "0.61.2"
|
||||||
|
|
@ -1848,127 +1664,6 @@ dependencies = [
|
||||||
"windows-link",
|
"windows-link",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm 0.48.5",
|
|
||||||
"windows_aarch64_msvc 0.48.5",
|
|
||||||
"windows_i686_gnu 0.48.5",
|
|
||||||
"windows_i686_msvc 0.48.5",
|
|
||||||
"windows_x86_64_gnu 0.48.5",
|
|
||||||
"windows_x86_64_gnullvm 0.48.5",
|
|
||||||
"windows_x86_64_msvc 0.48.5",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows-targets"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
|
||||||
dependencies = [
|
|
||||||
"windows_aarch64_gnullvm 0.52.6",
|
|
||||||
"windows_aarch64_msvc 0.52.6",
|
|
||||||
"windows_i686_gnu 0.52.6",
|
|
||||||
"windows_i686_gnullvm",
|
|
||||||
"windows_i686_msvc 0.52.6",
|
|
||||||
"windows_x86_64_gnu 0.52.6",
|
|
||||||
"windows_x86_64_gnullvm 0.52.6",
|
|
||||||
"windows_x86_64_msvc 0.52.6",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
|
||||||
|
|
||||||
[[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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnu"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_gnullvm"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_i686_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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
|
||||||
|
|
||||||
[[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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.48.5"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "windows_x86_64_gnullvm"
|
|
||||||
version = "0.52.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
|
||||||
|
|
||||||
[[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.6"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
|
|
@ -2082,7 +1777,7 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"os_pipe",
|
"os_pipe",
|
||||||
"rustix",
|
"rustix",
|
||||||
"thiserror 2.0.18",
|
"thiserror",
|
||||||
"tree_magic_mini",
|
"tree_magic_mini",
|
||||||
"wayland-backend",
|
"wayland-backend",
|
||||||
"wayland-client",
|
"wayland-client",
|
||||||
|
|
@ -2090,25 +1785,14 @@ dependencies = [
|
||||||
"wayland-protocols-wlr",
|
"wayland-protocols-wlr",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "xdg-home"
|
|
||||||
version = "1.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6"
|
|
||||||
dependencies = [
|
|
||||||
"libc",
|
|
||||||
"windows-sys 0.59.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zbus"
|
name = "zbus"
|
||||||
version = "4.4.0"
|
version = "5.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bb97012beadd29e654708a0fdb4c84bc046f537aecfde2c3ee0a9e4b4d48c725"
|
checksum = "c3bcbf15c8708d7fc1be0c993622e0a5cbd5e8b52bfa40afa4c3e0cd8d724ac1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-broadcast",
|
"async-broadcast",
|
||||||
"async-executor",
|
"async-executor",
|
||||||
"async-fs",
|
|
||||||
"async-io",
|
"async-io",
|
||||||
"async-lock",
|
"async-lock",
|
||||||
"async-process",
|
"async-process",
|
||||||
|
|
@ -2119,21 +1803,19 @@ dependencies = [
|
||||||
"enumflags2",
|
"enumflags2",
|
||||||
"event-listener",
|
"event-listener",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-lite",
|
||||||
"futures-util",
|
|
||||||
"hex",
|
"hex",
|
||||||
"nix",
|
"libc",
|
||||||
"ordered-stream",
|
"ordered-stream",
|
||||||
"rand",
|
"rustix",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_repr",
|
"serde_repr",
|
||||||
"sha1",
|
|
||||||
"static_assertions",
|
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"uds_windows",
|
"uds_windows",
|
||||||
"windows-sys 0.52.0",
|
"uuid",
|
||||||
"xdg-home",
|
"windows-sys",
|
||||||
|
"winnow",
|
||||||
"zbus_macros",
|
"zbus_macros",
|
||||||
"zbus_names",
|
"zbus_names",
|
||||||
"zvariant",
|
"zvariant",
|
||||||
|
|
@ -2141,25 +1823,27 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zbus_macros"
|
name = "zbus_macros"
|
||||||
version = "4.4.0"
|
version = "5.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "267db9407081e90bbfa46d841d3cbc60f59c0351838c4bc65199ecd79ab1983e"
|
checksum = "51fa5406ad9175a8c825a931f8cf347116b531b3634fcb0b627c290f1f2516ff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
|
"zbus_names",
|
||||||
|
"zvariant",
|
||||||
"zvariant_utils",
|
"zvariant_utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zbus_names"
|
name = "zbus_names"
|
||||||
version = "3.0.0"
|
version = "4.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
|
checksum = "7074f3e50b894eac91750142016d30d0a89be8e67dbfd9704fb875825760e52d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"static_assertions",
|
"winnow",
|
||||||
"zvariant",
|
"zvariant",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
@ -2206,22 +1890,23 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zvariant"
|
name = "zvariant"
|
||||||
version = "4.2.0"
|
version = "5.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2084290ab9a1c471c38fc524945837734fbf124487e105daec2bb57fd48c81fe"
|
checksum = "1c1567a6ec68df868cbbfde844cfc6d81649fe5109a62b116b19fabd53e618ee"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"endi",
|
"endi",
|
||||||
"enumflags2",
|
"enumflags2",
|
||||||
"serde",
|
"serde",
|
||||||
"static_assertions",
|
"winnow",
|
||||||
"zvariant_derive",
|
"zvariant_derive",
|
||||||
|
"zvariant_utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zvariant_derive"
|
name = "zvariant_derive"
|
||||||
version = "4.2.0"
|
version = "5.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "73e2ba546bda683a90652bac4a279bc146adad1386f25379cf73200d2002c449"
|
checksum = "c7d5b780599bbde114e39d9a0799577fad1ced5105d38515745f7b3099d8ceda"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
|
@ -2232,11 +1917,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zvariant_utils"
|
name = "zvariant_utils"
|
||||||
version = "2.1.0"
|
version = "3.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340"
|
checksum = "6d464f5733ffa07a3164d656f18533caace9d0638596721355d73256a410d691"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
"serde",
|
||||||
"syn",
|
"syn",
|
||||||
|
"winnow",
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ path = "src/main.rs"
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
|
||||||
# D-Bus (async, tokio-native)
|
# D-Bus (async, tokio-native)
|
||||||
zbus = { version = "4", features = ["tokio"] }
|
zbus = { version = "5", features = ["tokio"] }
|
||||||
|
|
||||||
# Wayland clipboard monitoring (custom event loop)
|
# Wayland clipboard monitoring (custom event loop)
|
||||||
wayland-client = "0.31"
|
wayland-client = "0.31"
|
||||||
|
|
@ -25,7 +25,7 @@ wayland-protocols-wlr = { version = "0.3", features = ["client"] }
|
||||||
wl-clipboard-rs = "0.9"
|
wl-clipboard-rs = "0.9"
|
||||||
|
|
||||||
# Storage
|
# Storage
|
||||||
rusqlite = { version = "0.31", features = ["bundled"] }
|
rusqlite = { version = "0.40", features = ["bundled"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
uuid = { version = "1", features = ["v4"] }
|
uuid = { version = "1", features = ["v4"] }
|
||||||
|
|
@ -41,7 +41,7 @@ tracing = "0.1"
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter", "fmt"] }
|
||||||
|
|
||||||
# XDG paths
|
# XDG paths
|
||||||
dirs = "5"
|
dirs = "6"
|
||||||
|
|
||||||
# Error handling
|
# Error handling
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/// Wayland clipboard monitor using the ext-data-control-v1 protocol with a
|
/// Wayland clipboard monitor using the ext-data-control-v1 protocol with a
|
||||||
/// zwlr-data-control-v1 fallback for wlroots-based compositors. GNOME's Mutter
|
/// zwlr-data-control-v1 fallback for wlroots-based compositors. GNOME's Mutter
|
||||||
/// exposes neither, so on GNOME this monitor does not bind and clipboard
|
/// exposes neither, so on GNOME this monitor does not bind and clipboard
|
||||||
/// content arrives from the extension via Meta.Selection + SubmitItem.
|
/// content arrives from the extension via Meta.Selection + `SubmitItem`.
|
||||||
///
|
///
|
||||||
/// Runs on a dedicated OS thread (NOT on the tokio runtime) to avoid blocking
|
/// Runs on a dedicated OS thread (NOT on the tokio runtime) to avoid blocking
|
||||||
/// the async executor. Communicates clipboard change events to the tokio world
|
/// the async executor. Communicates clipboard change events to the tokio world
|
||||||
|
|
@ -59,9 +59,9 @@ impl MonitorState {
|
||||||
self.offers.entry(id).or_default().push(mime);
|
self.offers.entry(id).or_default().push(mime);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn commit_selection(&mut self, offer_id: ObjectId) {
|
fn commit_selection(&mut self, offer_id: &ObjectId) {
|
||||||
// Take the mime list for this offer (and discard stale in-flight offers).
|
// Take the mime list for this offer (and discard stale in-flight offers).
|
||||||
let mimes = self.offers.remove(&offer_id).unwrap_or_default();
|
let mimes = self.offers.remove(offer_id).unwrap_or_default();
|
||||||
self.offers.clear(); // discard any superseded offers
|
self.offers.clear(); // discard any superseded offers
|
||||||
if !mimes.is_empty() {
|
if !mimes.is_empty() {
|
||||||
let _ = self.tx.send(ClipboardChange { mime_types: mimes });
|
let _ = self.tx.send(ClipboardChange { mime_types: mimes });
|
||||||
|
|
@ -119,7 +119,7 @@ impl Dispatch<ExtDataControlDeviceV1, ()> for MonitorState {
|
||||||
}
|
}
|
||||||
ext_data_control_device_v1::Event::Selection { id: Some(offer) } => {
|
ext_data_control_device_v1::Event::Selection { id: Some(offer) } => {
|
||||||
let oid = offer.id();
|
let oid = offer.id();
|
||||||
state.commit_selection(oid);
|
state.commit_selection(&oid);
|
||||||
// Politely destroy the offer - the compositor will clean up
|
// Politely destroy the offer - the compositor will clean up
|
||||||
// the Wayland object.
|
// the Wayland object.
|
||||||
offer.destroy();
|
offer.destroy();
|
||||||
|
|
@ -183,7 +183,7 @@ impl Dispatch<ZwlrDataControlDeviceV1, ()> for MonitorState {
|
||||||
}
|
}
|
||||||
zwlr_data_control_device_v1::Event::Selection { id: Some(offer) } => {
|
zwlr_data_control_device_v1::Event::Selection { id: Some(offer) } => {
|
||||||
let oid = offer.id();
|
let oid = offer.id();
|
||||||
state.commit_selection(oid);
|
state.commit_selection(&oid);
|
||||||
offer.destroy();
|
offer.destroy();
|
||||||
}
|
}
|
||||||
zwlr_data_control_device_v1::Event::Selection { id: None } => {
|
zwlr_data_control_device_v1::Event::Selection { id: None } => {
|
||||||
|
|
@ -233,7 +233,7 @@ pub fn spawn(tx: UnboundedSender<ClipboardChange>) -> Result<()> {
|
||||||
std::thread::Builder::new()
|
std::thread::Builder::new()
|
||||||
.name("strata-wl-monitor".into())
|
.name("strata-wl-monitor".into())
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
if let Err(e) = run_loop(conn, protocol, tx) {
|
if let Err(e) = run_loop(&conn, protocol, tx) {
|
||||||
tracing::error!("Clipboard monitor exited with error: {e:#}");
|
tracing::error!("Clipboard monitor exited with error: {e:#}");
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
@ -278,11 +278,11 @@ fn probe_protocol(conn: &Connection) -> Result<Protocol> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_loop(
|
fn run_loop(
|
||||||
conn: Connection,
|
conn: &Connection,
|
||||||
protocol: Protocol,
|
protocol: Protocol,
|
||||||
tx: UnboundedSender<ClipboardChange>,
|
tx: UnboundedSender<ClipboardChange>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let (globals, mut queue) = registry_queue_init::<MonitorState>(&conn)?;
|
let (globals, mut queue) = registry_queue_init::<MonitorState>(conn)?;
|
||||||
let qh = queue.handle();
|
let qh = queue.handle();
|
||||||
let mut state = MonitorState::new(tx);
|
let mut state = MonitorState::new(tx);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ pub fn write_to_clipboard(req: WriteRequest) -> Result<()> {
|
||||||
vec![
|
vec![
|
||||||
MimeSource {
|
MimeSource {
|
||||||
source: Source::Bytes(bytes.clone().into()),
|
source: Source::Bytes(bytes.clone().into()),
|
||||||
mime_type: MimeType::Specific(mime.clone()),
|
mime_type: MimeType::Specific(mime),
|
||||||
},
|
},
|
||||||
MimeSource {
|
MimeSource {
|
||||||
source: Source::Bytes(bytes.into()),
|
source: Source::Bytes(bytes.into()),
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
|
// SQLite is single-writer, and `lock_conn`'s guard is intentionally held for
|
||||||
|
// each function's whole body -- the upsert's SELECT-then-INSERT must be atomic
|
||||||
|
// under one lock. `significant_drop_tightening` would have us drop the guard
|
||||||
|
// earlier, which would break that guarantee, so it is allowed for this module.
|
||||||
|
#![allow(clippy::significant_drop_tightening)]
|
||||||
|
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use rusqlite::{params, Connection};
|
use rusqlite::{params, Connection, OptionalExtension};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Mutex, MutexGuard};
|
use std::sync::{Mutex, MutexGuard};
|
||||||
|
|
@ -21,11 +27,11 @@ pub struct ItemMeta {
|
||||||
pub content_text: Option<String>,
|
pub content_text: Option<String>,
|
||||||
pub source_app: Option<String>,
|
pub source_app: Option<String>,
|
||||||
pub created_at: i64,
|
pub created_at: i64,
|
||||||
/// True if this item has a stored thumbnail (clients should call get_thumbnail to fetch it).
|
/// True if this item has a stored thumbnail (clients should call `get_thumbnail` to fetch it).
|
||||||
pub has_thumbnail: bool,
|
pub has_thumbnail: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A row as stored in SQLite (blob is raw bytes, not base64).
|
/// A row as stored in `SQLite` (blob is raw bytes, not base64).
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct RawItem {
|
pub struct RawItem {
|
||||||
pub id: String,
|
pub id: String,
|
||||||
|
|
@ -43,12 +49,12 @@ pub struct Db {
|
||||||
|
|
||||||
/// Acquire the DB lock, transparently recovering from poison.
|
/// Acquire the DB lock, transparently recovering from poison.
|
||||||
///
|
///
|
||||||
/// A mutex is "poisoned" when a thread panics while holding it. For our SQLite
|
/// A mutex is "poisoned" when a thread panics while holding it. For our `SQLite`
|
||||||
/// connection this is safe to recover from because rusqlite uses RAII statements
|
/// connection this is safe to recover from because rusqlite uses RAII statements
|
||||||
/// and transactions - any in-flight statement or transaction has already been
|
/// and transactions - any in-flight statement or transaction has already been
|
||||||
/// rolled back by the time the panic unwinds past it. Without this recovery,
|
/// rolled back by the time the panic unwinds past it. Without this recovery,
|
||||||
/// a single panic anywhere in the daemon would permanently break ALL future
|
/// a single panic anywhere in the daemon would permanently break ALL future
|
||||||
/// database access (every subsequent .lock().unwrap() would panic too).
|
/// database access (every subsequent .`lock().unwrap()` would panic too).
|
||||||
fn lock_conn(m: &Mutex<Connection>) -> MutexGuard<'_, Connection> {
|
fn lock_conn(m: &Mutex<Connection>) -> MutexGuard<'_, Connection> {
|
||||||
match m.lock() {
|
match m.lock() {
|
||||||
Ok(g) => g,
|
Ok(g) => g,
|
||||||
|
|
@ -62,7 +68,7 @@ fn lock_conn(m: &Mutex<Connection>) -> MutexGuard<'_, Connection> {
|
||||||
impl Db {
|
impl Db {
|
||||||
pub fn open(path: &Path) -> Result<Self> {
|
pub fn open(path: &Path) -> Result<Self> {
|
||||||
let conn = Connection::open(path)
|
let conn = Connection::open(path)
|
||||||
.with_context(|| format!("Opening SQLite database at {:?}", path))?;
|
.with_context(|| format!("Opening SQLite database at {}", path.display()))?;
|
||||||
|
|
||||||
// Performance pragmas: WAL mode for concurrent reads, synchronous=NORMAL is safe
|
// Performance pragmas: WAL mode for concurrent reads, synchronous=NORMAL is safe
|
||||||
// for a clipboard history (we can tolerate losing the last item on a crash).
|
// for a clipboard history (we can tolerate losing the last item on a crash).
|
||||||
|
|
@ -140,14 +146,18 @@ impl Db {
|
||||||
let conn = lock_conn(&self.conn);
|
let conn = lock_conn(&self.conn);
|
||||||
let now_ms = chrono_now_ms();
|
let now_ms = chrono_now_ms();
|
||||||
|
|
||||||
// Check for existing item with this hash.
|
// Check for existing item with this hash. optional() maps "no match" to
|
||||||
|
// None; a real read error propagates instead of being swallowed (which
|
||||||
|
// would make a duplicate look new and then fail the INSERT on the UNIQUE
|
||||||
|
// index with a confusing error).
|
||||||
let existing: Option<String> = conn
|
let existing: Option<String> = conn
|
||||||
.query_row(
|
.query_row(
|
||||||
"SELECT id FROM clipboard_history WHERE content_hash = ?1",
|
"SELECT id FROM clipboard_history WHERE content_hash = ?1",
|
||||||
params![content_hash],
|
params![content_hash],
|
||||||
|row| row.get(0),
|
|row| row.get(0),
|
||||||
)
|
)
|
||||||
.ok();
|
.optional()
|
||||||
|
.context("Checking for existing item")?;
|
||||||
|
|
||||||
if let Some(id) = existing {
|
if let Some(id) = existing {
|
||||||
conn.execute(
|
conn.execute(
|
||||||
|
|
@ -206,9 +216,9 @@ impl Db {
|
||||||
Ok(items)
|
Ok(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Full-text search over content_text. Only text items can match - images
|
/// Full-text search over `content_text`. Only text items can match - images
|
||||||
/// and other non-text content are NOT indexed and never appear in results.
|
/// and other non-text content are NOT indexed and never appear in results.
|
||||||
/// Empty query returns []; callers should use get_history_page for that.
|
/// Empty query returns []; callers should use `get_history_page` for that.
|
||||||
pub fn search_history(&self, query: &str, limit: usize) -> Result<Vec<ItemMeta>> {
|
pub fn search_history(&self, query: &str, limit: usize) -> Result<Vec<ItemMeta>> {
|
||||||
let conn = lock_conn(&self.conn);
|
let conn = lock_conn(&self.conn);
|
||||||
|
|
||||||
|
|
@ -219,7 +229,7 @@ impl Db {
|
||||||
.map(|t| {
|
.map(|t| {
|
||||||
// Escape embedded double-quotes by doubling them per FTS5 syntax.
|
// Escape embedded double-quotes by doubling them per FTS5 syntax.
|
||||||
let escaped = t.replace('"', "\"\"");
|
let escaped = t.replace('"', "\"\"");
|
||||||
format!("\"{}\"*", escaped)
|
format!("\"{escaped}\"*")
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
@ -258,39 +268,43 @@ impl Db {
|
||||||
/// (text item, or doesn't exist).
|
/// (text item, or doesn't exist).
|
||||||
pub fn get_thumbnail(&self, id: &str) -> Result<Option<Vec<u8>>> {
|
pub fn get_thumbnail(&self, id: &str) -> Result<Option<Vec<u8>>> {
|
||||||
let conn = lock_conn(&self.conn);
|
let conn = lock_conn(&self.conn);
|
||||||
let blob: Option<Option<Vec<u8>>> = conn
|
// thumbnail_blob is itself nullable, so the row yields Option<Vec<u8>>.
|
||||||
|
// optional() maps a missing row to Ok(None); real errors propagate.
|
||||||
|
let blob = conn
|
||||||
.query_row(
|
.query_row(
|
||||||
"SELECT thumbnail_blob FROM clipboard_history WHERE id = ?1",
|
"SELECT thumbnail_blob FROM clipboard_history WHERE id = ?1",
|
||||||
params![id],
|
params![id],
|
||||||
|row| row.get(0),
|
|row| row.get::<_, Option<Vec<u8>>>(0),
|
||||||
)
|
)
|
||||||
.ok();
|
.optional()
|
||||||
|
.context("Fetching thumbnail")?;
|
||||||
Ok(blob.flatten())
|
Ok(blob.flatten())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch raw item content for clipboard write-back. Does not load
|
/// Fetch raw item content for clipboard write-back. Does not load
|
||||||
/// thumbnail_blob -- callers only need the original payload.
|
/// `thumbnail_blob` -- callers only need the original payload.
|
||||||
pub fn get_raw_item(&self, id: &str) -> Result<Option<RawItem>> {
|
pub fn get_raw_item(&self, id: &str) -> Result<Option<RawItem>> {
|
||||||
let conn = lock_conn(&self.conn);
|
let conn = lock_conn(&self.conn);
|
||||||
let result = conn
|
// optional() maps a missing row to Ok(None); real errors propagate
|
||||||
.query_row(
|
// instead of being silently swallowed as "not found".
|
||||||
"SELECT id, mime_type, content_text, content_blob, source_app, created_at
|
conn.query_row(
|
||||||
|
"SELECT id, mime_type, content_text, content_blob, source_app, created_at
|
||||||
FROM clipboard_history WHERE id = ?1",
|
FROM clipboard_history WHERE id = ?1",
|
||||||
params![id],
|
params![id],
|
||||||
|row| {
|
|row| {
|
||||||
Ok(RawItem {
|
Ok(RawItem {
|
||||||
id: row.get(0)?,
|
id: row.get(0)?,
|
||||||
mime_type: row.get(1)?,
|
mime_type: row.get(1)?,
|
||||||
content_text: row.get(2)?,
|
content_text: row.get(2)?,
|
||||||
content_blob: row.get(3)?,
|
content_blob: row.get(3)?,
|
||||||
thumbnail_blob: None,
|
thumbnail_blob: None,
|
||||||
source_app: row.get(4)?,
|
source_app: row.get(4)?,
|
||||||
created_at: row.get(5)?,
|
created_at: row.get(5)?,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.ok();
|
.optional()
|
||||||
Ok(result)
|
.context("Fetching clipboard item")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_item(&self, id: &str) -> Result<bool> {
|
pub fn delete_item(&self, id: &str) -> Result<bool> {
|
||||||
|
|
@ -306,7 +320,7 @@ impl Db {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prune history to `max_history` most recent items. Returns the IDs of
|
/// Prune history to `max_history` most recent items. Returns the IDs of
|
||||||
/// items that were deleted, so the caller can emit ItemDeleted signals
|
/// items that were deleted, so the caller can emit `ItemDeleted` signals
|
||||||
/// (lets clients clean up per-item caches like thumbnail files).
|
/// (lets clients clean up per-item caches like thumbnail files).
|
||||||
pub fn prune(&self, max_history: usize) -> Result<Vec<String>> {
|
pub fn prune(&self, max_history: usize) -> Result<Vec<String>> {
|
||||||
let conn = lock_conn(&self.conn);
|
let conn = lock_conn(&self.conn);
|
||||||
|
|
@ -331,10 +345,7 @@ impl Db {
|
||||||
}
|
}
|
||||||
// Delete by collected IDs so the ORDER BY subquery runs only once.
|
// Delete by collected IDs so the ORDER BY subquery runs only once.
|
||||||
let placeholders = ids.iter().map(|_| "?").collect::<Vec<_>>().join(", ");
|
let placeholders = ids.iter().map(|_| "?").collect::<Vec<_>>().join(", ");
|
||||||
let sql = format!(
|
let sql = format!("DELETE FROM clipboard_history WHERE id IN ({placeholders})");
|
||||||
"DELETE FROM clipboard_history WHERE id IN ({})",
|
|
||||||
placeholders
|
|
||||||
);
|
|
||||||
conn.execute(&sql, rusqlite::params_from_iter(ids.iter()))?;
|
conn.execute(&sql, rusqlite::params_from_iter(ids.iter()))?;
|
||||||
Ok(ids)
|
Ok(ids)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,22 @@
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use zbus::{interface, object_server::SignalContext};
|
use zbus::{interface, object_server::SignalEmitter};
|
||||||
|
|
||||||
use crate::db::{Db, RawItem};
|
use crate::db::{Db, RawItem};
|
||||||
|
|
||||||
/// Maximum thumbnail dimension for images (px). Larger images are resized down.
|
/// Maximum thumbnail dimension for images (px). Larger images are resized down.
|
||||||
pub const THUMB_PX: u32 = 200;
|
pub const THUMB_PX: u32 = 200;
|
||||||
/// Default maximum raw image size to accept (bytes). Overridable via SetConfig.
|
/// Default maximum raw image size to accept (bytes). Overridable via `SetConfig`.
|
||||||
pub const DEFAULT_MAX_IMAGE_BYTES: usize = 5 * 1024 * 1024;
|
pub const DEFAULT_MAX_IMAGE_BYTES: usize = 5 * 1024 * 1024;
|
||||||
/// Default maximum text size to accept. Overridable via SetConfig.
|
/// Default maximum text size to accept. Overridable via `SetConfig`.
|
||||||
pub const DEFAULT_MAX_TEXT_BYTES: usize = 1024 * 1024;
|
pub const DEFAULT_MAX_TEXT_BYTES: usize = 1024 * 1024;
|
||||||
/// Default maximum history item count. Overridable via SetConfig.
|
/// Default maximum history item count. Overridable via `SetConfig`.
|
||||||
pub const DEFAULT_MAX_HISTORY: usize = 200;
|
pub const DEFAULT_MAX_HISTORY: usize = 200;
|
||||||
|
|
||||||
/// Runtime-configurable limits shared between the D-Bus service and the
|
/// Runtime-configurable limits shared between the D-Bus service and the
|
||||||
/// clipboard processing tasks. All three are read on every ingest / prune
|
/// clipboard processing tasks. All three are read on every ingest / prune
|
||||||
/// call, so updates via SetConfig take effect immediately.
|
/// call, so updates via `SetConfig` take effect immediately.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Limits {
|
pub struct Limits {
|
||||||
pub max_history: Arc<AtomicUsize>,
|
pub max_history: Arc<AtomicUsize>,
|
||||||
|
|
@ -67,6 +67,8 @@ impl StrataManager {
|
||||||
/// hint is not forwarded, so this method cannot re-check it. Treat callers of
|
/// hint is not forwarded, so this method cannot re-check it. Treat callers of
|
||||||
/// `SubmitItem` as trusted (the session bus is per-user). Forwarding the
|
/// `SubmitItem` as trusted (the session bus is per-user). Forwarding the
|
||||||
/// sensitivity flag to enforce it here is left for a future contract change.
|
/// sensitivity flag to enforce it here is left for a future contract change.
|
||||||
|
// async is required by the zbus #[interface] method signature, not by the body.
|
||||||
|
#[allow(clippy::unused_async)]
|
||||||
async fn submit_item(&self, mime_type: String, content: Vec<u8>) -> zbus::fdo::Result<()> {
|
async fn submit_item(&self, mime_type: String, content: Vec<u8>) -> zbus::fdo::Result<()> {
|
||||||
self.submit_tx
|
self.submit_tx
|
||||||
.send(SubmitRequest {
|
.send(SubmitRequest {
|
||||||
|
|
@ -76,8 +78,8 @@ impl StrataManager {
|
||||||
.map_err(|e| zbus::fdo::Error::Failed(e.to_string()))
|
.map_err(|e| zbus::fdo::Error::Failed(e.to_string()))
|
||||||
}
|
}
|
||||||
/// Return a page of recent items as JSON metadata (no inline thumbnail bytes,
|
/// Return a page of recent items as JSON metadata (no inline thumbnail bytes,
|
||||||
/// content_text truncated to a preview). Clients call GetThumbnail(id) lazily
|
/// `content_text` truncated to a preview). Clients call GetThumbnail(id) lazily
|
||||||
/// for items with has_thumbnail=true and GetItemContent(id) for full content.
|
/// for items with `has_thumbnail=true` and GetItemContent(id) for full content.
|
||||||
/// `offset` is from the most recent item (0 = newest).
|
/// `offset` is from the most recent item (0 = newest).
|
||||||
async fn get_history(&self, offset: u32, limit: u32) -> zbus::fdo::Result<String> {
|
async fn get_history(&self, offset: u32, limit: u32) -> zbus::fdo::Result<String> {
|
||||||
let db = self.db.clone();
|
let db = self.db.clone();
|
||||||
|
|
@ -93,7 +95,7 @@ impl StrataManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Full-text search across the entire DB. Empty query returns []; callers
|
/// Full-text search across the entire DB. Empty query returns []; callers
|
||||||
/// should fall back to GetHistory in that case.
|
/// should fall back to `GetHistory` in that case.
|
||||||
async fn search_history(&self, query: String, limit: u32) -> zbus::fdo::Result<String> {
|
async fn search_history(&self, query: String, limit: u32) -> zbus::fdo::Result<String> {
|
||||||
let db = self.db.clone();
|
let db = self.db.clone();
|
||||||
let items = tokio::task::spawn_blocking(move || db.search_history(&query, limit as usize))
|
let items = tokio::task::spawn_blocking(move || db.search_history(&query, limit as usize))
|
||||||
|
|
@ -173,7 +175,7 @@ impl StrataManager {
|
||||||
async fn delete_item(
|
async fn delete_item(
|
||||||
&self,
|
&self,
|
||||||
id: String,
|
id: String,
|
||||||
#[zbus(signal_context)] ctx: SignalContext<'_>,
|
#[zbus(signal_context)] ctx: SignalEmitter<'_>,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
let db = self.db.clone();
|
let db = self.db.clone();
|
||||||
let id_clone = id.clone();
|
let id_clone = id.clone();
|
||||||
|
|
@ -190,7 +192,7 @@ impl StrataManager {
|
||||||
/// Remove all items from history.
|
/// Remove all items from history.
|
||||||
async fn clear_history(
|
async fn clear_history(
|
||||||
&self,
|
&self,
|
||||||
#[zbus(signal_context)] ctx: SignalContext<'_>,
|
#[zbus(signal_context)] ctx: SignalEmitter<'_>,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
let db = self.db.clone();
|
let db = self.db.clone();
|
||||||
tokio::task::spawn_blocking(move || db.clear_history())
|
tokio::task::spawn_blocking(move || db.clear_history())
|
||||||
|
|
@ -204,14 +206,14 @@ impl StrataManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Push runtime limits from the front-end. Takes effect immediately.
|
/// Push runtime limits from the front-end. Takes effect immediately.
|
||||||
/// All three values are absolute (max_text and max_image are bytes,
|
/// All three values are absolute (`max_text` and `max_image` are bytes,
|
||||||
/// not MB). 0 means "leave unchanged" for that field.
|
/// not MB). 0 means "leave unchanged" for that field.
|
||||||
async fn set_config(
|
async fn set_config(
|
||||||
&self,
|
&self,
|
||||||
max_history: u32,
|
max_history: u32,
|
||||||
max_text_bytes: u32,
|
max_text_bytes: u32,
|
||||||
max_image_bytes: u32,
|
max_image_bytes: u32,
|
||||||
#[zbus(signal_context)] ctx: SignalContext<'_>,
|
#[zbus(signal_context)] ctx: SignalEmitter<'_>,
|
||||||
) -> zbus::fdo::Result<()> {
|
) -> zbus::fdo::Result<()> {
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
if max_history > 0 {
|
if max_history > 0 {
|
||||||
|
|
@ -256,6 +258,8 @@ impl StrataManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gracefully shut down the daemon.
|
/// Gracefully shut down the daemon.
|
||||||
|
// async is required by the zbus #[interface] method signature, not by the body.
|
||||||
|
#[allow(clippy::unused_async)]
|
||||||
async fn shutdown(&self) {
|
async fn shutdown(&self) {
|
||||||
tracing::info!("Shutdown requested via D-Bus");
|
tracing::info!("Shutdown requested via D-Bus");
|
||||||
// Signal the main loop to exit. The reply is sent before the process exits
|
// Signal the main loop to exit. The reply is sent before the process exits
|
||||||
|
|
@ -268,12 +272,12 @@ impl StrataManager {
|
||||||
// -----------------------------------------------------------------
|
// -----------------------------------------------------------------
|
||||||
|
|
||||||
/// Emitted when a new item is stored (after dedup + thumbnail generation).
|
/// Emitted when a new item is stored (after dedup + thumbnail generation).
|
||||||
/// `preview` is a text excerpt (≤ PREVIEW_CHARS) for text items, or empty for
|
/// `preview` is a text excerpt (≤ `PREVIEW_CHARS`) for text items, or empty for
|
||||||
/// images and other binary types - clients should call GetThumbnail(id) to
|
/// images and other binary types - clients should call GetThumbnail(id) to
|
||||||
/// fetch image thumbnails lazily.
|
/// fetch image thumbnails lazily.
|
||||||
#[zbus(signal)]
|
#[zbus(signal)]
|
||||||
pub async fn item_added(
|
pub async fn item_added(
|
||||||
ctx: &SignalContext<'_>,
|
ctx: &SignalEmitter<'_>,
|
||||||
id: &str,
|
id: &str,
|
||||||
mime_type: &str,
|
mime_type: &str,
|
||||||
preview: &str,
|
preview: &str,
|
||||||
|
|
@ -281,9 +285,9 @@ impl StrataManager {
|
||||||
|
|
||||||
/// Emitted when an item is removed.
|
/// Emitted when an item is removed.
|
||||||
#[zbus(signal)]
|
#[zbus(signal)]
|
||||||
pub async fn item_deleted(ctx: &SignalContext<'_>, id: &str) -> zbus::Result<()>;
|
pub async fn item_deleted(ctx: &SignalEmitter<'_>, id: &str) -> zbus::Result<()>;
|
||||||
|
|
||||||
/// Emitted when the entire history is cleared.
|
/// Emitted when the entire history is cleared.
|
||||||
#[zbus(signal)]
|
#[zbus(signal)]
|
||||||
pub async fn history_cleared(ctx: &SignalContext<'_>) -> zbus::Result<()>;
|
pub async fn history_cleared(ctx: &SignalEmitter<'_>) -> zbus::Result<()>;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,19 +54,21 @@ async fn main() -> Result<()> {
|
||||||
.await
|
.await
|
||||||
.context("Building D-Bus connection")?;
|
.context("Building D-Bus connection")?;
|
||||||
|
|
||||||
// Request the well-known name with ReplaceExisting (try to take it from any
|
// Single-instance daemon: request the name with DoNotQueue. The extension
|
||||||
// outgoing instance) AND AllowReplacement (let the next instance take it
|
// spawns exactly one daemon and skips spawning if the name is already owned,
|
||||||
// from us). Both are needed for a clean hand-off on extension reload: without
|
// so if the name IS taken here, another instance is already serving - the
|
||||||
// AllowReplacement on the running instance, a new instance's ReplaceExisting
|
// request returns an error (rather than silently queuing, which would leave
|
||||||
// would be refused.
|
// us running without owning the name while clients talk to the other one)
|
||||||
|
// and we exit. We deliberately do NOT use ReplaceExisting: stealing the name
|
||||||
|
// would orphan the running instance (zbus does not terminate a replaced
|
||||||
|
// owner), so we let the existing one keep it and bow out.
|
||||||
dbus_conn
|
dbus_conn
|
||||||
.request_name_with_flags(
|
.request_name_with_flags(
|
||||||
"dev.edu4rdshl.Strata",
|
"dev.edu4rdshl.Strata",
|
||||||
zbus::fdo::RequestNameFlags::ReplaceExisting
|
zbus::fdo::RequestNameFlags::DoNotQueue.into(),
|
||||||
| zbus::fdo::RequestNameFlags::AllowReplacement,
|
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
.context("Acquiring D-Bus name dev.edu4rdshl.Strata")?;
|
.context("Acquiring D-Bus name dev.edu4rdshl.Strata (is another instance running?)")?;
|
||||||
|
|
||||||
tracing::info!("D-Bus service registered as dev.edu4rdshl.Strata");
|
tracing::info!("D-Bus service registered as dev.edu4rdshl.Strata");
|
||||||
|
|
||||||
|
|
@ -76,11 +78,12 @@ async fn main() -> Result<()> {
|
||||||
// so this fails to bind there and the extension feeds content via SubmitItem
|
// so this fails to bind there and the extension feeds content via SubmitItem
|
||||||
// instead. On wlroots compositors (Sway, Hyprland) the monitor is the path.
|
// instead. On wlroots compositors (Sway, Hyprland) the monitor is the path.
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
match clipboard::monitor::spawn(clip_tx) {
|
if clipboard::monitor::spawn(clip_tx).is_ok() {
|
||||||
Ok(()) => tracing::info!("Wayland clipboard monitor started"),
|
tracing::info!("Wayland clipboard monitor started");
|
||||||
Err(_) => tracing::info!(
|
} else {
|
||||||
|
tracing::info!(
|
||||||
"Wayland clipboard monitor unavailable, using GJS Meta.Selection path (expected on GNOME)"
|
"Wayland clipboard monitor unavailable, using GJS Meta.Selection path (expected on GNOME)"
|
||||||
),
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
@ -198,12 +201,11 @@ async fn process_change(
|
||||||
tracing::debug!("Skipping clipboard change marked as sensitive");
|
tracing::debug!("Skipping clipboard change marked as sensitive");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let mime = match pick_mime(mime_types) {
|
let mime = if let Some(m) = pick_mime(mime_types) {
|
||||||
Some(m) => m.to_string(),
|
m.to_string()
|
||||||
None => {
|
} else {
|
||||||
tracing::debug!("No usable MIME type in {:?}", mime_types);
|
tracing::debug!("No usable MIME type in {:?}", mime_types);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
tracing::debug!("Processing Wayland clipboard change, MIME: {}", mime);
|
tracing::debug!("Processing Wayland clipboard change, MIME: {}", mime);
|
||||||
|
|
@ -316,12 +318,12 @@ async fn process_bytes(
|
||||||
.await
|
.await
|
||||||
.context("Getting StrataManager interface ref")?;
|
.context("Getting StrataManager interface ref")?;
|
||||||
|
|
||||||
StrataManager::item_added(iface.signal_context(), &id, &mime, &preview)
|
StrataManager::item_added(iface.signal_emitter(), &id, &mime, &preview)
|
||||||
.await
|
.await
|
||||||
.context("Emitting ItemAdded signal")?;
|
.context("Emitting ItemAdded signal")?;
|
||||||
|
|
||||||
for pid in &pruned_ids {
|
for pid in &pruned_ids {
|
||||||
if let Err(e) = StrataManager::item_deleted(iface.signal_context(), pid).await {
|
if let Err(e) = StrataManager::item_deleted(iface.signal_emitter(), pid).await {
|
||||||
tracing::warn!("Emitting ItemDeleted for pruned id={}: {}", pid, e);
|
tracing::warn!("Emitting ItemDeleted for pruned id={}: {}", pid, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue