From 06c6be0b22008f1965438c1ddec17e637782a0a3 Mon Sep 17 00:00:00 2001 From: FabianLars-crabnebula Date: Wed, 30 Sep 2026 15:22:20 +0200 Subject: [PATCH 1/3] chore: raise msrv. update deps. fix clippy issues --- Cargo.lock | 539 +++++++++++--------------- Cargo.toml | 2 +- README.md | 2 +- crates/cve/src/lib.rs | 6 +- crates/cve/src/sources/osv.rs | 5 +- crates/detect/src/chromium_browser.rs | 2 +- crates/netmon-helper/src/main.rs | 4 +- crates/netmon/src/engine/tls.rs | 6 +- crates/vfs/src/mem.rs | 10 +- docs/index.html | 2 +- src-tauri/src/journal.rs | 4 +- 11 files changed, 242 insertions(+), 340 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d755039..6f04036 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "achilles" @@ -72,15 +72,15 @@ dependencies = [ [[package]] name = "alloc-no-stdlib" -version = "2.0.4" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" +checksum = "c2fb6cfd47bf496ff64095c20eaba0c201404ee38714d4142fcfa1dc334fcc7a" [[package]] name = "alloc-stdlib" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +checksum = "0b5c1865780388bfa186411ab5f247819487fc4864c6e9c3106611fa347586e1" dependencies = [ "alloc-no-stdlib", ] @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "app-audit" @@ -219,6 +219,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "base64ct" version = "1.8.3" @@ -291,9 +297,9 @@ dependencies = [ [[package]] name = "brotli" -version = "8.0.3" +version = "9.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8119e4516436f5708bbc474a9d395bf12f1b5395e93a92a56e647ac3388c8610" +checksum = "f8b851b75c23ca7873623d612fe49bd1989aeb03d08fb9432187eb253d3d4c6b" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -302,9 +308,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "5.0.1" +version = "6.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5962523e1b92ce1b5e793d9169b9943eece10d39f62550bc04bb605d75b94924" +checksum = "941cd9bd4ddab83cb46fa5a2d428f1c857b24ac78cb876cf7beb710840934bd7" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -415,12 +421,13 @@ dependencies = [ [[package]] name = "cargo_toml" -version = "0.22.3" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +checksum = "82f4b26e751e711a5302649417f2da046dce6391b2ea30a4820f37462314f0b9" dependencies = [ + "semver", "serde", - "toml 0.9.12+spec-1.1.0", + "toml 1.1.2+spec-1.1.0", ] [[package]] @@ -463,13 +470,13 @@ checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] name = "cfb" -version = "0.7.3" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +checksum = "a347dcabdae9c31b0825fd6a8bed285ec9c2acb89c47827126d52fa4f59cece3" dependencies = [ - "byteorder", "fnv", "uuid", + "web-time", ] [[package]] @@ -514,7 +521,7 @@ dependencies = [ "iana-time-zone", "num-traits", "serde", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -569,6 +576,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation" version = "0.10.1" @@ -592,7 +609,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" dependencies = [ "bitflags 2.12.1", - "core-foundation", + "core-foundation 0.10.1", "core-graphics-types", "foreign-types", "libc", @@ -605,7 +622,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ "bitflags 2.12.1", - "core-foundation", + "core-foundation 0.10.1", "libc", ] @@ -678,9 +695,9 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" dependencies = [ "crossbeam-utils", ] @@ -703,9 +720,9 @@ dependencies = [ [[package]] name = "cssparser" -version = "0.36.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dae61cf9c0abb83bd659dab65b7e4e38d8236824c85f0f804f173567bda257d2" +checksum = "8c9cdaae01d5ed7882b04d795e7f752f46ff52d2fa3b50a20d28c464510bba98" dependencies = [ "cssparser-macros", "dtoa-short", @@ -716,9 +733,9 @@ dependencies = [ [[package]] name = "cssparser-macros" -version = "0.6.1" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +checksum = "d045de693cb712d0b22c6a64be5b953f67b3ce00ab5ad3dd5d8b441886ab8e1a" dependencies = [ "quote", "syn 2.0.117", @@ -726,19 +743,9 @@ dependencies = [ [[package]] name = "ctor" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98" -dependencies = [ - "ctor-proc-macro", - "dtor", -] - -[[package]] -name = "ctor-proc-macro" -version = "0.0.7" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" +checksum = "914a755b7c2d4af2bdcff7ce1739e2db9a1b81a9b07123d8015786ae03c0980d" [[package]] name = "cve" @@ -929,6 +936,15 @@ dependencies = [ "dirs-sys 0.5.0", ] +[[package]] +name = "dirs" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d57d423b3c82e89b9a24ca3091fee61f456a26edbd28d26c65906f4bc1dcd8f" +dependencies = [ + "dirs-sys 0.5.0", +] + [[package]] name = "dirs-sys" version = "0.3.7" @@ -1000,9 +1016,9 @@ dependencies = [ [[package]] name = "dom_query" -version = "0.27.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89" +checksum = "fac5fca71e65e94cc718a6e2af65d6e0f9c6027751c2aa562fbb5087fda639bc" dependencies = [ "bit-set", "cssparser", @@ -1043,21 +1059,6 @@ dependencies = [ "dtoa", ] -[[package]] -name = "dtor" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1057d6c64987086ff8ed0fd3fbf377a6b7d205cc7715868cd401705f715cbe4" -dependencies = [ - "dtor-proc-macro", -] - -[[package]] -name = "dtor-proc-macro" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" - [[package]] name = "dunce" version = "1.0.5" @@ -1734,9 +1735,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "html5ever" -version = "0.38.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1054432bae2f14e0061e33d23402fbaa67a921d319d56adc6bcf887ddad1cbc2" +checksum = "46a1761807faccc9a19e86944bbf40610014066306f96edcdedc2fb714bcb7b8" dependencies = [ "log", "markup5ever", @@ -1803,9 +1804,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.9" +version = "0.27.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +checksum = "dfa8e654703247911e29c23fbeaa261834bd9bb74efba2f9acddc37bfb127f53" dependencies = [ "http", "hyper", @@ -1835,9 +1836,11 @@ dependencies = [ "percent-encoding", "pin-project-lite", "socket2", + "system-configuration", "tokio", "tower-service", "tracing", + "windows-registry", ] [[package]] @@ -2014,9 +2017,9 @@ dependencies = [ [[package]] name = "infer" -version = "0.19.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" +checksum = "f4200d433cbd5178df7797c9c2e75b348b728e39631cf14520d1e2fc424201f4" dependencies = [ "cfb", ] @@ -2105,7 +2108,7 @@ dependencies = [ "simd_cesu8", "thiserror 2.0.18", "walkdir", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -2163,21 +2166,21 @@ dependencies = [ [[package]] name = "json-patch" -version = "3.0.1" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" +checksum = "7421438de105a0827e44fadd05377727847d717c80ce29a229f85fd04c427b72" dependencies = [ "jsonptr", "serde", "serde_json", - "thiserror 1.0.69", + "thiserror 2.0.18", ] [[package]] name = "jsonptr" -version = "0.6.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" +checksum = "a5a3cc660ba5d72bce0b3bb295bf20847ccbb40fd423f3f05b61273672e561fe" dependencies = [ "serde", "serde_json", @@ -2185,13 +2188,12 @@ dependencies = [ [[package]] name = "keyboard-types" -version = "0.7.0" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +checksum = "0fbe853b403ae61a04233030ae8a79d94975281ed9770a1f9e246732b534b28d" dependencies = [ "bitflags 2.12.1", "serde", - "unicode-segmentation", ] [[package]] @@ -2256,7 +2258,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -2325,9 +2327,9 @@ dependencies = [ [[package]] name = "markup5ever" -version = "0.38.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8983d30f2915feeaaab2d6babdd6bc7e9ed1a00b66b5e6d74df19aa9c0e91862" +checksum = "7122d987ec5f704ee56f6e5b41a7d93722e9aae27ae07cafa4036c4d3f9757de" dependencies = [ "log", "tendril", @@ -2403,9 +2405,9 @@ dependencies = [ [[package]] name = "muda" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47a2e3dff89cd322c66647942668faee0a2b1f88ea6cbb4d374b4a8d7e92528c" +checksum = "cca139e57da4383727f189e43e66e84fa372347027fc996f9f1a007ec0a37996" dependencies = [ "crossbeam-channel", "dpi", @@ -2437,6 +2439,12 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + [[package]] name = "ndk-sys" version = "0.6.0+11769913" @@ -2548,7 +2556,7 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" dependencies = [ - "proc-macro-crate 3.5.0", + "proc-macro-crate 2.0.2", "proc-macro2", "quote", "syn 2.0.117", @@ -2575,6 +2583,7 @@ dependencies = [ "objc2", "objc2-core-foundation", "objc2-foundation", + "objc2-quartz-core", ] [[package]] @@ -3107,7 +3116,7 @@ dependencies = [ "libc", "redox_syscall 0.5.18", "smallvec", - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -3251,9 +3260,9 @@ checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" [[package]] name = "plist" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092791278e026273c1b65bbdcfbba3a300f2994c896bd01ab01da613c29c46f1" +checksum = "7da1d65da6dd5d1e44199ac0f58712d241c0f439f80adea8924d832384087f85" dependencies = [ "base64 0.22.1", "indexmap 2.14.0", @@ -3339,15 +3348,6 @@ dependencies = [ "toml_edit 0.20.2", ] -[[package]] -name = "proc-macro-crate" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" -dependencies = [ - "toml_edit 0.25.12+spec-1.1.0", -] - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -3383,9 +3383,9 @@ dependencies = [ [[package]] name = "quick-xml" -version = "0.39.4" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdcc8dd4e2f670d309a5f0e83fe36dfdc05af317008fea29144da1a2ac858e5e" +checksum = "e660451e55124f798a69a5af3f49ccfbefbd41910eefd25caf2393e1f3473ec1" dependencies = [ "memchr", ] @@ -3648,11 +3648,11 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.13.4" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" +checksum = "16a1cfa75cc186dd73d5818e510e042e40927bccc9c236b061cea97e1eb08029" dependencies = [ - "base64 0.22.1", + "base64 0.23.1", "bytes", "futures-core", "futures-util", @@ -3768,9 +3768,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "0d41d731c7d2f962d1ccc364cec258de3c0e93b38c2fb3ba97ac74513048d634" dependencies = [ "once_cell", "ring", @@ -3804,11 +3804,11 @@ dependencies = [ [[package]] name = "rustls-platform-verifier" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" +checksum = "1167586491e2b18b8bfbb293e8180ec17c201c4f076d7cb3070ca964e7598f98" dependencies = [ - "core-foundation", + "core-foundation 0.10.1", "core-foundation-sys", "jni 0.22.4", "log", @@ -3825,15 +3825,15 @@ dependencies = [ [[package]] name = "rustls-platform-verifier-android" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" +checksum = "eec689c0bc40ff2458a5977b6619cb718087084a18e02a131c599b62d05e1a5f" [[package]] name = "rustls-webpki" -version = "0.103.13" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c429a8649f110dddef65e2a5ad240f747e85f7758a6bccc7e5777bd33f756e" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ "ring", "rustls-pki-types", @@ -3977,7 +3977,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ "bitflags 2.12.1", - "core-foundation", + "core-foundation 0.10.1", "core-foundation-sys", "libc", "security-framework-sys", @@ -3995,9 +3995,9 @@ dependencies = [ [[package]] name = "selectors" -version = "0.36.1" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c" +checksum = "8adfa1c298912827b8a28b223b3b874357397ae706e6190acd9bf28cee99114d" dependencies = [ "bitflags 2.12.1", "cssparser", @@ -4452,9 +4452,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "swift-rs" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7" +checksum = "e45c444e496845d3f2a351146bff59aae4975b2280238df1dfaa0c7d1846f38e" dependencies = [ "base64 0.21.7", "serde", @@ -4516,6 +4516,27 @@ dependencies = [ "windows 0.57.0", ] +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.12.1", + "core-foundation 0.9.4", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -4531,13 +4552,13 @@ dependencies = [ [[package]] name = "tao" -version = "0.35.3" +version = "0.37.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1c93047acf68669466a34690ac58cca7010bd1b201e1ec86f1fd0a75d3dd4a9" +checksum = "f37f381f4e048e6cdf038b5705f8cf14ad108279d46eb968140a7b291aba9400" dependencies = [ "bitflags 2.12.1", "block2", - "core-foundation", + "core-foundation 0.10.1", "core-graphics", "crossbeam-channel", "dbus", @@ -4551,29 +4572,29 @@ dependencies = [ "libc", "log", "ndk", + "ndk-context", "ndk-sys", "objc2", "objc2-app-kit", "objc2-foundation", "objc2-ui-kit", - "once_cell", "parking_lot", "percent-encoding", "raw-window-handle", "tao-macros", "unicode-segmentation", "url", - "windows 0.61.3", - "windows-core 0.61.2", + "windows 0.62.2", + "windows-core 0.62.2", "windows-version", "x11-dl", ] [[package]] name = "tao-macros" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" +checksum = "5f7eeb6d99155545da6150a1795945f16ac9c178deb2a5f2e74d776107bd5849" dependencies = [ "proc-macro2", "quote", @@ -4599,14 +4620,14 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.11.2" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "437404997acf375d85f1177afa7e11bb971f274ed6a7b83a2a3e339015f4cc28" +checksum = "cb20ef8e6f97d6fe03039666cd82861f09a38b56291fa2f0f9fe140023f61c1a" dependencies = [ "anyhow", "bytes", "cookie", - "dirs 6.0.0", + "dirs 7.0.0", "dunce", "embed_plist", "getrandom 0.3.4", @@ -4627,7 +4648,7 @@ dependencies = [ "percent-encoding", "plist", "raw-window-handle", - "reqwest 0.13.4", + "reqwest 0.13.5", "serde", "serde_json", "serde_repr", @@ -4645,18 +4666,18 @@ dependencies = [ "webkit2gtk", "webview2-com", "window-vibrancy", - "windows 0.61.3", + "windows 0.62.2", ] [[package]] name = "tauri-build" -version = "2.6.2" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4aa1f9055fc23919a54e4e125052bed16ed04aef0487086e758fe01a67b451c7" +checksum = "5b5ae674f48836f5dd2eeaf9e221c095bd3e78a8d0439c77ca93b48740a1b644" dependencies = [ "anyhow", "cargo_toml", - "dirs 6.0.0", + "dirs 7.0.0", "glob", "heck 0.5.0", "json-patch", @@ -4671,16 +4692,16 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.6.2" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a0319528a025a38c4078e7dae2c446f4e63620ddb0659a643ede1cb38f90e9" +checksum = "3926b73ac01df7c14f19ff872cd56e67213a87acc0000ea37ddb300f3d11a3e3" dependencies = [ "base64 0.22.1", "brotli", "ico", "json-patch", "plist", - "png 0.17.16", + "png 0.18.1", "proc-macro2", "quote", "semver", @@ -4698,9 +4719,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.6.2" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6cb4e3896c21d2f6da5b31251d2faea0153bba56ed0e970f918115dbee4924" +checksum = "d21d0fa2c0529972ea6ecaf7404fcf40efac098eda0beb06ca682f41e33a6aa5" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -4712,9 +4733,9 @@ dependencies = [ [[package]] name = "tauri-plugin" -version = "2.6.2" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e126abc9e84e35cdfd01596140a73a1850cdb0df0a23acf0185776c30b469a6e" +checksum = "c9ff3ebb9fda56ceb93d46f6cbb126bae82951bf43498543a5163dde5def49a1" dependencies = [ "anyhow", "glob", @@ -4815,12 +4836,12 @@ dependencies = [ [[package]] name = "tauri-plugin-updater" -version = "2.10.1" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "806d9dac662c2e4594ff03c647a552f2c9bd544e7d0f683ec58f872f952ce4af" +checksum = "3cb0b2ea3e85ca287990d3859a29cc5cb18024240fd78f62e027fb7963670f18" dependencies = [ "base64 0.22.1", - "dirs 6.0.0", + "dirs 7.0.0", "flate2", "futures-util", "http", @@ -4829,7 +4850,7 @@ dependencies = [ "minisign-verify", "osakit", "percent-encoding", - "reqwest 0.13.4", + "reqwest 0.13.5", "rustls", "semver", "serde", @@ -4842,15 +4863,15 @@ dependencies = [ "time", "tokio", "url", - "windows-sys 0.60.2", + "windows-sys 0.61.2", "zip 4.6.1", ] [[package]] name = "tauri-runtime" -version = "2.11.2" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48222d7116c8807eaa6fe2f372e023fae125084e61e6eca6d70b7961cdf129ef" +checksum = "c9e6d5ef76985b32ff012a43b58df205d25a285e400ca878afcacddc5d5f3238" dependencies = [ "cookie", "dpi", @@ -4868,14 +4889,14 @@ dependencies = [ "url", "webkit2gtk", "webview2-com", - "windows 0.61.3", + "windows 0.62.2", ] [[package]] name = "tauri-runtime-wry" -version = "2.11.2" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b83849ee63ecb27a8e8d0fe51915ca215076914aca43f96db1179f0f415f6cd9" +checksum = "fa829eb69860cf1fb0bedb21d2d5f1effce3527d054a68ca1cd7355c654400a3" dependencies = [ "gtk", "http", @@ -4893,15 +4914,15 @@ dependencies = [ "url", "webkit2gtk", "webview2-com", - "windows 0.61.3", + "windows 0.62.2", "wry", ] [[package]] name = "tauri-utils" -version = "2.9.2" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092379df9a707631978e6c56b1bc2401d387f01e2d4a3c123360d167bbb9aa95" +checksum = "4dd257082deff79550de3409ed146104aeaf86fe38649615b04a304144939677" dependencies = [ "anyhow", "brotli", @@ -5126,9 +5147,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.4" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +checksum = "c9cc2678c2cdd569ef8215e2afd7954ada2ae20b4fdd2c5fe6139a3b02d105db" dependencies = [ "rustls", "tokio", @@ -5159,21 +5180,6 @@ dependencies = [ "toml_edit 0.20.2", ] -[[package]] -name = "toml" -version = "0.9.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" -dependencies = [ - "indexmap 2.14.0", - "serde_core", - "serde_spanned 1.1.1", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 0.7.15", -] - [[package]] name = "toml" version = "1.1.2+spec-1.1.0" @@ -5198,15 +5204,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", -] - [[package]] name = "toml_datetime" version = "1.1.1+spec-1.1.0" @@ -5240,18 +5237,6 @@ dependencies = [ "winnow 0.5.40", ] -[[package]] -name = "toml_edit" -version = "0.25.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" -dependencies = [ - "indexmap 2.14.0", - "toml_datetime 1.1.1+spec-1.1.0", - "toml_parser", - "winnow 1.0.3", -] - [[package]] name = "toml_parser" version = "1.1.2+spec-1.1.0" @@ -5333,12 +5318,12 @@ dependencies = [ [[package]] name = "tray-icon" -version = "0.23.1" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15edbb0d80583e85ee8df283410038e17314df5cba30da2087a54a85216c0773" +checksum = "b2b9c52859a94554803ccd4a24b98f74148ebc73b90676d783f3490b1bff9d72" dependencies = [ "crossbeam-channel", - "dirs 6.0.0", + "dirs 7.0.0", "libappindicator", "muda", "objc2", @@ -5377,47 +5362,6 @@ version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-ucd-ident" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - [[package]] name = "unicode-id-start" version = "1.4.0" @@ -5475,13 +5419,13 @@ dependencies = [ [[package]] name = "urlpattern" -version = "0.3.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" +checksum = "df16f50ef4cc145211879a3867ba757076b25dfee812040dcb0658bd9ae7904b" dependencies = [ + "icu_properties", "regex", "serde", - "unic-ucd-ident", "url", ] @@ -5804,16 +5748,14 @@ dependencies = [ [[package]] name = "webview2-com" -version = "0.38.2" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7130243a7a5b33c54a444e54842e6a9e133de08b5ad7b5861cd8ed9a6a5bc96a" +checksum = "3f89fca7a704cee10dcb3654c1dbb8941d1783132f1917358af75bec37a7d7e6" dependencies = [ "webview2-com-macros", "webview2-com-sys", - "windows 0.61.3", - "windows-core 0.61.2", - "windows-implement 0.60.2", - "windows-interface 0.59.3", + "windows 0.62.2", + "windows-core 0.62.2", ] [[package]] @@ -5829,13 +5771,13 @@ dependencies = [ [[package]] name = "webview2-com-sys" -version = "0.38.2" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "381336cfffd772377d291702245447a5251a2ffa5bad679c99e61bc48bacbf9c" +checksum = "b3a07132775117d6065853d9d1178157b8c90e228de47129d6bce2c7edebedfb" dependencies = [ "thiserror 2.0.18", - "windows 0.61.3", - "windows-core 0.61.2", + "windows 0.62.2", + "windows-core 0.62.2", ] [[package]] @@ -5882,16 +5824,17 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "window-vibrancy" -version = "0.6.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" +checksum = "111e51caca442cafd9bab396628ac4d814880eaea4e63dfd76a12e9f342b5580" dependencies = [ "objc2", "objc2-app-kit", "objc2-core-foundation", "objc2-foundation", + "objc2-quartz-core", "raw-window-handle", - "windows-sys 0.59.0", + "windows-sys 0.61.2", "windows-version", ] @@ -5917,24 +5860,23 @@ dependencies = [ [[package]] name = "windows" -version = "0.61.3" +version = "0.62.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" dependencies = [ "windows-collections", - "windows-core 0.61.2", + "windows-core 0.62.2", "windows-future", - "windows-link 0.1.3", "windows-numerics", ] [[package]] name = "windows-collections" -version = "0.2.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" dependencies = [ - "windows-core 0.61.2", + "windows-core 0.62.2", ] [[package]] @@ -5962,19 +5904,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", -] - [[package]] name = "windows-core" version = "0.62.2" @@ -5983,19 +5912,19 @@ checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" dependencies = [ "windows-implement 0.60.2", "windows-interface 0.59.3", - "windows-link 0.2.1", + "windows-link", "windows-result 0.4.1", "windows-strings 0.5.1", ] [[package]] name = "windows-future" -version = "0.2.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", + "windows-core 0.62.2", + "windows-link", "windows-threading", ] @@ -6065,12 +5994,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - [[package]] name = "windows-link" version = "0.2.1" @@ -6079,39 +6002,41 @@ checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" [[package]] name = "windows-numerics" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", + "windows-core 0.62.2", + "windows-link", ] [[package]] -name = "windows-result" -version = "0.1.2" +name = "windows-registry" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +checksum = "02752bf7fbdcce7f2a27a742f798510f3e5ad88dbe84871e5168e2120c3d5720" dependencies = [ - "windows-targets 0.52.6", + "windows-link", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] name = "windows-result" -version = "0.2.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" dependencies = [ "windows-targets 0.52.6", ] [[package]] name = "windows-result" -version = "0.3.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ - "windows-link 0.1.3", + "windows-targets 0.52.6", ] [[package]] @@ -6120,7 +6045,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -6133,22 +6058,13 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link 0.1.3", -] - [[package]] name = "windows-strings" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -6215,7 +6131,7 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -6270,7 +6186,7 @@ version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link 0.2.1", + "windows-link", "windows_aarch64_gnullvm 0.53.1", "windows_aarch64_msvc 0.53.1", "windows_i686_gnu 0.53.1", @@ -6283,11 +6199,11 @@ dependencies = [ [[package]] name = "windows-threading" -version = "0.1.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" dependencies = [ - "windows-link 0.1.3", + "windows-link", ] [[package]] @@ -6296,7 +6212,7 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" dependencies = [ - "windows-link 0.2.1", + "windows-link", ] [[package]] @@ -6518,20 +6434,11 @@ dependencies = [ "memchr", ] -[[package]] -name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" - [[package]] name = "winnow" version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" -dependencies = [ - "memchr", -] [[package]] name = "winreg" @@ -6664,15 +6571,15 @@ checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "wry" -version = "0.55.1" +version = "0.57.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186f9871daa55fd9c016578b810d149de58367113db7fb72b462d2323ce19514" +checksum = "a819957a01b3119af85e638a38d242af76dbc87d130dca67bfd0441072e21ff0" dependencies = [ "base64 0.22.1", "block2", "cookie", "crossbeam-channel", - "dirs 6.0.0", + "dirs 7.0.0", "dom_query", "dpi", "dunce", @@ -6700,8 +6607,8 @@ dependencies = [ "webkit2gtk", "webkit2gtk-sys", "webview2-com", - "windows 0.61.3", - "windows-core 0.61.2", + "windows 0.62.2", + "windows-core 0.62.2", "windows-version", "x11-dl", ] diff --git a/Cargo.toml b/Cargo.toml index 263a9d4..e676b6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ members = ["crates/*", "src-tauri"] [workspace.package] edition = "2021" -rust-version = "1.80" +rust-version = "1.90" license = "PolyForm-Noncommercial-1.0.0" authors = ["CrabNebula Ltd. "] repository = "https://github.com/crabnebula-dev/achilles" diff --git a/README.md b/README.md index 8d11f12..169fa1a 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Electron apps it audits actually looks like. ## Quickstart -Requirements: Rust 1.80+. macOS 12+, Windows 10+, or a Linux desktop. The GUI +Requirements: Rust 1.90+. macOS 12+, Windows 10+, or a Linux desktop. The GUI needs nothing else to run. ```sh diff --git a/crates/cve/src/lib.rs b/crates/cve/src/lib.rs index e6ea064..bc329ca 100644 --- a/crates/cve/src/lib.rs +++ b/crates/cve/src/lib.rs @@ -898,7 +898,7 @@ fn apply_age_filter(report: &mut CveReport, max_age_years: Option) { let cutoff = current.saturating_sub(max); let filter = |v: &mut Vec| { - v.retain(|a| advisory_year(a).map_or(true, |y| y >= cutoff)); + v.retain(|a| advisory_year(a).is_none_or(|y| y >= cutoff)); }; filter(&mut report.electron); @@ -928,7 +928,7 @@ pub fn filter_npm_by_age(results: &mut [NpmPackageAdvisories], max_age_years: Op let cutoff = current.saturating_sub(max); for r in results.iter_mut() { r.advisories - .retain(|a| advisory_year(a).map_or(true, |y| y >= cutoff)); + .retain(|a| advisory_year(a).is_none_or(|y| y >= cutoff)); } } @@ -964,7 +964,7 @@ fn current_year() -> Option { let mut year = 1970u32; let mut remaining = days; loop { - let leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; + let leap = (year.is_multiple_of(4) && !year.is_multiple_of(100)) || year.is_multiple_of(400); let in_year = if leap { 366 } else { 365 }; if remaining < in_year { return Some(year); diff --git a/crates/cve/src/sources/osv.rs b/crates/cve/src/sources/osv.rs index 8d26f7f..d6dfd65 100644 --- a/crates/cve/src/sources/osv.rs +++ b/crates/cve/src/sources/osv.rs @@ -256,10 +256,7 @@ fn fixed_for(affected: &[Affected], version: Option<&str>) -> Option { let Ok(fixed) = semver::Version::parse(at) else { continue; }; - // `map_or` rather than `is_none_or`: this crate's MSRV is - // 1.80 and the latter is only stable from 1.82. - #[allow(clippy::unnecessary_map_or)] - let opened = introduced.as_ref().map_or(true, |i| current >= *i); + let opened = introduced.as_ref().is_none_or(|i| current >= *i); if opened && current < fixed { return Some(at.to_owned()); } diff --git a/crates/detect/src/chromium_browser.rs b/crates/detect/src/chromium_browser.rs index 210a96b..9de3cd6 100644 --- a/crates/detect/src/chromium_browser.rs +++ b/crates/detect/src/chromium_browser.rs @@ -149,7 +149,7 @@ mod macos { .unwrap_or_else(|| name.into_owned()); if best .as_deref() - .map_or(true, |b| cmp_version(&version, b).is_gt()) + .is_none_or(|b| cmp_version(&version, b).is_gt()) { best = Some(version); } diff --git a/crates/netmon-helper/src/main.rs b/crates/netmon-helper/src/main.rs index 1783c0b..bd64ed5 100644 --- a/crates/netmon-helper/src/main.rs +++ b/crates/netmon-helper/src/main.rs @@ -57,7 +57,7 @@ async fn main() { async fn serve(stream: tokio::net::UnixStream) { use netmon::source::{CapturedEvent, PidFilter}; use netmon::wire; - use tokio::io::AsyncReadExt; + let (mut rd, mut wr) = stream.into_split(); @@ -70,7 +70,7 @@ async fn serve(stream: tokio::net::UnixStream) { #[cfg(target_os = "macos")] let source = netmon::direct_capture_source(); #[cfg(not(target_os = "macos"))] - let source: Box = { + let _source: Box = { let _ = &filter; let _ = wire::write_frame( &mut wr, diff --git a/crates/netmon/src/engine/tls.rs b/crates/netmon/src/engine/tls.rs index d8b2974..856cb07 100644 --- a/crates/netmon/src/engine/tls.rs +++ b/crates/netmon/src/engine/tls.rs @@ -118,7 +118,7 @@ fn parse_client_hello(b: &[u8]) -> Option { r.take(sid_len)?; // session id let cs_len = r.u16()? as usize; let cs = r.take(cs_len)?; - for pair in cs.chunks_exact(2) { + for pair in cs.as_chunks::<2>().0 { let id = u16::from_be_bytes([pair[0], pair[1]]); if !is_grease(id) { ch.ciphers.push(id); @@ -165,7 +165,7 @@ fn parse_u16_list(body: &[u8], strip_grease: bool) -> Vec { let Some(list) = r.take(list_len as usize) else { return Vec::new(); }; - list.chunks_exact(2) + list.as_chunks::<2>().0.iter() .map(|p| u16::from_be_bytes([p[0], p[1]])) .filter(|v| !strip_grease || !is_grease(*v)) .collect() @@ -180,7 +180,7 @@ fn parse_u16_list_u8len(body: &[u8]) -> Vec { let Some(list) = r.take(list_len as usize) else { return Vec::new(); }; - list.chunks_exact(2) + list.as_chunks::<2>().0.iter() .map(|p| u16::from_be_bytes([p[0], p[1]])) .filter(|v| !is_grease(*v)) .collect() diff --git a/crates/vfs/src/mem.rs b/crates/vfs/src/mem.rs index 077bf7f..f5449f7 100644 --- a/crates/vfs/src/mem.rs +++ b/crates/vfs/src/mem.rs @@ -193,13 +193,11 @@ pub fn read_dir(path: impl AsRef) -> io::Result { let dir = tree.resolve(path, 0).ok_or_else(|| not_found(path))?; match tree.nodes.get(&dir) { Some(Node::Dir) => {} - // `ErrorKind::NotADirectory` is only stable since 1.83; the - // workspace MSRV is 1.80, so use a generic error with a message. _ => { - return Err(io::Error::other(format!( - "vfs: not a directory: {}", - path.display() - ))) + return Err(io::Error::new( + io::ErrorKind::NotADirectory, + format!("vfs: not a directory: {}", path.display()), + )) } } let entries: Vec = tree diff --git a/docs/index.html b/docs/index.html index 6becacd..0096732 100644 --- a/docs/index.html +++ b/docs/index.html @@ -343,7 +343,7 @@

Static analysis

Build from source

- Requirements: Rust 1.80+, macOS 12+. The GUI needs nothing else to + Requirements: Rust 1.90+, macOS 12+. The GUI needs nothing else to run.

# launch the desktop app (auto-scans on open)
diff --git a/src-tauri/src/journal.rs b/src-tauri/src/journal.rs
index b9e2a81..2913d5a 100644
--- a/src-tauri/src/journal.rs
+++ b/src-tauri/src/journal.rs
@@ -245,7 +245,7 @@ pub(crate) fn format_iso(unix_secs: u64) -> String {
     let mut year = 1970u32;
     let mut days_remaining = days_since_epoch as i64;
     loop {
-        let is_leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
+        let is_leap = (year.is_multiple_of(4) && !year.is_multiple_of(100)) || year.is_multiple_of(400);
         let yr_days = if is_leap { 366 } else { 365 };
         if days_remaining < yr_days as i64 {
             break;
@@ -253,7 +253,7 @@ pub(crate) fn format_iso(unix_secs: u64) -> String {
         days_remaining -= yr_days as i64;
         year += 1;
     }
-    let is_leap = (year % 4 == 0 && year % 100 != 0) || year % 400 == 0;
+    let is_leap = (year.is_multiple_of(4) && !year.is_multiple_of(100)) || year.is_multiple_of(400);
     let mut month = 0u32;
     let mut day = days_remaining as u32 + 1;
     for (i, &dm) in DAYS_IN_MONTH.iter().enumerate() {

From 802e8ea1ad28e83c462590cea53875633a56b381 Mon Sep 17 00:00:00 2001
From: FabianLars-crabnebula 
Date: Wed, 30 Sep 2026 15:22:31 +0200
Subject: [PATCH 2/3] fmt

---
 crates/achilles-wasm/src/bindings.rs       |  10 +-
 crates/achilles-wasm/tests/upload.rs       |  10 +-
 crates/binmeta/src/lib.rs                  |  21 +-
 crates/cbom/src/aggregate.rs               |  76 +++----
 crates/cbom/src/cyclonedx.rs               |   7 +-
 crates/cbom/src/normalize.rs               | 219 +++++++++++++++++----
 crates/cbom/src/staticscan.rs              |  28 +--
 crates/cbom/tests/inventory.rs             |  35 +++-
 crates/cve/src/lib.rs                      |  17 +-
 crates/cve/src/sources/snapshot.rs         |   6 +-
 crates/detect/src/lib.rs                   |   2 +-
 crates/detect/src/strings.rs               |   3 +-
 crates/detect/tests/portable.rs            |  11 +-
 crates/netmon-helper/src/main.rs           |   1 -
 crates/netmon/src/backends/helper.rs       |   8 +-
 crates/netmon/src/backends/pcap_backend.rs |  21 +-
 crates/netmon/src/engine/mod.rs            |  51 ++++-
 crates/netmon/src/engine/tls.rs            |  30 ++-
 crates/netmon/src/lib.rs                   |   2 +-
 crates/netmon/tests/capture_loopback.rs    |   3 +-
 crates/netmon/tests/handshake.rs           |  15 +-
 crates/pkg/src/ar.rs                       |   6 +-
 crates/pkg/src/cache.rs                    |  10 +-
 crates/pkg/src/cpio.rs                     |   4 +-
 crates/pkg/src/decompress.rs               |   6 +-
 crates/pkg/src/lib.rs                      |  19 +-
 crates/pkg/src/rpm.rs                      |  13 +-
 crates/pkg/src/squashfs.rs                 |   6 +-
 crates/pkg/src/tar.rs                      |  11 +-
 crates/pkg/tests/real_packages.rs          |   9 +-
 crates/rust-audit/src/extract.rs           |   5 +-
 crates/scan/src/linux.rs                   |  15 +-
 crates/scan/src/linux/sandboxed.rs         |  36 +++-
 crates/vfs/src/platform.rs                 |   6 +-
 src-tauri/src/commands.rs                  |  34 ++--
 src-tauri/src/crypto_store.rs              |  11 +-
 src-tauri/src/helper_mac.rs                |   3 +-
 src-tauri/src/journal.rs                   |   3 +-
 src-tauri/src/lib.rs                       |  32 ++-
 src-tauri/src/reporting.rs                 |  14 +-
 40 files changed, 604 insertions(+), 215 deletions(-)

diff --git a/crates/achilles-wasm/src/bindings.rs b/crates/achilles-wasm/src/bindings.rs
index 2333a5e..30d9606 100644
--- a/crates/achilles-wasm/src/bindings.rs
+++ b/crates/achilles-wasm/src/bindings.rs
@@ -281,7 +281,12 @@ impl pkg::Sink for TreeSink<'_> {
         Ok(())
     }
 
-    fn file(&mut self, path: &std::path::Path, data: Vec, mode: u32) -> Result<(), pkg::PkgError> {
+    fn file(
+        &mut self,
+        path: &std::path::Path,
+        data: Vec,
+        mode: u32,
+    ) -> Result<(), pkg::PkgError> {
         self.0.insert_file_with_mode(path.to_path_buf(), data, mode);
         Ok(())
     }
@@ -291,7 +296,8 @@ impl pkg::Sink for TreeSink<'_> {
         path: &std::path::Path,
         target: &std::path::Path,
     ) -> Result<(), pkg::PkgError> {
-        self.0.insert_symlink(path.to_path_buf(), target.to_path_buf());
+        self.0
+            .insert_symlink(path.to_path_buf(), target.to_path_buf());
         Ok(())
     }
 }
diff --git a/crates/achilles-wasm/tests/upload.rs b/crates/achilles-wasm/tests/upload.rs
index dcb68aa..29b36a6 100644
--- a/crates/achilles-wasm/tests/upload.rs
+++ b/crates/achilles-wasm/tests/upload.rs
@@ -124,7 +124,10 @@ fn treats_a_picked_bundle_as_the_app() {
 #[test]
 fn finds_a_bundle_nested_below_the_picked_root() {
     let base = tempdir("find-nested");
-    write(&base.join("Apps/Signal.app/Contents/Info.plist"), b"");
+    write(
+        &base.join("Apps/Signal.app/Contents/Info.plist"),
+        b"",
+    );
 
     let app = find_app(&base, Platform::Macos).expect("nested bundle should be found");
     assert_eq!(app.root, base.join("Apps/Signal.app"));
@@ -287,7 +290,10 @@ fn payload_search_prefers_the_application_over_the_usr_bin_launcher() {
     write(&base.join("usr/bin/foo"), &elf(2048));
     write(&base.join("opt/Foo/foo"), &elf(200_000));
     write(&base.join("opt/Foo/libffmpeg.so"), &elf(400_000));
-    write(&base.join("usr/share/applications/foo.desktop"), b"[Desktop Entry]");
+    write(
+        &base.join("usr/share/applications/foo.desktop"),
+        b"[Desktop Entry]",
+    );
 
     let app = find_app_in_payload(&base).expect("app should be found");
     assert_eq!(app.root, base.join("opt/Foo"));
diff --git a/crates/binmeta/src/lib.rs b/crates/binmeta/src/lib.rs
index 17e4c9a..cff3b62 100644
--- a/crates/binmeta/src/lib.rs
+++ b/crates/binmeta/src/lib.rs
@@ -110,7 +110,6 @@ pub fn inspect(path: &Path) -> Result {
     }
 }
 
-
 // --- Mach-O -------------------------------------------------------------
 
 fn mach_arch(macho: &goblin::mach::MachO) -> Arch {
@@ -186,7 +185,12 @@ fn mach_arch(macho: &goblin::mach::MachO) -> Arch {
         })
         .collect();
     // `libs[0]` is a "self" placeholder for the binary itself, not a dependency.
-    let names: Vec<&str> = macho.libs.iter().copied().filter(|l| *l != "self").collect();
+    let names: Vec<&str> = macho
+        .libs
+        .iter()
+        .copied()
+        .filter(|l| *l != "self")
+        .collect();
     let linked_libraries = if names.len() == versions.len() {
         names
             .iter()
@@ -286,7 +290,11 @@ fn elf_arch(elf: &goblin::elf::Elf) -> Arch {
                     || d.info.flags_1 & goblin::elf::dynamic::DF_1_NOW != 0
             })
             .unwrap_or(false);
-        flags.push(if bind_now { "full-RELRO".into() } else { "partial-RELRO".into() });
+        flags.push(if bind_now {
+            "full-RELRO".into()
+        } else {
+            "partial-RELRO".into()
+        });
     }
 
     let sections = elf
@@ -381,7 +389,12 @@ fn pe_arch(pe: &goblin::pe::PE) -> Arch {
 
     Arch {
         arch,
-        kind: if pe.is_lib { "shared-library" } else { "executable" }.into(),
+        kind: if pe.is_lib {
+            "shared-library"
+        } else {
+            "executable"
+        }
+        .into(),
         bits: if pe.is_64 { 64 } else { 32 },
         endianness: "little".into(),
         entry: Some(format!("0x{:x}", pe.entry)),
diff --git a/crates/cbom/src/aggregate.rs b/crates/cbom/src/aggregate.rs
index cf7853e..303e08d 100644
--- a/crates/cbom/src/aggregate.rs
+++ b/crates/cbom/src/aggregate.rs
@@ -68,7 +68,9 @@ pub(crate) fn build(app: AppRef, evidence: &[CryptoEvidence]) -> CryptoInventory
         let prov = ev.provenance();
         let loc = ev.location();
         match ev {
-            CryptoEvidence::Protocol { family, version, .. } => {
+            CryptoEvidence::Protocol {
+                family, version, ..
+            } => {
                 let c = normalize::protocol(*family, version.as_deref());
                 protocols.insert(upsert(&mut assets, &c, prov, loc));
             }
@@ -113,46 +115,54 @@ pub(crate) fn build(app: AppRef, evidence: &[CryptoEvidence]) -> CryptoInventory
             } => {
                 // A certificate asset plus links to its sig + key algorithms.
                 let mut algo_refs = Vec::new();
-                if let Some(s) = signature_algorithm.as_deref().and_then(normalize::named_algorithm) {
+                if let Some(s) = signature_algorithm
+                    .as_deref()
+                    .and_then(normalize::named_algorithm)
+                {
                     algo_refs.push(upsert(&mut assets, &s, prov, loc));
                 }
-                if let Some(k) = public_key_algorithm.as_deref().and_then(normalize::named_algorithm) {
+                if let Some(k) = public_key_algorithm
+                    .as_deref()
+                    .and_then(normalize::named_algorithm)
+                {
                     algo_refs.push(upsert(&mut assets, &k, prov, loc));
                 }
                 let cert_ref = format!(
                     "crypto/certificate/{}",
                     slug(subject.as_deref().or(issuer.as_deref()).unwrap_or("cert"))
                 );
-                let a = assets.entry(cert_ref.clone()).or_insert_with(|| CryptoAsset {
-                    bom_ref: cert_ref.clone(),
-                    asset_type: AssetType::Certificate,
-                    name: subject.clone().unwrap_or_else(|| "certificate".into()),
-                    oid: None,
-                    primitive: None,
-                    parameter: None,
-                    crypto_functions: vec![],
-                    assessment: if *self_signed {
-                        QuantumAssessment::Weak
-                    } else {
-                        QuantumAssessment::NotApplicable
-                    },
-                    nist_level: 0,
-                    deprecated: false,
-                    provenance: BTreeSet::new(),
-                    occurrences: 0,
-                    locations: BTreeSet::new(),
-                    protocol: None,
-                    certificate: Some(CertSummary {
-                        subject: subject.clone(),
-                        issuer: issuer.clone(),
-                        not_before: *not_before,
-                        not_after: *not_after,
-                        self_signed: *self_signed,
-                        signature_algorithm: signature_algorithm.clone(),
-                        public_key_algorithm: public_key_algorithm.clone(),
-                    }),
-                    library_version: None,
-                });
+                let a = assets
+                    .entry(cert_ref.clone())
+                    .or_insert_with(|| CryptoAsset {
+                        bom_ref: cert_ref.clone(),
+                        asset_type: AssetType::Certificate,
+                        name: subject.clone().unwrap_or_else(|| "certificate".into()),
+                        oid: None,
+                        primitive: None,
+                        parameter: None,
+                        crypto_functions: vec![],
+                        assessment: if *self_signed {
+                            QuantumAssessment::Weak
+                        } else {
+                            QuantumAssessment::NotApplicable
+                        },
+                        nist_level: 0,
+                        deprecated: false,
+                        provenance: BTreeSet::new(),
+                        occurrences: 0,
+                        locations: BTreeSet::new(),
+                        protocol: None,
+                        certificate: Some(CertSummary {
+                            subject: subject.clone(),
+                            issuer: issuer.clone(),
+                            not_before: *not_before,
+                            not_after: *not_after,
+                            self_signed: *self_signed,
+                            signature_algorithm: signature_algorithm.clone(),
+                            public_key_algorithm: public_key_algorithm.clone(),
+                        }),
+                        library_version: None,
+                    });
                 a.occurrences += 1;
                 a.provenance.insert(prov);
                 if let Some(l) = loc {
diff --git a/crates/cbom/src/cyclonedx.rs b/crates/cbom/src/cyclonedx.rs
index 98bcd5b..fa82602 100644
--- a/crates/cbom/src/cyclonedx.rs
+++ b/crates/cbom/src/cyclonedx.rs
@@ -66,8 +66,11 @@ fn protocol_component(a: &CryptoAsset) -> Value {
             props["version"] = json!(v);
         }
         if !info.cipher_suites.is_empty() {
-            props["cipherSuites"] =
-                json!(info.cipher_suites.iter().map(|n| json!({ "name": n })).collect::>());
+            props["cipherSuites"] = json!(info
+                .cipher_suites
+                .iter()
+                .map(|n| json!({ "name": n }))
+                .collect::>());
         }
     }
     json!({
diff --git a/crates/cbom/src/normalize.rs b/crates/cbom/src/normalize.rs
index bd8c0af..61ea8ac 100644
--- a/crates/cbom/src/normalize.rs
+++ b/crates/cbom/src/normalize.rs
@@ -31,7 +31,9 @@ fn algo(
     assessment: QuantumAssessment,
 ) -> Canon {
     let funcs: &[&str] = match primitive {
-        Primitive::BlockCipher | Primitive::StreamCipher | Primitive::Pke => &["encrypt", "decrypt"],
+        Primitive::BlockCipher | Primitive::StreamCipher | Primitive::Pke => {
+            &["encrypt", "decrypt"]
+        }
         Primitive::Hash => &["digest"],
         Primitive::Mac => &["digest"],
         Primitive::Signature => &["sign", "verify"],
@@ -59,22 +61,56 @@ fn algo(
 // --- primitive builders (each returns a fresh Canon) --------------------
 
 fn ecdhe() -> Canon {
-    algo("ecdhe", "ECDHE", Primitive::KeyAgree, None, QuantumAssessment::QuantumVulnerable)
+    algo(
+        "ecdhe",
+        "ECDHE",
+        Primitive::KeyAgree,
+        None,
+        QuantumAssessment::QuantumVulnerable,
+    )
 }
 fn rsa_kx() -> Canon {
-    algo("rsa-kex", "RSA (key transport)", Primitive::Pke, None, QuantumAssessment::QuantumVulnerable)
+    algo(
+        "rsa-kex",
+        "RSA (key transport)",
+        Primitive::Pke,
+        None,
+        QuantumAssessment::QuantumVulnerable,
+    )
 }
 fn rsa_sig() -> Canon {
-    algo("rsa", "RSA", Primitive::Signature, None, QuantumAssessment::QuantumVulnerable)
+    algo(
+        "rsa",
+        "RSA",
+        Primitive::Signature,
+        None,
+        QuantumAssessment::QuantumVulnerable,
+    )
 }
 fn ecdsa() -> Canon {
-    algo("ecdsa", "ECDSA", Primitive::Signature, None, QuantumAssessment::QuantumVulnerable)
+    algo(
+        "ecdsa",
+        "ECDSA",
+        Primitive::Signature,
+        None,
+        QuantumAssessment::QuantumVulnerable,
+    )
 }
 fn ed25519() -> Canon {
-    algo("ed25519", "Ed25519", Primitive::Signature, Some("Ed25519"), QuantumAssessment::QuantumVulnerable)
+    algo(
+        "ed25519",
+        "Ed25519",
+        Primitive::Signature,
+        Some("Ed25519"),
+        QuantumAssessment::QuantumVulnerable,
+    )
 }
 fn aes(bits: u32, mode: &str, strong: bool) -> Canon {
-    let a = if strong { QuantumAssessment::Strong } else { QuantumAssessment::Acceptable };
+    let a = if strong {
+        QuantumAssessment::Strong
+    } else {
+        QuantumAssessment::Acceptable
+    };
     algo(
         &format!("aes-{bits}-{}", mode.to_lowercase()),
         &format!("AES-{bits}-{mode}"),
@@ -93,20 +129,54 @@ fn chacha20() -> Canon {
     )
 }
 fn tripledes() -> Canon {
-    algo("3des", "3DES-EDE-CBC", Primitive::BlockCipher, Some("112"), QuantumAssessment::Weak)
+    algo(
+        "3des",
+        "3DES-EDE-CBC",
+        Primitive::BlockCipher,
+        Some("112"),
+        QuantumAssessment::Weak,
+    )
 }
 fn rc4() -> Canon {
-    algo("rc4", "RC4", Primitive::StreamCipher, Some("128"), QuantumAssessment::ClassicallyBroken)
+    algo(
+        "rc4",
+        "RC4",
+        Primitive::StreamCipher,
+        Some("128"),
+        QuantumAssessment::ClassicallyBroken,
+    )
 }
 fn sha(bits: u32) -> Canon {
-    let a = if bits >= 384 { QuantumAssessment::Strong } else { QuantumAssessment::Acceptable };
-    algo(&format!("sha{bits}"), &format!("SHA-{bits}"), Primitive::Hash, Some(&bits.to_string()), a)
+    let a = if bits >= 384 {
+        QuantumAssessment::Strong
+    } else {
+        QuantumAssessment::Acceptable
+    };
+    algo(
+        &format!("sha{bits}"),
+        &format!("SHA-{bits}"),
+        Primitive::Hash,
+        Some(&bits.to_string()),
+        a,
+    )
 }
 fn sha1() -> Canon {
-    algo("sha1", "SHA-1", Primitive::Hash, Some("160"), QuantumAssessment::ClassicallyBroken)
+    algo(
+        "sha1",
+        "SHA-1",
+        Primitive::Hash,
+        Some("160"),
+        QuantumAssessment::ClassicallyBroken,
+    )
 }
 fn md5() -> Canon {
-    algo("md5", "MD5", Primitive::Hash, Some("128"), QuantumAssessment::ClassicallyBroken)
+    algo(
+        "md5",
+        "MD5",
+        Primitive::Hash,
+        Some("128"),
+        QuantumAssessment::ClassicallyBroken,
+    )
 }
 fn ml_kem(param: &str) -> Canon {
     algo(
@@ -118,7 +188,13 @@ fn ml_kem(param: &str) -> Canon {
     )
 }
 fn ml_dsa(param: &str) -> Canon {
-    algo(&format!("ml-dsa-{param}"), &format!("ML-DSA ({param})"), Primitive::Signature, Some(param), QuantumAssessment::PostQuantum)
+    algo(
+        &format!("ml-dsa-{param}"),
+        &format!("ML-DSA ({param})"),
+        Primitive::Signature,
+        Some(param),
+        QuantumAssessment::PostQuantum,
+    )
 }
 
 // --- TLS cipher-suite registry (representative) -------------------------
@@ -127,20 +203,53 @@ fn ml_dsa(param: &str) -> Canon {
 pub(crate) fn cipher_suite(id: u16) -> Option<(String, Vec)> {
     let (name, components): (&str, Vec) = match id {
         // TLS 1.3 (AEAD + hash; key exchange & auth negotiated separately)
-        0x1301 => ("TLS_AES_128_GCM_SHA256", vec![aes(128, "GCM", false), sha(256)]),
-        0x1302 => ("TLS_AES_256_GCM_SHA384", vec![aes(256, "GCM", true), sha(384)]),
+        0x1301 => (
+            "TLS_AES_128_GCM_SHA256",
+            vec![aes(128, "GCM", false), sha(256)],
+        ),
+        0x1302 => (
+            "TLS_AES_256_GCM_SHA384",
+            vec![aes(256, "GCM", true), sha(384)],
+        ),
         0x1303 => ("TLS_CHACHA20_POLY1305_SHA256", vec![chacha20(), sha(256)]),
         // TLS 1.2 ECDHE-AEAD
-        0xC02B => ("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", vec![ecdhe(), ecdsa(), aes(128, "GCM", false), sha(256)]),
-        0xC02F => ("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", vec![ecdhe(), rsa_sig(), aes(128, "GCM", false), sha(256)]),
-        0xC02C => ("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", vec![ecdhe(), ecdsa(), aes(256, "GCM", true), sha(384)]),
-        0xC030 => ("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", vec![ecdhe(), rsa_sig(), aes(256, "GCM", true), sha(384)]),
-        0xCCA9 => ("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", vec![ecdhe(), ecdsa(), chacha20(), sha(256)]),
-        0xCCA8 => ("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", vec![ecdhe(), rsa_sig(), chacha20(), sha(256)]),
+        0xC02B => (
+            "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
+            vec![ecdhe(), ecdsa(), aes(128, "GCM", false), sha(256)],
+        ),
+        0xC02F => (
+            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
+            vec![ecdhe(), rsa_sig(), aes(128, "GCM", false), sha(256)],
+        ),
+        0xC02C => (
+            "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
+            vec![ecdhe(), ecdsa(), aes(256, "GCM", true), sha(384)],
+        ),
+        0xC030 => (
+            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
+            vec![ecdhe(), rsa_sig(), aes(256, "GCM", true), sha(384)],
+        ),
+        0xCCA9 => (
+            "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
+            vec![ecdhe(), ecdsa(), chacha20(), sha(256)],
+        ),
+        0xCCA8 => (
+            "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256",
+            vec![ecdhe(), rsa_sig(), chacha20(), sha(256)],
+        ),
         // Legacy / weak
-        0x009C => ("TLS_RSA_WITH_AES_128_GCM_SHA256", vec![rsa_kx(), aes(128, "GCM", false), sha(256)]),
-        0x002F => ("TLS_RSA_WITH_AES_128_CBC_SHA", vec![rsa_kx(), aes(128, "CBC", false), sha1()]),
-        0x000A => ("TLS_RSA_WITH_3DES_EDE_CBC_SHA", vec![rsa_kx(), tripledes(), sha1()]),
+        0x009C => (
+            "TLS_RSA_WITH_AES_128_GCM_SHA256",
+            vec![rsa_kx(), aes(128, "GCM", false), sha(256)],
+        ),
+        0x002F => (
+            "TLS_RSA_WITH_AES_128_CBC_SHA",
+            vec![rsa_kx(), aes(128, "CBC", false), sha1()],
+        ),
+        0x000A => (
+            "TLS_RSA_WITH_3DES_EDE_CBC_SHA",
+            vec![rsa_kx(), tripledes(), sha1()],
+        ),
         0x0005 => ("TLS_RSA_WITH_RC4_128_SHA", vec![rsa_kx(), rc4(), sha1()]),
         _ => return None,
     };
@@ -151,11 +260,41 @@ pub(crate) fn cipher_suite(id: u16) -> Option<(String, Vec)> {
 
 pub(crate) fn group(id: u16) -> Option {
     Some(match id {
-        0x0017 => algo("secp256r1", "ECDH secp256r1 (P-256)", Primitive::KeyAgree, Some("P-256"), QuantumAssessment::QuantumVulnerable),
-        0x0018 => algo("secp384r1", "ECDH secp384r1 (P-384)", Primitive::KeyAgree, Some("P-384"), QuantumAssessment::QuantumVulnerable),
-        0x001D => algo("x25519", "X25519", Primitive::KeyAgree, Some("X25519"), QuantumAssessment::QuantumVulnerable),
-        0x001E => algo("x448", "X448", Primitive::KeyAgree, Some("X448"), QuantumAssessment::QuantumVulnerable),
-        0x0100 => algo("ffdhe2048", "FFDHE-2048", Primitive::KeyAgree, Some("2048"), QuantumAssessment::QuantumVulnerable),
+        0x0017 => algo(
+            "secp256r1",
+            "ECDH secp256r1 (P-256)",
+            Primitive::KeyAgree,
+            Some("P-256"),
+            QuantumAssessment::QuantumVulnerable,
+        ),
+        0x0018 => algo(
+            "secp384r1",
+            "ECDH secp384r1 (P-384)",
+            Primitive::KeyAgree,
+            Some("P-384"),
+            QuantumAssessment::QuantumVulnerable,
+        ),
+        0x001D => algo(
+            "x25519",
+            "X25519",
+            Primitive::KeyAgree,
+            Some("X25519"),
+            QuantumAssessment::QuantumVulnerable,
+        ),
+        0x001E => algo(
+            "x448",
+            "X448",
+            Primitive::KeyAgree,
+            Some("X448"),
+            QuantumAssessment::QuantumVulnerable,
+        ),
+        0x0100 => algo(
+            "ffdhe2048",
+            "FFDHE-2048",
+            Primitive::KeyAgree,
+            Some("2048"),
+            QuantumAssessment::QuantumVulnerable,
+        ),
         // Hybrid PQC key exchange (RFC drafts / deployed in browsers).
         0x11EC | 0x6399 => {
             let mut c = ml_kem("ML-KEM-768");
@@ -173,18 +312,18 @@ pub(crate) fn group(id: u16) -> Option {
 
 pub(crate) fn signature_scheme(id: u16) -> Option {
     Some(match id {
-        0x0401 | 0x0501 | 0x0601 => rsa_sig(),                     // rsa_pkcs1_sha256/384/512
-        0x0804..=0x0806 => rsa_sig(),                              // rsa_pss_*
-        0x0403 => ecdsa(),                                          // ecdsa_secp256r1_sha256
-        0x0503 => ecdsa(),                                          // ecdsa_secp384r1_sha384
-        0x0807 => ed25519(),                                        // ed25519
+        0x0401 | 0x0501 | 0x0601 => rsa_sig(), // rsa_pkcs1_sha256/384/512
+        0x0804..=0x0806 => rsa_sig(),          // rsa_pss_*
+        0x0403 => ecdsa(),                     // ecdsa_secp256r1_sha256
+        0x0503 => ecdsa(),                     // ecdsa_secp384r1_sha384
+        0x0807 => ed25519(),                   // ed25519
         0x0201 => {
             let mut c = rsa_sig();
             c.assessment = QuantumAssessment::Weak; // rsa_pkcs1_sha1
             c.deprecated = true;
             c
         }
-        0x0904..=0x0906 => ml_dsa("ML-DSA-65"),                     // provisional ML-DSA code points
+        0x0904..=0x0906 => ml_dsa("ML-DSA-65"), // provisional ML-DSA code points
         _ => return None,
     })
 }
@@ -201,7 +340,13 @@ pub(crate) fn named_algorithm(raw: &str) -> Option {
         _ if has("ml-dsa") || has("dilithium") => ml_dsa("ML-DSA-65"),
         _ if has("ed25519") => ed25519(),
         _ if has("ecdsa") => ecdsa(),
-        _ if has("ecdh") => algo("ecdh", "ECDH", Primitive::KeyAgree, None, QuantumAssessment::QuantumVulnerable),
+        _ if has("ecdh") => algo(
+            "ecdh",
+            "ECDH",
+            Primitive::KeyAgree,
+            None,
+            QuantumAssessment::QuantumVulnerable,
+        ),
         _ if has("rsa") => rsa_sig(),
         _ if has("chacha") => chacha20(),
         _ if has("aes") && has("256") => aes(256, "GCM", true),
diff --git a/crates/cbom/src/staticscan.rs b/crates/cbom/src/staticscan.rs
index 222187f..88ba05b 100644
--- a/crates/cbom/src/staticscan.rs
+++ b/crates/cbom/src/staticscan.rs
@@ -43,7 +43,10 @@ const MARKERS: &[(&[u8], Marker)] = &[
     (b"EVP_aes_128_gcm", Marker::Algorithm("aes-128-gcm")),
     (b"EVP_aes_256", Marker::Algorithm("aes-256")),
     (b"EVP_aes_128", Marker::Algorithm("aes-128")),
-    (b"EVP_chacha20_poly1305", Marker::Algorithm("chacha20-poly1305")),
+    (
+        b"EVP_chacha20_poly1305",
+        Marker::Algorithm("chacha20-poly1305"),
+    ),
     (b"chacha20_poly1305", Marker::Algorithm("chacha20-poly1305")),
     (b"EVP_sha256", Marker::Algorithm("sha256")),
     (b"SHA256_Init", Marker::Algorithm("sha256")),
@@ -104,8 +107,10 @@ fn crypto_library_from_name(name: &str) -> Option<&'static str> {
 /// Group 1 = product, group 2 = version. Requiring the version disambiguates a
 /// real library from an incidental name mention.
 static VERSION_RE: LazyLock = LazyLock::new(|| {
-    Regex::new(r"(OpenSSL|LibreSSL|libsodium|mbed TLS|GnuTLS|wolfSSL)[ /]v?(\d+\.\d+(?:\.\d+)?[a-z]?)")
-        .unwrap()
+    Regex::new(
+        r"(OpenSSL|LibreSSL|libsodium|mbed TLS|GnuTLS|wolfSSL)[ /]v?(\d+\.\d+(?:\.\d+)?[a-z]?)",
+    )
+    .unwrap()
 });
 
 /// Canonical library name for a `VERSION_RE` product capture.
@@ -239,8 +244,9 @@ fn candidate_binaries(root: &Path) -> Vec {
                 continue;
             };
             let lower = name.to_ascii_lowercase();
-            let crypto_lib = (lower.ends_with(".dylib") || lower.ends_with(".so") || lower.ends_with(".dll"))
-                && crypto_library_from_name(&lower).is_some();
+            let crypto_lib =
+                (lower.ends_with(".dylib") || lower.ends_with(".so") || lower.ends_with(".dll"))
+                    && crypto_library_from_name(&lower).is_some();
             if crypto_lib || is_framework_main(&path, name) {
                 out.push(path);
             }
@@ -291,12 +297,12 @@ mod tests {
             matches!(e, CryptoEvidence::Library { name, version, .. }
                 if name == "OpenSSL" && version.as_deref() == Some("3.3.1"))
         });
-        let has_aes = ev.iter().any(|e| {
-            matches!(e, CryptoEvidence::Algorithm { name, .. } if name == "aes-256-gcm")
-        });
-        let has_ecdsa = ev.iter().any(|e| {
-            matches!(e, CryptoEvidence::Algorithm { name, .. } if name == "ecdsa")
-        });
+        let has_aes = ev
+            .iter()
+            .any(|e| matches!(e, CryptoEvidence::Algorithm { name, .. } if name == "aes-256-gcm"));
+        let has_ecdsa = ev
+            .iter()
+            .any(|e| matches!(e, CryptoEvidence::Algorithm { name, .. } if name == "ecdsa"));
         assert!(has_lib, "OpenSSL 3.3.1 library evidence");
         assert!(has_aes, "AES-256-GCM algorithm evidence");
         assert!(has_ecdsa, "ECDSA algorithm evidence");
diff --git a/crates/cbom/tests/inventory.rs b/crates/cbom/tests/inventory.rs
index a73f1d3..61a44d7 100644
--- a/crates/cbom/tests/inventory.rs
+++ b/crates/cbom/tests/inventory.rs
@@ -59,11 +59,23 @@ fn cipher_suite_decomposes_into_classified_primitives() {
     }
 
     // ECDHE + RSA are quantum-vulnerable (NIST level 0); AES-128 is acceptable.
-    assert_eq!(by_ref("crypto/algorithm/ecdhe").unwrap().assessment, QuantumAssessment::QuantumVulnerable);
+    assert_eq!(
+        by_ref("crypto/algorithm/ecdhe").unwrap().assessment,
+        QuantumAssessment::QuantumVulnerable
+    );
     assert_eq!(by_ref("crypto/algorithm/ecdhe").unwrap().nist_level, 0);
-    assert_eq!(by_ref("crypto/algorithm/rsa").unwrap().assessment, QuantumAssessment::QuantumVulnerable);
-    assert_eq!(by_ref("crypto/algorithm/aes-128-gcm").unwrap().assessment, QuantumAssessment::Acceptable);
-    assert_eq!(by_ref("crypto/algorithm/aes-128-gcm").unwrap().nist_level, 1);
+    assert_eq!(
+        by_ref("crypto/algorithm/rsa").unwrap().assessment,
+        QuantumAssessment::QuantumVulnerable
+    );
+    assert_eq!(
+        by_ref("crypto/algorithm/aes-128-gcm").unwrap().assessment,
+        QuantumAssessment::Acceptable
+    );
+    assert_eq!(
+        by_ref("crypto/algorithm/aes-128-gcm").unwrap().nist_level,
+        1
+    );
 
     // x25519 group + TLS 1.2 protocol + OpenSSL library are all present.
     assert!(by_ref("crypto/algorithm/x25519").is_some());
@@ -98,7 +110,10 @@ fn exports_valid_cyclonedx_cbom() {
         .expect("ecdhe component");
     assert_eq!(ecdhe["type"], "cryptographic-asset");
     assert_eq!(ecdhe["cryptoProperties"]["assetType"], "algorithm");
-    assert_eq!(ecdhe["cryptoProperties"]["algorithmProperties"]["primitive"], "key-agree");
+    assert_eq!(
+        ecdhe["cryptoProperties"]["algorithmProperties"]["primitive"],
+        "key-agree"
+    );
     assert_eq!(
         ecdhe["cryptoProperties"]["algorithmProperties"]["nistQuantumSecurityLevel"],
         0
@@ -109,7 +124,10 @@ fn exports_valid_cyclonedx_cbom() {
         .iter()
         .find(|c| c["cryptoProperties"]["assetType"] == "protocol")
         .expect("protocol component");
-    assert_eq!(proto["cryptoProperties"]["protocolProperties"]["type"], "tls");
+    assert_eq!(
+        proto["cryptoProperties"]["protocolProperties"]["type"],
+        "tls"
+    );
 
     // OpenSSL is a library component (not a crypto-asset).
     let lib = comps
@@ -128,7 +146,10 @@ fn exports_valid_cyclonedx_cbom() {
         .unwrap()
         .iter()
         .any(|r| r == "crypto/protocol/tls-1.2"));
-    let proto_dep = deps.iter().find(|d| d["ref"] == "crypto/protocol/tls-1.2").unwrap();
+    let proto_dep = deps
+        .iter()
+        .find(|d| d["ref"] == "crypto/protocol/tls-1.2")
+        .unwrap();
     assert!(proto_dep["dependsOn"]
         .as_array()
         .unwrap()
diff --git a/crates/cve/src/lib.rs b/crates/cve/src/lib.rs
index bc329ca..013129f 100644
--- a/crates/cve/src/lib.rs
+++ b/crates/cve/src/lib.rs
@@ -312,7 +312,11 @@ impl Client_ {
                 (Bucket::Flutter, "flutter", versions.flutter.as_ref()),
                 (Bucket::Qt, "qt", versions.qt.as_ref()),
                 (Bucket::Nwjs, "nwjs", versions.nwjs.as_ref()),
-                (Bucket::ReactNative, "react_native", versions.react_native.as_ref()),
+                (
+                    Bucket::ReactNative,
+                    "react_native",
+                    versions.react_native.as_ref(),
+                ),
                 (Bucket::Wails, "wails", versions.wails.as_ref()),
                 (Bucket::Sciter, "sciter", versions.sciter.as_ref()),
                 (Bucket::Webkit, "webkit", versions.webkit.as_ref()),
@@ -436,7 +440,13 @@ impl Client_ {
                     "nvd",
                     "deno",
                     v,
-                    sources::nvd::lookup_cpe_with_key(http, "deno", "deno", v, s.nvd.api_key.as_deref())
+                    sources::nvd::lookup_cpe_with_key(
+                        http,
+                        "deno",
+                        "deno",
+                        v,
+                        s.nvd.api_key.as_deref()
+                    )
                 );
             }
             if s.euvd.enabled {
@@ -964,7 +974,8 @@ fn current_year() -> Option {
     let mut year = 1970u32;
     let mut remaining = days;
     loop {
-        let leap = (year.is_multiple_of(4) && !year.is_multiple_of(100)) || year.is_multiple_of(400);
+        let leap =
+            (year.is_multiple_of(4) && !year.is_multiple_of(100)) || year.is_multiple_of(400);
         let in_year = if leap { 366 } else { 365 };
         if remaining < in_year {
             return Some(year);
diff --git a/crates/cve/src/sources/snapshot.rs b/crates/cve/src/sources/snapshot.rs
index 32560e8..37a1d04 100644
--- a/crates/cve/src/sources/snapshot.rs
+++ b/crates/cve/src/sources/snapshot.rs
@@ -42,7 +42,11 @@ pub struct Snapshot {
 /// build, which has no cache dir — see the wasm `load` below.
 #[cfg(not(target_arch = "wasm32"))]
 fn snapshot_path() -> Option {
-    Some(dirs::cache_dir()?.join("achilles").join("vdb-snapshot.json"))
+    Some(
+        dirs::cache_dir()?
+            .join("achilles")
+            .join("vdb-snapshot.json"),
+    )
 }
 
 /// Load the snapshot from disk, or `None` if it's absent/unreadable/garbage.
diff --git a/crates/detect/src/lib.rs b/crates/detect/src/lib.rs
index fe4c8f2..6486c2b 100644
--- a/crates/detect/src/lib.rs
+++ b/crates/detect/src/lib.rs
@@ -44,8 +44,8 @@ mod system_webview;
 mod tauri;
 mod wails;
 
-pub use app::{is_app_binary, payload_executable, payload_name, DiscoveredApp};
 use app::Layout;
+pub use app::{is_app_binary, payload_executable, payload_name, DiscoveredApp};
 pub use bundle::BundleInfo;
 
 /// Read and parse a property list through [`vfs`] (so it works against the real
diff --git a/crates/detect/src/strings.rs b/crates/detect/src/strings.rs
index 41fefdd..e058ea2 100644
--- a/crates/detect/src/strings.rs
+++ b/crates/detect/src/strings.rs
@@ -57,8 +57,7 @@ pub fn scan_electron_version(binary_path: &Path) -> std::io::Result =
-    LazyLock::new(|| Regex::new(r"Deno/(\d+\.\d+\.\d+)").unwrap());
+static DENO_RE: LazyLock = LazyLock::new(|| Regex::new(r"Deno/(\d+\.\d+\.\d+)").unwrap());
 
 /// Scan a Tauri main binary for the Tauri crate version.
 pub fn scan_tauri_version(binary_path: &Path) -> std::io::Result> {
diff --git a/crates/detect/tests/portable.rs b/crates/detect/tests/portable.rs
index 253e675..e8eab3f 100644
--- a/crates/detect/tests/portable.rs
+++ b/crates/detect/tests/portable.rs
@@ -92,10 +92,15 @@ fn an_electron_appimage_is_expanded_and_detected() {
     // the payload search picks the app out of a whole tree, so it checks that a
     // candidate really is a binary rather than a script or a data file.
     let mut binary = b"\x7fELF".to_vec();
-    binary
-        .extend_from_slice(b"...Chrome/120.0.6099.109 ...Electron/28.1.0 ...node-v18.18.2/node.tar.gz...");
+    binary.extend_from_slice(
+        b"...Chrome/120.0.6099.109 ...Electron/28.1.0 ...node-v18.18.2/node.tar.gz...",
+    );
     fs::write(payload.join("electron-sample"), &binary).unwrap();
-    fs::write(payload.join("AppRun"), b"#!/bin/sh\nexec ./electron-sample\n").unwrap();
+    fs::write(
+        payload.join("AppRun"),
+        b"#!/bin/sh\nexec ./electron-sample\n",
+    )
+    .unwrap();
 
     let image = base.join("payload.squashfs");
     let built = Command::new("mksquashfs")
diff --git a/crates/netmon-helper/src/main.rs b/crates/netmon-helper/src/main.rs
index bd64ed5..f8e17e5 100644
--- a/crates/netmon-helper/src/main.rs
+++ b/crates/netmon-helper/src/main.rs
@@ -57,7 +57,6 @@ async fn main() {
 async fn serve(stream: tokio::net::UnixStream) {
     use netmon::source::{CapturedEvent, PidFilter};
     use netmon::wire;
-    
 
     let (mut rd, mut wr) = stream.into_split();
 
diff --git a/crates/netmon/src/backends/helper.rs b/crates/netmon/src/backends/helper.rs
index d6174c1..7c2cfc6 100644
--- a/crates/netmon/src/backends/helper.rs
+++ b/crates/netmon/src/backends/helper.rs
@@ -9,9 +9,7 @@ use tokio::net::UnixStream;
 use tokio::sync::mpsc;
 use tokio_util::sync::CancellationToken;
 
-use crate::source::{
-    CaptureError, CaptureHandle, CaptureSource, CapturedEvent, PidFilter,
-};
+use crate::source::{CaptureError, CaptureHandle, CaptureSource, CapturedEvent, PidFilter};
 use crate::wire;
 
 pub struct HelperSource;
@@ -28,7 +26,9 @@ impl CaptureSource for HelperSource {
     ) -> Result<(mpsc::Receiver, CaptureHandle), CaptureError> {
         let stream = UnixStream::connect(wire::HELPER_SOCKET_PATH)
             .await
-            .map_err(|e| CaptureError::Unavailable(format!("privileged helper not reachable: {e}")))?;
+            .map_err(|e| {
+                CaptureError::Unavailable(format!("privileged helper not reachable: {e}"))
+            })?;
         let (mut rd, mut wr) = stream.into_split();
 
         // Tell the helper which process to capture.
diff --git a/crates/netmon/src/backends/pcap_backend.rs b/crates/netmon/src/backends/pcap_backend.rs
index 5c733e6..9b93a08 100644
--- a/crates/netmon/src/backends/pcap_backend.rs
+++ b/crates/netmon/src/backends/pcap_backend.rs
@@ -102,11 +102,16 @@ const DLT_PKTAP_VALUES: [i32; 2] = [149, 258];
 // invoke it on the raw handle. The symbol lives in the libpcap the crate links.
 #[cfg(target_os = "macos")]
 extern "C" {
-    fn pcap_set_want_pktap(p: *mut std::ffi::c_void, want: std::os::raw::c_int)
-        -> std::os::raw::c_int;
+    fn pcap_set_want_pktap(
+        p: *mut std::ffi::c_void,
+        want: std::os::raw::c_int,
+    ) -> std::os::raw::c_int;
 }
 
-fn open(device: Option<&str>, want_pktap: bool) -> Result, pcap::Error> {
+fn open(
+    device: Option<&str>,
+    want_pktap: bool,
+) -> Result, pcap::Error> {
     let inactive = match device {
         Some(d) => pcap::Capture::from_device(d)?,
         None => {
@@ -301,11 +306,11 @@ fn run_loop(
 
 fn map_datalink(dlt: pcap::Linktype) -> Option {
     match dlt.0 {
-        1 => Some(LinkType::Ethernet),      // DLT_EN10MB
-        0 | 108 => Some(LinkType::Null),    // DLT_NULL / DLT_LOOP (BSD loopback, utun/VPN)
-        12 | 14 => Some(LinkType::RawIp),   // DLT_RAW
-        113 => Some(LinkType::LinuxSll),    // DLT_LINUX_SLL
-        _ => None,                          // other exotic link types — skipped for now
+        1 => Some(LinkType::Ethernet),    // DLT_EN10MB
+        0 | 108 => Some(LinkType::Null),  // DLT_NULL / DLT_LOOP (BSD loopback, utun/VPN)
+        12 | 14 => Some(LinkType::RawIp), // DLT_RAW
+        113 => Some(LinkType::LinuxSll),  // DLT_LINUX_SLL
+        _ => None,                        // other exotic link types — skipped for now
     }
 }
 
diff --git a/crates/netmon/src/engine/mod.rs b/crates/netmon/src/engine/mod.rs
index 78bccd0..7036260 100644
--- a/crates/netmon/src/engine/mod.rs
+++ b/crates/netmon/src/engine/mod.rs
@@ -27,7 +27,12 @@ pub struct Session {
 }
 
 impl Session {
-    pub fn new(session_id: String, target: TargetProcess, backend_id: String, started_at: u64) -> Self {
+    pub fn new(
+        session_id: String,
+        target: TargetProcess,
+        backend_id: String,
+        started_at: u64,
+    ) -> Self {
         Self {
             session_id,
             target,
@@ -46,11 +51,21 @@ impl Session {
     pub fn ingest(&mut self, ev: CapturedEvent) -> Vec {
         match ev {
             CapturedEvent::StreamData {
-                key, dir, bytes, at, ..
+                key,
+                dir,
+                bytes,
+                at,
+                ..
             } => {
                 self.last_at = at.max(self.last_at);
                 let dest = key.remote.to_string();
-                let is_new = self.touch_destination(&dest, key.remote.ip().to_string(), key.remote.port(), bytes.len() as u64, at);
+                let is_new = self.touch_destination(
+                    &dest,
+                    key.remote.ip().to_string(),
+                    key.remote.port(),
+                    bytes.len() as u64,
+                    at,
+                );
                 let mut out = self.new_dest_delta(&dest, is_new);
                 out.extend(self.handle_stream(&dest, dir, &bytes, at));
                 out
@@ -59,7 +74,13 @@ impl Session {
                 self.last_at = at.max(self.last_at);
                 self.flow_count += 1;
                 let dest = key.remote.to_string();
-                self.touch_destination(&dest, key.remote.ip().to_string(), key.remote.port(), 0, at);
+                self.touch_destination(
+                    &dest,
+                    key.remote.ip().to_string(),
+                    key.remote.port(),
+                    0,
+                    at,
+                );
                 vec![SessionDelta::Destination(self.destinations[&dest].clone())]
             }
             CapturedEvent::FlowClosed { .. } => vec![],
@@ -121,7 +142,13 @@ impl Session {
         }
     }
 
-    fn handle_stream(&mut self, dest: &str, dir: Direction, bytes: &[u8], _at: u64) -> Vec {
+    fn handle_stream(
+        &mut self,
+        dest: &str,
+        dir: Direction,
+        bytes: &[u8],
+        _at: u64,
+    ) -> Vec {
         let mut out = Vec::new();
         match tls::parse_handshake(bytes) {
             Some(tls::Handshake::Client(ch)) if dir == Direction::Outbound => {
@@ -129,7 +156,10 @@ impl Session {
                 let offered_versions: Vec = if ch.supported_versions.is_empty() {
                     tls::version_str(ch.legacy_version).into_iter().collect()
                 } else {
-                    ch.supported_versions.iter().filter_map(|v| tls::version_str(*v)).collect()
+                    ch.supported_versions
+                        .iter()
+                        .filter_map(|v| tls::version_str(*v))
+                        .collect()
                 };
                 let hs = TlsHandshake {
                     destination: dest.to_string(),
@@ -152,7 +182,9 @@ impl Session {
                         d.hostname.get_or_insert_with(|| sni.clone());
                     }
                 }
-                self.hs_by_dest.entry(dest.to_string()).or_insert(self.handshakes.len());
+                self.hs_by_dest
+                    .entry(dest.to_string())
+                    .or_insert(self.handshakes.len());
                 self.handshakes.push(hs.clone());
                 if let Some(d) = self.destinations.get(dest) {
                     out.push(SessionDelta::Destination(d.clone()));
@@ -163,7 +195,10 @@ impl Session {
                 if let Some(&idx) = self.hs_by_dest.get(dest) {
                     let hs = &mut self.handshakes[idx];
                     hs.cipher_suite_selected = Some(sh.cipher);
-                    let neg = sh.supported_version.or(Some(sh.legacy_version)).and_then(tls::version_str);
+                    let neg = sh
+                        .supported_version
+                        .or(Some(sh.legacy_version))
+                        .and_then(tls::version_str);
                     hs.negotiated_version = neg;
                     // TLS 1.3 encrypts the cert — mark that the record is partial
                     // (no certificate observable) so the UI can explain it.
diff --git a/crates/netmon/src/engine/tls.rs b/crates/netmon/src/engine/tls.rs
index 856cb07..ff7cc0e 100644
--- a/crates/netmon/src/engine/tls.rs
+++ b/crates/netmon/src/engine/tls.rs
@@ -61,7 +61,12 @@ impl<'a> Reader<'a> {
         if self.remaining() < 3 {
             return None;
         }
-        let v = u32::from_be_bytes([0, self.b[self.pos], self.b[self.pos + 1], self.b[self.pos + 2]]);
+        let v = u32::from_be_bytes([
+            0,
+            self.b[self.pos],
+            self.b[self.pos + 1],
+            self.b[self.pos + 2],
+        ]);
         self.pos += 3;
         Some(v)
     }
@@ -140,7 +145,9 @@ fn parse_extensions(ext: &[u8], ch: &mut ClientHello) {
     while r.remaining() >= 4 {
         let Some(ext_type) = r.u16() else { break };
         let Some(len) = r.u16() else { break };
-        let Some(body) = r.take(len as usize) else { break };
+        let Some(body) = r.take(len as usize) else {
+            break;
+        };
         if !is_grease(ext_type) {
             ch.ext_types.push(ext_type);
         }
@@ -165,7 +172,9 @@ fn parse_u16_list(body: &[u8], strip_grease: bool) -> Vec {
     let Some(list) = r.take(list_len as usize) else {
         return Vec::new();
     };
-    list.as_chunks::<2>().0.iter()
+    list.as_chunks::<2>()
+        .0
+        .iter()
         .map(|p| u16::from_be_bytes([p[0], p[1]]))
         .filter(|v| !strip_grease || !is_grease(*v))
         .collect()
@@ -180,7 +189,9 @@ fn parse_u16_list_u8len(body: &[u8]) -> Vec {
     let Some(list) = r.take(list_len as usize) else {
         return Vec::new();
     };
-    list.as_chunks::<2>().0.iter()
+    list.as_chunks::<2>()
+        .0
+        .iter()
         .map(|p| u16::from_be_bytes([p[0], p[1]]))
         .filter(|v| !is_grease(*v))
         .collect()
@@ -235,7 +246,9 @@ fn parse_server_hello(b: &[u8]) -> Option {
         while er.remaining() >= 4 {
             let Some(t) = er.u16() else { break };
             let Some(len) = er.u16() else { break };
-            let Some(body) = er.take(len as usize) else { break };
+            let Some(body) = er.take(len as usize) else {
+                break;
+            };
             if t == 0x002b && body.len() >= 2 {
                 sh.supported_version = Some(u16::from_be_bytes([body[0], body[1]]));
             }
@@ -246,7 +259,12 @@ fn parse_server_hello(b: &[u8]) -> Option {
 
 /// Compute the JA3 fingerprint (raw decimal string + md5 hex) from a ClientHello.
 pub fn ja3(ch: &ClientHello) -> (String, String) {
-    let join = |v: &[u16]| v.iter().map(|x| x.to_string()).collect::>().join("-");
+    let join = |v: &[u16]| {
+        v.iter()
+            .map(|x| x.to_string())
+            .collect::>()
+            .join("-")
+    };
     let point_fmts = ch
         .point_formats
         .iter()
diff --git a/crates/netmon/src/lib.rs b/crates/netmon/src/lib.rs
index 1fa9911..eaf489f 100644
--- a/crates/netmon/src/lib.rs
+++ b/crates/netmon/src/lib.rs
@@ -15,9 +15,9 @@ pub mod model;
 pub mod source;
 pub mod wire;
 
-pub use backends::{capture_available, default_source, helper_reachable, list_processes};
 #[cfg(target_os = "macos")]
 pub use backends::direct_capture_source;
+pub use backends::{capture_available, default_source, helper_reachable, list_processes};
 pub use engine::Session;
 pub use model::{
     Destination, L7Kind, RunningProcess, SessionDelta, SessionMeta, SessionReport, TargetProcess,
diff --git a/crates/netmon/tests/capture_loopback.rs b/crates/netmon/tests/capture_loopback.rs
index 40ef7aa..60c9ef2 100644
--- a/crates/netmon/tests/capture_loopback.rs
+++ b/crates/netmon/tests/capture_loopback.rs
@@ -63,7 +63,8 @@ fn captures_our_own_loopback_clienthello() {
     thread::sleep(Duration::from_millis(300));
     {
         let mut c = TcpStream::connect(("127.0.0.1", PORT)).expect("connect");
-        c.write_all(&client_hello_record()).expect("send ClientHello");
+        c.write_all(&client_hello_record())
+            .expect("send ClientHello");
         c.flush().ok();
         // Hold the socket open briefly so the segment flushes before FIN.
         thread::sleep(Duration::from_millis(100));
diff --git a/crates/netmon/tests/handshake.rs b/crates/netmon/tests/handshake.rs
index 162ed92..c1492b7 100644
--- a/crates/netmon/tests/handshake.rs
+++ b/crates/netmon/tests/handshake.rs
@@ -51,9 +51,18 @@ fn client_hello_yields_handshake_and_cbom() {
         },
         &evidence,
     );
-    assert!(inv.assets.iter().any(|a| a.bom_ref == "crypto/algorithm/ecdhe"));
-    assert!(inv.assets.iter().any(|a| a.bom_ref == "crypto/algorithm/x25519"));
-    assert!(inv.assets.iter().any(|a| a.bom_ref == "crypto/algorithm/aes-128-gcm"));
+    assert!(inv
+        .assets
+        .iter()
+        .any(|a| a.bom_ref == "crypto/algorithm/ecdhe"));
+    assert!(inv
+        .assets
+        .iter()
+        .any(|a| a.bom_ref == "crypto/algorithm/x25519"));
+    assert!(inv
+        .assets
+        .iter()
+        .any(|a| a.bom_ref == "crypto/algorithm/aes-128-gcm"));
     assert_eq!(inv.readiness.grade, "vulnerable"); // ECDHE/RSA/x25519 present
 }
 
diff --git a/crates/pkg/src/ar.rs b/crates/pkg/src/ar.rs
index 07983af..b439c0c 100644
--- a/crates/pkg/src/ar.rs
+++ b/crates/pkg/src/ar.rs
@@ -66,7 +66,11 @@ fn members(bytes: &[u8]) -> impl Iterator> {
             // GNU appends `/` to member names to allow trailing spaces.
             .trim_end_matches('/')
             .to_string();
-        let size: usize = std::str::from_utf8(&header[48..58]).ok()?.trim().parse().ok()?;
+        let size: usize = std::str::from_utf8(&header[48..58])
+            .ok()?
+            .trim()
+            .parse()
+            .ok()?;
         let start = pos + HEADER_LEN;
         let data = bytes.get(start..start.checked_add(size)?)?;
         // Members are padded to an even offset.
diff --git a/crates/pkg/src/cache.rs b/crates/pkg/src/cache.rs
index d4b354e..6167c87 100644
--- a/crates/pkg/src/cache.rs
+++ b/crates/pkg/src/cache.rs
@@ -37,7 +37,10 @@ pub fn extract_cached_in(file: &Path, cache_root: &Path) -> Result sink.dir(&path)?,
             S_IFLNK => {
-                let target = String::from_utf8_lossy(data).trim_end_matches('\0').to_string();
+                let target = String::from_utf8_lossy(data)
+                    .trim_end_matches('\0')
+                    .to_string();
                 sink.symlink(&path, &link_target(base, &target))?;
             }
             S_IFREG => {
diff --git a/crates/pkg/src/decompress.rs b/crates/pkg/src/decompress.rs
index 964a6ae..d3d7f83 100644
--- a/crates/pkg/src/decompress.rs
+++ b/crates/pkg/src/decompress.rs
@@ -69,7 +69,11 @@ impl Codec {
 /// `expected` is the output size when the container knows it (squashfs blocks
 /// do). It sizes the buffer up front, and for [`Codec::Lz4Block`] — a raw block
 /// with no framing — it is *required*, since the format carries no length.
-pub fn decompress(codec: Codec, input: &[u8], expected: Option) -> Result, PkgError> {
+pub fn decompress(
+    codec: Codec,
+    input: &[u8],
+    expected: Option,
+) -> Result, PkgError> {
     let mut out = Vec::with_capacity(expected.unwrap_or(input.len() * 3).min(64 << 20));
     match codec {
         Codec::None => out.extend_from_slice(input),
diff --git a/crates/pkg/src/lib.rs b/crates/pkg/src/lib.rs
index b475d63..0b4ee0e 100644
--- a/crates/pkg/src/lib.rs
+++ b/crates/pkg/src/lib.rs
@@ -255,8 +255,18 @@ pub fn sniff(bytes: &[u8], filename: &str) -> Option {
 /// True for the tarball spellings that actually appear on download pages.
 fn is_tarball_name(lower: &str) -> bool {
     const SUFFIXES: &[&str] = &[
-        ".tar", ".tar.gz", ".tgz", ".tar.xz", ".txz", ".tar.bz2", ".tbz2", ".tbz", ".tar.zst",
-        ".tzst", ".tar.lz4", ".tar.lzma",
+        ".tar",
+        ".tar.gz",
+        ".tgz",
+        ".tar.xz",
+        ".txz",
+        ".tar.bz2",
+        ".tbz2",
+        ".tbz",
+        ".tar.zst",
+        ".tzst",
+        ".tar.lz4",
+        ".tar.lzma",
     ];
     SUFFIXES.iter().any(|s| lower.ends_with(s))
 }
@@ -400,6 +410,9 @@ mod tests {
             link_target(base, "/usr/lib/libfoo.so"),
             Path::new("/scan/usr/lib/libfoo.so")
         );
-        assert_eq!(link_target(base, "../lib/libfoo.so"), Path::new("../lib/libfoo.so"));
+        assert_eq!(
+            link_target(base, "../lib/libfoo.so"),
+            Path::new("../lib/libfoo.so")
+        );
     }
 }
diff --git a/crates/pkg/src/rpm.rs b/crates/pkg/src/rpm.rs
index 335f413..523252b 100644
--- a/crates/pkg/src/rpm.rs
+++ b/crates/pkg/src/rpm.rs
@@ -95,7 +95,10 @@ impl Header {
         let store = index + count * INDEX_ENTRY;
         let end = store + store_len;
         if end > bytes.len() {
-            return Err(PkgError::Malformed("rpm", "header runs past end of file".into()));
+            return Err(PkgError::Malformed(
+                "rpm",
+                "header runs past end of file".into(),
+            ));
         }
         Ok(Header {
             index,
@@ -108,7 +111,8 @@ impl Header {
     /// The NUL-terminated string stored for `tag`, if present.
     fn string(&self, bytes: &[u8], tag: u32) -> Option {
         for i in 0..self.count {
-            let entry = bytes.get(self.index + i * INDEX_ENTRY..self.index + (i + 1) * INDEX_ENTRY)?;
+            let entry =
+                bytes.get(self.index + i * INDEX_ENTRY..self.index + (i + 1) * INDEX_ENTRY)?;
             if be32(&entry[0..4]) != tag {
                 continue;
             }
@@ -190,6 +194,9 @@ mod tests {
     #[test]
     fn a_non_cpio_payload_is_reported_rather_than_misparsed() {
         let rpm = build(&[(TAG_PAYLOADFORMAT, "drpm")], b"delta");
-        assert!(matches!(super::payload(&rpm), Err(PkgError::Unsupported(_))));
+        assert!(matches!(
+            super::payload(&rpm),
+            Err(PkgError::Unsupported(_))
+        ));
     }
 }
diff --git a/crates/pkg/src/squashfs.rs b/crates/pkg/src/squashfs.rs
index 2d8bca7..29960b5 100644
--- a/crates/pkg/src/squashfs.rs
+++ b/crates/pkg/src/squashfs.rs
@@ -615,8 +615,10 @@ mod tests {
         listing.extend_from_slice(&1u32.to_le_bytes()); // count, less one
         listing.extend_from_slice(&0u32.to_le_bytes()); // inode block offset
         listing.extend_from_slice(&0u32.to_le_bytes()); // base inode number
-        for (offset, kind, name) in [(file_off, INODE_FILE, "app"), (link_off, INODE_SYMLINK, "link")]
-        {
+        for (offset, kind, name) in [
+            (file_off, INODE_FILE, "app"),
+            (link_off, INODE_SYMLINK, "link"),
+        ] {
             listing.extend_from_slice(&offset.to_le_bytes());
             listing.extend_from_slice(&0u16.to_le_bytes()); // inode number delta
             listing.extend_from_slice(&kind.to_le_bytes());
diff --git a/crates/pkg/src/tar.rs b/crates/pkg/src/tar.rs
index 18e4f93..1097f52 100644
--- a/crates/pkg/src/tar.rs
+++ b/crates/pkg/src/tar.rs
@@ -15,10 +15,7 @@ const BLOCK: usize = 512;
 /// first header rather than at offset 0, which is why a `.tar` needs looking
 /// *into* rather than sniffing.
 pub fn is_tar(bytes: &[u8]) -> bool {
-    bytes
-        .get(257..262)
-        .map(|m| m == b"ustar")
-        .unwrap_or(false)
+    bytes.get(257..262).map(|m| m == b"ustar").unwrap_or(false)
 }
 
 pub fn unpack(
@@ -209,7 +206,11 @@ mod tests {
 
     fn run(archive: &[u8]) -> (Collector, Unpacked) {
         let mut sink = Collector::default();
-        let mut out = Unpacked::new(Format::Tarball, Path::new("/scan"), crate::MAX_PAYLOAD_BYTES);
+        let mut out = Unpacked::new(
+            Format::Tarball,
+            Path::new("/scan"),
+            crate::MAX_PAYLOAD_BYTES,
+        );
         unpack(archive, Path::new("/scan"), &mut sink, &mut out).unwrap();
         (sink, out)
     }
diff --git a/crates/pkg/tests/real_packages.rs b/crates/pkg/tests/real_packages.rs
index cbf274b..a7f48f5 100644
--- a/crates/pkg/tests/real_packages.rs
+++ b/crates/pkg/tests/real_packages.rs
@@ -36,7 +36,10 @@ fn noisy_blob(len: usize) -> Vec {
 fn source_tree(root: &Path) -> BTreeMap> {
     let mut files = BTreeMap::new();
     files.insert("bin/app".to_string(), noisy_blob(400 * 1024));
-    files.insert("bin/tiny.txt".to_string(), b"small enough to be a fragment\n".to_vec());
+    files.insert(
+        "bin/tiny.txt".to_string(),
+        b"small enough to be a fragment\n".to_vec(),
+    );
     files.insert(
         "share/nested/deep/resources.json".to_string(),
         br#"{"name":"fixture"}"#.to_vec(),
@@ -111,7 +114,9 @@ fn squashfs_images_from_mksquashfs_round_trip_in_every_compression() {
     for compression in ["gzip", "xz", "zstd", "lz4"] {
         let image = dir.join(format!("{compression}.squashfs"));
         let mut cmd = Command::new("mksquashfs");
-        cmd.arg(&src).arg(&image).args(["-comp", compression, "-noappend", "-no-progress"]);
+        cmd.arg(&src)
+            .arg(&image)
+            .args(["-comp", compression, "-noappend", "-no-progress"]);
         // lz4 needs an explicit flag to be accepted as a filesystem compressor.
         if compression == "lz4" {
             cmd.arg("-Xhc");
diff --git a/crates/rust-audit/src/extract.rs b/crates/rust-audit/src/extract.rs
index ff0df4e..015f471 100644
--- a/crates/rust-audit/src/extract.rs
+++ b/crates/rust-audit/src/extract.rs
@@ -38,7 +38,10 @@ pub(crate) fn parse_version_info(json: &str) -> Option> {
             .filter_map(|p| {
                 semver::Version::parse(&p.version)
                     .ok()
-                    .map(|version| AuditedCrate { name: p.name, version })
+                    .map(|version| AuditedCrate {
+                        name: p.name,
+                        version,
+                    })
             })
             .collect(),
     )
diff --git a/crates/scan/src/linux.rs b/crates/scan/src/linux.rs
index 7632c75..199aaf4 100644
--- a/crates/scan/src/linux.rs
+++ b/crates/scan/src/linux.rs
@@ -222,11 +222,7 @@ fn follow_wrapper(path: &Path, depth: u8) -> Option {
 ///
 /// Without this every such path is dangling and the follow fails, leaving the
 /// app resolved to nothing but its runner.
-pub(crate) fn follow_wrapper_in(
-    path: &Path,
-    depth: u8,
-    payload: Option<&Path>,
-) -> Option {
+pub(crate) fn follow_wrapper_in(path: &Path, depth: u8, payload: Option<&Path>) -> Option {
     if depth >= 5 {
         return Some(path.to_path_buf());
     }
@@ -259,10 +255,7 @@ pub(crate) fn follow_wrapper_in(
     .collect();
     // `$SNAP` is where a snap's own launcher expects to find its files.
     if let Some(payload) = payload {
-        vars.insert(
-            "SNAP".to_string(),
-            payload.to_string_lossy().into_owned(),
-        );
+        vars.insert("SNAP".to_string(), payload.to_string_lossy().into_owned());
     }
 
     let mut target: Option = None;
@@ -315,7 +308,9 @@ pub(crate) fn follow_wrapper_in(
 /// app's own tree — to where that file is on the host. `None` when the path
 /// isn't under `/app` and so needs no rewriting.
 pub(crate) fn map_sandbox_path(path: &Path, payload: &Path) -> Option {
-    path.strip_prefix("/app").ok().map(|rest| payload.join(rest))
+    path.strip_prefix("/app")
+        .ok()
+        .map(|rest| payload.join(rest))
 }
 
 /// Pick the executable token from the tokens following `exec`, skipping
diff --git a/crates/scan/src/linux/sandboxed.rs b/crates/scan/src/linux/sandboxed.rs
index 899c9a5..2816266 100644
--- a/crates/scan/src/linux/sandboxed.rs
+++ b/crates/scan/src/linux/sandboxed.rs
@@ -383,10 +383,7 @@ mod tests {
 
     /// Build a flatpak-shaped `files/` tree in a temp dir.
     fn flatpak_files(name: &str) -> PathBuf {
-        let dir = std::env::temp_dir().join(format!(
-            "scan-flatpak-{}-{name}",
-            std::process::id()
-        ));
+        let dir = std::env::temp_dir().join(format!("scan-flatpak-{}-{name}", std::process::id()));
         let _ = std::fs::remove_dir_all(&dir);
         std::fs::create_dir_all(dir.join("bin")).unwrap();
         dir
@@ -412,7 +409,10 @@ mod tests {
         // The premise: from the host, that link points at nothing.
         assert!(!entry.exists(), "the link should be dangling on the host");
 
-        assert_eq!(resolve_entry(&entry, &files, 0).as_deref(), Some(real.as_path()));
+        assert_eq!(
+            resolve_entry(&entry, &files, 0).as_deref(),
+            Some(real.as_path())
+        );
         let _ = std::fs::remove_dir_all(&files);
     }
 
@@ -426,9 +426,16 @@ mod tests {
         std::fs::write(&real, b"\x7fELF").unwrap();
 
         let entry = files.join("bin/spotify");
-        std::fs::write(&entry, b"#!/bin/sh\nexec /app/extra/Spotify/spotify \"$@\"\n").unwrap();
+        std::fs::write(
+            &entry,
+            b"#!/bin/sh\nexec /app/extra/Spotify/spotify \"$@\"\n",
+        )
+        .unwrap();
 
-        assert_eq!(resolve_entry(&entry, &files, 0).as_deref(), Some(real.as_path()));
+        assert_eq!(
+            resolve_entry(&entry, &files, 0).as_deref(),
+            Some(real.as_path())
+        );
         let _ = std::fs::remove_dir_all(&files);
     }
 
@@ -437,11 +444,20 @@ mod tests {
     /// first would vanish from the scan.
     #[test]
     fn identity_is_the_payload_never_the_shared_runner() {
-        let a = describe(PathBuf::from("/f/app/A/files"), Some("/f/app/A/files/bin/a".into()));
-        let b = describe(PathBuf::from("/f/app/B/files"), Some("/f/app/B/files/bin/b".into()));
+        let a = describe(
+            PathBuf::from("/f/app/A/files"),
+            Some("/f/app/A/files/bin/a".into()),
+        );
+        let b = describe(
+            PathBuf::from("/f/app/B/files"),
+            Some("/f/app/B/files/bin/b".into()),
+        );
         assert_ne!(a.path, b.path);
         assert_eq!(a.root, Path::new("/f/app/A/files/bin"));
-        assert_eq!(a.executable.as_deref(), Some(Path::new("/f/app/A/files/bin/a")));
+        assert_eq!(
+            a.executable.as_deref(),
+            Some(Path::new("/f/app/A/files/bin/a"))
+        );
     }
 
     /// An app with no native binary (GJS, Python) still gets a distinct
diff --git a/crates/vfs/src/platform.rs b/crates/vfs/src/platform.rs
index f6984ad..a123b0a 100644
--- a/crates/vfs/src/platform.rs
+++ b/crates/vfs/src/platform.rs
@@ -176,7 +176,11 @@ mod tests {
         .unwrap();
 
         assert_eq!(elsewhere, (DEFAULT, Platform::Linux));
-        assert_eq!(platform(), Platform::Windows, "the other thread's set leaked");
+        assert_eq!(
+            platform(),
+            Platform::Windows,
+            "the other thread's set leaked"
+        );
         reset_platform();
     }
 
diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs
index 557cca2..9684fcc 100644
--- a/src-tauri/src/commands.rs
+++ b/src-tauri/src/commands.rs
@@ -381,21 +381,20 @@ pub async fn netmon_stop(
     // It usually finished during the recording, so this is instant; a bound
     // guards the rare case of a very short recording over a huge bundle, in which
     // case we ship the runtime-only inventory and the scan's result is dropped.
-    let static_ev = match tokio::time::timeout(
-        std::time::Duration::from_secs(20),
-        active.static_scan,
-    )
-    .await
-    {
-        Ok(Ok(ev)) => ev,
-        _ => Vec::new(),
-    };
+    let static_ev =
+        match tokio::time::timeout(std::time::Duration::from_secs(20), active.static_scan).await {
+            Ok(Ok(ev)) => ev,
+            _ => Vec::new(),
+        };
     evidence.extend(static_ev);
 
     let target = &active.meta.target;
 
     let app_ref = cbom::AppRef {
-        name: target.display_name.clone().unwrap_or_else(|| "application".into()),
+        name: target
+            .display_name
+            .clone()
+            .unwrap_or_else(|| "application".into()),
         version: None,
         bundle_id: target.bundle_id.clone(),
         path: active.app_path.clone().or_else(|| target.exe_path.clone()),
@@ -470,10 +469,7 @@ pub async fn crypto_inventory(
 
 /// Load the last persisted crypto inventory for an app (retained across runs).
 #[tauri::command]
-pub async fn crypto_load(
-    path: String,
-    bundle_id: Option,
-) -> Option {
+pub async fn crypto_load(path: String, bundle_id: Option) -> Option {
     crate::crypto_store::load(&path, bundle_id.as_deref())
 }
 
@@ -611,12 +607,18 @@ pub(crate) fn compute_os_info() -> OsInfo {
         "macos" => match major {
             Some(m) if m < 14 => (
                 true,
-                Some("macOS is out of date — update for the latest Safari/WebKit security fixes.".into()),
+                Some(
+                    "macOS is out of date — update for the latest Safari/WebKit security fixes."
+                        .into(),
+                ),
             ),
             _ => (false, None),
         },
         "windows" => match major {
-            Some(m) if m < 10 => (true, Some("Windows is out of date — update for current security fixes.".into())),
+            Some(m) if m < 10 => (
+                true,
+                Some("Windows is out of date — update for current security fixes.".into()),
+            ),
             _ => (false, None),
         },
         _ => (false, None),
diff --git a/src-tauri/src/crypto_store.rs b/src-tauri/src/crypto_store.rs
index da0a5fb..c156fb1 100644
--- a/src-tauri/src/crypto_store.rs
+++ b/src-tauri/src/crypto_store.rs
@@ -7,9 +7,8 @@
 use std::path::{Path, PathBuf};
 
 fn store_dir() -> std::io::Result {
-    let base = dirs::data_dir().ok_or_else(|| {
-        std::io::Error::new(std::io::ErrorKind::NotFound, "no data directory")
-    })?;
+    let base = dirs::data_dir()
+        .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, "no data directory"))?;
     let dir = base.join("achilles").join("crypto");
     std::fs::create_dir_all(&dir)?;
     Ok(dir)
@@ -44,7 +43,11 @@ fn slug(path: &str, bundle_id: Option<&str>) -> String {
 }
 
 fn file_for(path: &str, bundle_id: Option<&str>) -> Option {
-    Some(store_dir().ok()?.join(format!("{}.json", slug(path, bundle_id))))
+    Some(
+        store_dir()
+            .ok()?
+            .join(format!("{}.json", slug(path, bundle_id))),
+    )
 }
 
 /// Persist the inventory for an app (best-effort; failures are ignored).
diff --git a/src-tauri/src/helper_mac.rs b/src-tauri/src/helper_mac.rs
index 7ef51df..21b62f4 100644
--- a/src-tauri/src/helper_mac.rs
+++ b/src-tauri/src/helper_mac.rs
@@ -77,7 +77,8 @@ pub fn uninstall() -> Result<(), String> {
     if status == SMAppServiceStatus::NotRegistered || status == SMAppServiceStatus::NotFound {
         return Ok(());
     }
-    unsafe { service().unregisterAndReturnError() }.map_err(|e| e.localizedDescription().to_string())
+    unsafe { service().unregisterAndReturnError() }
+        .map_err(|e| e.localizedDescription().to_string())
 }
 
 /// Open System Settings → General → Login Items & Extensions for approval.
diff --git a/src-tauri/src/journal.rs b/src-tauri/src/journal.rs
index 2913d5a..067624a 100644
--- a/src-tauri/src/journal.rs
+++ b/src-tauri/src/journal.rs
@@ -245,7 +245,8 @@ pub(crate) fn format_iso(unix_secs: u64) -> String {
     let mut year = 1970u32;
     let mut days_remaining = days_since_epoch as i64;
     loop {
-        let is_leap = (year.is_multiple_of(4) && !year.is_multiple_of(100)) || year.is_multiple_of(400);
+        let is_leap =
+            (year.is_multiple_of(4) && !year.is_multiple_of(100)) || year.is_multiple_of(400);
         let yr_days = if is_leap { 366 } else { 365 };
         if days_remaining < yr_days as i64 {
             break;
diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs
index 6ac64ce..ca1eb06 100644
--- a/src-tauri/src/lib.rs
+++ b/src-tauri/src/lib.rs
@@ -21,7 +21,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
 use tauri::menu::{Menu, MenuItem, PredefinedMenuItem};
 use tauri::tray::TrayIconBuilder;
 use tauri::{AppHandle, Manager, WindowEvent, Wry};
-use tauri_plugin_autostart::{ManagerExt, MacosLauncher};
+use tauri_plugin_autostart::{MacosLauncher, ManagerExt};
 
 /// Serialises reassessment runs so the scheduler, tray, and manual command can
 /// never overlap. Held as Tauri-managed state.
@@ -96,7 +96,10 @@ fn tray_risk_text(last: &Option) -> String {
             if flagged == 0 {
                 format!("✓ {} apps — none at risk", r.risk.total)
             } else if r.risk.bad > 0 {
-                format!("⚠ {flagged} of {} apps at risk ({} high)", r.risk.total, r.risk.bad)
+                format!(
+                    "⚠ {flagged} of {} apps at risk ({} high)",
+                    r.risk.total, r.risk.bad
+                )
             } else {
                 format!("⚠ {flagged} of {} apps at risk", r.risk.total)
             }
@@ -109,7 +112,10 @@ fn tray_risk_text(last: &Option) -> String {
 fn tray_os_text() -> (String, bool) {
     let info = commands::compute_os_info();
     if info.outdated {
-        (format!("⚠ System update available — {}", info.display), true)
+        (
+            format!("⚠ System update available — {}", info.display),
+            true,
+        )
     } else {
         (format!("✓ System up to date — {}", info.display), false)
     }
@@ -205,7 +211,10 @@ pub async fn run_reassessment(app: AppHandle) {
             }
         }
     };
-    *app.state::().last.lock().expect("tray status lock") = Some(last);
+    *app.state::()
+        .last
+        .lock()
+        .expect("tray status lock") = Some(last);
     refresh_tray_status(&app);
 }
 
@@ -355,8 +364,13 @@ fn setup_tray(app: &AppHandle) -> tauri::Result<()> {
     let (os_text, os_actionable) = tray_os_text();
     let risk = MenuItem::with_id(app, "risk_show", tray_risk_text(&None), true, None::<&str>)?;
     let os = MenuItem::with_id(app, "os_update", os_text, os_actionable, None::<&str>)?;
-    let reporting =
-        MenuItem::with_id(app, "reporting_status", tray_reporting_text(&None), false, None::<&str>)?;
+    let reporting = MenuItem::with_id(
+        app,
+        "reporting_status",
+        tray_reporting_text(&None),
+        false,
+        None::<&str>,
+    )?;
     let sep = PredefinedMenuItem::separator(app)?;
     let show = MenuItem::with_id(app, "show", "Show", true, None::<&str>)?;
     let reassess = MenuItem::with_id(app, "reassess", "Reassess now", true, None::<&str>)?;
@@ -369,7 +383,11 @@ fn setup_tray(app: &AppHandle) -> tauri::Result<()> {
     // Keep the status items so the scheduler can relabel them later.
     {
         let state = app.state::();
-        state.risk_item.lock().expect("tray item lock").replace(risk);
+        state
+            .risk_item
+            .lock()
+            .expect("tray item lock")
+            .replace(risk);
         state.os_item.lock().expect("tray item lock").replace(os);
         state
             .reporting_item
diff --git a/src-tauri/src/reporting.rs b/src-tauri/src/reporting.rs
index b9b8cbb..7d6db66 100644
--- a/src-tauri/src/reporting.rs
+++ b/src-tauri/src/reporting.rs
@@ -65,8 +65,8 @@ impl Default for ReportingConfig {
             vdb_enabled: false,
             vdb_url: String::new(),
             vdb_token: String::new(),
-            vdb_refresh_secs: 86_400,          // daily
-            vdb_max_age_secs: 14 * 86_400,     // two weeks
+            vdb_refresh_secs: 86_400,      // daily
+            vdb_max_age_secs: 14 * 86_400, // two weeks
         }
     }
 }
@@ -284,7 +284,9 @@ pub struct RiskSummary {
 /// (`Framework::Unknown`) are dropped from the reported inventory — they add
 /// noise, not signal — but still counted in the risk total.
 async fn collect_inventory() -> Result<(Vec, RiskSummary), String> {
-    let apps = scan::discover_applications().await.map_err(|e| e.to_string())?;
+    let apps = scan::discover_applications()
+        .await
+        .map_err(|e| e.to_string())?;
 
     let (tx, mut rx) = tokio::sync::mpsc::channel(64);
     tokio::spawn(scan::scan(apps, 8, tx));
@@ -421,7 +423,11 @@ pub async fn reassess_and_report(app: AppHandle) -> Result/achilles/vdb-snapshot.json`).
 fn vdb_snapshot_path() -> Option {
-    Some(dirs::cache_dir()?.join("achilles").join("vdb-snapshot.json"))
+    Some(
+        dirs::cache_dir()?
+            .join("achilles")
+            .join("vdb-snapshot.json"),
+    )
 }
 
 /// Status pushed to the frontend after a VDB refresh attempt.

From 963f3d2953162cd82a747e9b4bc435df69067534 Mon Sep 17 00:00:00 2001
From: FabianLars-crabnebula 
Date: Wed, 30 Sep 2026 15:23:11 +0200
Subject: [PATCH 3/3] serde_with

---
 Cargo.lock | 146 ++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 129 insertions(+), 17 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 6f04036..f291d85 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -766,9 +766,9 @@ dependencies = [
 
 [[package]]
 name = "darling"
-version = "0.23.0"
+version = "0.24.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d"
+checksum = "ed17f5901b6630b993ca003def43f2f8ef4014fc13b047b57aad617ff32bc2ec"
 dependencies = [
  "darling_core",
  "darling_macro",
@@ -776,26 +776,26 @@ dependencies = [
 
 [[package]]
 name = "darling_core"
-version = "0.23.0"
+version = "0.24.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0"
+checksum = "6837e2cf7485aaae18f86181d2f0e9a7ed297a025e220aeabf63fdebd3a2ddff"
 dependencies = [
  "ident_case",
  "proc-macro2",
  "quote",
  "strsim",
- "syn 2.0.117",
+ "syn 3.0.6",
 ]
 
 [[package]]
 name = "darling_macro"
-version = "0.23.0"
+version = "0.24.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d"
+checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785"
 dependencies = [
  "darling_core",
  "quote",
- "syn 2.0.117",
+ "syn 3.0.6",
 ]
 
 [[package]]
@@ -818,6 +818,37 @@ dependencies = [
  "windows-sys 0.61.2",
 ]
 
+[[package]]
+name = "defmt"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1"
+dependencies = [
+ "bitflags 1.3.2",
+ "defmt-macros",
+]
+
+[[package]]
+name = "defmt-macros"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8"
+dependencies = [
+ "defmt-parser",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "defmt-parser"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e"
+dependencies = [
+ "thiserror 2.0.18",
+]
+
 [[package]]
 name = "der"
 version = "0.7.10"
@@ -1855,7 +1886,7 @@ dependencies = [
  "js-sys",
  "log",
  "wasm-bindgen",
- "windows-core 0.62.2",
+ "windows-core 0.57.0",
 ]
 
 [[package]]
@@ -2078,6 +2109,60 @@ dependencies = [
  "system-deps",
 ]
 
+[[package]]
+name = "jiff"
+version = "0.2.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ab1baf72f08796de0260609515130699b890ac25f30e610ad894bc5856cafdb"
+dependencies = [
+ "defmt",
+ "jiff-core",
+ "jiff-static",
+ "jiff-tzdb-platform",
+ "log",
+ "portable-atomic",
+ "portable-atomic-util",
+ "serde_core",
+ "windows-link",
+]
+
+[[package]]
+name = "jiff-core"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e52fe76043ccecc9005d2305ebaadf7d7fc0cc89ca6baa10a94d6bc68c7128c"
+dependencies = [
+ "defmt",
+ "log",
+]
+
+[[package]]
+name = "jiff-static"
+version = "0.2.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "378268a1116ad67ae6228701118ac9f491d78fda38a40a1f1a9e1348de6f7212"
+dependencies = [
+ "jiff-core",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.117",
+]
+
+[[package]]
+name = "jiff-tzdb"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e"
+
+[[package]]
+name = "jiff-tzdb-platform"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8"
+dependencies = [
+ "jiff-tzdb",
+]
+
 [[package]]
 name = "jni"
 version = "0.21.1"
@@ -3297,6 +3382,21 @@ dependencies = [
  "miniz_oxide",
 ]
 
+[[package]]
+name = "portable-atomic"
+version = "1.15.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
+
+[[package]]
+name = "portable-atomic-util"
+version = "0.2.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715"
+dependencies = [
+ "portable-atomic",
+]
+
 [[package]]
 name = "potential_utf"
 version = "0.1.5"
@@ -4083,9 +4183,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.150"
+version = "1.0.151"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
+checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
 dependencies = [
  "itoa",
  "memchr",
@@ -4137,16 +4237,17 @@ dependencies = [
 
 [[package]]
 name = "serde_with"
-version = "3.20.0"
+version = "3.24.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e72c1c2cb7b223fafb600a619537a871c2818583d619401b785e7c0b746ccde2"
+checksum = "df9adc193c780ef8f159aee8b61e2d5801aaa555e6eb0947fe45530ec506296f"
 dependencies = [
- "base64 0.22.1",
+ "base64 0.23.1",
  "bs58",
  "chrono",
  "hex",
  "indexmap 1.9.3",
  "indexmap 2.14.0",
+ "jiff",
  "schemars 0.9.0",
  "schemars 1.2.1",
  "serde_core",
@@ -4157,14 +4258,14 @@ dependencies = [
 
 [[package]]
 name = "serde_with_macros"
-version = "3.20.0"
+version = "3.24.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b90c488738ecb4fb0262f41f43bc40efc5868d9fb744319ddf5f5317f417bfac"
+checksum = "3e17bbc68e28663bbbb90df47e058aa7eda4fb445b89fe70457bb94fbccf6e49"
 dependencies = [
  "darling",
  "proc-macro2",
  "quote",
- "syn 2.0.117",
+ "syn 3.0.6",
 ]
 
 [[package]]
@@ -4482,6 +4583,17 @@ dependencies = [
  "unicode-ident",
 ]
 
+[[package]]
+name = "syn"
+version = "3.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8593e8e72159ed2257d083c7a454a85cbf854f37a0966d8d483aff8c8a3ebcee"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
 [[package]]
 name = "sync_wrapper"
 version = "1.0.2"