From 40814a7efbb026c643322c9070b97ef40ccd3bab Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 20 Feb 2025 22:35:09 +0100 Subject: [PATCH 01/44] TODO Update dependencies --- Cargo.lock | 620 ++++++++++++++++++++++------------------------------- Cargo.toml | 53 ++--- 2 files changed, 288 insertions(+), 385 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18a0db8..9f4c43f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,30 +4,18 @@ version = 4 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy 0.7.34", -] +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aho-corasick" @@ -40,9 +28,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -61,37 +49,38 @@ checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" [[package]] name = "async-trait" @@ -106,50 +95,48 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-lc-rs" -version = "1.9.0" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f95446d919226d587817a7d21379e6eb099b97b45110a7f272a444ca5c54070" +checksum = "4c2b7ddaa2c56a367ad27a094ad8ef4faacf8a617c2575acb2ba88949df999ca" dependencies = [ "aws-lc-sys", - "mirai-annotations", "paste", "zeroize", ] [[package]] name = "aws-lc-sys" -version = "0.21.2" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3ddc4a5b231dd6958b140ff3151b6412b3f4321fab354f399eec8f14b06df62" +checksum = "54ac4f13dad353b209b34cbec082338202cbc01c8f00336b55c750c13ac91f8f" dependencies = [ "bindgen", "cc", "cmake", "dunce", "fs_extra", - "libc", "paste", ] [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] [[package]] @@ -177,9 +164,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "block-buffer" @@ -190,6 +177,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.10.0" @@ -207,9 +200,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.2" +version = "1.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" +checksum = "0c3d1b2e905a3a7b00a6141adb0e4c0bb941d11caf55349d863942a1cc44e3c9" dependencies = [ "jobserver", "libc", @@ -284,18 +277,18 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "cmake" -version = "0.1.52" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" dependencies = [ "cc", ] [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "cookie" @@ -345,7 +338,7 @@ dependencies = [ "rusqlite", "rustls", "serde_json", - "thiserror 1.0.61", + "thiserror", "tokio", "toss", "unicode-width", @@ -359,7 +352,7 @@ dependencies = [ "cove-input", "cove-macro", "serde", - "thiserror 1.0.61", + "thiserror", "toml", ] @@ -373,7 +366,7 @@ dependencies = [ "parking_lot", "serde", "serde_either", - "thiserror 1.0.61", + "thiserror", "toss", ] @@ -388,24 +381,24 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crossterm" -version = "0.27.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ "bitflags", "crossterm_winapi", - "libc", - "mio 0.8.11", + "mio", "parking_lot", + "rustix", "signal-hook", "signal-hook-mio", "winapi", @@ -432,9 +425,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" [[package]] name = "deranged" @@ -457,23 +450,23 @@ dependencies = [ [[package]] name = "directories" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -494,30 +487,29 @@ dependencies = [ [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "euphoxide" version = "0.5.1" -source = "git+https://github.com/Garmelon/euphoxide.git#1d444684f7f292183c1ab5c89fef3872dadf96fd" dependencies = [ "async-trait", "caseless", @@ -548,9 +540,9 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fnv" @@ -558,6 +550,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + [[package]] name = "fs_extra" version = "1.3.0" @@ -626,35 +624,35 @@ dependencies = [ "cfg-if", "libc", "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.5", + "windows-targets", ] [[package]] name = "gimli" -version = "0.28.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ - "ahash", + "foldhash", ] [[package]] name = "hashlink" -version = "0.9.1" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ "hashbrown", ] @@ -667,18 +665,18 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "http" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -687,15 +685,15 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" [[package]] name = "indexmap" -version = "2.2.6" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", "hashbrown", @@ -722,9 +720,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -737,9 +735,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jiff" @@ -752,7 +750,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -804,7 +802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets", ] [[package]] @@ -819,9 +817,9 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.28.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" +checksum = "ad8935b44e7c13394a179a438e0cebba0fe08fe01b54f152e29a93b5cf993fd4" dependencies = [ "cc", "pkg-config", @@ -839,9 +837,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "lock_api" @@ -861,9 +859,9 @@ checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "minimal-lexical" @@ -873,23 +871,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "b3b1c9bd4fe1f0f8b387f6eb9eb3b4a1aa26185e5750efb9140301703f62cd1b" dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "log", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "adler2", ] [[package]] @@ -899,16 +885,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", + "log", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] -[[package]] -name = "mirai-annotations" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" - [[package]] name = "nom" version = "7.1.3" @@ -936,24 +917,24 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "open" -version = "5.1.3" +version = "5.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb49fbd5616580e9974662cb96a3463da4476e649a7e4b258df0de065db0657" +checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95" dependencies = [ "is-wsl", "libc", @@ -962,9 +943,9 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "option-ext" @@ -983,9 +964,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1001,7 +982,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets", ] [[package]] @@ -1012,15 +993,15 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -1030,9 +1011,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "portable-atomic" @@ -1057,15 +1038,18 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy 0.7.35", +] [[package]] name = "prettyplease" -version = "0.2.25" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" dependencies = [ "proc-macro2", "syn", @@ -1073,18 +1057,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.83" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -1122,29 +1106,29 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror 1.0.61", + "thiserror", ] [[package]] name = "regex" -version = "1.10.4" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1154,9 +1138,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1165,30 +1149,29 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "ring" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "e75ec5e92c4d8aede845126adc388046234541629e76029599ed35a003c7ed24" dependencies = [ "cc", "cfg-if", "getrandom 0.2.15", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] [[package]] name = "rusqlite" -version = "0.31.0" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae" +checksum = "1c6d5e5acb6f6129fe3f7ba0a7fc77bca1942cb568535e18e7bc40262baf3110" dependencies = [ "bitflags", "fallible-iterator", @@ -1213,22 +1196,22 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" dependencies = [ "aws-lc-rs", "log", @@ -1253,9 +1236,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" [[package]] name = "rustls-webpki" @@ -1271,17 +1254,17 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1292,9 +1275,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "3.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ "bitflags", "core-foundation", @@ -1305,9 +1288,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -1367,9 +1350,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -1403,12 +1386,12 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", - "mio 0.8.11", + "mio", "signal-hook", ] @@ -1432,26 +1415,20 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "strsim" version = "0.11.1" @@ -1460,15 +1437,15 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.87" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -1477,23 +1454,16 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" dependencies = [ "cfg-if", "fastrand", + "getrandom 0.3.1", + "once_cell", "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "thiserror" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" -dependencies = [ - "thiserror-impl 1.0.61", + "windows-sys 0.59.0", ] [[package]] @@ -1502,18 +1472,7 @@ version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ - "thiserror-impl 2.0.11", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "thiserror-impl", ] [[package]] @@ -1529,9 +1488,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -1550,9 +1509,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -1560,9 +1519,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" dependencies = [ "tinyvec_macros", ] @@ -1582,7 +1541,7 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.3", + "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -1604,12 +1563,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ "rustls", - "rustls-pki-types", "tokio", ] @@ -1642,9 +1600,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.13" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" dependencies = [ "serde", "serde_spanned", @@ -1654,18 +1612,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.13" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", "serde", @@ -1676,8 +1634,7 @@ dependencies = [ [[package]] name = "toss" -version = "0.2.3" -source = "git+https://github.com/Garmelon/toss.git?tag=v0.2.3#b1d7221bae9e1bb57d8e5b49c315dc3ca56e947a" +version = "0.3.0" dependencies = [ "async-trait", "crossterm", @@ -1701,21 +1658,21 @@ dependencies = [ "rustls", "rustls-pki-types", "sha1", - "thiserror 2.0.11", + "thiserror", "utf-8", ] [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] name = "unicode-linebreak" @@ -1734,15 +1691,15 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "untrusted" @@ -1758,14 +1715,13 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "vault" -version = "0.4.0" -source = "git+https://github.com/Garmelon/vault.git?tag=v0.4.0#a53254d2e787d15fd2d00584fddf9b84e79572ee" +version = "0.5.0" dependencies = [ "rusqlite", "tokio", @@ -1779,9 +1735,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" @@ -1832,150 +1788,93 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.8" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" +checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" dependencies = [ "memchr", ] @@ -1991,11 +1890,12 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "zerocopy-derive 0.7.34", + "byteorder", + "zerocopy-derive 0.7.35", ] [[package]] @@ -2009,9 +1909,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", @@ -2031,6 +1931,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/Cargo.toml b/Cargo.toml index a4bbb26..b6edc2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,43 +7,46 @@ version = "0.8.3" edition = "2021" [workspace.dependencies] -anyhow = "1.0.86" -async-trait = "0.1.80" -clap = { version = "4.5.4", features = ["derive", "deprecated"] } +anyhow = "1.0.96" +async-trait = "0.1.86" +clap = { version = "4.5.30", features = ["derive", "deprecated"] } cookie = "0.18.1" -crossterm = "0.27.0" -directories = "5.0.1" +crossterm = "0.28.1" +directories = "6.0.0" edit = "0.1.5" jiff = "0.2.1" linkify = "0.10.0" -log = { version = "0.4.21", features = ["std"] } -once_cell = "1.19.0" -open = "5.1.3" -parking_lot = "0.12.2" -proc-macro2 = "1.0.83" -quote = "1.0.36" -rusqlite = { version = "0.31.0", features = ["bundled", "time"] } -rustls = "0.23.19" -serde = { version = "1.0.202", features = ["derive"] } +log = { version = "0.4.25", features = ["std"] } +once_cell = "1.20.2" +open = "5.3.2" +parking_lot = "0.12.3" +proc-macro2 = "1.0.93" +quote = "1.0.38" +rusqlite = { version = "0.33.0", features = ["bundled", "time"] } +rustls = "0.23.23" +serde = { version = "1.0.218", features = ["derive"] } serde_either = "0.2.1" -serde_json = "1.0.117" -syn = "2.0.65" -thiserror = "1.0.61" -tokio = { version = "1.37.0", features = ["full"] } -toml = "0.8.13" -unicode-width = "0.1.12" +serde_json = "1.0.139" +syn = "2.0.98" +thiserror = "2.0.11" +tokio = { version = "1.43.0", features = ["full"] } +toml = "0.8.20" +unicode-width = "0.2.0" [workspace.dependencies.euphoxide] -git = "https://github.com/Garmelon/euphoxide.git" +path = "../euphoxide" +# git = "https://github.com/Garmelon/euphoxide.git" features = ["bot"] [workspace.dependencies.toss] -git = "https://github.com/Garmelon/toss.git" -tag = "v0.2.3" +path = "../toss" +# git = "https://github.com/Garmelon/toss.git" +# tag = "v0.2.3" [workspace.dependencies.vault] -git = "https://github.com/Garmelon/vault.git" -tag = "v0.4.0" +path = "../vault" +# git = "https://github.com/Garmelon/vault.git" +# tag = "v0.4.0" features = ["tokio"] [workspace.lints] From f1a3c0a8cfb34bc52f5da3b0727583d8685f75f3 Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 20 Feb 2025 23:57:41 +0100 Subject: [PATCH 02/44] TODO Debug sqlite performance --- Cargo.lock | 49 ++++++++++++++++++++++++++---------------- Cargo.toml | 15 +++++++++++-- cove/src/vault/euph.rs | 40 +++++++++++++++++++++++++++------- 3 files changed, 75 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9f4c43f..5341662 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,18 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy 0.7.35", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -550,12 +562,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" - [[package]] name = "fs_extra" version = "1.3.0" @@ -641,20 +647,26 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "foldhash", + "ahash", ] [[package]] -name = "hashlink" -version = "0.10.0" +name = "hashbrown" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "hashlink" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -696,7 +708,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.2", ] [[package]] @@ -817,11 +829,10 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.31.0" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad8935b44e7c13394a179a438e0cebba0fe08fe01b54f152e29a93b5cf993fd4" +checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" dependencies = [ - "cc", "pkg-config", "vcpkg", ] @@ -1169,9 +1180,9 @@ dependencies = [ [[package]] name = "rusqlite" -version = "0.33.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c6d5e5acb6f6129fe3f7ba0a7fc77bca1942cb568535e18e7bc40262baf3110" +checksum = "b838eba278d213a8beaf485bd313fd580ca4505a00d5871caeb1457c55322cae" dependencies = [ "bitflags", "fallible-iterator", diff --git a/Cargo.toml b/Cargo.toml index b6edc2c..02b4525 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,10 @@ open = "5.3.2" parking_lot = "0.12.3" proc-macro2 = "1.0.93" quote = "1.0.38" -rusqlite = { version = "0.33.0", features = ["bundled", "time"] } +rusqlite = { version = "0.31.0", features = [ + # "bundled", + "time", +] } rustls = "0.23.23" serde = { version = "1.0.218", features = ["derive"] } serde_either = "0.2.1" @@ -46,7 +49,7 @@ path = "../toss" [workspace.dependencies.vault] path = "../vault" # git = "https://github.com/Garmelon/vault.git" -# tag = "v0.4.0" +# tag = "v0.5.0" features = ["tokio"] [workspace.lints] @@ -74,3 +77,11 @@ clippy.use_self = "warn" [profile.dev.package."*"] opt-level = 3 + +# For profiling + +[profile.release] +debug = 1 + +[rust] +debuginfo-level = 1 diff --git a/cove/src/vault/euph.rs b/cove/src/vault/euph.rs index c7d6410..8ee7b72 100644 --- a/cove/src/vault/euph.rs +++ b/cove/src/vault/euph.rs @@ -1,4 +1,5 @@ use std::str::FromStr; +use std::time::Instant; use std::{fmt, mem}; use async_trait::async_trait; @@ -686,12 +687,12 @@ impl Action for GetTree { type Error = rusqlite::Error; fn run(self, conn: &mut Connection) -> Result { - let msgs = conn - .prepare( - " + let start = Instant::now(); + + let query = " WITH RECURSIVE tree (domain, room, id) AS ( - VALUES (?, ?, ?) + VALUES (:domain, :room, :id) UNION SELECT euph_msgs.domain, euph_msgs.room, euph_msgs.id FROM euph_msgs @@ -700,14 +701,35 @@ impl Action for GetTree { AND tree.room = euph_msgs.room AND tree.id = euph_msgs.parent ) - SELECT id, parent, time, name, content, seen + SELECT id, parent, time, 'name', 'content', 1 FROM euph_msgs JOIN tree USING (domain, room, id) ORDER BY id ASC - ", - )? + "; + + let mut statement = conn.prepare(&format!("EXPLAIN QUERY PLAN {query}"))?; + let mut rows = statement.query(named_params! { + ":domain": self.room.domain, + ":room": self.room.name, + ":id": WSnowflake(self.root_id.0), + })?; + + while let Some(row) = rows.next()? { + let id = row.get::<_, i64>("id")?; + let parent = row.get::<_, i64>("parent")?; + let notused = row.get::<_, i64>("notused")?; + let detail = row.get::<_, String>("detail")?; + eprintln!("{parent:3} -> {id:3} (notused {notused:3}): {detail}"); + } + + let msgs = conn + .prepare(query)? .query_map( - params![self.room.domain, self.room.name, WSnowflake(self.root_id.0)], + named_params! { + ":domain": self.room.domain, + ":room": self.room.name, + ":id": WSnowflake(self.root_id.0), + }, |row| { Ok(SmallMessage { id: MessageId(row.get::<_, WSnowflake>(0)?.0), @@ -720,6 +742,8 @@ impl Action for GetTree { }, )? .collect::>()?; + let end = Instant::now(); + eprintln!("{:10}", end.duration_since(start).as_micros()); Ok(Tree::new(self.root_id, msgs)) } } From bd43fe060b6a0ab85b8ff28e92dd36820500e5a3 Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 20 Feb 2025 22:35:09 +0100 Subject: [PATCH 03/44] Update dependencies Except rusqlite and vault, because newer sqlite versions appear to result in a *very* big performance drop. I suspect the query planner, though I really have no idea. --- Cargo.lock | 597 +++++++++++++++++++++++------------------------------ Cargo.toml | 41 ++-- 2 files changed, 277 insertions(+), 361 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 18a0db8..e77a3ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 4 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" @@ -26,7 +26,7 @@ dependencies = [ "cfg-if", "once_cell", "version_check", - "zerocopy 0.7.34", + "zerocopy 0.7.35", ] [[package]] @@ -40,9 +40,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.14" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -61,37 +61,38 @@ checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" [[package]] name = "anstyle-parse" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.3" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.3" +version = "3.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "once_cell", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" [[package]] name = "async-trait" @@ -106,50 +107,48 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-lc-rs" -version = "1.9.0" +version = "1.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f95446d919226d587817a7d21379e6eb099b97b45110a7f272a444ca5c54070" +checksum = "4cd755adf9707cf671e31d944a189be3deaaeee11c8bc1d669bb8022ac90fbd0" dependencies = [ "aws-lc-sys", - "mirai-annotations", "paste", "zeroize", ] [[package]] name = "aws-lc-sys" -version = "0.21.2" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3ddc4a5b231dd6958b140ff3151b6412b3f4321fab354f399eec8f14b06df62" +checksum = "0f9dd2e03ee80ca2822dd6ea431163d2ef259f2066a4d6ccaca6d9dcb386aa43" dependencies = [ "bindgen", "cc", "cmake", "dunce", "fs_extra", - "libc", "paste", ] [[package]] name = "backtrace" -version = "0.3.71" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets", ] [[package]] @@ -177,9 +176,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "block-buffer" @@ -190,6 +189,12 @@ dependencies = [ "generic-array", ] +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.10.0" @@ -207,9 +212,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.2" +version = "1.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" +checksum = "0c3d1b2e905a3a7b00a6141adb0e4c0bb941d11caf55349d863942a1cc44e3c9" dependencies = [ "jobserver", "libc", @@ -284,18 +289,18 @@ checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" [[package]] name = "cmake" -version = "0.1.52" +version = "0.1.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c682c223677e0e5b6b7f63a64b9351844c3f1b1678a68b7ee617e30fb082620e" +checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" dependencies = [ "cc", ] [[package]] name = "colorchoice" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "cookie" @@ -345,7 +350,7 @@ dependencies = [ "rusqlite", "rustls", "serde_json", - "thiserror 1.0.61", + "thiserror", "tokio", "toss", "unicode-width", @@ -359,7 +364,7 @@ dependencies = [ "cove-input", "cove-macro", "serde", - "thiserror 1.0.61", + "thiserror", "toml", ] @@ -373,7 +378,7 @@ dependencies = [ "parking_lot", "serde", "serde_either", - "thiserror 1.0.61", + "thiserror", "toss", ] @@ -388,24 +393,24 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ "libc", ] [[package]] name = "crossterm" -version = "0.27.0" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" dependencies = [ "bitflags", "crossterm_winapi", - "libc", - "mio 0.8.11", + "mio", "parking_lot", + "rustix", "signal-hook", "signal-hook-mio", "winapi", @@ -432,9 +437,9 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.6.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" [[package]] name = "deranged" @@ -457,23 +462,23 @@ dependencies = [ [[package]] name = "directories" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -494,30 +499,30 @@ dependencies = [ [[package]] name = "either" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "euphoxide" -version = "0.5.1" -source = "git+https://github.com/Garmelon/euphoxide.git#1d444684f7f292183c1ab5c89fef3872dadf96fd" +version = "0.6.0" +source = "git+https://github.com/Garmelon/euphoxide.git?tag=v0.6.0#4f7cc49b636301ce9beea9324a0a1390f8391009" dependencies = [ "async-trait", "caseless", @@ -548,9 +553,9 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fnv" @@ -626,20 +631,20 @@ dependencies = [ "cfg-if", "libc", "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.5", + "windows-targets", ] [[package]] name = "gimli" -version = "0.28.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "hashbrown" @@ -650,13 +655,19 @@ dependencies = [ "ahash", ] +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + [[package]] name = "hashlink" version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", ] [[package]] @@ -667,18 +678,18 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "http" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -687,18 +698,18 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" [[package]] name = "indexmap" -version = "2.2.6" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.2", ] [[package]] @@ -722,9 +733,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.0" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itertools" @@ -737,9 +748,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jiff" @@ -752,7 +763,7 @@ dependencies = [ "portable-atomic", "portable-atomic-util", "serde", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -804,7 +815,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets", ] [[package]] @@ -839,9 +850,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "lock_api" @@ -861,9 +872,9 @@ checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "memchr" -version = "2.7.2" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "minimal-lexical" @@ -873,23 +884,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "b3b1c9bd4fe1f0f8b387f6eb9eb3b4a1aa26185e5750efb9140301703f62cd1b" dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" -dependencies = [ - "libc", - "log", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", + "adler2", ] [[package]] @@ -899,16 +898,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", + "log", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] -[[package]] -name = "mirai-annotations" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9be0862c1b3f26a88803c4a49de6889c10e608b3ee9344e6ef5b45fb37ad3d1" - [[package]] name = "nom" version = "7.1.3" @@ -936,24 +930,24 @@ dependencies = [ [[package]] name = "object" -version = "0.32.2" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "open" -version = "5.1.3" +version = "5.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb49fbd5616580e9974662cb96a3463da4476e649a7e4b258df0de065db0657" +checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95" dependencies = [ "is-wsl", "libc", @@ -962,9 +956,9 @@ dependencies = [ [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "option-ext" @@ -983,9 +977,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -1001,7 +995,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets", ] [[package]] @@ -1012,15 +1006,15 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pathdiff" -version = "0.2.1" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -1030,9 +1024,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "portable-atomic" @@ -1057,15 +1051,18 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy 0.7.35", +] [[package]] name = "prettyplease" -version = "0.2.25" +version = "0.2.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" dependencies = [ "proc-macro2", "syn", @@ -1073,18 +1070,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.83" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] @@ -1122,29 +1119,29 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.1" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.5" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror 1.0.61", + "thiserror", ] [[package]] name = "regex" -version = "1.10.4" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1154,9 +1151,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1165,21 +1162,20 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.3" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "ring" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +checksum = "e75ec5e92c4d8aede845126adc388046234541629e76029599ed35a003c7ed24" dependencies = [ "cc", "cfg-if", "getrandom 0.2.15", "libc", - "spin", "untrusted", "windows-sys 0.52.0", ] @@ -1213,22 +1209,22 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.19" +version = "0.23.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" dependencies = [ "aws-lc-rs", "log", @@ -1253,9 +1249,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" [[package]] name = "rustls-webpki" @@ -1271,17 +1267,17 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1292,9 +1288,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "3.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ "bitflags", "core-foundation", @@ -1305,9 +1301,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -1367,9 +1363,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -1403,12 +1399,12 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", - "mio 0.8.11", + "mio", "signal-hook", ] @@ -1432,26 +1428,20 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - [[package]] name = "strsim" version = "0.11.1" @@ -1460,15 +1450,15 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.87" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ "proc-macro2", "quote", @@ -1477,23 +1467,16 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.10.1" +version = "3.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" dependencies = [ "cfg-if", "fastrand", + "getrandom 0.3.1", + "once_cell", "rustix", - "windows-sys 0.52.0", -] - -[[package]] -name = "thiserror" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" -dependencies = [ - "thiserror-impl 1.0.61", + "windows-sys 0.59.0", ] [[package]] @@ -1502,18 +1485,7 @@ version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" dependencies = [ - "thiserror-impl 2.0.11", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" -dependencies = [ - "proc-macro2", - "quote", - "syn", + "thiserror-impl", ] [[package]] @@ -1529,9 +1501,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -1550,9 +1522,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -1560,9 +1532,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" dependencies = [ "tinyvec_macros", ] @@ -1582,7 +1554,7 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.3", + "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -1604,12 +1576,11 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ "rustls", - "rustls-pki-types", "tokio", ] @@ -1642,9 +1613,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.13" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e43f8cc456c9704c851ae29c67e17ef65d2c30017c17a9765b89c382dc8bba" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" dependencies = [ "serde", "serde_spanned", @@ -1654,18 +1625,18 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] [[package]] name = "toml_edit" -version = "0.22.13" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c127785850e8c20836d49732ae6abfa47616e60bf9d9f57c43c250361a9db96c" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", "serde", @@ -1676,8 +1647,8 @@ dependencies = [ [[package]] name = "toss" -version = "0.2.3" -source = "git+https://github.com/Garmelon/toss.git?tag=v0.2.3#b1d7221bae9e1bb57d8e5b49c315dc3ca56e947a" +version = "0.3.1" +source = "git+https://github.com/Garmelon/toss.git?tag=v0.3.1#be7eff0979e0e95d070e7c9cea42c328ffd04cc4" dependencies = [ "async-trait", "crossterm", @@ -1701,21 +1672,21 @@ dependencies = [ "rustls", "rustls-pki-types", "sha1", - "thiserror 2.0.11", + "thiserror", "utf-8", ] [[package]] name = "typenum" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" [[package]] name = "unicode-linebreak" @@ -1734,15 +1705,15 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.12" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f5e5f3158ecfd4b8ff6fe086db7c8467a2dfdac97fe420f2b7c4aa97af66d6" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "untrusted" @@ -1758,9 +1729,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "vault" @@ -1779,9 +1750,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wasi" @@ -1832,150 +1803,93 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", ] [[package]] name = "windows-targets" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" -dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.5", - "windows_x86_64_gnu 0.52.5", - "windows_x86_64_gnullvm 0.52.5", - "windows_x86_64_msvc 0.52.5", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.48.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.6.8" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c52e9c97a68071b23e836c9380edae937f17b9c4667bd021973efc689f618d" +checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" dependencies = [ "memchr", ] @@ -1991,11 +1905,12 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "zerocopy-derive 0.7.34", + "byteorder", + "zerocopy-derive 0.7.35", ] [[package]] @@ -2009,9 +1924,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.7.34" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", @@ -2031,6 +1946,6 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" diff --git a/Cargo.toml b/Cargo.toml index a4bbb26..10e1968 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,39 +7,40 @@ version = "0.8.3" edition = "2021" [workspace.dependencies] -anyhow = "1.0.86" -async-trait = "0.1.80" -clap = { version = "4.5.4", features = ["derive", "deprecated"] } +anyhow = "1.0.96" +async-trait = "0.1.86" +clap = { version = "4.5.30", features = ["derive", "deprecated"] } cookie = "0.18.1" -crossterm = "0.27.0" -directories = "5.0.1" +crossterm = "0.28.1" +directories = "6.0.0" edit = "0.1.5" jiff = "0.2.1" linkify = "0.10.0" -log = { version = "0.4.21", features = ["std"] } -once_cell = "1.19.0" -open = "5.1.3" -parking_lot = "0.12.2" -proc-macro2 = "1.0.83" -quote = "1.0.36" +log = { version = "0.4.25", features = ["std"] } +once_cell = "1.20.2" +open = "5.3.2" +parking_lot = "0.12.3" +proc-macro2 = "1.0.93" +quote = "1.0.38" rusqlite = { version = "0.31.0", features = ["bundled", "time"] } -rustls = "0.23.19" -serde = { version = "1.0.202", features = ["derive"] } +rustls = "0.23.23" +serde = { version = "1.0.218", features = ["derive"] } serde_either = "0.2.1" -serde_json = "1.0.117" -syn = "2.0.65" -thiserror = "1.0.61" -tokio = { version = "1.37.0", features = ["full"] } -toml = "0.8.13" -unicode-width = "0.1.12" +serde_json = "1.0.139" +syn = "2.0.98" +thiserror = "2.0.11" +tokio = { version = "1.43.0", features = ["full"] } +toml = "0.8.20" +unicode-width = "0.2.0" [workspace.dependencies.euphoxide] git = "https://github.com/Garmelon/euphoxide.git" +tag = "v0.6.0" features = ["bot"] [workspace.dependencies.toss] git = "https://github.com/Garmelon/toss.git" -tag = "v0.2.3" +tag = "v0.3.1" [workspace.dependencies.vault] git = "https://github.com/Garmelon/vault.git" From f45e66f572e10b993bbec6db4e36519143c07a94 Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 21 Feb 2025 12:11:58 +0100 Subject: [PATCH 04/44] Fix or ignore 2024 edition migration lints --- Cargo.toml | 6 +++++- cove/src/ui/chat/tree/renderer.rs | 2 +- cove/src/ui/euph/account.rs | 2 +- cove/src/ui/euph/inspect.rs | 4 ++-- cove/src/ui/euph/nick_list.rs | 2 +- cove/src/ui/euph/popup.rs | 4 ++-- cove/src/ui/euph/room.rs | 2 +- cove/src/ui/key_bindings.rs | 2 +- cove/src/ui/rooms.rs | 2 +- 9 files changed, 15 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 10e1968..96c02c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,7 +68,11 @@ rust.unused_lifetimes = "warn" rust.unused_qualifications = "warn" # Clippy clippy.use_self = "warn" - +# Migrating to the 2024 edition +rust.rust_2024_compatibility = "warn" +rust.edition_2024_expr_fragment_specifier = { level = "allow", priority = 1 } +rust.if_let_rescope = { level = "allow", priority = 1 } +rust.tail_expr_drop_order = { level = "allow", priority = 1 } [profile.dev.package."*"] opt-level = 3 diff --git a/cove/src/ui/chat/tree/renderer.rs b/cove/src/ui/chat/tree/renderer.rs index 845e803..3aeadb1 100644 --- a/cove/src/ui/chat/tree/renderer.rs +++ b/cove/src/ui/chat/tree/renderer.rs @@ -437,7 +437,7 @@ where pub fn into_visible_blocks( self, - ) -> impl Iterator, Block>)> { + ) -> impl Iterator, Block>)> + use { let area = renderer::visible_area(&self); self.blocks .into_iter() diff --git a/cove/src/ui/euph/account.rs b/cove/src/ui/euph/account.rs index 359e9d5..b97f014 100644 --- a/cove/src/ui/euph/account.rs +++ b/cove/src/ui/euph/account.rs @@ -66,7 +66,7 @@ impl LoggedOut { pub struct LoggedIn(PersonalAccountView); impl LoggedIn { - fn widget(&self) -> impl Widget { + fn widget(&self) -> impl Widget + use<> { let bold = Style::new().bold(); Join5::vertical( Text::new(("Logged in", bold.green())).segment(), diff --git a/cove/src/ui/euph/inspect.rs b/cove/src/ui/euph/inspect.rs index 25620a2..d1e2380 100644 --- a/cove/src/ui/euph/inspect.rs +++ b/cove/src/ui/euph/inspect.rs @@ -91,7 +91,7 @@ fn message_lines(mut text: Styled, msg: &Message) -> Styled { text } -pub fn session_widget(session: &SessionInfo) -> impl Widget { +pub fn session_widget(session: &SessionInfo) -> impl Widget + use<> { let heading_style = Style::new().bold(); let text = match session { @@ -108,7 +108,7 @@ pub fn session_widget(session: &SessionInfo) -> impl Widget { Popup::new(Text::new(text), "Inspect session") } -pub fn message_widget(msg: &Message) -> impl Widget { +pub fn message_widget(msg: &Message) -> impl Widget + use<> { let heading_style = Style::new().bold(); let mut text = Styled::new("Message", heading_style).then_plain("\n"); diff --git a/cove/src/ui/euph/nick_list.rs b/cove/src/ui/euph/nick_list.rs index 23160bd..47f09c7 100644 --- a/cove/src/ui/euph/nick_list.rs +++ b/cove/src/ui/euph/nick_list.rs @@ -14,7 +14,7 @@ pub fn widget<'a>( list: &'a mut ListState, joined: &Joined, focused: bool, -) -> impl Widget + 'a { +) -> impl Widget + use<'a> { let mut list_builder = ListBuilder::new(); render_rows(&mut list_builder, joined, focused); list_builder.build(list) diff --git a/cove/src/ui/euph/popup.rs b/cove/src/ui/euph/popup.rs index f70e999..61b3ad5 100644 --- a/cove/src/ui/euph/popup.rs +++ b/cove/src/ui/euph/popup.rs @@ -12,7 +12,7 @@ pub enum RoomPopup { } impl RoomPopup { - fn server_error_widget(description: &str, reason: &str) -> impl Widget { + fn server_error_widget(description: &str, reason: &str) -> impl Widget + use<> { let border_style = Style::new().red().bold(); let text = Styled::new_plain(description) .then_plain("\n\n") @@ -23,7 +23,7 @@ impl RoomPopup { Popup::new(Text::new(text), ("Error", border_style)).with_border_style(border_style) } - pub fn widget(&self) -> impl Widget { + pub fn widget(&self) -> impl Widget + use<> { match self { Self::Error { description, diff --git a/cove/src/ui/euph/room.rs b/cove/src/ui/euph/room.rs index 15da008..0b36535 100644 --- a/cove/src/ui/euph/room.rs +++ b/cove/src/ui/euph/room.rs @@ -287,7 +287,7 @@ impl EuphRoom { .boxed_async() } - async fn status_widget(&self, state: Option<&euph::State>) -> impl Widget { + async fn status_widget(&self, state: Option<&euph::State>) -> impl Widget + use<> { let room_style = Style::new().bold().blue(); let mut info = Styled::new(format!("{} ", self.domain()), Style::new().grey()) .then(format!("&{}", self.name()), room_style); diff --git a/cove/src/ui/key_bindings.rs b/cove/src/ui/key_bindings.rs index 8fceda6..f5fa714 100644 --- a/cove/src/ui/key_bindings.rs +++ b/cove/src/ui/key_bindings.rs @@ -69,7 +69,7 @@ fn render_group_info(builder: &mut Builder, group_info: KeyGroupInfo<'_>) { pub fn widget<'a>( list: &'a mut ListState, config: &Config, -) -> impl Widget + 'a { +) -> impl Widget + use<'a> { let mut list_builder = ListBuilder::new(); for group_info in config.keys.groups() { diff --git a/cove/src/ui/rooms.rs b/cove/src/ui/rooms.rs index 0157b01..a7bb6f8 100644 --- a/cove/src/ui/rooms.rs +++ b/cove/src/ui/rooms.rs @@ -423,7 +423,7 @@ impl Rooms { list: &'a mut ListState, order: Order, euph_rooms: &HashMap, - ) -> impl Widget + 'a { + ) -> impl Widget + use<'a> { let version_info = Styled::new_plain("Welcome to ") .then(format!("{NAME} {VERSION}"), Style::new().yellow().bold()) .then_plain("!"); From 25d2cc7c9826295ea535e47863b26a18efe349ef Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 21 Feb 2025 12:15:13 +0100 Subject: [PATCH 05/44] Migrate to 2024 edition --- Cargo.toml | 9 ++------- rustfmt.toml | 1 + 2 files changed, 3 insertions(+), 7 deletions(-) create mode 100644 rustfmt.toml diff --git a/Cargo.toml b/Cargo.toml index 96c02c1..a58b43d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [workspace] -resolver = "2" +resolver = "3" members = ["cove", "cove-*"] [workspace.package] version = "0.8.3" -edition = "2021" +edition = "2024" [workspace.dependencies] anyhow = "1.0.96" @@ -68,11 +68,6 @@ rust.unused_lifetimes = "warn" rust.unused_qualifications = "warn" # Clippy clippy.use_self = "warn" -# Migrating to the 2024 edition -rust.rust_2024_compatibility = "warn" -rust.edition_2024_expr_fragment_specifier = { level = "allow", priority = 1 } -rust.if_let_rescope = { level = "allow", priority = 1 } -rust.tail_expr_drop_order = { level = "allow", priority = 1 } [profile.dev.package."*"] opt-level = 3 diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..8153a3d --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +style_edition = "2021" From 816d8f86a3034b7fccd871e9f6dcfaabf046c123 Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 21 Feb 2025 12:17:43 +0100 Subject: [PATCH 06/44] Migrate rustfmt style to 2024 edition --- cove-input/src/keys.rs | 4 ++-- cove-macro/src/lib.rs | 2 +- cove/src/main.rs | 2 +- cove/src/ui/chat.rs | 2 +- cove/src/ui/chat/blocks.rs | 2 +- cove/src/ui/chat/tree.rs | 4 ++-- cove/src/ui/chat/tree/renderer.rs | 4 ++-- cove/src/ui/chat/tree/scroll.rs | 6 +++--- cove/src/ui/chat/tree/widgets.rs | 2 +- cove/src/ui/euph/account.rs | 2 +- cove/src/ui/euph/auth.rs | 4 ++-- cove/src/ui/euph/inspect.rs | 2 +- cove/src/ui/euph/links.rs | 2 +- cove/src/ui/euph/nick.rs | 2 +- cove/src/ui/euph/nick_list.rs | 2 +- cove/src/ui/euph/popup.rs | 2 +- cove/src/ui/euph/room.rs | 2 +- cove/src/ui/key_bindings.rs | 2 +- cove/src/ui/rooms.rs | 2 +- cove/src/ui/rooms/connect.rs | 2 +- cove/src/ui/rooms/delete.rs | 2 +- cove/src/vault.rs | 2 +- cove/src/vault/euph.rs | 6 +++--- rustfmt.toml | 1 - 24 files changed, 31 insertions(+), 32 deletions(-) delete mode 100644 rustfmt.toml diff --git a/cove-input/src/keys.rs b/cove-input/src/keys.rs index 337a5f3..7e5cfa0 100644 --- a/cove-input/src/keys.rs +++ b/cove-input/src/keys.rs @@ -3,7 +3,7 @@ use std::num::ParseIntError; use std::str::FromStr; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; -use serde::{de::Error, Deserialize, Deserializer}; +use serde::{Deserialize, Deserializer, de::Error}; use serde::{Serialize, Serializer}; use serde_either::SingleOrVec; @@ -117,7 +117,7 @@ impl KeyPress { "alt" if !self.alt => self.alt = true, "any" if !self.shift && !self.ctrl && !self.alt => self.any = true, m @ ("shift" | "ctrl" | "alt" | "any") => { - return Err(ParseKeysError::ConflictingModifier(m.to_string())) + return Err(ParseKeysError::ConflictingModifier(m.to_string())); } m => return Err(ParseKeysError::UnknownModifier(m.to_string())), } diff --git a/cove-macro/src/lib.rs b/cove-macro/src/lib.rs index fd09f5f..c655f2a 100644 --- a/cove-macro/src/lib.rs +++ b/cove-macro/src/lib.rs @@ -1,4 +1,4 @@ -use syn::{parse_macro_input, DeriveInput}; +use syn::{DeriveInput, parse_macro_input}; mod document; mod key_group; diff --git a/cove/src/main.rs b/cove/src/main.rs index 6596eab..fe9a9c1 100644 --- a/cove/src/main.rs +++ b/cove/src/main.rs @@ -15,8 +15,8 @@ use std::path::PathBuf; use anyhow::Context; use clap::Parser; -use cove_config::doc::Document; use cove_config::Config; +use cove_config::doc::Document; use directories::{BaseDirs, ProjectDirs}; use log::info; use tokio::sync::mpsc; diff --git a/cove/src/ui/chat.rs b/cove/src/ui/chat.rs index cc7acc7..69f5e2b 100644 --- a/cove/src/ui/chat.rs +++ b/cove/src/ui/chat.rs @@ -6,8 +6,8 @@ mod widgets; use cove_config::Keys; use cove_input::InputEvent; -use jiff::tz::TimeZone; use jiff::Timestamp; +use jiff::tz::TimeZone; use toss::widgets::{BoxedAsync, EditorState}; use toss::{Styled, WidgetExt}; diff --git a/cove/src/ui/chat/blocks.rs b/cove/src/ui/chat/blocks.rs index 1b91864..8360e83 100644 --- a/cove/src/ui/chat/blocks.rs +++ b/cove/src/ui/chat/blocks.rs @@ -1,6 +1,6 @@ //! Common rendering logic. -use std::collections::{vec_deque, VecDeque}; +use std::collections::{VecDeque, vec_deque}; use toss::widgets::Predrawn; diff --git a/cove/src/ui/chat/tree.rs b/cove/src/ui/chat/tree.rs index b01602c..9ac31f8 100644 --- a/cove/src/ui/chat/tree.rs +++ b/cove/src/ui/chat/tree.rs @@ -16,13 +16,13 @@ use toss::widgets::EditorState; use toss::{AsyncWidget, Frame, Pos, Size, WidgetExt, WidthDb}; use crate::store::{Msg, MsgStore}; -use crate::ui::{util, ChatMsg, UiError}; +use crate::ui::{ChatMsg, UiError, util}; use crate::util::InfallibleExt; use self::renderer::{TreeContext, TreeRenderer}; -use super::cursor::Cursor; use super::Reaction; +use super::cursor::Cursor; pub struct TreeViewState> { store: S, diff --git a/cove/src/ui/chat/tree/renderer.rs b/cove/src/ui/chat/tree/renderer.rs index 3aeadb1..192e46c 100644 --- a/cove/src/ui/chat/tree/renderer.rs +++ b/cove/src/ui/chat/tree/renderer.rs @@ -9,10 +9,10 @@ use toss::widgets::{EditorState, Empty, Predrawn, Resize}; use toss::{Size, Widget, WidthDb}; use crate::store::{Msg, MsgStore, Tree}; +use crate::ui::ChatMsg; use crate::ui::chat::blocks::{Block, Blocks, Range}; use crate::ui::chat::cursor::Cursor; -use crate::ui::chat::renderer::{self, overlaps, Renderer}; -use crate::ui::ChatMsg; +use crate::ui::chat::renderer::{self, Renderer, overlaps}; use crate::util::InfallibleExt; use super::widgets; diff --git a/cove/src/ui/chat/tree/scroll.rs b/cove/src/ui/chat/tree/scroll.rs index b02c4a1..73e0e71 100644 --- a/cove/src/ui/chat/tree/scroll.rs +++ b/cove/src/ui/chat/tree/scroll.rs @@ -1,12 +1,12 @@ -use toss::widgets::EditorState; use toss::WidthDb; +use toss::widgets::EditorState; use crate::store::{Msg, MsgStore}; -use crate::ui::chat::cursor::Cursor; use crate::ui::ChatMsg; +use crate::ui::chat::cursor::Cursor; -use super::renderer::{TreeContext, TreeRenderer}; use super::TreeViewState; +use super::renderer::{TreeContext, TreeRenderer}; impl TreeViewState where diff --git a/cove/src/ui/chat/tree/widgets.rs b/cove/src/ui/chat/tree/widgets.rs index b302670..bc807d7 100644 --- a/cove/src/ui/chat/tree/widgets.rs +++ b/cove/src/ui/chat/tree/widgets.rs @@ -6,8 +6,8 @@ use toss::widgets::{Boxed, EditorState, Join2, Join4, Join5, Text}; use toss::{Style, Styled, WidgetExt}; use crate::store::Msg; -use crate::ui::chat::widgets::{Indent, Seen, Time}; use crate::ui::ChatMsg; +use crate::ui::chat::widgets::{Indent, Seen, Time}; use crate::util; pub const PLACEHOLDER: &str = "[...]"; diff --git a/cove/src/ui/euph/account.rs b/cove/src/ui/euph/account.rs index b97f014..a982711 100644 --- a/cove/src/ui/euph/account.rs +++ b/cove/src/ui/euph/account.rs @@ -8,7 +8,7 @@ use toss::{Style, Widget, WidgetExt}; use crate::euph::{self, Room}; use crate::ui::widgets::Popup; -use crate::ui::{util, UiError}; +use crate::ui::{UiError, util}; use super::popup::PopupResult; diff --git a/cove/src/ui/euph/auth.rs b/cove/src/ui/euph/auth.rs index b938ff1..2fbc1c0 100644 --- a/cove/src/ui/euph/auth.rs +++ b/cove/src/ui/euph/auth.rs @@ -1,11 +1,11 @@ use cove_config::Keys; use cove_input::InputEvent; -use toss::widgets::EditorState; use toss::Widget; +use toss::widgets::EditorState; use crate::euph::Room; use crate::ui::widgets::Popup; -use crate::ui::{util, UiError}; +use crate::ui::{UiError, util}; use super::popup::PopupResult; diff --git a/cove/src/ui/euph/inspect.rs b/cove/src/ui/euph/inspect.rs index d1e2380..e2bcf33 100644 --- a/cove/src/ui/euph/inspect.rs +++ b/cove/src/ui/euph/inspect.rs @@ -6,8 +6,8 @@ use euphoxide::conn::SessionInfo; use toss::widgets::Text; use toss::{Style, Styled, Widget}; -use crate::ui::widgets::Popup; use crate::ui::UiError; +use crate::ui::widgets::Popup; use super::popup::PopupResult; diff --git a/cove/src/ui/euph/links.rs b/cove/src/ui/euph/links.rs index 8e3f535..b3e5fb4 100644 --- a/cove/src/ui/euph/links.rs +++ b/cove/src/ui/euph/links.rs @@ -7,7 +7,7 @@ use toss::widgets::{Join2, Text}; use toss::{Style, Styled, Widget, WidgetExt}; use crate::ui::widgets::{ListBuilder, ListState, Popup}; -use crate::ui::{key_bindings, util, UiError}; +use crate::ui::{UiError, key_bindings, util}; use super::popup::PopupResult; diff --git a/cove/src/ui/euph/nick.rs b/cove/src/ui/euph/nick.rs index 0bb1062..91bdd10 100644 --- a/cove/src/ui/euph/nick.rs +++ b/cove/src/ui/euph/nick.rs @@ -6,7 +6,7 @@ use toss::{Style, Widget}; use crate::euph::{self, Room}; use crate::ui::widgets::Popup; -use crate::ui::{util, UiError}; +use crate::ui::{UiError, util}; use super::popup::PopupResult; diff --git a/cove/src/ui/euph/nick_list.rs b/cove/src/ui/euph/nick_list.rs index 47f09c7..8401c80 100644 --- a/cove/src/ui/euph/nick_list.rs +++ b/cove/src/ui/euph/nick_list.rs @@ -7,8 +7,8 @@ use toss::widgets::{Background, Text}; use toss::{Style, Styled, Widget, WidgetExt}; use crate::euph; -use crate::ui::widgets::{ListBuilder, ListState}; use crate::ui::UiError; +use crate::ui::widgets::{ListBuilder, ListState}; pub fn widget<'a>( list: &'a mut ListState, diff --git a/cove/src/ui/euph/popup.rs b/cove/src/ui/euph/popup.rs index 61b3ad5..e9d4671 100644 --- a/cove/src/ui/euph/popup.rs +++ b/cove/src/ui/euph/popup.rs @@ -4,8 +4,8 @@ use crossterm::style::Stylize; use toss::widgets::Text; use toss::{Style, Styled, Widget}; -use crate::ui::widgets::Popup; use crate::ui::UiError; +use crate::ui::widgets::Popup; pub enum RoomPopup { Error { description: String, reason: String }, diff --git a/cove/src/ui/euph/room.rs b/cove/src/ui/euph/room.rs index 0b36535..eafd789 100644 --- a/cove/src/ui/euph/room.rs +++ b/cove/src/ui/euph/room.rs @@ -16,7 +16,7 @@ use crate::euph; use crate::macros::logging_unwrap; use crate::ui::chat::{ChatState, Reaction}; use crate::ui::widgets::ListState; -use crate::ui::{util, UiError, UiEvent}; +use crate::ui::{UiError, UiEvent, util}; use crate::vault::EuphRoomVault; use super::account::AccountUiState; diff --git a/cove/src/ui/key_bindings.rs b/cove/src/ui/key_bindings.rs index f5fa714..de3c889 100644 --- a/cove/src/ui/key_bindings.rs +++ b/cove/src/ui/key_bindings.rs @@ -9,7 +9,7 @@ use toss::widgets::{Either2, Join2, Padding, Text}; use toss::{Style, Styled, Widget, WidgetExt}; use super::widgets::{ListBuilder, ListState, Popup}; -use super::{util, UiError}; +use super::{UiError, util}; type Line = Either2, Text>>; type Builder = ListBuilder<'static, Infallible, Line>; diff --git a/cove/src/ui/rooms.rs b/cove/src/ui/rooms.rs index a7bb6f8..f26defa 100644 --- a/cove/src/ui/rooms.rs +++ b/cove/src/ui/rooms.rs @@ -28,7 +28,7 @@ use self::delete::{DeleteResult, DeleteState}; use super::euph::room::EuphRoom; use super::widgets::{ListBuilder, ListState}; -use super::{key_bindings, util, UiError, UiEvent}; +use super::{UiError, UiEvent, key_bindings, util}; enum State { ShowList, diff --git a/cove/src/ui/rooms/connect.rs b/cove/src/ui/rooms/connect.rs index 2bf90c5..4ad3c39 100644 --- a/cove/src/ui/rooms/connect.rs +++ b/cove/src/ui/rooms/connect.rs @@ -5,7 +5,7 @@ use toss::widgets::{EditorState, Empty, Join2, Join3, Text}; use toss::{Style, Styled, Widget, WidgetExt}; use crate::ui::widgets::Popup; -use crate::ui::{util, UiError}; +use crate::ui::{UiError, util}; use crate::vault::RoomIdentifier; #[derive(Clone, Copy, PartialEq, Eq)] diff --git a/cove/src/ui/rooms/delete.rs b/cove/src/ui/rooms/delete.rs index 5a20415..d5b6884 100644 --- a/cove/src/ui/rooms/delete.rs +++ b/cove/src/ui/rooms/delete.rs @@ -5,7 +5,7 @@ use toss::widgets::{EditorState, Empty, Join2, Text}; use toss::{Style, Styled, Widget, WidgetExt}; use crate::ui::widgets::Popup; -use crate::ui::{util, UiError}; +use crate::ui::{UiError, util}; use crate::vault::RoomIdentifier; pub struct DeleteState { diff --git a/cove/src/vault.rs b/cove/src/vault.rs index 6861901..512dfd2 100644 --- a/cove/src/vault.rs +++ b/cove/src/vault.rs @@ -6,8 +6,8 @@ use std::fs; use std::path::Path; use rusqlite::Connection; -use vault::tokio::TokioVault; use vault::Action; +use vault::tokio::TokioVault; pub use self::euph::{EuphRoomVault, EuphVault, RoomIdentifier}; diff --git a/cove/src/vault/euph.rs b/cove/src/vault/euph.rs index c7d6410..3e98590 100644 --- a/cove/src/vault/euph.rs +++ b/cove/src/vault/euph.rs @@ -5,7 +5,7 @@ use async_trait::async_trait; use cookie::{Cookie, CookieJar}; use euphoxide::api::{Message, MessageId, SessionId, SessionView, Snowflake, Time, UserId}; use rusqlite::types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef}; -use rusqlite::{named_params, params, Connection, OptionalExtension, Row, ToSql, Transaction}; +use rusqlite::{Connection, OptionalExtension, Row, ToSql, Transaction, named_params, params}; use vault::Action; use crate::euph::SmallMessage; @@ -16,7 +16,7 @@ struct WSnowflake(Snowflake); impl ToSql for WSnowflake { fn to_sql(&self) -> rusqlite::Result> { - self.0 .0.to_sql() + self.0.0.to_sql() } } @@ -31,7 +31,7 @@ struct WTime(Time); impl ToSql for WTime { fn to_sql(&self) -> rusqlite::Result> { - let timestamp = self.0 .0; + let timestamp = self.0.0; Ok(ToSqlOutput::Owned(Value::Integer(timestamp))) } } diff --git a/rustfmt.toml b/rustfmt.toml deleted file mode 100644 index 8153a3d..0000000 --- a/rustfmt.toml +++ /dev/null @@ -1 +0,0 @@ -style_edition = "2021" From fbc64de60713c8e7f065ad36ca055be9bf4f1b8d Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 21 Feb 2025 12:42:51 +0100 Subject: [PATCH 07/44] Merge and reorder imports This change brings them in-line with the default settings of rust-analyzer. Originally, I disliked this style, but by now, I've grown used to it and prefer it slightly. Also, I like staying on the default path since I usually don't need to check the imports to see if rust-analyzer messed anything up (except for omitting the self:: when importing modules defined in the current module, grr :D). I've also come around to the idea of trailing mod definitions instead of putting them at the top: I would also put module definitions that contain code instead of referencing another file below the imports. It feels weird to have code above imports. So it just makes sense to do the same for all types of mod definitions. If rustfmt ever gains stable support for grouping imports, I'll probably use that instead. --- .vscode/settings.json | 2 +- cove-config/src/doc.rs | 3 +- cove-config/src/lib.rs | 19 ++++++----- cove-input/src/keys.rs | 7 ++-- cove-input/src/lib.rs | 7 ++-- cove-macro/src/document.rs | 3 +- cove-macro/src/key_group.rs | 3 +- cove-macro/src/util.rs | 7 ++-- cove/src/euph.rs | 8 ++--- cove/src/euph/room.rs | 24 ++++++------- cove/src/euph/small_message.rs | 3 +- cove/src/export.rs | 12 ++++--- cove/src/export/text.rs | 4 +-- cove/src/logger.rs | 10 +++--- cove/src/main.rs | 33 +++++++++--------- cove/src/store.rs | 5 +-- cove/src/ui.rs | 52 ++++++++++++++-------------- cove/src/ui/chat.rs | 32 +++++++++--------- cove/src/ui/chat/cursor.rs | 3 +- cove/src/ui/chat/tree.rs | 22 ++++++------ cove/src/ui/chat/tree/renderer.rs | 27 +++++++++------ cove/src/ui/chat/tree/scroll.rs | 16 +++++---- cove/src/ui/chat/tree/widgets.rs | 18 ++++++---- cove/src/ui/chat/widgets.rs | 6 ++-- cove/src/ui/euph/account.rs | 16 +++++---- cove/src/ui/euph/auth.rs | 10 +++--- cove/src/ui/euph/inspect.rs | 12 +++---- cove/src/ui/euph/links.rs | 15 +++++---- cove/src/ui/euph/nick.rs | 10 +++--- cove/src/ui/euph/nick_list.rs | 22 ++++++++---- cove/src/ui/euph/popup.rs | 6 ++-- cove/src/ui/euph/room.rs | 48 ++++++++++++++++---------- cove/src/ui/key_bindings.rs | 12 ++++--- cove/src/ui/rooms.rs | 56 +++++++++++++++++++------------ cove/src/ui/rooms/connect.rs | 13 ++++--- cove/src/ui/rooms/delete.rs | 13 ++++--- cove/src/ui/widgets.rs | 6 ++-- cove/src/ui/widgets/popup.rs | 6 ++-- cove/src/util.rs | 3 +- cove/src/vault.rs | 16 ++++----- cove/src/vault/euph.rs | 15 +++++---- 41 files changed, 332 insertions(+), 273 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7a89179..4e428aa 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,7 @@ "files.insertFinalNewline": true, "rust-analyzer.cargo.features": "all", "rust-analyzer.imports.granularity.enforce": true, - "rust-analyzer.imports.granularity.group": "module", + "rust-analyzer.imports.granularity.group": "crate", "rust-analyzer.imports.group.enable": true, "evenBetterToml.formatter.columnWidth": 100, } diff --git a/cove-config/src/doc.rs b/cove-config/src/doc.rs index 16ed3ac..35f6074 100644 --- a/cove-config/src/doc.rs +++ b/cove-config/src/doc.rs @@ -1,7 +1,6 @@ //! Auto-generate markdown documentation. -use std::collections::HashMap; -use std::path::PathBuf; +use std::{collections::HashMap, path::PathBuf}; use cove_input::KeyBinding; pub use cove_macro::Document; diff --git a/cove-config/src/lib.rs b/cove-config/src/lib.rs index 026ce9e..0d350ed 100644 --- a/cove-config/src/lib.rs +++ b/cove-config/src/lib.rs @@ -1,16 +1,17 @@ -pub mod doc; -mod euph; -mod keys; - -use std::io::ErrorKind; -use std::path::{Path, PathBuf}; -use std::{fs, io}; +use std::{ + fs, + io::{self, ErrorKind}, + path::{Path, PathBuf}, +}; use doc::Document; use serde::Deserialize; -pub use crate::euph::*; -pub use crate::keys::*; +pub use crate::{euph::*, keys::*}; + +pub mod doc; +mod euph; +mod keys; #[derive(Debug, thiserror::Error)] pub enum Error { diff --git a/cove-input/src/keys.rs b/cove-input/src/keys.rs index 7e5cfa0..8d2fdf1 100644 --- a/cove-input/src/keys.rs +++ b/cove-input/src/keys.rs @@ -1,10 +1,7 @@ -use std::fmt; -use std::num::ParseIntError; -use std::str::FromStr; +use std::{fmt, num::ParseIntError, str::FromStr}; use crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; -use serde::{Deserialize, Deserializer, de::Error}; -use serde::{Serialize, Serializer}; +use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error}; use serde_either::SingleOrVec; #[derive(Debug, thiserror::Error)] diff --git a/cove-input/src/lib.rs b/cove-input/src/lib.rs index c15c4c3..f6b2e92 100644 --- a/cove-input/src/lib.rs +++ b/cove-input/src/lib.rs @@ -1,7 +1,4 @@ -mod keys; - -use std::io; -use std::sync::Arc; +use std::{io, sync::Arc}; pub use cove_macro::KeyGroup; use crossterm::event::{Event, KeyEvent, KeyEventKind}; @@ -10,6 +7,8 @@ use toss::{Frame, Terminal, WidthDb}; pub use crate::keys::*; +mod keys; + pub struct KeyBindingInfo<'a> { pub name: &'static str, pub binding: &'a KeyBinding, diff --git a/cove-macro/src/document.rs b/cove-macro/src/document.rs index e8e248e..afec84d 100644 --- a/cove-macro/src/document.rs +++ b/cove-macro/src/document.rs @@ -1,7 +1,6 @@ use proc_macro2::TokenStream; use quote::quote; -use syn::spanned::Spanned; -use syn::{Data, DataEnum, DataStruct, DeriveInput, Field, Ident, LitStr}; +use syn::{Data, DataEnum, DataStruct, DeriveInput, Field, Ident, LitStr, spanned::Spanned}; use crate::util::{self, SerdeDefault}; diff --git a/cove-macro/src/key_group.rs b/cove-macro/src/key_group.rs index 84d8cff..832bfd3 100644 --- a/cove-macro/src/key_group.rs +++ b/cove-macro/src/key_group.rs @@ -1,7 +1,6 @@ use proc_macro2::TokenStream; use quote::quote; -use syn::spanned::Spanned; -use syn::{Data, DeriveInput}; +use syn::{Data, DeriveInput, spanned::Spanned}; use crate::util; diff --git a/cove-macro/src/util.rs b/cove-macro/src/util.rs index b7bf62a..d73b7ca 100644 --- a/cove-macro/src/util.rs +++ b/cove-macro/src/util.rs @@ -1,8 +1,9 @@ use proc_macro2::{Span, TokenStream}; use quote::quote; -use syn::parse::Parse; -use syn::punctuated::Punctuated; -use syn::{Attribute, Expr, ExprLit, ExprPath, Field, Lit, LitStr, Path, Token, Type}; +use syn::{ + Attribute, Expr, ExprLit, ExprPath, Field, Lit, LitStr, Path, Token, Type, parse::Parse, + punctuated::Punctuated, +}; pub fn bail(span: Span, message: &str) -> syn::Result { Err(syn::Error::new(span, message)) diff --git a/cove/src/euph.rs b/cove/src/euph.rs index ab93753..d1fd872 100644 --- a/cove/src/euph.rs +++ b/cove/src/euph.rs @@ -1,7 +1,7 @@ -mod room; -mod small_message; -mod util; - pub use room::*; pub use small_message::*; pub use util::*; + +mod room; +mod small_message; +mod util; diff --git a/cove/src/euph/room.rs b/cove/src/euph/room.rs index 64ddfe6..17aafe4 100644 --- a/cove/src/euph/room.rs +++ b/cove/src/euph/room.rs @@ -1,21 +1,19 @@ // TODO Remove rl2dev-specific code -use std::convert::Infallible; -use std::time::Duration; +use std::{convert::Infallible, time::Duration}; -use euphoxide::api::packet::ParsedPacket; -use euphoxide::api::{ - Auth, AuthOption, Data, Log, Login, Logout, MessageId, Nick, Send, SendEvent, SendReply, Time, - UserId, +use euphoxide::{ + api::{ + Auth, AuthOption, Data, Log, Login, Logout, MessageId, Nick, Send, SendEvent, SendReply, + Time, UserId, packet::ParsedPacket, + }, + bot::instance::{ConnSnapshot, Event, Instance, InstanceConfig}, + conn::{self, ConnTx, Joined}, }; -use euphoxide::bot::instance::{ConnSnapshot, Event, Instance, InstanceConfig}; -use euphoxide::conn::{self, ConnTx, Joined}; -use log::{debug, error, info, warn}; -use tokio::select; -use tokio::sync::oneshot; +use log::{debug, info, warn}; +use tokio::{select, sync::oneshot}; -use crate::macros::logging_unwrap; -use crate::vault::EuphRoomVault; +use crate::{macros::logging_unwrap, vault::EuphRoomVault}; const LOG_INTERVAL: Duration = Duration::from_secs(10); diff --git a/cove/src/euph/small_message.rs b/cove/src/euph/small_message.rs index 994b0ae..20596fa 100644 --- a/cove/src/euph/small_message.rs +++ b/cove/src/euph/small_message.rs @@ -5,8 +5,7 @@ use euphoxide::api::{MessageId, Snowflake, Time}; use jiff::Timestamp; use toss::{Style, Styled}; -use crate::store::Msg; -use crate::ui::ChatMsg; +use crate::{store::Msg, ui::ChatMsg}; use super::util; diff --git a/cove/src/export.rs b/cove/src/export.rs index 0ad9414..80db7b6 100644 --- a/cove/src/export.rs +++ b/cove/src/export.rs @@ -1,13 +1,15 @@ //! Export logs from the vault to plain text files. +use std::{ + fs::File, + io::{self, BufWriter, Write}, +}; + +use crate::vault::{EuphRoomVault, EuphVault, RoomIdentifier}; + mod json; mod text; -use std::fs::File; -use std::io::{self, BufWriter, Write}; - -use crate::vault::{EuphRoomVault, EuphVault, RoomIdentifier}; - #[derive(Debug, Clone, Copy, clap::ValueEnum)] pub enum Format { /// Human-readable tree-structured messages. diff --git a/cove/src/export/text.rs b/cove/src/export/text.rs index 23a75d8..2ca6687 100644 --- a/cove/src/export/text.rs +++ b/cove/src/export/text.rs @@ -3,9 +3,7 @@ use std::io::Write; use euphoxide::api::MessageId; use unicode_width::UnicodeWidthStr; -use crate::euph::SmallMessage; -use crate::store::Tree; -use crate::vault::EuphRoomVault; +use crate::{euph::SmallMessage, store::Tree, vault::EuphRoomVault}; const TIME_FORMAT: &str = "%Y-%m-%d %H:%M:%S"; const TIME_EMPTY: &str = " "; diff --git a/cove/src/logger.rs b/cove/src/logger.rs index 5574960..940e1a9 100644 --- a/cove/src/logger.rs +++ b/cove/src/logger.rs @@ -1,6 +1,4 @@ -use std::convert::Infallible; -use std::sync::Arc; -use std::vec; +use std::{convert::Infallible, sync::Arc, vec}; use async_trait::async_trait; use crossterm::style::Stylize; @@ -10,8 +8,10 @@ use parking_lot::Mutex; use tokio::sync::mpsc; use toss::{Style, Styled}; -use crate::store::{Msg, MsgStore, Path, Tree}; -use crate::ui::ChatMsg; +use crate::{ + store::{Msg, MsgStore, Path, Tree}, + ui::ChatMsg, +}; #[derive(Debug, Clone)] pub struct LogMsg { diff --git a/cove/src/main.rs b/cove/src/main.rs index fe9a9c1..642b62e 100644 --- a/cove/src/main.rs +++ b/cove/src/main.rs @@ -1,6 +1,23 @@ // TODO Remove unnecessary Debug impls and compare compile times // TODO Invoke external notification command? +use std::path::PathBuf; + +use anyhow::Context; +use clap::Parser; +use cove_config::{Config, doc::Document}; +use directories::{BaseDirs, ProjectDirs}; +use log::info; +use tokio::sync::mpsc; +use toss::Terminal; + +use crate::{ + logger::Logger, + ui::Ui, + vault::Vault, + version::{NAME, VERSION}, +}; + mod euph; mod export; mod logger; @@ -11,22 +28,6 @@ mod util; mod vault; mod version; -use std::path::PathBuf; - -use anyhow::Context; -use clap::Parser; -use cove_config::Config; -use cove_config::doc::Document; -use directories::{BaseDirs, ProjectDirs}; -use log::info; -use tokio::sync::mpsc; -use toss::Terminal; - -use crate::logger::Logger; -use crate::ui::Ui; -use crate::vault::Vault; -use crate::version::{NAME, VERSION}; - #[derive(Debug, clap::Parser)] enum Command { /// Run the client interactively (default). diff --git a/cove/src/store.rs b/cove/src/store.rs index f6c85b7..f64f71e 100644 --- a/cove/src/store.rs +++ b/cove/src/store.rs @@ -1,7 +1,4 @@ -use std::collections::HashMap; -use std::fmt::Debug; -use std::hash::Hash; -use std::vec; +use std::{collections::HashMap, fmt::Debug, hash::Hash, vec}; use async_trait::async_trait; diff --git a/cove/src/ui.rs b/cove/src/ui.rs index 0263325..1c03834 100644 --- a/cove/src/ui.rs +++ b/cove/src/ui.rs @@ -1,3 +1,30 @@ +use std::{ + convert::Infallible, + io, + sync::{Arc, Weak}, + time::{Duration, Instant}, +}; + +use cove_config::Config; +use cove_input::InputEvent; +use jiff::tz::TimeZone; +use parking_lot::FairMutex; +use tokio::{ + sync::mpsc::{self, UnboundedReceiver, UnboundedSender, error::TryRecvError}, + task, +}; +use toss::{Terminal, WidgetExt, widgets::BoxedAsync}; + +use crate::{ + logger::{LogMsg, Logger}, + macros::logging_unwrap, + util::InfallibleExt, + vault::Vault, +}; + +pub use self::chat::ChatMsg; +use self::{chat::ChatState, rooms::Rooms, widgets::ListState}; + mod chat; mod euph; mod key_bindings; @@ -5,31 +32,6 @@ mod rooms; mod util; mod widgets; -use std::convert::Infallible; -use std::io; -use std::sync::{Arc, Weak}; -use std::time::{Duration, Instant}; - -use cove_config::Config; -use cove_input::InputEvent; -use jiff::tz::TimeZone; -use parking_lot::FairMutex; -use tokio::sync::mpsc::error::TryRecvError; -use tokio::sync::mpsc::{self, UnboundedReceiver, UnboundedSender}; -use tokio::task; -use toss::widgets::BoxedAsync; -use toss::{Terminal, WidgetExt}; - -use crate::logger::{LogMsg, Logger}; -use crate::macros::logging_unwrap; -use crate::util::InfallibleExt; -use crate::vault::Vault; - -pub use self::chat::ChatMsg; -use self::chat::ChatState; -use self::rooms::Rooms; -use self::widgets::ListState; - /// Time to spend batch processing events before redrawing the screen. const EVENT_PROCESSING_TIME: Duration = Duration::from_millis(1000 / 15); // 15 fps diff --git a/cove/src/ui/chat.rs b/cove/src/ui/chat.rs index 69f5e2b..405339b 100644 --- a/cove/src/ui/chat.rs +++ b/cove/src/ui/chat.rs @@ -1,24 +1,26 @@ +use cove_config::Keys; +use cove_input::InputEvent; +use jiff::{Timestamp, tz::TimeZone}; +use toss::{ + Styled, WidgetExt, + widgets::{BoxedAsync, EditorState}, +}; + +use crate::{ + store::{Msg, MsgStore}, + util, +}; + +use super::UiError; + +use self::{cursor::Cursor, tree::TreeViewState}; + mod blocks; mod cursor; mod renderer; mod tree; mod widgets; -use cove_config::Keys; -use cove_input::InputEvent; -use jiff::Timestamp; -use jiff::tz::TimeZone; -use toss::widgets::{BoxedAsync, EditorState}; -use toss::{Styled, WidgetExt}; - -use crate::store::{Msg, MsgStore}; -use crate::util; - -use self::cursor::Cursor; -use self::tree::TreeViewState; - -use super::UiError; - pub trait ChatMsg { fn time(&self) -> Option; fn styled(&self) -> (Styled, Styled); diff --git a/cove/src/ui/chat/cursor.rs b/cove/src/ui/chat/cursor.rs index 561f4ed..87bd8fc 100644 --- a/cove/src/ui/chat/cursor.rs +++ b/cove/src/ui/chat/cursor.rs @@ -1,7 +1,6 @@ //! Common cursor movement logic. -use std::collections::HashSet; -use std::hash::Hash; +use std::{collections::HashSet, hash::Hash}; use crate::store::{Msg, MsgStore, Tree}; diff --git a/cove/src/ui/chat/tree.rs b/cove/src/ui/chat/tree.rs index 9ac31f8..043e109 100644 --- a/cove/src/ui/chat/tree.rs +++ b/cove/src/ui/chat/tree.rs @@ -2,27 +2,27 @@ // TODO Focusing on sub-trees -mod renderer; -mod scroll; -mod widgets; - use std::collections::HashSet; use async_trait::async_trait; use cove_config::Keys; use cove_input::InputEvent; use jiff::tz::TimeZone; -use toss::widgets::EditorState; -use toss::{AsyncWidget, Frame, Pos, Size, WidgetExt, WidthDb}; +use toss::{AsyncWidget, Frame, Pos, Size, WidgetExt, WidthDb, widgets::EditorState}; -use crate::store::{Msg, MsgStore}; -use crate::ui::{ChatMsg, UiError, util}; -use crate::util::InfallibleExt; +use crate::{ + store::{Msg, MsgStore}, + ui::{UiError, util}, + util::InfallibleExt, +}; + +use super::{ChatMsg, Reaction, cursor::Cursor}; use self::renderer::{TreeContext, TreeRenderer}; -use super::Reaction; -use super::cursor::Cursor; +mod renderer; +mod scroll; +mod widgets; pub struct TreeViewState> { store: S, diff --git a/cove/src/ui/chat/tree/renderer.rs b/cove/src/ui/chat/tree/renderer.rs index 192e46c..142624e 100644 --- a/cove/src/ui/chat/tree/renderer.rs +++ b/cove/src/ui/chat/tree/renderer.rs @@ -1,19 +1,26 @@ //! A [`Renderer`] for message trees. -use std::collections::HashSet; -use std::convert::Infallible; +use std::{collections::HashSet, convert::Infallible}; use async_trait::async_trait; use jiff::tz::TimeZone; -use toss::widgets::{EditorState, Empty, Predrawn, Resize}; -use toss::{Size, Widget, WidthDb}; +use toss::{ + Size, Widget, WidthDb, + widgets::{EditorState, Empty, Predrawn, Resize}, +}; -use crate::store::{Msg, MsgStore, Tree}; -use crate::ui::ChatMsg; -use crate::ui::chat::blocks::{Block, Blocks, Range}; -use crate::ui::chat::cursor::Cursor; -use crate::ui::chat::renderer::{self, Renderer, overlaps}; -use crate::util::InfallibleExt; +use crate::{ + store::{Msg, MsgStore, Tree}, + ui::{ + ChatMsg, + chat::{ + blocks::{Block, Blocks, Range}, + cursor::Cursor, + renderer::{self, Renderer, overlaps}, + }, + }, + util::InfallibleExt, +}; use super::widgets; diff --git a/cove/src/ui/chat/tree/scroll.rs b/cove/src/ui/chat/tree/scroll.rs index 73e0e71..ab3ddae 100644 --- a/cove/src/ui/chat/tree/scroll.rs +++ b/cove/src/ui/chat/tree/scroll.rs @@ -1,12 +1,14 @@ -use toss::WidthDb; -use toss::widgets::EditorState; +use toss::{WidthDb, widgets::EditorState}; -use crate::store::{Msg, MsgStore}; -use crate::ui::ChatMsg; -use crate::ui::chat::cursor::Cursor; +use crate::{ + store::{Msg, MsgStore}, + ui::{ChatMsg, chat::cursor::Cursor}, +}; -use super::TreeViewState; -use super::renderer::{TreeContext, TreeRenderer}; +use super::{ + TreeViewState, + renderer::{TreeContext, TreeRenderer}, +}; impl TreeViewState where diff --git a/cove/src/ui/chat/tree/widgets.rs b/cove/src/ui/chat/tree/widgets.rs index bc807d7..d46920e 100644 --- a/cove/src/ui/chat/tree/widgets.rs +++ b/cove/src/ui/chat/tree/widgets.rs @@ -2,13 +2,19 @@ use std::convert::Infallible; use crossterm::style::Stylize; use jiff::tz::TimeZone; -use toss::widgets::{Boxed, EditorState, Join2, Join4, Join5, Text}; -use toss::{Style, Styled, WidgetExt}; +use toss::{ + Style, Styled, WidgetExt, + widgets::{Boxed, EditorState, Join2, Join4, Join5, Text}, +}; -use crate::store::Msg; -use crate::ui::ChatMsg; -use crate::ui::chat::widgets::{Indent, Seen, Time}; -use crate::util; +use crate::{ + store::Msg, + ui::{ + ChatMsg, + chat::widgets::{Indent, Seen, Time}, + }, + util, +}; pub const PLACEHOLDER: &str = "[...]"; diff --git a/cove/src/ui/chat/widgets.rs b/cove/src/ui/chat/widgets.rs index 43ad29e..e0e2fe5 100644 --- a/cove/src/ui/chat/widgets.rs +++ b/cove/src/ui/chat/widgets.rs @@ -2,8 +2,10 @@ use std::convert::Infallible; use crossterm::style::Stylize; use jiff::Zoned; -use toss::widgets::{Boxed, Empty, Text}; -use toss::{Frame, Pos, Size, Style, Widget, WidgetExt, WidthDb}; +use toss::{ + Frame, Pos, Size, Style, Widget, WidgetExt, WidthDb, + widgets::{Boxed, Empty, Text}, +}; use crate::util::InfallibleExt; diff --git a/cove/src/ui/euph/account.rs b/cove/src/ui/euph/account.rs index a982711..48731d9 100644 --- a/cove/src/ui/euph/account.rs +++ b/cove/src/ui/euph/account.rs @@ -1,14 +1,16 @@ use cove_config::Keys; use cove_input::InputEvent; use crossterm::style::Stylize; -use euphoxide::api::PersonalAccountView; -use euphoxide::conn; -use toss::widgets::{EditorState, Empty, Join3, Join4, Join5, Text}; -use toss::{Style, Widget, WidgetExt}; +use euphoxide::{api::PersonalAccountView, conn}; +use toss::{ + Style, Widget, WidgetExt, + widgets::{EditorState, Empty, Join3, Join4, Join5, Text}, +}; -use crate::euph::{self, Room}; -use crate::ui::widgets::Popup; -use crate::ui::{UiError, util}; +use crate::{ + euph::{self, Room}, + ui::{UiError, util, widgets::Popup}, +}; use super::popup::PopupResult; diff --git a/cove/src/ui/euph/auth.rs b/cove/src/ui/euph/auth.rs index 2fbc1c0..259e204 100644 --- a/cove/src/ui/euph/auth.rs +++ b/cove/src/ui/euph/auth.rs @@ -1,11 +1,11 @@ use cove_config::Keys; use cove_input::InputEvent; -use toss::Widget; -use toss::widgets::EditorState; +use toss::{Widget, widgets::EditorState}; -use crate::euph::Room; -use crate::ui::widgets::Popup; -use crate::ui::{UiError, util}; +use crate::{ + euph::Room, + ui::{UiError, util, widgets::Popup}, +}; use super::popup::PopupResult; diff --git a/cove/src/ui/euph/inspect.rs b/cove/src/ui/euph/inspect.rs index e2bcf33..b3c4e0e 100644 --- a/cove/src/ui/euph/inspect.rs +++ b/cove/src/ui/euph/inspect.rs @@ -1,13 +1,13 @@ use cove_config::Keys; use cove_input::InputEvent; use crossterm::style::Stylize; -use euphoxide::api::{Message, NickEvent, SessionView}; -use euphoxide::conn::SessionInfo; -use toss::widgets::Text; -use toss::{Style, Styled, Widget}; +use euphoxide::{ + api::{Message, NickEvent, SessionView}, + conn::SessionInfo, +}; +use toss::{Style, Styled, Widget, widgets::Text}; -use crate::ui::UiError; -use crate::ui::widgets::Popup; +use crate::ui::{UiError, widgets::Popup}; use super::popup::PopupResult; diff --git a/cove/src/ui/euph/links.rs b/cove/src/ui/euph/links.rs index b3e5fb4..14496a6 100644 --- a/cove/src/ui/euph/links.rs +++ b/cove/src/ui/euph/links.rs @@ -1,13 +1,16 @@ use cove_config::{Config, Keys}; use cove_input::InputEvent; -use crossterm::event::KeyCode; -use crossterm::style::Stylize; +use crossterm::{event::KeyCode, style::Stylize}; use linkify::{LinkFinder, LinkKind}; -use toss::widgets::{Join2, Text}; -use toss::{Style, Styled, Widget, WidgetExt}; +use toss::{ + Style, Styled, Widget, WidgetExt, + widgets::{Join2, Text}, +}; -use crate::ui::widgets::{ListBuilder, ListState, Popup}; -use crate::ui::{UiError, key_bindings, util}; +use crate::ui::{ + UiError, key_bindings, util, + widgets::{ListBuilder, ListState, Popup}, +}; use super::popup::PopupResult; diff --git a/cove/src/ui/euph/nick.rs b/cove/src/ui/euph/nick.rs index 91bdd10..1940fac 100644 --- a/cove/src/ui/euph/nick.rs +++ b/cove/src/ui/euph/nick.rs @@ -1,12 +1,12 @@ use cove_config::Keys; use cove_input::InputEvent; use euphoxide::conn::Joined; -use toss::widgets::EditorState; -use toss::{Style, Widget}; +use toss::{Style, Widget, widgets::EditorState}; -use crate::euph::{self, Room}; -use crate::ui::widgets::Popup; -use crate::ui::{UiError, util}; +use crate::{ + euph::{self, Room}, + ui::{UiError, util, widgets::Popup}, +}; use super::popup::PopupResult; diff --git a/cove/src/ui/euph/nick_list.rs b/cove/src/ui/euph/nick_list.rs index 8401c80..e1e4e3d 100644 --- a/cove/src/ui/euph/nick_list.rs +++ b/cove/src/ui/euph/nick_list.rs @@ -1,14 +1,22 @@ use std::iter; use crossterm::style::{Color, Stylize}; -use euphoxide::api::{NickEvent, SessionId, SessionType, SessionView, UserId}; -use euphoxide::conn::{Joined, SessionInfo}; -use toss::widgets::{Background, Text}; -use toss::{Style, Styled, Widget, WidgetExt}; +use euphoxide::{ + api::{NickEvent, SessionId, SessionType, SessionView, UserId}, + conn::{Joined, SessionInfo}, +}; +use toss::{ + Style, Styled, Widget, WidgetExt, + widgets::{Background, Text}, +}; -use crate::euph; -use crate::ui::UiError; -use crate::ui::widgets::{ListBuilder, ListState}; +use crate::{ + euph, + ui::{ + UiError, + widgets::{ListBuilder, ListState}, + }, +}; pub fn widget<'a>( list: &'a mut ListState, diff --git a/cove/src/ui/euph/popup.rs b/cove/src/ui/euph/popup.rs index e9d4671..3f8caaa 100644 --- a/cove/src/ui/euph/popup.rs +++ b/cove/src/ui/euph/popup.rs @@ -1,11 +1,9 @@ use std::io; use crossterm::style::Stylize; -use toss::widgets::Text; -use toss::{Style, Styled, Widget}; +use toss::{Style, Styled, Widget, widgets::Text}; -use crate::ui::UiError; -use crate::ui::widgets::Popup; +use crate::ui::{UiError, widgets::Popup}; pub enum RoomPopup { Error { description: String, reason: String }, diff --git a/cove/src/ui/euph/room.rs b/cove/src/ui/euph/room.rs index eafd789..7d4b49c 100644 --- a/cove/src/ui/euph/room.rs +++ b/cove/src/ui/euph/room.rs @@ -3,26 +3,40 @@ use std::collections::VecDeque; use cove_config::{Config, Keys}; use cove_input::InputEvent; use crossterm::style::Stylize; -use euphoxide::api::{Data, Message, MessageId, PacketType, SessionId}; -use euphoxide::bot::instance::{Event, ServerConfig}; -use euphoxide::conn::{self, Joined, Joining, SessionInfo}; +use euphoxide::{ + api::{Data, Message, MessageId, PacketType, SessionId}, + bot::instance::{Event, ServerConfig}, + conn::{self, Joined, Joining, SessionInfo}, +}; use jiff::tz::TimeZone; -use tokio::sync::oneshot::error::TryRecvError; -use tokio::sync::{mpsc, oneshot}; -use toss::widgets::{BoxedAsync, EditorState, Join2, Layer, Text}; -use toss::{Style, Styled, Widget, WidgetExt}; +use tokio::sync::{ + mpsc, + oneshot::{self, error::TryRecvError}, +}; +use toss::{ + Style, Styled, Widget, WidgetExt, + widgets::{BoxedAsync, EditorState, Join2, Layer, Text}, +}; -use crate::euph; -use crate::macros::logging_unwrap; -use crate::ui::chat::{ChatState, Reaction}; -use crate::ui::widgets::ListState; -use crate::ui::{UiError, UiEvent, util}; -use crate::vault::EuphRoomVault; +use crate::{ + euph, + macros::logging_unwrap, + ui::{ + UiError, UiEvent, + chat::{ChatState, Reaction}, + util, + widgets::ListState, + }, + vault::EuphRoomVault, +}; -use super::account::AccountUiState; -use super::links::LinksState; -use super::popup::{PopupResult, RoomPopup}; -use super::{auth, inspect, nick, nick_list}; +use super::{ + account::AccountUiState, + auth, inspect, + links::LinksState, + nick, nick_list, + popup::{PopupResult, RoomPopup}, +}; #[derive(Debug, Clone, Copy, PartialEq, Eq)] enum Focus { diff --git a/cove/src/ui/key_bindings.rs b/cove/src/ui/key_bindings.rs index de3c889..daedc16 100644 --- a/cove/src/ui/key_bindings.rs +++ b/cove/src/ui/key_bindings.rs @@ -5,11 +5,15 @@ use std::convert::Infallible; use cove_config::{Config, Keys}; use cove_input::{InputEvent, KeyBinding, KeyBindingInfo, KeyGroupInfo}; use crossterm::style::Stylize; -use toss::widgets::{Either2, Join2, Padding, Text}; -use toss::{Style, Styled, Widget, WidgetExt}; +use toss::{ + Style, Styled, Widget, WidgetExt, + widgets::{Either2, Join2, Padding, Text}, +}; -use super::widgets::{ListBuilder, ListState, Popup}; -use super::{UiError, util}; +use super::{ + UiError, util, + widgets::{ListBuilder, ListState, Popup}, +}; type Line = Either2, Text>>; type Builder = ListBuilder<'static, Infallible, Line>; diff --git a/cove/src/ui/rooms.rs b/cove/src/ui/rooms.rs index f26defa..a6e7b34 100644 --- a/cove/src/ui/rooms.rs +++ b/cove/src/ui/rooms.rs @@ -1,34 +1,46 @@ -mod connect; -mod delete; - -use std::collections::hash_map::Entry; -use std::collections::{HashMap, HashSet}; -use std::iter; -use std::sync::{Arc, Mutex}; -use std::time::Duration; +use std::{ + collections::{HashMap, HashSet, hash_map::Entry}, + iter, + sync::{Arc, Mutex}, + time::Duration, +}; use cove_config::{Config, Keys, RoomsSortOrder}; use cove_input::InputEvent; use crossterm::style::Stylize; -use euphoxide::api::SessionType; -use euphoxide::bot::instance::{Event, ServerConfig}; -use euphoxide::conn::{self, Joined}; +use euphoxide::{ + api::SessionType, + bot::instance::{Event, ServerConfig}, + conn::{self, Joined}, +}; use jiff::tz::TimeZone; use tokio::sync::mpsc; -use toss::widgets::{BoxedAsync, Empty, Join2, Text}; -use toss::{Style, Styled, Widget, WidgetExt}; +use toss::{ + Style, Styled, Widget, WidgetExt, + widgets::{BoxedAsync, Empty, Join2, Text}, +}; -use crate::euph; -use crate::macros::logging_unwrap; -use crate::vault::{EuphVault, RoomIdentifier, Vault}; -use crate::version::{NAME, VERSION}; +use crate::{ + euph, + macros::logging_unwrap, + vault::{EuphVault, RoomIdentifier, Vault}, + version::{NAME, VERSION}, +}; -use self::connect::{ConnectResult, ConnectState}; -use self::delete::{DeleteResult, DeleteState}; +use super::{ + UiError, UiEvent, + euph::room::EuphRoom, + key_bindings, util, + widgets::{ListBuilder, ListState}, +}; -use super::euph::room::EuphRoom; -use super::widgets::{ListBuilder, ListState}; -use super::{UiError, UiEvent, key_bindings, util}; +use self::{ + connect::{ConnectResult, ConnectState}, + delete::{DeleteResult, DeleteState}, +}; + +mod connect; +mod delete; enum State { ShowList, diff --git a/cove/src/ui/rooms/connect.rs b/cove/src/ui/rooms/connect.rs index 4ad3c39..ce53775 100644 --- a/cove/src/ui/rooms/connect.rs +++ b/cove/src/ui/rooms/connect.rs @@ -1,12 +1,15 @@ use cove_config::Keys; use cove_input::InputEvent; use crossterm::style::Stylize; -use toss::widgets::{EditorState, Empty, Join2, Join3, Text}; -use toss::{Style, Styled, Widget, WidgetExt}; +use toss::{ + Style, Styled, Widget, WidgetExt, + widgets::{EditorState, Empty, Join2, Join3, Text}, +}; -use crate::ui::widgets::Popup; -use crate::ui::{UiError, util}; -use crate::vault::RoomIdentifier; +use crate::{ + ui::{UiError, util, widgets::Popup}, + vault::RoomIdentifier, +}; #[derive(Clone, Copy, PartialEq, Eq)] enum Focus { diff --git a/cove/src/ui/rooms/delete.rs b/cove/src/ui/rooms/delete.rs index d5b6884..aafaad8 100644 --- a/cove/src/ui/rooms/delete.rs +++ b/cove/src/ui/rooms/delete.rs @@ -1,12 +1,15 @@ use cove_config::Keys; use cove_input::InputEvent; use crossterm::style::Stylize; -use toss::widgets::{EditorState, Empty, Join2, Text}; -use toss::{Style, Styled, Widget, WidgetExt}; +use toss::{ + Style, Styled, Widget, WidgetExt, + widgets::{EditorState, Empty, Join2, Text}, +}; -use crate::ui::widgets::Popup; -use crate::ui::{UiError, util}; -use crate::vault::RoomIdentifier; +use crate::{ + ui::{UiError, util, widgets::Popup}, + vault::RoomIdentifier, +}; pub struct DeleteState { id: RoomIdentifier, diff --git a/cove/src/ui/widgets.rs b/cove/src/ui/widgets.rs index aed063a..c00d26e 100644 --- a/cove/src/ui/widgets.rs +++ b/cove/src/ui/widgets.rs @@ -1,5 +1,5 @@ -mod list; -mod popup; - pub use self::list::*; pub use self::popup::*; + +mod list; +mod popup; diff --git a/cove/src/ui/widgets/popup.rs b/cove/src/ui/widgets/popup.rs index 40b41cb..559e283 100644 --- a/cove/src/ui/widgets/popup.rs +++ b/cove/src/ui/widgets/popup.rs @@ -1,5 +1,7 @@ -use toss::widgets::{Background, Border, Desync, Float, Layer2, Padding, Text}; -use toss::{Frame, Size, Style, Styled, Widget, WidgetExt, WidthDb}; +use toss::{ + Frame, Size, Style, Styled, Widget, WidgetExt, WidthDb, + widgets::{Background, Border, Desync, Float, Layer2, Padding, Text}, +}; type Body = Background>>; type Title = Float>>>; diff --git a/cove/src/util.rs b/cove/src/util.rs index ff8a05a..c6a572c 100644 --- a/cove/src/util.rs +++ b/cove/src/util.rs @@ -1,5 +1,4 @@ -use std::convert::Infallible; -use std::env; +use std::{convert::Infallible, env}; use jiff::tz::TimeZone; diff --git a/cove/src/vault.rs b/cove/src/vault.rs index 512dfd2..05bd1a5 100644 --- a/cove/src/vault.rs +++ b/cove/src/vault.rs @@ -1,16 +1,14 @@ +use std::{fs, path::Path}; + +use rusqlite::Connection; +use vault::{Action, tokio::TokioVault}; + +pub use self::euph::{EuphRoomVault, EuphVault, RoomIdentifier}; + mod euph; mod migrate; mod prepare; -use std::fs; -use std::path::Path; - -use rusqlite::Connection; -use vault::Action; -use vault::tokio::TokioVault; - -pub use self::euph::{EuphRoomVault, EuphVault, RoomIdentifier}; - #[derive(Debug, Clone)] pub struct Vault { tokio_vault: TokioVault, diff --git a/cove/src/vault/euph.rs b/cove/src/vault/euph.rs index 3e98590..931091c 100644 --- a/cove/src/vault/euph.rs +++ b/cove/src/vault/euph.rs @@ -1,15 +1,18 @@ -use std::str::FromStr; -use std::{fmt, mem}; +use std::{fmt, mem, str::FromStr}; use async_trait::async_trait; use cookie::{Cookie, CookieJar}; use euphoxide::api::{Message, MessageId, SessionId, SessionView, Snowflake, Time, UserId}; -use rusqlite::types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef}; -use rusqlite::{Connection, OptionalExtension, Row, ToSql, Transaction, named_params, params}; +use rusqlite::{ + Connection, OptionalExtension, Row, ToSql, Transaction, named_params, params, + types::{FromSql, FromSqlError, ToSqlOutput, Value, ValueRef}, +}; use vault::Action; -use crate::euph::SmallMessage; -use crate::store::{MsgStore, Path, Tree}; +use crate::{ + euph::SmallMessage, + store::{MsgStore, Path, Tree}, +}; /// Wrapper for [`Snowflake`] that implements useful rusqlite traits. struct WSnowflake(Snowflake); From d29e3e6651cf3a62c419c324a225e6202ffebfcf Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 21 Feb 2025 13:24:04 +0100 Subject: [PATCH 08/44] Set up GitHub CI --- .github/workflows/build.yml | 72 +++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..f02d5dd --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,72 @@ +# What software is installed by default: +# https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources + +name: build + +on: + push: + pull_request: + +defaults: + run: + shell: bash + +jobs: + build: + strategy: + matrix: + os: + - ubuntu-latest + - windows-latest + - macos-latest + - macos-13 + runs-on: ${{ matrix.os }} + steps: + - name: Check out repo + uses: actions/checkout@v4 + + - name: Set up rust + run: rustup update + + - name: Build + run: cargo build --release + + - name: Record target triple + run: rustc -vV | awk '/^host/ { print $2 }' > target/release/host + + - name: Upload + uses: actions/upload-artifact@v4 + with: + name: cove-${{ matrix.os }} + path: | + target/release/cove + target/release/cove.exe + target/release/host + + release: + runs-on: ubuntu-latest + if: ${{ startsWith(github.ref, 'refs/tags/v') }} + needs: + - build + permissions: + contents: write + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + + - name: Zip artifacts + run: | + chmod +x cove-ubuntu-latest/cove + chmod +x cove-windows-latest/cove.exe + chmod +x cove-macos-latest/cove + chmod +x cove-macos-13/cove + zip -jr "cove-$(cat cove-ubuntu-latest/host).zip" cove-ubuntu-latest/cove + zip -jr "cove-$(cat cove-windows-latest/host).zip" cove-windows-latest/cove.exe + zip -jr "cove-$(cat cove-macos-latest/host).zip" cove-macos-latest/cove + zip -jr "cove-$(cat cove-macos-13/host).zip" cove-macos-13/cove + + - name: Create new release + uses: softprops/action-gh-release@v2 + with: + body: Automated release, see [CHANGELOG.md](CHANGELOG.md) for more details. + files: "*.zip" From 6c884f3077e9f951c63b58fcbf6864f3065f6036 Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 21 Feb 2025 19:15:33 +0100 Subject: [PATCH 09/44] Update RPIT lifetime bounds for the 2024 edition When the bound matches the implicit bound, i.e. when you'd just write impl ... + use<'_> then it can be omitted. My gut instinct is to always write the bound explicitly, but maybe that'll harm readability once I'm more used to how bounds work now. Anyways, always try to keep the bound as small as possible, ideally just impl ... + use<> --- cove/src/ui/euph/account.rs | 4 ++-- cove/src/ui/euph/auth.rs | 2 +- cove/src/ui/euph/links.rs | 2 +- cove/src/ui/euph/nick.rs | 2 +- cove/src/ui/rooms/connect.rs | 2 +- cove/src/ui/rooms/delete.rs | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cove/src/ui/euph/account.rs b/cove/src/ui/euph/account.rs index 48731d9..7aa776f 100644 --- a/cove/src/ui/euph/account.rs +++ b/cove/src/ui/euph/account.rs @@ -35,7 +35,7 @@ impl LoggedOut { } } - fn widget(&mut self) -> impl Widget + '_ { + fn widget(&mut self) -> impl Widget { let bold = Style::new().bold(); Join4::vertical( Text::new(("Not logged in", bold.yellow())).segment(), @@ -111,7 +111,7 @@ impl AccountUiState { } } - pub fn widget(&mut self) -> impl Widget + '_ { + pub fn widget(&mut self) -> impl Widget { let inner = match self { Self::LoggedOut(logged_out) => logged_out.widget().first2(), Self::LoggedIn(logged_in) => logged_in.widget().second2(), diff --git a/cove/src/ui/euph/auth.rs b/cove/src/ui/euph/auth.rs index 259e204..15f8fe1 100644 --- a/cove/src/ui/euph/auth.rs +++ b/cove/src/ui/euph/auth.rs @@ -13,7 +13,7 @@ pub fn new() -> EditorState { EditorState::new() } -pub fn widget(editor: &mut EditorState) -> impl Widget + '_ { +pub fn widget(editor: &mut EditorState) -> impl Widget { Popup::new( editor.widget().with_hidden_default_placeholder(), "Enter password", diff --git a/cove/src/ui/euph/links.rs b/cove/src/ui/euph/links.rs index 14496a6..a452669 100644 --- a/cove/src/ui/euph/links.rs +++ b/cove/src/ui/euph/links.rs @@ -38,7 +38,7 @@ impl LinksState { } } - pub fn widget(&mut self) -> impl Widget + '_ { + pub fn widget(&mut self) -> impl Widget { let style_selected = Style::new().black().on_white(); let mut list_builder = ListBuilder::new(); diff --git a/cove/src/ui/euph/nick.rs b/cove/src/ui/euph/nick.rs index 1940fac..707e992 100644 --- a/cove/src/ui/euph/nick.rs +++ b/cove/src/ui/euph/nick.rs @@ -14,7 +14,7 @@ pub fn new(joined: Joined) -> EditorState { EditorState::with_initial_text(joined.session.name) } -pub fn widget(editor: &mut EditorState) -> impl Widget + '_ { +pub fn widget(editor: &mut EditorState) -> impl Widget { let inner = editor .widget() .with_highlight(|s| euph::style_nick_exact(s, Style::new())); diff --git a/cove/src/ui/rooms/connect.rs b/cove/src/ui/rooms/connect.rs index ce53775..83a359e 100644 --- a/cove/src/ui/rooms/connect.rs +++ b/cove/src/ui/rooms/connect.rs @@ -84,7 +84,7 @@ impl ConnectState { ConnectResult::Unhandled } - pub fn widget(&mut self) -> impl Widget + '_ { + pub fn widget(&mut self) -> impl Widget { let room_style = Style::new().bold().blue(); let domain_style = Style::new().grey(); diff --git a/cove/src/ui/rooms/delete.rs b/cove/src/ui/rooms/delete.rs index aafaad8..baa96b1 100644 --- a/cove/src/ui/rooms/delete.rs +++ b/cove/src/ui/rooms/delete.rs @@ -47,7 +47,7 @@ impl DeleteState { DeleteResult::Unhandled } - pub fn widget(&mut self) -> impl Widget + '_ { + pub fn widget(&mut self) -> impl Widget { let warn_style = Style::new().bold().red(); let room_style = Style::new().bold().blue(); let text = Styled::new_plain("Are you sure you want to delete ") From bf11e055b6fff0e51f2c5f71d3b9e0ae2db26782 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 22 Feb 2025 12:33:59 +0100 Subject: [PATCH 10/44] Reformat changelog There should always be space around headlines and lists in markdown documents. --- CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6864032..f365f7b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). Procedure when bumping the version number: + 1. Update dependencies and flake in a separate commit 2. Set version number in `Cargo.toml` 3. Add new section in this changelog @@ -16,20 +17,24 @@ Procedure when bumping the version number: ## Unreleased ### Updated + - Documentation for `time_zone` config option ## v0.8.3 - 2024-05-20 ### Changed + - Updated list of emoji names ## v0.8.2 - 2024-04-25 ### Changed + - Renamed `json-stream` export format to `json-lines` (see ) - Changed `json-lines` file extension from `.json` to `.jsonl` ### Fixed + - Crash when window is too small while empty message editor is visible - Mistakes in output and docs - Cove not cleaning up terminal state properly @@ -37,16 +42,19 @@ Procedure when bumping the version number: ## v0.8.1 - 2024-01-11 ### Added + - Support for setting window title - More information to room list heading - Key bindings for live caesar cipher de- and encoding ### Removed + - Key binding to open present page ## v0.8.0 - 2024-01-04 ### Added + - Support for multiple euph server domains - Support for `TZ` environment variable - `time_zone` config option @@ -56,6 +64,7 @@ Procedure when bumping the version number: - Welcome info box next to room list ### Changed + - The default euph domain is now https://euphoria.leet.nu/ everywhere - The config file format was changed to support multiple euph servers with different domains. Options previously located at `euph.rooms.*` should be reviewed and moved to `euph.servers."euphoria.leet.nu".rooms.*`. @@ -64,17 +73,20 @@ Procedure when bumping the version number: - Reduced connection timeout from 30 seconds to 10 seconds ### Fixed + - Room deletion popup accepting any room name - Duplicated key presses on Windows ## v0.7.1 - 2023-08-31 ### Changed + - Updated dependencies ## v0.7.0 - 2023-05-14 ### Added + - Auto-generated config documentation - in [CONFIG.md](CONFIG.md) - via `help-config` CLI command @@ -82,6 +94,7 @@ Procedure when bumping the version number: - `measure_widths` config option ### Changed + - Overhauled widget system and extracted generic widgets to [toss](https://github.com/Garmelon/toss) - Overhauled config system to support auto-generating documentation - Overhauled key binding system to make key bindings configurable @@ -95,15 +108,18 @@ Procedure when bumping the version number: ## v0.6.1 - 2023-04-10 ### Changed + - Improved JSON export performance - Always show rooms from config file in room list ### Fixed + - Rooms reconnecting instead of showing error popups ## v0.6.0 - 2023-04-04 ### Added + - Emoji support - `flake.nix`, making cove available as a nix flake - `json-stream` room export format @@ -111,31 +127,37 @@ Procedure when bumping the version number: - `--verbose` flag ### Changed + - Non-export info is now printed to stderr instead of stdout - Recognizes links without scheme (e.g. `euphoria.io` instead of `https://euphoria.io`) - Rooms waiting for reconnect are no longer sorted to bottom in default sort order ### Fixed + - Mentions not being stopped by `>` ## v0.5.2 - 2023-01-14 ### Added + - Key binding to open present page ### Changed + - Always connect to &rl2dev in ephemeral mode - Reduce amount of messages per &rl2dev log request ## v0.5.1 - 2022-11-27 ### Changed + - Increase reconnect delay to one minute - Print errors that occurred while cove was running more compactly ## v0.5.0 - 2022-09-26 ### Added + - Key bindings to navigate nick list - Room deletion confirmation popup - Message inspection popup @@ -144,10 +166,12 @@ Procedure when bumping the version number: - `rooms_sort_order` config option ### Changed + - Use nick changes to detect sessions for nick list - Support Unicode 15 ### Fixed + - Cursor being visible through popups - Cursor in lists when highlighted item moves off-screen - User disappearing from nick list when only one of their sessions disconnects @@ -155,6 +179,7 @@ Procedure when bumping the version number: ## v0.4.0 - 2022-09-01 ### Added + - Config file and `--config` cli option - `data_dir` config option - `ephemeral` config option @@ -170,14 +195,17 @@ Procedure when bumping the version number: - Key bindings to view and open links in a message ### Changed + - Some key bindings in the rooms list ### Fixed + - Rooms being stuck in "Connecting" state ## v0.3.0 - 2022-08-22 ### Added + - Account login and logout - Authentication dialog for password-protected rooms - Error popups in rooms when something goes wrong @@ -185,10 +213,12 @@ Procedure when bumping the version number: - Key binding to download more logs ### Changed + - Reduced amount of unnecessary redraws - Description of `export` CLI command ### Fixed + - Crash when connecting to nonexistent rooms - Crash when connecting to rooms that require authentication - Pasting multi-line strings into the editor @@ -196,15 +226,18 @@ Procedure when bumping the version number: ## v0.2.1 - 2022-08-11 ### Added + - Support for modifiers on special keys via the [kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/) ### Fixed + - Joining new rooms no longer crashes cove - Scrolling when exiting message editor ## v0.2.0 - 2022-08-10 ### Added + - New messages are now marked as unseen - Sub-trees can now be folded - Support for pasting text into editors @@ -217,10 +250,12 @@ Procedure when bumping the version number: - Support for exporting multiple/all rooms at once ### Changed + - Reorganized export command - Slowed down room history download speed ### Fixed + - Chat rendering when deleting and re-joining a room - Spacing in some popups From 866176dab64fc2a08b393dcc33076d05da38eafa Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 22 Feb 2025 12:30:38 +0100 Subject: [PATCH 11/44] Move cursor to new room in room list --- CHANGELOG.md | 1 + cove/src/ui/rooms.rs | 1 + cove/src/ui/widgets/list.rs | 6 ++++++ 3 files changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f365f7b..fb950a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Procedure when bumping the version number: ### Updated - Documentation for `time_zone` config option +- When connecting to a room using `n` in the room list, the cursor now moves to that room ## v0.8.3 - 2024-05-20 diff --git a/cove/src/ui/rooms.rs b/cove/src/ui/rooms.rs index a6e7b34..04bce02 100644 --- a/cove/src/ui/rooms.rs +++ b/cove/src/ui/rooms.rs @@ -589,6 +589,7 @@ impl Rooms { return true; } ConnectResult::Connect(room) => { + self.list.move_cursor_to_id(&room); self.connect_to_room(room.clone()).await; self.state = State::ShowRoom(room); return true; diff --git a/cove/src/ui/widgets/list.rs b/cove/src/ui/widgets/list.rs index bb27540..3d7c6c8 100644 --- a/cove/src/ui/widgets/list.rs +++ b/cove/src/ui/widgets/list.rs @@ -239,6 +239,12 @@ impl ListState { }) } + pub fn move_cursor_to_id(&mut self, id: &Id) { + if let Some(new_cursor) = self.selectable_of_id(id) { + self.move_cursor_to(new_cursor); + } + } + fn fix_cursor(&mut self) { let new_cursor = if let Some(cursor) = &self.cursor { self.selectable_of_id(&cursor.id) From e750f81b11395843da3ee0e44b477dfd9d1e67bb Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 22 Feb 2025 16:42:26 +0100 Subject: [PATCH 12/44] Drop once_cell dependency It's now part of the standard library :D --- Cargo.lock | 1 - Cargo.toml | 1 - cove/Cargo.toml | 1 - cove/src/euph/util.rs | 5 +++-- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e77a3ad..6b262c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -344,7 +344,6 @@ dependencies = [ "jiff", "linkify", "log", - "once_cell", "open", "parking_lot", "rusqlite", diff --git a/Cargo.toml b/Cargo.toml index a58b43d..93e13c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,6 @@ edit = "0.1.5" jiff = "0.2.1" linkify = "0.10.0" log = { version = "0.4.25", features = ["std"] } -once_cell = "1.20.2" open = "5.3.2" parking_lot = "0.12.3" proc-macro2 = "1.0.93" diff --git a/cove/Cargo.toml b/cove/Cargo.toml index 0ca2a2f..3a60a5d 100644 --- a/cove/Cargo.toml +++ b/cove/Cargo.toml @@ -17,7 +17,6 @@ euphoxide.workspace = true jiff.workspace = true linkify.workspace = true log.workspace = true -once_cell.workspace = true open.workspace = true parking_lot.workspace = true rusqlite.workspace = true diff --git a/cove/src/euph/util.rs b/cove/src/euph/util.rs index fdf11a3..aff2192 100644 --- a/cove/src/euph/util.rs +++ b/cove/src/euph/util.rs @@ -1,9 +1,10 @@ +use std::sync::LazyLock; + use crossterm::style::{Color, Stylize}; use euphoxide::Emoji; -use once_cell::sync::Lazy; use toss::{Style, Styled}; -pub static EMOJI: Lazy = Lazy::new(Emoji::load); +pub static EMOJI: LazyLock = LazyLock::new(Emoji::load); /// Convert HSL to RGB following [this approach from wikipedia][1]. /// From 2fa1bec421ec9c9f621cf660bd7684924e6cf206 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 04:24:06 +0100 Subject: [PATCH 13/44] Remove special rl2dev code --- CHANGELOG.md | 4 ++++ cove/src/euph/room.rs | 22 +++------------------- 2 files changed, 7 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb950a5..2335f41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,10 @@ Procedure when bumping the version number: - Documentation for `time_zone` config option - When connecting to a room using `n` in the room list, the cursor now moves to that room +### Removed + +- Special handling of &rl2dev + ## v0.8.3 - 2024-05-20 ### Changed diff --git a/cove/src/euph/room.rs b/cove/src/euph/room.rs index 17aafe4..a4e29cf 100644 --- a/cove/src/euph/room.rs +++ b/cove/src/euph/room.rs @@ -1,5 +1,3 @@ -// TODO Remove rl2dev-specific code - use std::{convert::Infallible, time::Duration}; use euphoxide::{ @@ -71,20 +69,13 @@ impl Room { where F: Fn(Event) + std::marker::Send + Sync + 'static, { - // &rl2dev's message history is broken and requesting old messages past - // a certain point results in errors. Cove should not keep retrying log - // requests when hitting that limit, so &rl2dev is always opened in - // ephemeral mode. - let is_rl2dev = vault.room().domain == "euphoria.io" && vault.room().name == "rl2dev"; - let ephemeral = vault.vault().vault().ephemeral() || is_rl2dev; - Self { - vault, - ephemeral, + ephemeral: vault.vault().vault().ephemeral(), instance: instance_config.build(on_event), state: State::Disconnected, last_msg_id: None, log_request_canary: None, + vault, } } @@ -192,14 +183,7 @@ impl Room { debug!("{:?}: requesting logs", vault.room()); - // &rl2dev's message history is broken and requesting old messages past - // a certain point results in errors. By reducing the amount of messages - // in each log request, we can get closer to this point. Since &rl2dev - // is fairly low in activity, this should be fine. - let is_rl2dev = vault.room().domain == "euphoria.io" && vault.room().name == "rl2dev"; - let n = if is_rl2dev { 50 } else { 1000 }; - - let _ = conn_tx.send(Log { n, before }).await; + let _ = conn_tx.send(Log { n: 1000, before }).await; // The code handling incoming events and replies also handles // `LogReply`s, so we don't need to do anything special here. } From 900a686d0deab4ce64b1b4a4f78824af8eea0f71 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 04:28:21 +0100 Subject: [PATCH 14/44] Fix changelog heading "Updated" does not conform to Keep a Changelog. --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2335f41..a4339bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,9 +16,9 @@ Procedure when bumping the version number: ## Unreleased -### Updated +### Changed -- Documentation for `time_zone` config option +- Updated documentation for `time_zone` config option - When connecting to a room using `n` in the room list, the cursor now moves to that room ### Removed From 17185ea5362c8f9b46f9a12a3e55a51faffc5840 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 18:31:20 +0100 Subject: [PATCH 15/44] Add unicode-based grapheme width estimation method --- CHANGELOG.md | 6 ++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- cove-config/src/lib.rs | 32 +++++++++++++++++++++++++++----- cove/src/main.rs | 21 +++++++++++++++++++++ 5 files changed, 56 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4339bb..433634a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,12 @@ Procedure when bumping the version number: ## Unreleased +### Added + +- Unicode-based grapheme width estimation method + - `width_estimation_method` config option + - `--width-estimation-method` option + ### Changed - Updated documentation for `time_zone` config option diff --git a/Cargo.lock b/Cargo.lock index 6b262c4..86ebb73 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1647,7 +1647,7 @@ dependencies = [ [[package]] name = "toss" version = "0.3.1" -source = "git+https://github.com/Garmelon/toss.git?tag=v0.3.1#be7eff0979e0e95d070e7c9cea42c328ffd04cc4" +source = "git+https://github.com/Garmelon/toss.git?rev=423dd100c1360decffc5107ea4757d751ac0f4db#423dd100c1360decffc5107ea4757d751ac0f4db" dependencies = [ "async-trait", "crossterm", diff --git a/Cargo.toml b/Cargo.toml index 93e13c4..f8445e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ features = ["bot"] [workspace.dependencies.toss] git = "https://github.com/Garmelon/toss.git" -tag = "v0.3.1" +rev = "423dd100c1360decffc5107ea4757d751ac0f4db" [workspace.dependencies.vault] git = "https://github.com/Garmelon/vault.git" diff --git a/cove-config/src/lib.rs b/cove-config/src/lib.rs index 0d350ed..85b418e 100644 --- a/cove-config/src/lib.rs +++ b/cove-config/src/lib.rs @@ -5,7 +5,7 @@ use std::{ }; use doc::Document; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; pub use crate::{euph::*, keys::*}; @@ -21,6 +21,14 @@ pub enum Error { Toml(#[from] toml::de::Error), } +#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, Document)] +#[serde(rename_all = "snake_case")] +pub enum WidthEstimationMethod { + #[default] + Legacy, + Unicode, +} + #[derive(Debug, Default, Deserialize, Document)] pub struct Config { /// The directory that cove stores its data in when not running in ephemeral @@ -41,12 +49,26 @@ pub struct Config { #[serde(default)] pub ephemeral: bool, - /// Whether to measure the width of characters as displayed by the terminal - /// emulator instead of guessing the width. + /// How to estimate the width of graphemes (i.e. characters) as displayed by + /// the terminal emulator. + /// + /// `"legacy"`: Use a legacy method that should mostly work on most terminal + /// emulators. This method will never be correct in all cases since every + /// terminal emulator handles grapheme widths slightly differently. However, + /// those cases are usually rare (unless you view a lot of emoji). + /// + /// `"unicode"`: Use the unicode standard in a best-effort manner to + /// determine grapheme widths. + /// + /// This method is used when `measure_widths` is set to `false`. + #[serde(default)] + pub width_estimation_method: WidthEstimationMethod, + + /// Whether to measure the width of graphemes (i.e. characters) as displayed + /// by the terminal emulator instead of estimating the width. /// /// Enabling this makes rendering a bit slower but more accurate. The screen - /// might also flash when encountering new characters (or, more accurately, - /// graphemes). + /// might also flash when encountering new graphemes. /// /// See also the `--measure-widths` command line option. #[serde(default)] diff --git a/cove/src/main.rs b/cove/src/main.rs index 642b62e..51bc502 100644 --- a/cove/src/main.rs +++ b/cove/src/main.rs @@ -46,6 +46,12 @@ enum Command { HelpConfig, } +#[derive(Debug, Clone, Copy, clap::ValueEnum)] +enum WidthEstimationMethod { + Legacy, + Unicode, +} + impl Default for Command { fn default() -> Self { Self::Run @@ -79,6 +85,11 @@ struct Args { #[arg(long, short)] offline: bool, + /// Method for estimating the width of characters as displayed by the + /// terminal emulator. + #[arg(long, short)] + width_estimation_method: Option, + /// Measure the width of characters as displayed by the terminal emulator /// instead of guessing the width. #[arg(long, short)] @@ -114,6 +125,12 @@ fn update_config_with_args(config: &mut Config, args: &Args) { } config.ephemeral |= args.ephemeral; + if let Some(method) = args.width_estimation_method { + config.width_estimation_method = match method { + WidthEstimationMethod::Legacy => cove_config::WidthEstimationMethod::Legacy, + WidthEstimationMethod::Unicode => cove_config::WidthEstimationMethod::Unicode, + } + } config.measure_widths |= args.measure_widths; config.offline |= args.offline; } @@ -182,6 +199,10 @@ async fn run( let mut terminal = Terminal::new()?; terminal.set_measuring(config.measure_widths); + terminal.set_width_estimation_method(match config.width_estimation_method { + cove_config::WidthEstimationMethod::Legacy => toss::WidthEstimationMethod::Legacy, + cove_config::WidthEstimationMethod::Unicode => toss::WidthEstimationMethod::Unicode, + }); Ui::run(config, tz, &mut terminal, vault.clone(), logger, logger_rx).await?; drop(terminal); From 8040b82ff15909aa2b6f169b9feb017e00105167 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 20:22:04 +0100 Subject: [PATCH 16/44] Refactor euph message content highlighting --- cove/src/euph.rs | 2 + cove/src/euph/highlight.rs | 203 ++++++++++++++++++++++++++++++++ cove/src/euph/small_message.rs | 206 +-------------------------------- 3 files changed, 210 insertions(+), 201 deletions(-) create mode 100644 cove/src/euph/highlight.rs diff --git a/cove/src/euph.rs b/cove/src/euph.rs index d1fd872..77bf1db 100644 --- a/cove/src/euph.rs +++ b/cove/src/euph.rs @@ -1,7 +1,9 @@ +pub use highlight::*; pub use room::*; pub use small_message::*; pub use util::*; +mod highlight; mod room; mod small_message; mod util; diff --git a/cove/src/euph/highlight.rs b/cove/src/euph/highlight.rs new file mode 100644 index 0000000..e60a302 --- /dev/null +++ b/cove/src/euph/highlight.rs @@ -0,0 +1,203 @@ +use std::ops::Range; + +use crossterm::style::Stylize; +use toss::{Style, Styled}; + +use crate::euph::util; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum SpanType { + Mention, + Room, + Emoji, +} + +fn nick_char(ch: char) -> bool { + // Closely following the heim mention regex: + // https://github.com/euphoria-io/heim/blob/978c921063e6b06012fc8d16d9fbf1b3a0be1191/client/lib/stores/chat.js#L14-L15 + // `>` has been experimentally confirmed to delimit mentions as well. + match ch { + ',' | '.' | '!' | '?' | ';' | '&' | '<' | '>' | '\'' | '"' => false, + _ => !ch.is_whitespace(), + } +} + +fn room_char(ch: char) -> bool { + // Basically just \w, see also + // https://github.com/euphoria-io/heim/blob/978c921063e6b06012fc8d16d9fbf1b3a0be1191/client/lib/ui/MessageText.js#L66 + ch.is_ascii_alphanumeric() || ch == '_' +} + +struct SpanFinder<'a> { + content: &'a str, + + span: Option<(SpanType, usize)>, + room_or_mention_possible: bool, + + result: Vec<(SpanType, Range)>, +} + +impl<'a> SpanFinder<'a> { + fn is_valid_span(&self, span: SpanType, range: Range) -> bool { + let text = &self.content[range.start..range.end]; + match span { + SpanType::Mention => range.len() > 1 && text.starts_with('@'), + SpanType::Room => range.len() > 1 && text.starts_with('&'), + SpanType::Emoji => { + if range.len() <= 2 { + return false; + } + + let Some(name) = Some(text) + .and_then(|it| it.strip_prefix(':')) + .and_then(|it| it.strip_suffix(':')) + else { + return false; + }; + + util::EMOJI.get(name).is_some() + } + } + } + + fn close_span(&mut self, end: usize) { + let Some((span, start)) = self.span else { + return; + }; + if self.is_valid_span(span, start..end) { + self.result.push((span, start..end)); + } + self.span = None; + } + + fn open_span(&mut self, span: SpanType, start: usize) { + self.close_span(start); + self.span = Some((span, start)) + } + + fn step(&mut self, idx: usize, char: char) { + match (char, self.span) { + ('@', _) if self.room_or_mention_possible => self.open_span(SpanType::Mention, idx), + ('&', _) if self.room_or_mention_possible => self.open_span(SpanType::Room, idx), + (':', None) => self.open_span(SpanType::Emoji, idx), + (':', Some((SpanType::Emoji, _))) => self.close_span(idx + 1), + (c, Some((SpanType::Mention, _))) if !nick_char(c) => self.close_span(idx), + (c, Some((SpanType::Room, _))) if !room_char(c) => self.close_span(idx), + _ => {} + } + + // More permissive than the heim web client + self.room_or_mention_possible = !char.is_alphanumeric(); + } + + fn find(content: &'a str) -> Vec<(SpanType, Range)> { + let mut this = Self { + content, + span: None, + room_or_mention_possible: true, + result: vec![], + }; + + for (idx, char) in content.char_indices() { + this.step(idx, char); + } + + this.close_span(content.len()); + + this.result + } +} + +pub fn find_spans(content: &str) -> Vec<(SpanType, Range)> { + SpanFinder::find(content) +} + +/// Highlight spans in a string. +/// +/// The list of spans must be non-overlapping and in ascending order. +/// +/// If `exact` is specified, colon-delimited emoji are not replaced with their +/// unicode counterparts. +pub fn apply_spans( + content: &str, + spans: &[(SpanType, Range)], + base: Style, + exact: bool, +) -> Styled { + let mut result = Styled::default(); + let mut i = 0; + + for (span, range) in spans { + assert!(i <= range.start); + assert!(range.end <= content.len()); + + if i < range.start { + result = result.then_plain(&content[i..range.start]); + } + + let text = &content[range.start..range.end]; + result = match span { + SpanType::Mention if exact => result.and_then(util::style_nick_exact(text, base)), + SpanType::Mention => result.and_then(util::style_nick(text, base)), + SpanType::Room => result.then(text, base.blue().bold()), + SpanType::Emoji if exact => result.then(text, base.magenta()), + SpanType::Emoji => { + let name = text.strip_prefix(':').unwrap_or(text); + let name = name.strip_suffix(':').unwrap_or(name); + if let Some(Some(replacement)) = util::EMOJI.get(name) { + result.then_plain(replacement) + } else { + result.then(name, base.magenta()) + } + } + }; + + i = range.end; + } + + if i < content.len() { + result = result.then_plain(&content[i..]); + } + + result +} + +/// Highlight an euphoria message's content. +/// +/// If `exact` is specified, colon-delimited emoji are not replaced with their +/// unicode counterparts. +pub fn highlight(content: &str, base: Style, exact: bool) -> Styled { + apply_spans(content, &find_spans(content), base, exact) +} + +#[cfg(test)] +mod tests { + + use crate::euph::SpanType; + + use super::find_spans; + + #[test] + fn mentions() { + assert_eq!(find_spans("@foo"), vec![(SpanType::Mention, 0..4)]); + assert_eq!(find_spans("a @foo b"), vec![(SpanType::Mention, 2..6)]); + assert_eq!(find_spans("@@foo@"), vec![(SpanType::Mention, 1..6)]); + assert_eq!(find_spans("a @b@c d"), vec![(SpanType::Mention, 2..6)]); + assert_eq!( + find_spans("a @b @c d"), + vec![(SpanType::Mention, 2..4), (SpanType::Mention, 5..7)] + ); + } + + #[test] + fn rooms() { + assert_eq!(find_spans("&foo"), vec![(SpanType::Room, 0..4)]); + assert_eq!(find_spans("a &foo b"), vec![(SpanType::Room, 2..6)]); + assert_eq!(find_spans("&&foo&"), vec![(SpanType::Room, 1..5)]); + assert_eq!(find_spans("a &b&c d"), vec![(SpanType::Room, 2..4)]); + assert_eq!( + find_spans("a &b &c d"), + vec![(SpanType::Room, 2..4), (SpanType::Room, 5..7)] + ); + } +} diff --git a/cove/src/euph/small_message.rs b/cove/src/euph/small_message.rs index 20596fa..003cd40 100644 --- a/cove/src/euph/small_message.rs +++ b/cove/src/euph/small_message.rs @@ -1,5 +1,3 @@ -use std::mem; - use crossterm::style::Stylize; use euphoxide::api::{MessageId, Snowflake, Time}; use jiff::Timestamp; @@ -7,200 +5,6 @@ use toss::{Style, Styled}; use crate::{store::Msg, ui::ChatMsg}; -use super::util; - -fn nick_char(ch: char) -> bool { - // Closely following the heim mention regex: - // https://github.com/euphoria-io/heim/blob/978c921063e6b06012fc8d16d9fbf1b3a0be1191/client/lib/stores/chat.js#L14-L15 - // `>` has been experimentally confirmed to delimit mentions as well. - match ch { - ',' | '.' | '!' | '?' | ';' | '&' | '<' | '>' | '\'' | '"' => false, - _ => !ch.is_whitespace(), - } -} - -fn room_char(ch: char) -> bool { - // Basically just \w, see also - // https://github.com/euphoria-io/heim/blob/978c921063e6b06012fc8d16d9fbf1b3a0be1191/client/lib/ui/MessageText.js#L66 - ch.is_ascii_alphanumeric() || ch == '_' -} - -enum Span { - Nothing, - Mention, - Room, - Emoji, -} - -struct Highlighter<'a> { - content: &'a str, - base_style: Style, - exact: bool, - - span: Span, - span_start: usize, - room_or_mention_possible: bool, - - result: Styled, -} - -impl<'a> Highlighter<'a> { - /// Does *not* guarantee `self.span_start == idx` after running! - fn close_mention(&mut self, idx: usize) { - let span_length = idx.saturating_sub(self.span_start); - if span_length <= 1 { - // We can repurpose the current span - self.span = Span::Nothing; - return; - } - - let text = &self.content[self.span_start..idx]; // Includes @ - self.result = mem::take(&mut self.result).and_then(if self.exact { - util::style_nick_exact(text, self.base_style) - } else { - util::style_nick(text, self.base_style) - }); - - self.span = Span::Nothing; - self.span_start = idx; - } - - /// Does *not* guarantee `self.span_start == idx` after running! - fn close_room(&mut self, idx: usize) { - let span_length = idx.saturating_sub(self.span_start); - if span_length <= 1 { - // We can repurpose the current span - self.span = Span::Nothing; - return; - } - - self.result = mem::take(&mut self.result).then( - &self.content[self.span_start..idx], - self.base_style.blue().bold(), - ); - - self.span = Span::Nothing; - self.span_start = idx; - } - - // Warning: `idx` is the index of the closing colon. - fn close_emoji(&mut self, idx: usize) { - let name = &self.content[self.span_start + 1..idx]; - if let Some(replace) = util::EMOJI.get(name) { - match replace { - Some(replace) if !self.exact => { - self.result = mem::take(&mut self.result).then(replace, self.base_style); - } - _ => { - let text = &self.content[self.span_start..=idx]; - let style = self.base_style.magenta(); - self.result = mem::take(&mut self.result).then(text, style); - } - } - - self.span = Span::Nothing; - self.span_start = idx + 1; - } else { - self.close_plain(idx); - self.span = Span::Emoji; - } - } - - /// Guarantees `self.span_start == idx` after running. - fn close_plain(&mut self, idx: usize) { - if self.span_start == idx { - // Span has length 0 - return; - } - - self.result = - mem::take(&mut self.result).then(&self.content[self.span_start..idx], self.base_style); - - self.span = Span::Nothing; - self.span_start = idx; - } - - fn close_span_before_current_char(&mut self, idx: usize, char: char) { - match self.span { - Span::Mention if !nick_char(char) => self.close_mention(idx), - Span::Room if !room_char(char) => self.close_room(idx), - Span::Emoji if char == '&' || char == '@' => { - self.span = Span::Nothing; - } - _ => {} - } - } - - fn update_span_with_current_char(&mut self, idx: usize, char: char) { - match self.span { - Span::Nothing if char == '@' && self.room_or_mention_possible => { - self.close_plain(idx); - self.span = Span::Mention; - } - Span::Nothing if char == '&' && self.room_or_mention_possible => { - self.close_plain(idx); - self.span = Span::Room; - } - Span::Nothing if char == ':' => { - self.close_plain(idx); - self.span = Span::Emoji; - } - Span::Emoji if char == ':' => self.close_emoji(idx), - _ => {} - } - } - - fn close_final_span(&mut self) { - let idx = self.content.len(); - if self.span_start >= idx { - return; // Span has no contents - } - - match self.span { - Span::Mention => self.close_mention(idx), - Span::Room => self.close_room(idx), - _ => {} - } - - self.close_plain(idx); - } - - fn step(&mut self, idx: usize, char: char) { - if self.span_start < idx { - self.close_span_before_current_char(idx, char); - } - - self.update_span_with_current_char(idx, char); - - // More permissive than the heim web client - self.room_or_mention_possible = !char.is_alphanumeric(); - } - - fn highlight(content: &'a str, base_style: Style, exact: bool) -> Styled { - let mut this = Self { - content: if exact { content } else { content.trim() }, - base_style, - exact, - span: Span::Nothing, - span_start: 0, - room_or_mention_possible: true, - result: Styled::default(), - }; - - for (idx, char) in (if exact { content } else { content.trim() }).char_indices() { - this.step(idx, char); - } - - this.close_final_span(); - - this.result - } -} - -fn highlight_content(content: &str, base_style: Style, exact: bool) -> Styled { - Highlighter::highlight(content, base_style, exact) -} - #[derive(Debug, Clone)] pub struct SmallMessage { pub id: MessageId, @@ -221,22 +25,22 @@ fn style_me() -> Style { fn styled_nick(nick: &str) -> Styled { Styled::new_plain("[") - .and_then(util::style_nick(nick, Style::new())) + .and_then(super::style_nick(nick, Style::new())) .then_plain("]") } fn styled_nick_me(nick: &str) -> Styled { let style = style_me(); - Styled::new("*", style).and_then(util::style_nick(nick, style)) + Styled::new("*", style).and_then(super::style_nick(nick, style)) } fn styled_content(content: &str) -> Styled { - highlight_content(content.trim(), Style::new(), false) + super::highlight(content.trim(), Style::new(), false) } fn styled_content_me(content: &str) -> Styled { let style = style_me(); - highlight_content(content.trim(), style, false).then("*", style) + super::highlight(content.trim(), style, false).then("*", style) } fn styled_editor_content(content: &str) -> Styled { @@ -245,7 +49,7 @@ fn styled_editor_content(content: &str) -> Styled { } else { Style::new() }; - highlight_content(content, style, true) + super::highlight(content, style, true) } impl Msg for SmallMessage { From bf9a9d640ba7a15d37dc906bfabbb21b4e316629 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 21:32:44 +0100 Subject: [PATCH 17/44] Navigate to rooms using message links list --- CHANGELOG.md | 1 + cove/src/ui/euph/links.rs | 117 +++++++++++++++++++++++++------------- cove/src/ui/euph/popup.rs | 1 + cove/src/ui/euph/room.rs | 43 +++++++++++--- cove/src/ui/rooms.rs | 13 ++++- 5 files changed, 123 insertions(+), 52 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 433634a..f75a3d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ Procedure when bumping the version number: - Unicode-based grapheme width estimation method - `width_estimation_method` config option - `--width-estimation-method` option +- Room links are now included in the `I` message links list ### Changed diff --git a/cove/src/ui/euph/links.rs b/cove/src/ui/euph/links.rs index a452669..20e2219 100644 --- a/cove/src/ui/euph/links.rs +++ b/cove/src/ui/euph/links.rs @@ -7,16 +7,25 @@ use toss::{ widgets::{Join2, Text}, }; -use crate::ui::{ - UiError, key_bindings, util, - widgets::{ListBuilder, ListState, Popup}, +use crate::{ + euph::{self, SpanType}, + ui::{ + UiError, key_bindings, util, + widgets::{ListBuilder, ListState, Popup}, + }, }; use super::popup::PopupResult; +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)] +enum Link { + Url(String), + Room(String), +} + pub struct LinksState { config: &'static Config, - links: Vec, + links: Vec, list: ListState, } @@ -24,12 +33,34 @@ const NUMBER_KEYS: [char; 10] = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0 impl LinksState { pub fn new(config: &'static Config, content: &str) -> Self { - let links = LinkFinder::new() + let mut links = vec![]; + + // Collect URL-like links + for link in LinkFinder::new() .url_must_have_scheme(false) .kinds(&[LinkKind::Url]) .links(content) - .map(|l| l.as_str().to_string()) - .collect(); + { + links.push(( + link.start(), + link.end(), + Link::Url(link.as_str().to_string()), + )); + } + + // Collect room links + for (span, range) in euph::find_spans(content) { + if span == SpanType::Room { + let name = &content[range.start + 1..range.end]; + links.push((range.start, range.end, Link::Room(name.to_string()))); + } + } + + links.sort(); + let links = links + .into_iter() + .map(|(_, _, link)| link) + .collect::>(); Self { config, @@ -49,29 +80,29 @@ impl LinksState { for (id, link) in self.links.iter().enumerate() { let link = link.clone(); - if let Some(&number_key) = NUMBER_KEYS.get(id) { - list_builder.add_sel(id, move |selected| { - let text = if selected { - Styled::new(format!("[{number_key}]"), style_selected.bold()) - .then(" ", style_selected) - .then(link, style_selected) - } else { - Styled::new(format!("[{number_key}]"), Style::new().dark_grey().bold()) - .then_plain(" ") - .then_plain(link) - }; - Text::new(text) - }); - } else { - list_builder.add_sel(id, move |selected| { - let text = if selected { - Styled::new(format!(" {link}"), style_selected) - } else { - Styled::new_plain(format!(" {link}")) - }; - Text::new(text) - }); - } + list_builder.add_sel(id, move |selected| { + let mut text = Styled::default(); + + // Number key indicator + text = match NUMBER_KEYS.get(id) { + None if selected => text.then(" ", style_selected), + None => text.then_plain(" "), + Some(key) if selected => text.then(format!("[{key}] "), style_selected.bold()), + Some(key) => text.then(format!("[{key}] "), Style::new().dark_grey().bold()), + }; + + // The link itself + text = match link { + Link::Url(url) if selected => text.then(url, style_selected), + Link::Url(url) => text.then_plain(url), + Link::Room(name) if selected => { + text.then(format!("&{name}"), style_selected.bold()) + } + Link::Room(name) => text.then(format!("&{name}"), Style::new().blue().bold()), + }; + + Text::new(text) + }); } let hint_style = Style::new().grey().italic(); @@ -95,18 +126,24 @@ impl LinksState { } fn open_link_by_id(&self, id: usize) -> PopupResult { - if let Some(link) = self.links.get(id) { - // The `http://` or `https://` schema is necessary for open::that to - // successfully open the link in the browser. - let link = if link.starts_with("http://") || link.starts_with("https://") { - link.clone() - } else { - format!("https://{link}") - }; + match self.links.get(id) { + Some(Link::Url(url)) => { + // The `http://` or `https://` schema is necessary for + // open::that to successfully open the link in the browser. + let link = if url.starts_with("http://") || url.starts_with("https://") { + url.clone() + } else { + format!("https://{url}") + }; - if let Err(error) = open::that(&link) { - return PopupResult::ErrorOpeningLink { link, error }; + if let Err(error) = open::that(&link) { + return PopupResult::ErrorOpeningLink { link, error }; + } } + + Some(Link::Room(name)) => return PopupResult::SwitchToRoom { name: name.clone() }, + + _ => {} } PopupResult::Handled } diff --git a/cove/src/ui/euph/popup.rs b/cove/src/ui/euph/popup.rs index 3f8caaa..c434fb6 100644 --- a/cove/src/ui/euph/popup.rs +++ b/cove/src/ui/euph/popup.rs @@ -35,5 +35,6 @@ pub enum PopupResult { NotHandled, Handled, Close, + SwitchToRoom { name: String }, ErrorOpeningLink { link: String, error: io::Error }, } diff --git a/cove/src/ui/euph/room.rs b/cove/src/ui/euph/room.rs index 7d4b49c..83d7e96 100644 --- a/cove/src/ui/euph/room.rs +++ b/cove/src/ui/euph/room.rs @@ -27,7 +27,7 @@ use crate::{ util, widgets::ListState, }, - vault::EuphRoomVault, + vault::{EuphRoomVault, RoomIdentifier}, }; use super::{ @@ -500,18 +500,22 @@ impl EuphRoom { false } - pub async fn handle_input_event(&mut self, event: &mut InputEvent<'_>, keys: &Keys) -> bool { + pub async fn handle_input_event( + &mut self, + event: &mut InputEvent<'_>, + keys: &Keys, + ) -> RoomResult { if !self.popups.is_empty() { if event.matches(&keys.general.abort) { self.popups.pop_back(); - return true; + return RoomResult::Handled; } // Prevent event from reaching anything below the popup - return false; + return RoomResult::NotHandled; } let result = match &mut self.state { - State::Normal => return self.handle_normal_input_event(event, keys).await, + State::Normal => return self.handle_normal_input_event(event, keys).await.into(), State::Auth(editor) => auth::handle_input_event(event, keys, &self.room, editor), State::Nick(editor) => nick::handle_input_event(event, keys, &self.room, editor), State::Account(account) => account.handle_input_event(event, keys, &self.room), @@ -522,18 +526,24 @@ impl EuphRoom { }; match result { - PopupResult::NotHandled => false, - PopupResult::Handled => true, + PopupResult::NotHandled => RoomResult::NotHandled, + PopupResult::Handled => RoomResult::Handled, PopupResult::Close => { self.state = State::Normal; - true + RoomResult::Handled } + PopupResult::SwitchToRoom { name } => RoomResult::SwitchToRoom { + room: RoomIdentifier { + domain: self.vault().room().domain.clone(), + name, + }, + }, PopupResult::ErrorOpeningLink { link, error } => { self.popups.push_front(RoomPopup::Error { description: format!("Failed to open link: {link}"), reason: format!("{error}"), }); - true + RoomResult::Handled } } } @@ -638,3 +648,18 @@ impl EuphRoom { true } } + +pub enum RoomResult { + NotHandled, + Handled, + SwitchToRoom { room: RoomIdentifier }, +} + +impl From for RoomResult { + fn from(value: bool) -> Self { + match value { + true => Self::Handled, + false => Self::NotHandled, + } + } +} diff --git a/cove/src/ui/rooms.rs b/cove/src/ui/rooms.rs index 04bce02..80089da 100644 --- a/cove/src/ui/rooms.rs +++ b/cove/src/ui/rooms.rs @@ -29,7 +29,7 @@ use crate::{ use super::{ UiError, UiEvent, - euph::room::EuphRoom, + euph::room::{EuphRoom, RoomResult}, key_bindings, util, widgets::{ListBuilder, ListState}, }; @@ -574,8 +574,15 @@ impl Rooms { } State::ShowRoom(name) => { if let Some(room) = self.euph_rooms.get_mut(name) { - if room.handle_input_event(event, keys).await { - return true; + match room.handle_input_event(event, keys).await { + RoomResult::NotHandled => {} + RoomResult::Handled => return true, + RoomResult::SwitchToRoom { room } => { + self.list.move_cursor_to_id(&room); + self.connect_to_room(room.clone()).await; + self.state = State::ShowRoom(room); + return true; + } } if event.matches(&keys.general.abort) { self.state = State::ShowList; From 24c8c92070a067c2aac0c107a30a93bae0e5c27a Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 21:42:13 +0100 Subject: [PATCH 18/44] Update emoji --- CHANGELOG.md | 1 + Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f75a3d8..ccf0f11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ Procedure when bumping the version number: - Updated documentation for `time_zone` config option - When connecting to a room using `n` in the room list, the cursor now moves to that room +- Updated list of emoji names ### Removed diff --git a/Cargo.lock b/Cargo.lock index 86ebb73..b289bd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -521,7 +521,7 @@ dependencies = [ [[package]] name = "euphoxide" version = "0.6.0" -source = "git+https://github.com/Garmelon/euphoxide.git?tag=v0.6.0#4f7cc49b636301ce9beea9324a0a1390f8391009" +source = "git+https://github.com/Garmelon/euphoxide.git?rev=6eea194d52fb63d7fb260d06e61d0625addf8c67#6eea194d52fb63d7fb260d06e61d0625addf8c67" dependencies = [ "async-trait", "caseless", diff --git a/Cargo.toml b/Cargo.toml index f8445e5..a0de23f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ unicode-width = "0.2.0" [workspace.dependencies.euphoxide] git = "https://github.com/Garmelon/euphoxide.git" -tag = "v0.6.0" +rev = "6eea194d52fb63d7fb260d06e61d0625addf8c67" features = ["bot"] [workspace.dependencies.toss] From 315db430105b58a9cdfbededc06876257df56992 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 21:46:32 +0100 Subject: [PATCH 19/44] Fix /me not being grey and italic --- cove/src/euph/highlight.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cove/src/euph/highlight.rs b/cove/src/euph/highlight.rs index e60a302..e7892a8 100644 --- a/cove/src/euph/highlight.rs +++ b/cove/src/euph/highlight.rs @@ -132,7 +132,7 @@ pub fn apply_spans( assert!(range.end <= content.len()); if i < range.start { - result = result.then_plain(&content[i..range.start]); + result = result.then(&content[i..range.start], base); } let text = &content[range.start..range.end]; @@ -145,7 +145,7 @@ pub fn apply_spans( let name = text.strip_prefix(':').unwrap_or(text); let name = name.strip_suffix(':').unwrap_or(name); if let Some(Some(replacement)) = util::EMOJI.get(name) { - result.then_plain(replacement) + result.then(replacement, base) } else { result.then(name, base.magenta()) } @@ -156,7 +156,7 @@ pub fn apply_spans( } if i < content.len() { - result = result.then_plain(&content[i..]); + result = result.then(&content[i..], base); } result From 9435fbece6abecd148d0937283abb315cbfcb659 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 21:56:18 +0100 Subject: [PATCH 20/44] Fix mention highlighting --- cove/src/euph/highlight.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/cove/src/euph/highlight.rs b/cove/src/euph/highlight.rs index e7892a8..e69fd10 100644 --- a/cove/src/euph/highlight.rs +++ b/cove/src/euph/highlight.rs @@ -77,6 +77,7 @@ impl<'a> SpanFinder<'a> { fn step(&mut self, idx: usize, char: char) { match (char, self.span) { + ('@', Some((SpanType::Mention, _))) => {} // Continue the mention ('@', _) if self.room_or_mention_possible => self.open_span(SpanType::Mention, idx), ('&', _) if self.room_or_mention_possible => self.open_span(SpanType::Room, idx), (':', None) => self.open_span(SpanType::Emoji, idx), @@ -180,8 +181,9 @@ mod tests { #[test] fn mentions() { assert_eq!(find_spans("@foo"), vec![(SpanType::Mention, 0..4)]); + assert_eq!(find_spans("&@foo"), vec![(SpanType::Mention, 1..5)]); assert_eq!(find_spans("a @foo b"), vec![(SpanType::Mention, 2..6)]); - assert_eq!(find_spans("@@foo@"), vec![(SpanType::Mention, 1..6)]); + assert_eq!(find_spans("@@foo@@"), vec![(SpanType::Mention, 0..7)]); assert_eq!(find_spans("a @b@c d"), vec![(SpanType::Mention, 2..6)]); assert_eq!( find_spans("a @b @c d"), @@ -192,12 +194,18 @@ mod tests { #[test] fn rooms() { assert_eq!(find_spans("&foo"), vec![(SpanType::Room, 0..4)]); + assert_eq!(find_spans("@&foo"), vec![(SpanType::Room, 1..5)]); assert_eq!(find_spans("a &foo b"), vec![(SpanType::Room, 2..6)]); - assert_eq!(find_spans("&&foo&"), vec![(SpanType::Room, 1..5)]); + assert_eq!(find_spans("&&foo&&"), vec![(SpanType::Room, 1..5)]); assert_eq!(find_spans("a &b&c d"), vec![(SpanType::Room, 2..4)]); assert_eq!( find_spans("a &b &c d"), vec![(SpanType::Room, 2..4), (SpanType::Room, 5..7)] ); } + + #[test] + fn emoji_in_mentions() { + assert_eq!(find_spans(" @a:b:c "), vec![(SpanType::Mention, 1..7)]); + } } From b4c4a89625b50a3c723146435b4c253980e8476f Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 22:03:42 +0100 Subject: [PATCH 21/44] Fix mention color of non-ascii nicks The old code included the @ in mention color computations. If the nick consisted only of weird unicode characters, this resulted in an incorrect color being computed. --- cove/src/euph/highlight.rs | 4 ++-- cove/src/euph/util.rs | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/cove/src/euph/highlight.rs b/cove/src/euph/highlight.rs index e69fd10..0e7fb56 100644 --- a/cove/src/euph/highlight.rs +++ b/cove/src/euph/highlight.rs @@ -138,8 +138,8 @@ pub fn apply_spans( let text = &content[range.start..range.end]; result = match span { - SpanType::Mention if exact => result.and_then(util::style_nick_exact(text, base)), - SpanType::Mention => result.and_then(util::style_nick(text, base)), + SpanType::Mention if exact => result.and_then(util::style_mention_exact(text, base)), + SpanType::Mention => result.and_then(util::style_mention(text, base)), SpanType::Room => result.then(text, base.blue().bold()), SpanType::Emoji if exact => result.then(text, base.magenta()), SpanType::Emoji => { diff --git a/cove/src/euph/util.rs b/cove/src/euph/util.rs index aff2192..c2928ab 100644 --- a/cove/src/euph/util.rs +++ b/cove/src/euph/util.rs @@ -55,3 +55,17 @@ pub fn style_nick(nick: &str, base: Style) -> Styled { pub fn style_nick_exact(nick: &str, base: Style) -> Styled { Styled::new(nick, nick_style(nick, base)) } + +pub fn style_mention(mention: &str, base: Style) -> Styled { + let nick = mention + .strip_prefix('@') + .expect("mention must start with @"); + Styled::new(EMOJI.replace(mention), nick_style(nick, base)) +} + +pub fn style_mention_exact(mention: &str, base: Style) -> Styled { + let nick = mention + .strip_prefix('@') + .expect("mention must start with @"); + Styled::new(mention, nick_style(nick, base)) +} From b64f56fce54219c60b2e27591951b6c963f93711 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 22:41:25 +0100 Subject: [PATCH 22/44] Fix nick color in rare edge cases --- CHANGELOG.md | 4 ++++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ccf0f11..86159d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,10 @@ Procedure when bumping the version number: - Special handling of &rl2dev +### Fixed + +- Nick color in rare edge cases + ## v0.8.3 - 2024-05-20 ### Changed diff --git a/Cargo.lock b/Cargo.lock index b289bd3..98db605 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -521,7 +521,7 @@ dependencies = [ [[package]] name = "euphoxide" version = "0.6.0" -source = "git+https://github.com/Garmelon/euphoxide.git?rev=6eea194d52fb63d7fb260d06e61d0625addf8c67#6eea194d52fb63d7fb260d06e61d0625addf8c67" +source = "git+https://github.com/Garmelon/euphoxide.git?rev=095d2cea86a574732e82385e217381b35cf65e4d#095d2cea86a574732e82385e217381b35cf65e4d" dependencies = [ "async-trait", "caseless", diff --git a/Cargo.toml b/Cargo.toml index a0de23f..6fbcf0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ unicode-width = "0.2.0" [workspace.dependencies.euphoxide] git = "https://github.com/Garmelon/euphoxide.git" -rev = "6eea194d52fb63d7fb260d06e61d0625addf8c67" +rev = "095d2cea86a574732e82385e217381b35cf65e4d" features = ["bot"] [workspace.dependencies.toss] From 972e4938aab8b8a7cc8c2fe5b89f9ddbf2cca618 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 22:46:09 +0100 Subject: [PATCH 23/44] Run tests in CI --- .github/workflows/build.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f02d5dd..012c48e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,6 +31,9 @@ jobs: - name: Build run: cargo build --release + - name: Test + run: cargo test --release + - name: Record target triple run: rustc -vV | awk '/^host/ { print $2 }' > target/release/host From 967293db379d4ba962cfb851d5cf4750b54d2101 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 22:54:03 +0100 Subject: [PATCH 24/44] Fix links wrapping into oblivion --- CHANGELOG.md | 1 + cove/src/ui/euph/links.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86159d0..e2344ff 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ Procedure when bumping the version number: ### Fixed - Nick color in rare edge cases +- Message link list rendering bug ## v0.8.3 - 2024-05-20 diff --git a/cove/src/ui/euph/links.rs b/cove/src/ui/euph/links.rs index 20e2219..c64830d 100644 --- a/cove/src/ui/euph/links.rs +++ b/cove/src/ui/euph/links.rs @@ -101,7 +101,7 @@ impl LinksState { Link::Room(name) => text.then(format!("&{name}"), Style::new().blue().bold()), }; - Text::new(text) + Text::new(text).with_wrap(false) }); } From cab37cb633961ff1b791e2ea5a79bae03576f477 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 22:55:47 +0100 Subject: [PATCH 25/44] Fix non-replaceable emoji being rendered without colons --- cove/src/euph/highlight.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cove/src/euph/highlight.rs b/cove/src/euph/highlight.rs index 0e7fb56..1c9abd0 100644 --- a/cove/src/euph/highlight.rs +++ b/cove/src/euph/highlight.rs @@ -148,7 +148,7 @@ pub fn apply_spans( if let Some(Some(replacement)) = util::EMOJI.get(name) { result.then(replacement, base) } else { - result.then(name, base.magenta()) + result.then(text, base.magenta()) } } }; From 03b91ec1cdf871370208d03dd1e86faf789f41cc Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 23:08:17 +0100 Subject: [PATCH 26/44] Mention ghostty in config docs --- cove-config/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cove-config/src/lib.rs b/cove-config/src/lib.rs index 85b418e..24ffcd3 100644 --- a/cove-config/src/lib.rs +++ b/cove-config/src/lib.rs @@ -58,7 +58,8 @@ pub struct Config { /// those cases are usually rare (unless you view a lot of emoji). /// /// `"unicode"`: Use the unicode standard in a best-effort manner to - /// determine grapheme widths. + /// determine grapheme widths. Some terminals (e.g. ghostty) can make use of + /// this. /// /// This method is used when `measure_widths` is set to `false`. #[serde(default)] From 56896a861e33e6d546fb00fa040942b13ec84863 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 23:08:29 +0100 Subject: [PATCH 27/44] Mention release binaries in readme --- README.md | 63 +++++-------------------------------------------------- 1 file changed, 5 insertions(+), 58 deletions(-) diff --git a/README.md b/README.md index e99e545..22fef83 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,11 @@ real-time chat platform. It runs on Linux, Windows, and macOS. +## Installing cove + +Download a binary of your choice from the +[latest release on GitHub](https://github.com/Garmelon/cove/releases/latest). + ## Using cove To start cove, simply run `cove` in your terminal. For more info about the @@ -26,61 +31,3 @@ file or via `cove help-config`. When launched, cove prints the location it is loading its config file from. To configure cove, create a config file at that location. This location can be changed via the `--config` command line option. - -## Installation - -At this point, cove is not available via any package manager. - -Cove is available as a Nix Flake. To try it out, you can use -```bash -$ nix run --override-input nixpkgs nixpkgs github:Garmelon/cove/latest -``` - -## Manual installation - -This section contains instructions on how to install cove by compiling it yourself. -It doesn't assume you know how to program, but it does assume basic familiarity with the command line on your platform of choice. -Cove runs in the terminal, after all. - -### Installing rustup - -Cove is written in Rust, so the first step is to install rustup. Either install -it from your package manager of choice (if you have one) or use the -[installer](https://rustup.rs/). - -Test your installation by running `rustup --version` and `cargo --version`. If -rustup is installed correctly, both of these should show a version number. - -Cove is designed on the current version of the stable toolchain. If cove doesn't -compile, you can try switching to the stable toolchain and updating it using the -following commands: -```bash -$ rustup default stable -$ rustup update -``` - -### Installing cove - -To install or update to the latest release of cove, run the following command: - -```bash -$ cargo install --force --git https://github.com/Garmelon/cove --branch latest -``` - -If you like to live dangerously and want to install or update to the latest, -bleeding-edge, possibly-broken commit from the repo's main branch, run the -following command. - -**Warning:** This could corrupt your vault. Make sure to make a backup before -running the command. - -```bash -$ cargo install --force --git https://github.com/Garmelon/cove -``` - -To install a specific version of cove, run the following command and substitute -in the full version you want to install: - -```bash -$ cargo install --force --git https://github.com/Garmelon/cove --tag v0.1.0 -``` From cc436bbb3a1332bde383b7e5b440e45ecd0144a4 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 23:40:58 +0100 Subject: [PATCH 28/44] Mention --width-estimation-method in config docs --- cove-config/src/lib.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cove-config/src/lib.rs b/cove-config/src/lib.rs index 24ffcd3..a2a5cb9 100644 --- a/cove-config/src/lib.rs +++ b/cove-config/src/lib.rs @@ -62,6 +62,8 @@ pub struct Config { /// this. /// /// This method is used when `measure_widths` is set to `false`. + /// + /// See also the `--width-estimation-method` command line option. #[serde(default)] pub width_estimation_method: WidthEstimationMethod, From 676c92752df7070b1fb6c874d4978c65fc8571a9 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 23:39:22 +0100 Subject: [PATCH 29/44] Remove flake A bit annoying to keep up-to-date since I don't use it myself. --- flake.lock | 47 ----------------------------------------------- flake.nix | 29 ----------------------------- 2 files changed, 76 deletions(-) delete mode 100644 flake.lock delete mode 100644 flake.nix diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 1e52d47..0000000 --- a/flake.lock +++ /dev/null @@ -1,47 +0,0 @@ -{ - "nodes": { - "naersk": { - "inputs": { - "nixpkgs": [ - "nixpkgs" - ] - }, - "locked": { - "lastModified": 1713520724, - "narHash": "sha256-CO8MmVDmqZX2FovL75pu5BvwhW+Vugc7Q6ze7Hj8heI=", - "owner": "nix-community", - "repo": "naersk", - "rev": "c5037590290c6c7dae2e42e7da1e247e54ed2d49", - "type": "github" - }, - "original": { - "owner": "nix-community", - "repo": "naersk", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1714068967, - "narHash": "sha256-jfQUewdwBVs0HHLH10qxyn0+J53e1aQoPSkuBnYf15s=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "10b682b6e5ed139ee2bef863ada3043f2d79c1cc", - "type": "github" - }, - "original": { - "owner": "NixOS", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "naersk": "naersk", - "nixpkgs": "nixpkgs" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index 286f9b7..0000000 --- a/flake.nix +++ /dev/null @@ -1,29 +0,0 @@ -{ - description = "TUI client for euphoria.leet.nu, a threaded real-time chat platform"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs"; - - naersk.url = "github:nix-community/naersk"; - naersk.inputs.nixpkgs.follows = "nixpkgs"; - }; - - outputs = { self, nixpkgs, naersk }: - let forAllSystems = nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed; - in { - packages = forAllSystems (system: - let - pkgs = import nixpkgs { inherit system; }; - naersk' = pkgs.callPackage naersk { }; - cargoToml = pkgs.lib.importTOML ./Cargo.toml; - in - { - default = naersk'.buildPackage { - name = "cove"; - version = cargoToml.workspace.package.version; - root = ./.; - }; - } - ); - }; -} From b207e91c256046691e1e450419129c61ea74db69 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 23:38:02 +0100 Subject: [PATCH 30/44] Update dependencies --- Cargo.lock | 12 ++++++------ Cargo.toml | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 98db605..0f41db7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -520,8 +520,8 @@ dependencies = [ [[package]] name = "euphoxide" -version = "0.6.0" -source = "git+https://github.com/Garmelon/euphoxide.git?rev=095d2cea86a574732e82385e217381b35cf65e4d#095d2cea86a574732e82385e217381b35cf65e4d" +version = "0.6.1" +source = "git+https://github.com/Garmelon/euphoxide.git?tag=v0.6.1#7a292c429ad44aa6aa52fc381e3168841d6303b0" dependencies = [ "async-trait", "caseless", @@ -865,9 +865,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.25" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] name = "memchr" @@ -1646,8 +1646,8 @@ dependencies = [ [[package]] name = "toss" -version = "0.3.1" -source = "git+https://github.com/Garmelon/toss.git?rev=423dd100c1360decffc5107ea4757d751ac0f4db#423dd100c1360decffc5107ea4757d751ac0f4db" +version = "0.3.2" +source = "git+https://github.com/Garmelon/toss.git?tag=v0.3.2#d28ce90ec7590778e6035a7b00b1d85064f03dbf" dependencies = [ "async-trait", "crossterm", diff --git a/Cargo.toml b/Cargo.toml index 6fbcf0c..119f98e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ directories = "6.0.0" edit = "0.1.5" jiff = "0.2.1" linkify = "0.10.0" -log = { version = "0.4.25", features = ["std"] } +log = { version = "0.4.26", features = ["std"] } open = "5.3.2" parking_lot = "0.12.3" proc-macro2 = "1.0.93" @@ -34,12 +34,12 @@ unicode-width = "0.2.0" [workspace.dependencies.euphoxide] git = "https://github.com/Garmelon/euphoxide.git" -rev = "095d2cea86a574732e82385e217381b35cf65e4d" +tag = "v0.6.1" features = ["bot"] [workspace.dependencies.toss] git = "https://github.com/Garmelon/toss.git" -rev = "423dd100c1360decffc5107ea4757d751ac0f4db" +tag = "v0.3.2" [workspace.dependencies.vault] git = "https://github.com/Garmelon/vault.git" From 4cf6a15577ad5abd31550f5b23a72ab979a865dd Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 23 Feb 2025 23:43:38 +0100 Subject: [PATCH 31/44] Bump version to 0.9.0 --- CHANGELOG.md | 5 +++-- CONFIG.md | 60 +++++++++++++++++++++++++++++++++++----------------- Cargo.lock | 8 +++---- Cargo.toml | 2 +- 4 files changed, 49 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2344ff..ed799ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,12 @@ Procedure when bumping the version number: 4. Run `cargo run help-config > CONFIG.md` 5. Commit with message `Bump version to X.Y.Z` 6. Create tag named `vX.Y.Z` -7. Fast-forward branch `latest` -8. Push `master`, `latest` and the new tag +7. Push `master` and the new tag ## Unreleased +## v0.9.0 - 2025-02-23 + ### Added - Unicode-based grapheme width estimation method diff --git a/CONFIG.md b/CONFIG.md index 66625d0..feec645 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -93,9 +93,9 @@ Whether to automatically join this room on startup. **Type:** boolean **Default:** `false` -If `euph.rooms..username` is set, this will force cove to set the -username even if there is already a different username associated with -the current session. +If `euph.servers..rooms..username` is set, this will force +cove to set the username even if there is already a different username +associated with the current session. ### `euph.servers..rooms..password` @@ -607,12 +607,11 @@ Move to root. **Type:** boolean **Default:** `false` -Whether to measure the width of characters as displayed by the terminal -emulator instead of guessing the width. +Whether to measure the width of graphemes (i.e. characters) as displayed +by the terminal emulator instead of estimating the width. Enabling this makes rendering a bit slower but more accurate. The screen -might also flash when encountering new characters (or, more accurately, -graphemes). +might also flash when encountering new graphemes. See also the `--measure-widths` command line option. @@ -656,18 +655,41 @@ order of priority): Time zone that chat timestamps should be displayed in. -This option is interpreted as a POSIX TZ string. It is described here in -further detail: - +This option can either be the string `"localtime"`, a [POSIX TZ string], +or a [tz identifier] from the [tz database]. -On a normal system, the string `"localtime"` as well as any value from -the "TZ identifier" column of the following wikipedia article should be -valid TZ strings: - +When not set or when set to `"localtime"`, cove attempts to use your +system's configured time zone, falling back to UTC. -If the `TZ` environment variable exists, it overrides this option. If -neither exist, cove uses the system's local time zone. +When the string begins with a colon or doesn't match the a POSIX TZ +string format, it is interpreted as a tz identifier and looked up in +your system's tz database (or a bundled tz database on Windows). -**Warning:** On Windows, cove can't get the local time zone and uses UTC -instead. However, you can still specify a path to a tz data file or a -custom time zone string. +If the `TZ` environment variable exists, it overrides this option. + +[POSIX TZ string]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html#tag_08_03 +[tz identifier]: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones +[tz database]: https://en.wikipedia.org/wiki/Tz_database + +### `width_estimation_method` + +**Required:** yes +**Type:** string +**Values:** `"legacy"`, `"unicode"` +**Default:** `"legacy"` + +How to estimate the width of graphemes (i.e. characters) as displayed by +the terminal emulator. + +`"legacy"`: Use a legacy method that should mostly work on most terminal +emulators. This method will never be correct in all cases since every +terminal emulator handles grapheme widths slightly differently. However, +those cases are usually rare (unless you view a lot of emoji). + +`"unicode"`: Use the unicode standard in a best-effort manner to +determine grapheme widths. Some terminals (e.g. ghostty) can make use of +this. + +This method is used when `measure_widths` is set to `false`. + +See also the `--width-estimation-method` command line option. diff --git a/Cargo.lock b/Cargo.lock index 0f41db7..cc86a84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,7 +330,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cove" -version = "0.8.3" +version = "0.9.0" dependencies = [ "anyhow", "async-trait", @@ -358,7 +358,7 @@ dependencies = [ [[package]] name = "cove-config" -version = "0.8.3" +version = "0.9.0" dependencies = [ "cove-input", "cove-macro", @@ -369,7 +369,7 @@ dependencies = [ [[package]] name = "cove-input" -version = "0.8.3" +version = "0.9.0" dependencies = [ "cove-macro", "crossterm", @@ -383,7 +383,7 @@ dependencies = [ [[package]] name = "cove-macro" -version = "0.8.3" +version = "0.9.0" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 119f98e..26aa29d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = ["cove", "cove-*"] [workspace.package] -version = "0.8.3" +version = "0.9.0" edition = "2024" [workspace.dependencies] From 30c344031a9f5d7f45ec8311902aca84d7484e42 Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 28 Feb 2025 14:32:30 +0100 Subject: [PATCH 32/44] Fix rendering glitches with unicode-based width estimation --- CHANGELOG.md | 4 ++++ Cargo.lock | 4 ++-- Cargo.toml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed799ba..41d2586 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ Procedure when bumping the version number: ## Unreleased +### Fixed + +- Rendering glitches with unicode-based width estimation + ## v0.9.0 - 2025-02-23 ### Added diff --git a/Cargo.lock b/Cargo.lock index cc86a84..e9ceb10 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1646,8 +1646,8 @@ dependencies = [ [[package]] name = "toss" -version = "0.3.2" -source = "git+https://github.com/Garmelon/toss.git?tag=v0.3.2#d28ce90ec7590778e6035a7b00b1d85064f03dbf" +version = "0.3.3" +source = "git+https://github.com/Garmelon/toss.git?tag=v0.3.3#96b2e13c4a4b0174601d90246d92d148c4230eeb" dependencies = [ "async-trait", "crossterm", diff --git a/Cargo.toml b/Cargo.toml index 26aa29d..322724f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ features = ["bot"] [workspace.dependencies.toss] git = "https://github.com/Garmelon/toss.git" -tag = "v0.3.2" +tag = "v0.3.3" [workspace.dependencies.vault] git = "https://github.com/Garmelon/vault.git" From 6157ca5088ac4d6e6ebc6452d0704d2d6f48ff7a Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 1 Mar 2025 14:26:18 +0100 Subject: [PATCH 33/44] Update dependencies --- Cargo.lock | 62 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 2 +- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e9ceb10..5e5b86a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,9 +113,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-lc-rs" -version = "1.12.4" +version = "1.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd755adf9707cf671e31d944a189be3deaaeee11c8bc1d669bb8022ac90fbd0" +checksum = "5e4e8200b9a4a5801a769d50eeabc05670fec7e959a8cb7a63a93e4e519942ae" dependencies = [ "aws-lc-sys", "paste", @@ -176,9 +176,9 @@ dependencies = [ [[package]] name = "bitflags" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "block-buffer" @@ -212,9 +212,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.14" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3d1b2e905a3a7b00a6141adb0e4c0bb941d11caf55349d863942a1cc44e3c9" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ "jobserver", "libc", @@ -249,9 +249,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.30" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92b7b18d71fad5313a1e320fa9897994228ce274b60faa4d694fe0ea89cd9e6d" +checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" dependencies = [ "clap_builder", "clap_derive", @@ -259,9 +259,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.30" +version = "4.5.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35db2071778a7344791a4fb4f95308b5673d219dee3ae348b86642574ecc90c" +checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" dependencies = [ "anstream", "anstyle", @@ -498,9 +498,9 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" [[package]] name = "equivalent" @@ -803,9 +803,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.169" +version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" [[package]] name = "libloading" @@ -883,9 +883,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3b1c9bd4fe1f0f8b387f6eb9eb3b4a1aa26185e5750efb9140301703f62cd1b" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ "adler2", ] @@ -1029,9 +1029,9 @@ checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "portable-atomic" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" [[package]] name = "portable-atomic-util" @@ -1093,7 +1093,7 @@ checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_chacha", "rand_core", - "zerocopy 0.8.20", + "zerocopy 0.8.21", ] [[package]] @@ -1108,19 +1108,19 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.1" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88e0da7a2c97baa202165137c158d0a2e824ac465d13d81046727b34cb247d3" +checksum = "7a509b1a2ffbe92afab0e55c8fd99dea1c280e8171bd2d88682bb20bc41cbc2c" dependencies = [ "getrandom 0.3.1", - "zerocopy 0.8.20", + "zerocopy 0.8.21", ] [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" dependencies = [ "bitflags", ] @@ -1167,9 +1167,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "ring" -version = "0.17.9" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75ec5e92c4d8aede845126adc388046234541629e76029599ed35a003c7ed24" +checksum = "da5349ae27d3887ca812fb375b45a4fbb36d8d12d2df394968cd86e35683fe73" dependencies = [ "cc", "cfg-if", @@ -1914,11 +1914,11 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde3bb8c68a8f3f1ed4ac9221aad6b10cece3e60a8e2ea54a6a2dec806d0084c" +checksum = "dcf01143b2dd5d134f11f545cf9f1431b13b749695cb33bcce051e7568f99478" dependencies = [ - "zerocopy-derive 0.8.20", + "zerocopy-derive 0.8.21", ] [[package]] @@ -1934,9 +1934,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eea57037071898bf96a6da35fd626f4f27e9cee3ead2a6c703cf09d472b2e700" +checksum = "712c8386f4f4299382c9abee219bee7084f78fb939d88b6840fcc1320d5f6da2" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 322724f..cd023a1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ edition = "2024" [workspace.dependencies] anyhow = "1.0.96" async-trait = "0.1.86" -clap = { version = "4.5.30", features = ["derive", "deprecated"] } +clap = { version = "4.5.31", features = ["derive", "deprecated"] } cookie = "0.18.1" crossterm = "0.28.1" directories = "6.0.0" From 496cdde18d33cd898e6628ba0636dc03761cf9c8 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 1 Mar 2025 14:38:41 +0100 Subject: [PATCH 34/44] Bump version to 0.9.1 --- CHANGELOG.md | 2 ++ Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41d2586..de7a07e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ Procedure when bumping the version number: ## Unreleased +## v0.9.1 - 2025-03-01 + ### Fixed - Rendering glitches with unicode-based width estimation diff --git a/Cargo.lock b/Cargo.lock index 5e5b86a..60c89b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -330,7 +330,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cove" -version = "0.9.0" +version = "0.9.1" dependencies = [ "anyhow", "async-trait", @@ -358,7 +358,7 @@ dependencies = [ [[package]] name = "cove-config" -version = "0.9.0" +version = "0.9.1" dependencies = [ "cove-input", "cove-macro", @@ -369,7 +369,7 @@ dependencies = [ [[package]] name = "cove-input" -version = "0.9.0" +version = "0.9.1" dependencies = [ "cove-macro", "crossterm", @@ -383,7 +383,7 @@ dependencies = [ [[package]] name = "cove-macro" -version = "0.9.0" +version = "0.9.1" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index cd023a1..2937074 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = ["cove", "cove-*"] [workspace.package] -version = "0.9.0" +version = "0.9.1" edition = "2024" [workspace.dependencies] From a17630aeaaa902ead46de58d87ceb1ec8703fcfc Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 8 Mar 2025 19:21:01 +0100 Subject: [PATCH 35/44] Ring bell when mentioned --- CHANGELOG.md | 4 ++++ Cargo.lock | 4 ++-- Cargo.toml | 2 +- cove-config/src/lib.rs | 4 ++++ cove/src/ui/euph/room.rs | 44 +++++++++++++++++++++++++++++++++++++--- cove/src/ui/rooms.rs | 16 ++++++++++++--- 6 files changed, 65 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de7a07e..4136ab3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ Procedure when bumping the version number: ## Unreleased +### Added + +- `bell_on_mention` config option + ## v0.9.1 - 2025-03-01 ### Fixed diff --git a/Cargo.lock b/Cargo.lock index 60c89b6..58a545e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1646,8 +1646,8 @@ dependencies = [ [[package]] name = "toss" -version = "0.3.3" -source = "git+https://github.com/Garmelon/toss.git?tag=v0.3.3#96b2e13c4a4b0174601d90246d92d148c4230eeb" +version = "0.3.4" +source = "git+https://github.com/Garmelon/toss.git?tag=v0.3.4#57aa8c59308f6f0aa82bde415a42b56c3d6f7c4d" dependencies = [ "async-trait", "crossterm", diff --git a/Cargo.toml b/Cargo.toml index 2937074..a4278ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,7 @@ features = ["bot"] [workspace.dependencies.toss] git = "https://github.com/Garmelon/toss.git" -tag = "v0.3.3" +tag = "v0.3.4" [workspace.dependencies.vault] git = "https://github.com/Garmelon/vault.git" diff --git a/cove-config/src/lib.rs b/cove-config/src/lib.rs index a2a5cb9..0cb6cc7 100644 --- a/cove-config/src/lib.rs +++ b/cove-config/src/lib.rs @@ -100,6 +100,10 @@ pub struct Config { #[serde(default)] pub rooms_sort_order: RoomsSortOrder, + /// Ring the bell (character 0x07) when you are mentioned in a room. + #[serde(default)] + pub bell_on_mention: bool, + /// Time zone that chat timestamps should be displayed in. /// /// This option can either be the string `"localtime"`, a [POSIX TZ string], diff --git a/cove/src/ui/euph/room.rs b/cove/src/ui/euph/room.rs index 83d7e96..ebae5a8 100644 --- a/cove/src/ui/euph/room.rs +++ b/cove/src/ui/euph/room.rs @@ -4,8 +4,8 @@ use cove_config::{Config, Keys}; use cove_input::InputEvent; use crossterm::style::Stylize; use euphoxide::{ - api::{Data, Message, MessageId, PacketType, SessionId}, - bot::instance::{Event, ServerConfig}, + api::{Data, Message, MessageId, PacketType, SessionId, packet::ParsedPacket}, + bot::instance::{ConnSnapshot, Event, ServerConfig}, conn::{self, Joined, Joining, SessionInfo}, }; use jiff::tz::TimeZone; @@ -19,7 +19,7 @@ use toss::{ }; use crate::{ - euph, + euph::{self, SpanType}, macros::logging_unwrap, ui::{ UiError, UiEvent, @@ -73,6 +73,8 @@ pub struct EuphRoom { last_msg_sent: Option>, nick_list: ListState, + + mentioned: bool, } impl EuphRoom { @@ -96,6 +98,7 @@ impl EuphRoom { chat: ChatState::new(vault, tz), last_msg_sent: None, nick_list: ListState::new(), + mentioned: false, } } @@ -164,6 +167,12 @@ impl EuphRoom { } } + pub fn retrieve_mentioned(&mut self) -> bool { + let mentioned = self.mentioned; + self.mentioned = false; + mentioned + } + pub async fn unseen_msgs_count(&self) -> usize { logging_unwrap!(self.vault().unseen_msgs_count().await) } @@ -557,6 +566,35 @@ impl EuphRoom { return false; } + if let Event::Packet( + _, + ParsedPacket { + content: Ok(Data::SendEvent(send)), + .. + }, + ConnSnapshot { + state: conn::State::Joined(joined), + .. + }, + ) = &event + { + let normalized_name = euphoxide::nick::normalize(&joined.session.name); + let content = &*send.0.content; + for (rtype, rspan) in euph::find_spans(content) { + if rtype != SpanType::Mention { + continue; + } + let Some(mention) = content[rspan].strip_prefix('@') else { + continue; + }; + let normalized_mention = euphoxide::nick::normalize(mention); + if normalized_name == normalized_mention { + self.mentioned = true; + break; + } + } + } + // We handle the packet internally first because the room event handling // will consume it while we only need a reference. let handled = if let Event::Packet(_, packet, _) = &event { diff --git a/cove/src/ui/rooms.rs b/cove/src/ui/rooms.rs index 80089da..f901f30 100644 --- a/cove/src/ui/rooms.rs +++ b/cove/src/ui/rooms.rs @@ -17,7 +17,7 @@ use jiff::tz::TimeZone; use tokio::sync::mpsc; use toss::{ Style, Styled, Widget, WidgetExt, - widgets::{BoxedAsync, Empty, Join2, Text}, + widgets::{BellState, BoxedAsync, Empty, Join2, Text}, }; use crate::{ @@ -95,6 +95,7 @@ pub struct Rooms { list: ListState, order: Order, + bell: BellState, euph_servers: HashMap, euph_rooms: HashMap, @@ -115,6 +116,7 @@ impl Rooms { state: State::ShowList, list: ListState::new(), order: Order::from_rooms_sort_order(config.rooms_sort_order), + bell: BellState::new(), euph_servers: HashMap::new(), euph_rooms: HashMap::new(), }; @@ -244,7 +246,9 @@ impl Rooms { .retain(|n, r| !r.stopped() || rooms_set.contains(n)); for room in rooms_set { - self.get_or_insert_room(room).await.retain(); + let room = self.get_or_insert_room(room).await; + room.retain(); + self.bell.ring |= room.retrieve_mentioned(); } } @@ -254,7 +258,7 @@ impl Rooms { _ => self.stabilize_rooms().await, } - match &mut self.state { + let widget = match &mut self.state { State::ShowList => Self::rooms_widget( &self.vault, self.config, @@ -297,6 +301,12 @@ impl Rooms { .below(delete.widget()) .desync() .boxed_async(), + }; + + if self.config.bell_on_mention { + widget.above(self.bell.widget().desync()).boxed_async() + } else { + widget } } From 74fbf386b2e1769821a5f0bbdc4175a61ef63310 Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 14 Mar 2025 15:08:00 +0100 Subject: [PATCH 36/44] Update dependencies --- CHANGELOG.md | 2 +- Cargo.lock | 236 +++++++++++++++++++++++++++------------------------ Cargo.toml | 22 ++--- 3 files changed, 137 insertions(+), 123 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4136ab3..a14ead2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). Procedure when bumping the version number: -1. Update dependencies and flake in a separate commit +1. Update dependencies in a separate commit 2. Set version number in `Cargo.toml` 3. Add new section in this changelog 4. Run `cargo run help-config > CONFIG.md` diff --git a/Cargo.lock b/Cargo.lock index 58a545e..6a83e5d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -90,15 +90,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b964d184e89d9b6b67dd2715bc8e74cf3107fb2b529990c90cf517326150bf4" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "async-trait" -version = "0.1.86" +version = "0.1.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d" +checksum = "d556ec1359574147ec0c4fc5eb525f3f23263a592b1a9c07e0a75b427de55c97" dependencies = [ "proc-macro2", "quote", @@ -113,27 +113,25 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "aws-lc-rs" -version = "1.12.5" +version = "1.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e4e8200b9a4a5801a769d50eeabc05670fec7e959a8cb7a63a93e4e519942ae" +checksum = "dabb68eb3a7aa08b46fddfd59a3d55c978243557a90ab804769f7e20e67d2b01" dependencies = [ "aws-lc-sys", - "paste", "zeroize", ] [[package]] name = "aws-lc-sys" -version = "0.26.0" +version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9dd2e03ee80ca2822dd6ea431163d2ef259f2066a4d6ccaca6d9dcb386aa43" +checksum = "6bbe221bbf523b625a4dd8585c7f38166e31167ec2ca98051dbcb4c3b6e825d2" dependencies = [ "bindgen", "cc", "cmake", "dunce", "fs_extra", - "paste", ] [[package]] @@ -189,17 +187,11 @@ dependencies = [ "generic-array", ] -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - [[package]] name = "bytes" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "caseless" @@ -249,9 +241,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.31" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "027bb0d98429ae334a8698531da7077bdf906419543a35a55c2cb1b66437d767" +checksum = "6088f3ae8c3608d19260cd7445411865a485688711b78b5be70d78cd96136f83" dependencies = [ "clap_builder", "clap_derive", @@ -259,9 +251,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.31" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5589e0cba072e0f3d23791efac0fd8627b49c829c196a492e88168e6a669d863" +checksum = "22a7ef7f676155edfb82daa97f99441f3ebf4a58d5e32f295a56259f1b6facc8" dependencies = [ "anstream", "anstyle", @@ -271,9 +263,9 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.28" +version = "4.5.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" dependencies = [ "heck", "proc-macro2", @@ -409,7 +401,7 @@ dependencies = [ "crossterm_winapi", "mio", "parking_lot", - "rustix", + "rustix 0.38.44", "signal-hook", "signal-hook-mio", "winapi", @@ -498,9 +490,9 @@ dependencies = [ [[package]] name = "either" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7914353092ddf589ad78f25c5c1c21b7f80b0ff8621e7c814c3485b5306da9d" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "equivalent" @@ -686,9 +678,9 @@ dependencies = [ [[package]] name = "http" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -697,15 +689,15 @@ dependencies = [ [[package]] name = "httparse" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "indexmap" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", "hashbrown 0.15.2", @@ -747,16 +739,17 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3590fea8e9e22d449600c9bbd481a8163bef223e4ff938e5f55899f8cf1adb93" +checksum = "d699bc6dfc879fb1bf9bdff0d4c56f0884fc6f0d0eb0fba397a6d00cd9a6b85e" dependencies = [ + "jiff-static", "jiff-tzdb-platform", "log", "portable-atomic", @@ -766,10 +759,21 @@ dependencies = [ ] [[package]] -name = "jiff-tzdb" -version = "0.1.2" +name = "jiff-static" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2cec2f5d266af45a071ece48b1fb89f3b00b2421ac3a5fe10285a6caaa60d3" +checksum = "8d16e75759ee0aa64c57a56acbf43916987b20c77373cb7e808979e02b93c9f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "962e1dfe9b2d75a84536cf5bf5eaaa4319aa7906c7160134a22883ac316d5f31" [[package]] name = "jiff-tzdb-platform" @@ -803,9 +807,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.170" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libloading" @@ -853,6 +857,12 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "linux-raw-sys" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" + [[package]] name = "lock_api" version = "0.4.12" @@ -938,9 +948,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.3" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" [[package]] name = "open" @@ -997,12 +1007,6 @@ dependencies = [ "windows-targets", ] -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - [[package]] name = "pathdiff" version = "0.2.3" @@ -1023,9 +1027,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "portable-atomic" @@ -1050,18 +1054,18 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "zerocopy 0.7.35", + "zerocopy 0.8.23", ] [[package]] name = "prettyplease" -version = "0.2.29" +version = "0.2.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" +checksum = "5316f57387668042f561aae71480de936257848f9c43ce528e311d89a07cadeb" dependencies = [ "proc-macro2", "syn", @@ -1069,18 +1073,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.38" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] @@ -1093,7 +1097,7 @@ checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" dependencies = [ "rand_chacha", "rand_core", - "zerocopy 0.8.21", + "zerocopy 0.8.23", ] [[package]] @@ -1108,19 +1112,18 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a509b1a2ffbe92afab0e55c8fd99dea1c280e8171bd2d88682bb20bc41cbc2c" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ "getrandom 0.3.1", - "zerocopy 0.8.21", ] [[package]] name = "redox_syscall" -version = "0.5.9" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ "bitflags", ] @@ -1167,9 +1170,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "ring" -version = "0.17.11" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da5349ae27d3887ca812fb375b45a4fbb36d8d12d2df394968cd86e35683fe73" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", @@ -1215,7 +1218,20 @@ dependencies = [ "bitflags", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.9.3", "windows-sys 0.59.0", ] @@ -1266,9 +1282,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.19" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "schannel" @@ -1310,9 +1326,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] @@ -1329,9 +1345,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -1350,9 +1366,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.139" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -1455,9 +1471,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.98" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -1466,32 +1482,31 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.17.1" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" +checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600" dependencies = [ - "cfg-if", "fastrand", "getrandom 0.3.1", "once_cell", - "rustix", + "rustix 1.0.2", "windows-sys 0.59.0", ] [[package]] name = "thiserror" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.11" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", @@ -1500,9 +1515,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.37" +version = "0.3.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8" dependencies = [ "deranged", "itoa", @@ -1515,15 +1530,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef" [[package]] name = "time-macros" -version = "0.2.19" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c" dependencies = [ "num-conv", "time-core", @@ -1531,9 +1546,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" dependencies = [ "tinyvec_macros", ] @@ -1546,9 +1561,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.43.0" +version = "1.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" dependencies = [ "backtrace", "bytes", @@ -1575,9 +1590,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.1" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ "rustls", "tokio", @@ -1683,9 +1698,9 @@ checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "unicode-ident" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00e2473a93778eb0bad35909dff6a10d28e63f792f16ed15e404fca9d5eeedbe" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-linebreak" @@ -1777,7 +1792,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix", + "rustix 0.38.44", ] [[package]] @@ -1886,9 +1901,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" +checksum = "0e97b544156e9bebe1a0ffbc03484fc1ffe3100cbce3ffb17eac35f7cdd7ab36" dependencies = [ "memchr", ] @@ -1908,17 +1923,16 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ - "byteorder", "zerocopy-derive 0.7.35", ] [[package]] name = "zerocopy" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf01143b2dd5d134f11f545cf9f1431b13b749695cb33bcce051e7568f99478" +checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" dependencies = [ - "zerocopy-derive 0.8.21", + "zerocopy-derive 0.8.23", ] [[package]] @@ -1934,9 +1948,9 @@ dependencies = [ [[package]] name = "zerocopy-derive" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712c8386f4f4299382c9abee219bee7084f78fb939d88b6840fcc1320d5f6da2" +checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index a4278ed..f4f81a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,28 +7,28 @@ version = "0.9.1" edition = "2024" [workspace.dependencies] -anyhow = "1.0.96" -async-trait = "0.1.86" -clap = { version = "4.5.31", features = ["derive", "deprecated"] } +anyhow = "1.0.97" +async-trait = "0.1.87" +clap = { version = "4.5.32", features = ["derive", "deprecated"] } cookie = "0.18.1" crossterm = "0.28.1" directories = "6.0.0" edit = "0.1.5" -jiff = "0.2.1" +jiff = "0.2.4" linkify = "0.10.0" log = { version = "0.4.26", features = ["std"] } open = "5.3.2" parking_lot = "0.12.3" -proc-macro2 = "1.0.93" -quote = "1.0.38" +proc-macro2 = "1.0.94" +quote = "1.0.40" rusqlite = { version = "0.31.0", features = ["bundled", "time"] } rustls = "0.23.23" -serde = { version = "1.0.218", features = ["derive"] } +serde = { version = "1.0.219", features = ["derive"] } serde_either = "0.2.1" -serde_json = "1.0.139" -syn = "2.0.98" -thiserror = "2.0.11" -tokio = { version = "1.43.0", features = ["full"] } +serde_json = "1.0.140" +syn = "2.0.100" +thiserror = "2.0.12" +tokio = { version = "1.44.1", features = ["full"] } toml = "0.8.20" unicode-width = "0.2.0" From ca0f0b6c31d78420ad1599fb3f9d61052cb580da Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 14 Mar 2025 15:09:01 +0100 Subject: [PATCH 37/44] Bump version to 0.9.2 --- CHANGELOG.md | 2 ++ CONFIG.md | 8 ++++++++ Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a14ead2..1f06e21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ Procedure when bumping the version number: ## Unreleased +## v0.9.2 - 2025-03-14 + ### Added - `bell_on_mention` config option diff --git a/CONFIG.md b/CONFIG.md index feec645..e537310 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -53,6 +53,14 @@ Available modifiers: ## Available options +### `bell_on_mention` + +**Required:** yes +**Type:** boolean +**Default:** `false` + +Ring the bell (character 0x07) when you are mentioned in a room. + ### `data_dir` **Required:** no diff --git a/Cargo.lock b/Cargo.lock index 6a83e5d..157b640 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cove" -version = "0.9.1" +version = "0.9.2" dependencies = [ "anyhow", "async-trait", @@ -350,7 +350,7 @@ dependencies = [ [[package]] name = "cove-config" -version = "0.9.1" +version = "0.9.2" dependencies = [ "cove-input", "cove-macro", @@ -361,7 +361,7 @@ dependencies = [ [[package]] name = "cove-input" -version = "0.9.1" +version = "0.9.2" dependencies = [ "cove-macro", "crossterm", @@ -375,7 +375,7 @@ dependencies = [ [[package]] name = "cove-macro" -version = "0.9.1" +version = "0.9.2" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index f4f81a5..0fa473f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = ["cove", "cove-*"] [workspace.package] -version = "0.9.1" +version = "0.9.2" edition = "2024" [workspace.dependencies] From 8b928184e89b9ac5aee23eed4c9d084d5416c55d Mon Sep 17 00:00:00 2001 From: Joscha Date: Tue, 8 Apr 2025 23:51:39 +0200 Subject: [PATCH 38/44] Fix autojoin key connecting to non-autojoin rooms --- CHANGELOG.md | 4 ++++ cove/src/ui/rooms.rs | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f06e21..3682c75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ Procedure when bumping the version number: ## Unreleased +### Fixed + +- `keys.rooms.action.connect_autojoin` connecting to non-autojoin rooms + ## v0.9.2 - 2025-03-14 ### Added diff --git a/cove/src/ui/rooms.rs b/cove/src/ui/rooms.rs index f901f30..c3d6a40 100644 --- a/cove/src/ui/rooms.rs +++ b/cove/src/ui/rooms.rs @@ -536,7 +536,10 @@ impl Rooms { } if event.matches(&keys.rooms.action.connect_autojoin) { for (domain, server) in &self.config.euph.servers { - for name in server.rooms.keys() { + for (name, room) in &server.rooms { + if !room.autojoin { + continue; + } let id = RoomIdentifier::new(domain.clone(), name.clone()); self.connect_to_room(id).await; } From 40de073799666aa3c4b2e00c078d38c638f29bd2 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 31 May 2025 13:11:50 +0200 Subject: [PATCH 39/44] Silence clippy warning --- cove/src/ui.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/cove/src/ui.rs b/cove/src/ui.rs index 1c03834..5ebd540 100644 --- a/cove/src/ui.rs +++ b/cove/src/ui.rs @@ -50,6 +50,7 @@ impl From for UiError { } } +#[expect(clippy::large_enum_variant)] pub enum UiEvent { GraphemeWidthsChanged, LogChanged, From 732d4627754b5d8ccad6b26a065fbef27761ba5e Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 31 May 2025 13:38:54 +0200 Subject: [PATCH 40/44] Add user id based emoji hash Helpful in scenarios where you want to disambiguate people based on their user id at a glance. --- CHANGELOG.md | 4 ++++ cove-config/src/keys.rs | 4 ++++ cove/src/euph/small_message.rs | 15 ++++++++++++++- cove/src/euph/util.rs | 15 ++++++++++++++- cove/src/store.rs | 4 ++++ cove/src/ui/chat.rs | 8 ++++++++ cove/src/ui/chat/tree.rs | 5 +++++ cove/src/ui/chat/tree/renderer.rs | 2 ++ cove/src/ui/chat/tree/scroll.rs | 1 + cove/src/ui/chat/tree/widgets.rs | 9 ++++++++- cove/src/vault/euph.rs | 18 ++++++++++-------- 11 files changed, 74 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3682c75..e92f49b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ Procedure when bumping the version number: ## Unreleased +### Added + +- Key bindings for emoji-based user id hashing + ### Fixed - `keys.rooms.action.connect_autojoin` connecting to non-autojoin rooms diff --git a/cove-config/src/keys.rs b/cove-config/src/keys.rs index 8b5adeb..47c171c 100644 --- a/cove-config/src/keys.rs +++ b/cove-config/src/keys.rs @@ -104,6 +104,7 @@ default_bindings! { pub fn mark_older_seen => ["ctrl+s"]; pub fn info => ["i"]; pub fn links => ["I"]; + pub fn toggle_nick_emoji => ["e"]; pub fn increase_caesar => ["c"]; pub fn decrease_caesar => ["C"]; } @@ -356,6 +357,9 @@ pub struct TreeAction { /// List links found in message. #[serde(default = "default::tree_action::links")] pub links: KeyBinding, + /// Toggle agent id based nick emoji. + #[serde(default = "default::tree_action::toggle_nick_emoji")] + pub toggle_nick_emoji: KeyBinding, /// Increase caesar cipher rotation. #[serde(default = "default::tree_action::increase_caesar")] pub increase_caesar: KeyBinding, diff --git a/cove/src/euph/small_message.rs b/cove/src/euph/small_message.rs index 003cd40..d306226 100644 --- a/cove/src/euph/small_message.rs +++ b/cove/src/euph/small_message.rs @@ -1,15 +1,20 @@ +use std::hash::{DefaultHasher, Hash, Hasher}; + use crossterm::style::Stylize; -use euphoxide::api::{MessageId, Snowflake, Time}; +use euphoxide::api::{MessageId, Snowflake, Time, UserId}; use jiff::Timestamp; use toss::{Style, Styled}; use crate::{store::Msg, ui::ChatMsg}; +use super::util; + #[derive(Debug, Clone)] pub struct SmallMessage { pub id: MessageId, pub parent: Option, pub time: Time, + pub user_id: UserId, pub nick: String, pub content: String, pub seen: bool, @@ -70,6 +75,14 @@ impl Msg for SmallMessage { fn last_possible_id() -> Self::Id { MessageId(Snowflake::MAX) } + + fn nick_emoji(&self) -> Option { + let mut hasher = DefaultHasher::new(); + self.user_id.0.hash(&mut hasher); + let hash = hasher.finish(); + let emoji = &util::EMOJI_LIST[hash as usize % util::EMOJI_LIST.len()]; + Some(emoji.clone()) + } } impl ChatMsg for SmallMessage { diff --git a/cove/src/euph/util.rs b/cove/src/euph/util.rs index c2928ab..ecea304 100644 --- a/cove/src/euph/util.rs +++ b/cove/src/euph/util.rs @@ -1,4 +1,4 @@ -use std::sync::LazyLock; +use std::{collections::HashSet, sync::LazyLock}; use crossterm::style::{Color, Stylize}; use euphoxide::Emoji; @@ -6,6 +6,19 @@ use toss::{Style, Styled}; pub static EMOJI: LazyLock = LazyLock::new(Emoji::load); +pub static EMOJI_LIST: LazyLock> = LazyLock::new(|| { + let mut list = EMOJI + .0 + .values() + .flatten() + .cloned() + .collect::>() + .into_iter() + .collect::>(); + list.sort_unstable(); + list +}); + /// Convert HSL to RGB following [this approach from wikipedia][1]. /// /// `h` must be in the range `[0, 360]`, `s` and `l` in the range `[0, 1]`. diff --git a/cove/src/store.rs b/cove/src/store.rs index f64f71e..b7031c1 100644 --- a/cove/src/store.rs +++ b/cove/src/store.rs @@ -8,6 +8,10 @@ pub trait Msg { fn parent(&self) -> Option; fn seen(&self) -> bool; + fn nick_emoji(&self) -> Option { + None + } + fn last_possible_id() -> Self::Id; } diff --git a/cove/src/ui/chat.rs b/cove/src/ui/chat.rs index 405339b..02adeb7 100644 --- a/cove/src/ui/chat.rs +++ b/cove/src/ui/chat.rs @@ -37,6 +37,7 @@ pub struct ChatState> { cursor: Cursor, editor: EditorState, + nick_emoji: bool, caesar: i8, mode: Mode, @@ -48,6 +49,7 @@ impl + Clone> ChatState { Self { cursor: Cursor::Bottom, editor: EditorState::new(), + nick_emoji: false, caesar: 0, mode: Mode::Tree, @@ -79,6 +81,7 @@ impl> ChatState { &mut self.editor, nick, focused, + self.nick_emoji, self.caesar, ) .boxed_async(), @@ -117,6 +120,11 @@ impl> ChatState { Reaction::Composed { parent, content } } + Reaction::NotHandled if event.matches(&keys.tree.action.toggle_nick_emoji) => { + self.nick_emoji = !self.nick_emoji; + Reaction::Handled + } + Reaction::NotHandled if event.matches(&keys.tree.action.increase_caesar) => { self.caesar = (self.caesar + 1).rem_euclid(26); Reaction::Handled diff --git a/cove/src/ui/chat/tree.rs b/cove/src/ui/chat/tree.rs index 043e109..d9905fc 100644 --- a/cove/src/ui/chat/tree.rs +++ b/cove/src/ui/chat/tree.rs @@ -389,6 +389,7 @@ impl> TreeViewState { editor: &'a mut EditorState, nick: String, focused: bool, + nick_emoji: bool, caesar: i8, ) -> TreeView<'a, M, S> { TreeView { @@ -397,6 +398,7 @@ impl> TreeViewState { editor, nick, focused, + nick_emoji, caesar, } } @@ -410,6 +412,8 @@ pub struct TreeView<'a, M: Msg, S: MsgStore> { nick: String, focused: bool, + + nick_emoji: bool, caesar: i8, } @@ -438,6 +442,7 @@ where size, nick: self.nick.clone(), focused: self.focused, + nick_emoji: self.nick_emoji, caesar: self.caesar, last_cursor: self.state.last_cursor.clone(), last_cursor_top: self.state.last_cursor_top, diff --git a/cove/src/ui/chat/tree/renderer.rs b/cove/src/ui/chat/tree/renderer.rs index 142624e..225191b 100644 --- a/cove/src/ui/chat/tree/renderer.rs +++ b/cove/src/ui/chat/tree/renderer.rs @@ -80,6 +80,7 @@ pub struct TreeContext { pub size: Size, pub nick: String, pub focused: bool, + pub nick_emoji: bool, pub caesar: i8, pub last_cursor: Cursor, pub last_cursor_top: i32, @@ -207,6 +208,7 @@ where self.tz.clone(), indent, msg, + self.context.nick_emoji, self.context.caesar, folded_info, ); diff --git a/cove/src/ui/chat/tree/scroll.rs b/cove/src/ui/chat/tree/scroll.rs index ab3ddae..a8a1305 100644 --- a/cove/src/ui/chat/tree/scroll.rs +++ b/cove/src/ui/chat/tree/scroll.rs @@ -22,6 +22,7 @@ where size: self.last_size, nick: self.last_nick.clone(), focused: true, + nick_emoji: false, caesar: 0, last_cursor: self.last_cursor.clone(), last_cursor_top: self.last_cursor_top, diff --git a/cove/src/ui/chat/tree/widgets.rs b/cove/src/ui/chat/tree/widgets.rs index d46920e..dd7fa89 100644 --- a/cove/src/ui/chat/tree/widgets.rs +++ b/cove/src/ui/chat/tree/widgets.rs @@ -59,10 +59,17 @@ pub fn msg( tz: TimeZone, indent: usize, msg: &M, + nick_emoji: bool, caesar: i8, folded_info: Option, ) -> Boxed<'static, Infallible> { - let (nick, mut content) = msg.styled(); + let (mut nick, mut content) = msg.styled(); + + if nick_emoji { + if let Some(emoji) = msg.nick_emoji() { + nick = nick.then_plain("(").then_plain(emoji).then_plain(")"); + } + } if caesar != 0 { // Apply caesar in inverse because we're decoding diff --git a/cove/src/vault/euph.rs b/cove/src/vault/euph.rs index 931091c..4a4109e 100644 --- a/cove/src/vault/euph.rs +++ b/cove/src/vault/euph.rs @@ -611,7 +611,7 @@ impl Action for GetMsg { let msg = conn .query_row( " - SELECT id, parent, time, name, content, seen + SELECT id, parent, time, user_id, name, content, seen FROM euph_msgs WHERE domain = ? AND room = ? @@ -623,9 +623,10 @@ impl Action for GetMsg { id: MessageId(row.get::<_, WSnowflake>(0)?.0), parent: row.get::<_, Option>(1)?.map(|s| MessageId(s.0)), time: row.get::<_, WTime>(2)?.0, - nick: row.get(3)?, - content: row.get(4)?, - seen: row.get(5)?, + user_id: UserId(row.get(3)?), + nick: row.get(4)?, + content: row.get(5)?, + seen: row.get(6)?, }) }, ) @@ -703,7 +704,7 @@ impl Action for GetTree { AND tree.room = euph_msgs.room AND tree.id = euph_msgs.parent ) - SELECT id, parent, time, name, content, seen + SELECT id, parent, time, user_id, name, content, seen FROM euph_msgs JOIN tree USING (domain, room, id) ORDER BY id ASC @@ -716,9 +717,10 @@ impl Action for GetTree { id: MessageId(row.get::<_, WSnowflake>(0)?.0), parent: row.get::<_, Option>(1)?.map(|s| MessageId(s.0)), time: row.get::<_, WTime>(2)?.0, - nick: row.get(3)?, - content: row.get(4)?, - seen: row.get(5)?, + user_id: UserId(row.get(3)?), + nick: row.get(4)?, + content: row.get(5)?, + seen: row.get(6)?, }) }, )? From b70d7548da28ff89966eae52595cacb930b315ad Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 31 May 2025 13:54:07 +0200 Subject: [PATCH 41/44] Bump version to 0.9.3 --- CHANGELOG.md | 2 ++ CONFIG.md | 8 ++++++++ Cargo.lock | 8 ++++---- Cargo.toml | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e92f49b..7d87d77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ Procedure when bumping the version number: ## Unreleased +## v0.9.3 - 2025-05-31 + ### Added - Key bindings for emoji-based user id hashing diff --git a/CONFIG.md b/CONFIG.md index e537310..82a7242 100644 --- a/CONFIG.md +++ b/CONFIG.md @@ -537,6 +537,14 @@ Reply to message, inline if possible. Reply opposite to normal reply. +### `keys.tree.action.toggle_nick_emoji` + +**Required:** yes +**Type:** key binding +**Default:** `"e"` + +Toggle agent id based nick emoji. + ### `keys.tree.action.toggle_seen` **Required:** yes diff --git a/Cargo.lock b/Cargo.lock index 157b640..2f45a5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cove" -version = "0.9.2" +version = "0.9.3" dependencies = [ "anyhow", "async-trait", @@ -350,7 +350,7 @@ dependencies = [ [[package]] name = "cove-config" -version = "0.9.2" +version = "0.9.3" dependencies = [ "cove-input", "cove-macro", @@ -361,7 +361,7 @@ dependencies = [ [[package]] name = "cove-input" -version = "0.9.2" +version = "0.9.3" dependencies = [ "cove-macro", "crossterm", @@ -375,7 +375,7 @@ dependencies = [ [[package]] name = "cove-macro" -version = "0.9.2" +version = "0.9.3" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 0fa473f..33f245f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ resolver = "3" members = ["cove", "cove-*"] [workspace.package] -version = "0.9.2" +version = "0.9.3" edition = "2024" [workspace.dependencies] From 67e77c88800c02305ad2464380f38e4ff27d797d Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 31 May 2025 15:04:17 +0200 Subject: [PATCH 42/44] Show emoji hash in nick list --- CHANGELOG.md | 4 +++ cove/src/euph/small_message.rs | 8 +---- cove/src/euph/util.rs | 16 ++++++++-- cove/src/ui/chat.rs | 4 +++ cove/src/ui/euph/nick_list.rs | 56 +++++++++++++++++++++++++++++----- cove/src/ui/euph/room.rs | 15 ++++++--- 6 files changed, 81 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d87d77..76fa94a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,10 @@ Procedure when bumping the version number: ## Unreleased +### Changed + +- Display emoji user id hashes in the nick list + ## v0.9.3 - 2025-05-31 ### Added diff --git a/cove/src/euph/small_message.rs b/cove/src/euph/small_message.rs index d306226..5db1790 100644 --- a/cove/src/euph/small_message.rs +++ b/cove/src/euph/small_message.rs @@ -1,5 +1,3 @@ -use std::hash::{DefaultHasher, Hash, Hasher}; - use crossterm::style::Stylize; use euphoxide::api::{MessageId, Snowflake, Time, UserId}; use jiff::Timestamp; @@ -77,11 +75,7 @@ impl Msg for SmallMessage { } fn nick_emoji(&self) -> Option { - let mut hasher = DefaultHasher::new(); - self.user_id.0.hash(&mut hasher); - let hash = hasher.finish(); - let emoji = &util::EMOJI_LIST[hash as usize % util::EMOJI_LIST.len()]; - Some(emoji.clone()) + Some(util::user_id_emoji(&self.user_id)) } } diff --git a/cove/src/euph/util.rs b/cove/src/euph/util.rs index ecea304..ea1782a 100644 --- a/cove/src/euph/util.rs +++ b/cove/src/euph/util.rs @@ -1,7 +1,11 @@ -use std::{collections::HashSet, sync::LazyLock}; +use std::{ + collections::HashSet, + hash::{DefaultHasher, Hash, Hasher}, + sync::LazyLock, +}; use crossterm::style::{Color, Stylize}; -use euphoxide::Emoji; +use euphoxide::{Emoji, api::UserId}; use toss::{Style, Styled}; pub static EMOJI: LazyLock = LazyLock::new(Emoji::load); @@ -82,3 +86,11 @@ pub fn style_mention_exact(mention: &str, base: Style) -> Styled { .expect("mention must start with @"); Styled::new(mention, nick_style(nick, base)) } + +pub fn user_id_emoji(user_id: &UserId) -> String { + let mut hasher = DefaultHasher::new(); + user_id.0.hash(&mut hasher); + let hash = hasher.finish(); + let emoji = &EMOJI_LIST[hash as usize % EMOJI_LIST.len()]; + emoji.clone() +} diff --git a/cove/src/ui/chat.rs b/cove/src/ui/chat.rs index 02adeb7..1116935 100644 --- a/cove/src/ui/chat.rs +++ b/cove/src/ui/chat.rs @@ -58,6 +58,10 @@ impl + Clone> ChatState { store, } } + + pub fn nick_emoji(&self) -> bool { + self.nick_emoji + } } impl> ChatState { diff --git a/cove/src/ui/euph/nick_list.rs b/cove/src/ui/euph/nick_list.rs index e1e4e3d..8fbdb7b 100644 --- a/cove/src/ui/euph/nick_list.rs +++ b/cove/src/ui/euph/nick_list.rs @@ -22,9 +22,10 @@ pub fn widget<'a>( list: &'a mut ListState, joined: &Joined, focused: bool, + nick_emoji: bool, ) -> impl Widget + use<'a> { let mut list_builder = ListBuilder::new(); - render_rows(&mut list_builder, joined, focused); + render_rows(&mut list_builder, joined, focused, nick_emoji); list_builder.build(list) } @@ -70,6 +71,7 @@ fn render_rows( list_builder: &mut ListBuilder<'_, SessionId, Background>, joined: &Joined, focused: bool, + nick_emoji: bool, ) { let mut people = vec![]; let mut bots = vec![]; @@ -95,10 +97,38 @@ fn render_rows( lurkers.sort_unstable(); nurkers.sort_unstable(); - render_section(list_builder, "People", &people, &joined.session, focused); - render_section(list_builder, "Bots", &bots, &joined.session, focused); - render_section(list_builder, "Lurkers", &lurkers, &joined.session, focused); - render_section(list_builder, "Nurkers", &nurkers, &joined.session, focused); + render_section( + list_builder, + "People", + &people, + &joined.session, + focused, + nick_emoji, + ); + render_section( + list_builder, + "Bots", + &bots, + &joined.session, + focused, + nick_emoji, + ); + render_section( + list_builder, + "Lurkers", + &lurkers, + &joined.session, + focused, + nick_emoji, + ); + render_section( + list_builder, + "Nurkers", + &nurkers, + &joined.session, + focused, + nick_emoji, + ); } fn render_section( @@ -107,6 +137,7 @@ fn render_section( sessions: &[HalfSession], own_session: &SessionView, focused: bool, + nick_emoji: bool, ) { if sessions.is_empty() { return; @@ -124,7 +155,7 @@ fn render_section( list_builder.add_unsel(Text::new(row).background()); for session in sessions { - render_row(list_builder, session, own_session, focused); + render_row(list_builder, session, own_session, focused, nick_emoji); } } @@ -133,6 +164,7 @@ fn render_row( session: &HalfSession, own_session: &SessionView, focused: bool, + nick_emoji: bool, ) { let (name, style, style_inv, perms_style_inv) = if session.name.is_empty() { let name = "lurk".to_string(); @@ -166,16 +198,24 @@ fn render_row( " " }; + let emoji = if nick_emoji { + format!(" ({})", euph::user_id_emoji(&session.id)) + } else { + "".to_string() + }; + list_builder.add_sel(session.session_id.clone(), move |selected| { if focused && selected { let text = Styled::new_plain(owner) .then(name, style_inv) - .then(perms, perms_style_inv); + .then(perms, perms_style_inv) + .then(emoji, perms_style_inv); Text::new(text).background().with_style(style_inv) } else { let text = Styled::new_plain(owner) .then(&name, style) - .then_plain(perms); + .then_plain(perms) + .then_plain(emoji); Text::new(text).background() } }); diff --git a/cove/src/ui/euph/room.rs b/cove/src/ui/euph/room.rs index ebae5a8..fe1f768 100644 --- a/cove/src/ui/euph/room.rs +++ b/cove/src/ui/euph/room.rs @@ -291,11 +291,16 @@ impl EuphRoom { joined: &Joined, focus: Focus, ) -> BoxedAsync<'a, UiError> { - let nick_list_widget = nick_list::widget(nick_list, joined, focus == Focus::NickList) - .padding() - .with_right(1) - .border() - .desync(); + let nick_list_widget = nick_list::widget( + nick_list, + joined, + focus == Focus::NickList, + chat.nick_emoji(), + ) + .padding() + .with_right(1) + .border() + .desync(); let chat_widget = chat.widget(joined.session.name.clone(), focus == Focus::Chat); From 2ca6190d97fb9ae7da4189720f89ba0b7579b02b Mon Sep 17 00:00:00 2001 From: Joscha Date: Sat, 31 May 2025 15:08:24 +0200 Subject: [PATCH 43/44] Use older ubuntu runner for older glibc version --- .github/workflows/build.yml | 6 +++--- CHANGELOG.md | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 012c48e..4660d0f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -16,7 +16,7 @@ jobs: strategy: matrix: os: - - ubuntu-latest + - ubuntu-22.04 - windows-latest - macos-latest - macos-13 @@ -59,11 +59,11 @@ jobs: - name: Zip artifacts run: | - chmod +x cove-ubuntu-latest/cove + chmod +x cove-ubuntu-22.04/cove chmod +x cove-windows-latest/cove.exe chmod +x cove-macos-latest/cove chmod +x cove-macos-13/cove - zip -jr "cove-$(cat cove-ubuntu-latest/host).zip" cove-ubuntu-latest/cove + zip -jr "cove-$(cat cove-ubuntu-22.04/host).zip" cove-ubuntu-22.04/cove zip -jr "cove-$(cat cove-windows-latest/host).zip" cove-windows-latest/cove.exe zip -jr "cove-$(cat cove-macos-latest/host).zip" cove-macos-latest/cove zip -jr "cove-$(cat cove-macos-13/host).zip" cove-macos-13/cove diff --git a/CHANGELOG.md b/CHANGELOG.md index 76fa94a..3f9ce8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Procedure when bumping the version number: ### Changed - Display emoji user id hashes in the nick list +- Compile linux binary with older glibc version ## v0.9.3 - 2025-05-31 From 10214f33695ad3eb8b87802d8d683cea5c618bf4 Mon Sep 17 00:00:00 2001 From: Joscha Date: Fri, 27 Jun 2025 11:03:06 +0200 Subject: [PATCH 44/44] Fix clippy warning --- cove/src/ui/euph/room.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cove/src/ui/euph/room.rs b/cove/src/ui/euph/room.rs index fe1f768..7e8ff99 100644 --- a/cove/src/ui/euph/room.rs +++ b/cove/src/ui/euph/room.rs @@ -121,7 +121,7 @@ impl EuphRoom { .server_config .clone() .room(self.vault().room().name.clone()) - .name(format!("{room:?}-{}", next_instance_id)) + .name(format!("{room:?}-{next_instance_id}")) .human(true) .username(self.room_config.username.clone()) .force_username(self.room_config.force_username)