diff --git a/Cargo.lock b/Cargo.lock index f378ae5..6490294 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,12 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "ahash" version = "0.8.11" @@ -61,9 +67,9 @@ checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" [[package]] name = "approx" @@ -111,7 +117,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.4", "object", "rustc-demangle", ] @@ -187,9 +193,9 @@ checksum = "64fa3c856b712db6612c019f14756e64e4bcea13337a6b33b696333a9eaa2d06" [[package]] name = "bytemuck" -version = "1.17.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" +checksum = "94bbb0ad554ad961ddc5da507a12a29b14e4ae5bda06b19f575a3e6079d2e2ae" [[package]] name = "byteorder" @@ -243,9 +249,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.13" +version = "1.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" +checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" dependencies = [ "jobserver", "libc", @@ -314,9 +320,9 @@ checksum = "3618cccc083bb987a415d85c02ca6c9994ea5b44731ec28b9ecf09658655fba9" [[package]] name = "const_panic" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" +checksum = "7782af8f90fe69a4bb41e460abe1727d493403d8b2cc43201a3a3e906b24379f" dependencies = [ "const_panic_proc_macros", "typewit", @@ -324,13 +330,13 @@ dependencies = [ [[package]] name = "const_panic_proc_macros" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395398edf7e8b0a812e905c150c438520ab077c4f9f931556302c48dd4e8ada9" +checksum = "e15066a3ad67370e5311151e6c2574f51e80bd9a88ad8af5823d4f4ca4a230e0" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.77", "unicode-xid", ] @@ -352,9 +358,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] @@ -448,7 +454,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -459,7 +465,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -477,9 +483,9 @@ dependencies = [ [[package]] name = "dashmap" -version = "6.0.1" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804c8821570c3f8b70230c2ba75ffa5c0f9a4189b9a432b6656c536712acae28" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", "crossbeam-utils", @@ -517,33 +523,33 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7" +checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d" +checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "derive_builder_macro" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" +checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" dependencies = [ "derive_builder_core", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -641,9 +647,9 @@ checksum = "dd2e7510819d6fbf51a5545c8f922716ecfb14df168a3242f7d33e0239efe6a1" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fdeflate" @@ -656,13 +662,13 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.31" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" +checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" dependencies = [ "crc32fast", "libz-sys", - "miniz_oxide", + "miniz_oxide 0.8.0", ] [[package]] @@ -758,7 +764,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -876,9 +882,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ "atomic-waker", "bytes", @@ -1028,7 +1034,7 @@ dependencies = [ "hyper", "hyper-util", "rustls 0.22.4", - "rustls-native-certs", + "rustls-native-certs 0.7.3", "rustls-pki-types", "tokio", "tokio-rustls 0.25.0", @@ -1037,16 +1043,16 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http", "hyper", "hyper-util", "rustls 0.23.12", - "rustls-native-certs", + "rustls-native-certs 0.8.0", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", @@ -1114,9 +1120,9 @@ checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" [[package]] name = "indexmap" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", "hashbrown", @@ -1177,7 +1183,7 @@ dependencies = [ "http", "http-body-util", "hyper", - "hyper-rustls 0.27.2", + "hyper-rustls 0.27.3", "hyper-util", "lavalink_rs_macros", "oneshot", @@ -1200,7 +1206,7 @@ checksum = "426ef2204d4fa6806fa6a00fdd747f7312645fcd30cf9208a5bdfeec6f3b9a41" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1214,9 +1220,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.157" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374af5f94e54fa97cf75e945cce8a6b201e88a1a07e688b47dfd2a59c66dbd86" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libgit2-sys" @@ -1238,9 +1244,9 @@ checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" [[package]] name = "libsqlite3-sys" -version = "0.28.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c10584274047cb335c23d3e61bcef8e323adae7c5c8c760540f73610177fc3f" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ "cc", "pkg-config", @@ -1249,9 +1255,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.19" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc53a7799a7496ebc9fd29f31f7df80e83c9bda5299768af5f9e59eeea74647" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" dependencies = [ "cc", "libc", @@ -1300,7 +1306,7 @@ dependencies = [ "color-eyre", "const-str", "const_panic", - "dashmap 6.0.1", + "dashmap 6.1.0", "dotenvy", "dotenvy_macro", "futures", @@ -1362,7 +1368,7 @@ dependencies = [ "itertools", "quote", "serde", - "syn 2.0.75", + "syn 2.0.77", "toml", ] @@ -1407,6 +1413,15 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + [[package]] name = "mio" version = "1.0.2" @@ -1593,14 +1608,14 @@ dependencies = [ "by_address", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -1620,7 +1635,7 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.3", + "redox_syscall", "smallvec", "windows-targets 0.52.6", ] @@ -1663,7 +1678,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1715,7 +1730,7 @@ dependencies = [ "crc32fast", "fdeflate", "flate2", - "miniz_oxide", + "miniz_oxide 0.7.4", ] [[package]] @@ -1735,11 +1750,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit", ] [[package]] @@ -1777,9 +1792,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1834,15 +1849,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "redox_syscall" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.5.3" @@ -1963,7 +1969,7 @@ dependencies = [ "regex", "relative-path", "rustc_version", - "syn 2.0.75", + "syn 2.0.77", "unicode-ident", ] @@ -1975,18 +1981,18 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" dependencies = [ "bitflags 2.6.0", "errno", @@ -1995,17 +2001,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "ring", - "rustls-webpki 0.101.7", - "sct", -] - [[package]] name = "rustls" version = "0.22.4" @@ -2015,7 +2010,7 @@ dependencies = [ "log", "ring", "rustls-pki-types", - "rustls-webpki 0.102.6", + "rustls-webpki", "subtle", "zeroize", ] @@ -2029,31 +2024,35 @@ dependencies = [ "once_cell", "ring", "rustls-pki-types", - "rustls-webpki 0.102.6", + "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls-native-certs" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ "openssl-probe", - "rustls-pemfile 2.1.3", + "rustls-pemfile", "rustls-pki-types", "schannel", "security-framework", ] [[package]] -name = "rustls-pemfile" -version = "1.0.4" +name = "rustls-native-certs" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" dependencies = [ - "base64 0.21.7", + "openssl-probe", + "rustls-pemfile", + "rustls-pki-types", + "schannel", + "security-framework", ] [[package]] @@ -2074,19 +2073,9 @@ checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.102.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustls-webpki" -version = "0.102.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56" dependencies = [ "ring", "rustls-pki-types", @@ -2107,11 +2096,11 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2120,16 +2109,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "security-framework" version = "2.11.1" @@ -2164,9 +2143,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -2183,20 +2162,20 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", "memchr", @@ -2223,7 +2202,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -2370,9 +2349,9 @@ dependencies = [ [[package]] name = "sqlformat" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f895e3734318cc55f1fe66258926c9b910c124d47520339efecbb6c59cec7c1f" +checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790" dependencies = [ "nom", "unicode_categories", @@ -2380,9 +2359,9 @@ dependencies = [ [[package]] name = "sqlx" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27144619c6e5802f1380337a209d2ac1c431002dd74c6e60aebff3c506dc4f0c" +checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e" dependencies = [ "sqlx-core", "sqlx-macros", @@ -2393,9 +2372,9 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a999083c1af5b5d6c071d34a708a19ba3e02106ad82ef7bbd69f5e48266b613b" +checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e" dependencies = [ "atoi", "byteorder", @@ -2418,8 +2397,8 @@ dependencies = [ "once_cell", "paste", "percent-encoding", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", + "rustls 0.23.12", + "rustls-pemfile", "serde", "serde_json", "sha2", @@ -2435,22 +2414,22 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23217eb7d86c584b8cbe0337b9eacf12ab76fe7673c513141ec42565698bb88" +checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657" dependencies = [ "proc-macro2", "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "sqlx-macros-core" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a099220ae541c5db479c6424bdf1b200987934033c2584f79a0e1693601e776" +checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5" dependencies = [ "dotenvy", "either", @@ -2466,7 +2445,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.75", + "syn 2.0.77", "tempfile", "tokio", "url", @@ -2474,9 +2453,9 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5afe4c38a9b417b6a9a5eeffe7235d0a106716495536e7727d1c7f4b1ff3eba6" +checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a" dependencies = [ "atoi", "base64 0.22.1", @@ -2516,9 +2495,9 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1dbb157e65f10dbe01f729339c06d239120221c9ad9fa0ba8408c4cc18ecf21" +checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8" dependencies = [ "atoi", "base64 0.22.1", @@ -2554,9 +2533,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.8.0" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2cdd83c008a622d94499c0006d8ee5f821f36c89b7d625c900e5dc30b5c5ee" +checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680" dependencies = [ "atoi", "flume", @@ -2611,9 +2590,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.75" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -2664,7 +2643,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -2738,9 +2717,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.3" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -2761,7 +2740,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -2788,9 +2767,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -2806,7 +2785,7 @@ dependencies = [ "futures-util", "log", "rustls 0.22.4", - "rustls-native-certs", + "rustls-native-certs 0.7.3", "rustls-pki-types", "tokio", "tokio-rustls 0.25.0", @@ -2815,9 +2794,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", @@ -2840,7 +2819,7 @@ dependencies = [ "http", "httparse", "ring", - "rustls-native-certs", + "rustls-native-certs 0.7.3", "rustls-pki-types", "sha1_smol", "simdutf8", @@ -2859,7 +2838,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.20", + "toml_edit", ] [[package]] @@ -2871,17 +2850,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.40", -] - [[package]] name = "toml_edit" version = "0.22.20" @@ -2892,7 +2860,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.18", + "winnow", ] [[package]] @@ -2942,7 +2910,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -3122,7 +3090,7 @@ checksum = "e6c07ac7c9d2d086291765ceecafcd52ce6dc33ab0ade02e06509eb416d88470" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -3223,9 +3191,9 @@ dependencies = [ [[package]] name = "unicode-properties" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" +checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524" [[package]] name = "unicode-segmentation" @@ -3235,9 +3203,9 @@ checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" [[package]] name = "unicode_categories" @@ -3360,9 +3328,12 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "webpki-roots" -version = "0.25.4" +version = "0.26.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" +checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a" +dependencies = [ + "rustls-pki-types", +] [[package]] name = "weezl" @@ -3372,11 +3343,11 @@ checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] name = "whoami" -version = "1.5.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" dependencies = [ - "redox_syscall 0.4.1", + "redox_syscall", "wasite", ] @@ -3569,15 +3540,6 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - [[package]] name = "winnow" version = "0.6.18" @@ -3605,7 +3567,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] diff --git a/flake.lock b/flake.lock index ef45a86..e2a711b 100644 --- a/flake.lock +++ b/flake.lock @@ -41,11 +41,11 @@ "pre-commit-hooks": "pre-commit-hooks" }, "locked": { - "lastModified": 1725567101, - "narHash": "sha256-gFCoG9udcJShDUxj+6KjUYB7Kuk+NAxJaMJJFMeRBJ4=", + "lastModified": 1725637114, + "narHash": "sha256-+hsiHWbqkS098soB1o4URP3frnjhoRvyVfWs6byv4Zk=", "owner": "cachix", "repo": "devenv", - "rev": "a5460083c31d190ce44c8286a7ff9b6d2ade016b", + "rev": "c31e347a96dbb7718a0279afa993752a7dfc6a39", "type": "github" }, "original": { @@ -93,11 +93,11 @@ "rust-analyzer-src": "rust-analyzer-src" }, "locked": { - "lastModified": 1725604324, - "narHash": "sha256-+VgeYuaCQn5vmoH1GTYQzvVTtWxirZmdDQJKr8uLgQI=", + "lastModified": 1725690497, + "narHash": "sha256-5fT+96rV7Hx29HG+4/oBbr3V+yExKuLN2vcBcPbVBlU=", "owner": "nix-community", "repo": "fenix", - "rev": "d9afdb4465ba2f20bb73b0ff5d2c2837cafc2e14", + "rev": "4b8d964df93d1f918ee6c4f003b3548c432cc866", "type": "github" }, "original": { @@ -417,11 +417,11 @@ "rust-analyzer-src": { "flake": false, "locked": { - "lastModified": 1725548942, - "narHash": "sha256-ZnF5MaOAeiiKIATYN4rrqNsnhSQOQ+Hvfg0mHLvN04Y=", + "lastModified": 1725630423, + "narHash": "sha256-gNCLk3Zg7JlAwmWbVHTH6f3+iqdeQ4fheOotCZy8x5M=", "owner": "rust-lang", "repo": "rust-analyzer", - "rev": "124c7482167ff6eea4f7663c0be87ea568ccd8c6", + "rev": "08c7bbc2dbe4dcc8968484f1a0e1e6fe7a1d4f6d", "type": "github" }, "original": { diff --git a/lyra/Cargo.toml b/lyra/Cargo.toml index 4aeef86..58fee18 100644 --- a/lyra/Cargo.toml +++ b/lyra/Cargo.toml @@ -37,22 +37,22 @@ lyra_ext = { path = "../lyra_ext" } paste = "1.0.15" const-str = "0.5.7" -const_panic = { version = "0.2.8", features = ["derive"] } +const_panic = { version = "0.2.9", features = ["derive"] } bitflags = "2.6.0" -dashmap = "6.0.1" +dashmap = "6.1.0" dotenvy = "0.15.7" dotenvy_macro = "0.15.7" thiserror = "1.0.63" color-eyre = "0.6.3" futures = "0.3.30" -tokio = { version = "1.39.3", features = [ +tokio = { version = "1.40.0", features = [ "sync", "signal", "rt-multi-thread", "macros", ] } -serde = "1.0.208" -serde_json = "1.0.125" +serde = "1.0.210" +serde_json = "1.0.128" regex = "1.10.6" linkify = "0.10.0" fuzzy-matcher = "0.3.7" @@ -62,7 +62,7 @@ tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } rand = "0.8.5" itertools = "0.13.0" rayon = "1.10.0" -sqlx = { version = "0.8.0", features = ["postgres", "runtime-tokio-rustls"] } +sqlx = { version = "0.8.2", features = ["postgres", "runtime-tokio-rustls"] } mixbox = "2.0.0" lavalink-rs = { version = "0.13.0", features = ["twilight16"] } aho-corasick = "1.1.3" diff --git a/lyra/src/command/macros.rs b/lyra/src/command/macros.rs index ffe4057..27a7804 100644 --- a/lyra/src/command/macros.rs +++ b/lyra/src/command/macros.rs @@ -1,9 +1,11 @@ macro_rules! out { ($cnt: expr, $ctx: expr) => { + use crate::core::model::AcknowledgementAware; $ctx.respond($cnt).await?; return Ok(()); }; ($cnt: expr, ?$ctx: expr) => { + use crate::core::model::AcknowledgementAware; $ctx.respond($cnt).await?; }; } @@ -20,37 +22,25 @@ macro_rules! out { macro_rules! out_or_fol { ($cnt: expr, $ctx: expr) => { - if $ctx.acknowledged() { - $ctx.followup(&$cnt).await?; - return Ok(()); - } - $ctx.respond($cnt).await?; + use crate::core::model::AcknowledgementAware; + $ctx.respond_or_followup($cnt).await?; return Ok(()); }; ($cnt: expr, ?$ctx: expr) => { - if $ctx.acknowledged() { - $ctx.followup(&$cnt).await?; - } else { - $ctx.respond($cnt).await?; - } + use crate::core::model::AcknowledgementAware; + $ctx.respond_or_followup($cnt).await?; }; } macro_rules! out_or_upd { ($cnt: expr, $ctx: expr) => { - if $ctx.acknowledged() { - $ctx.update_no_components_embeds(&$cnt).await?; - return Ok(()); - } - $ctx.respond($cnt).await?; + use crate::core::model::AcknowledgementAware; + $ctx.respond_or_update($cnt).await?; return Ok(()); }; ($cnt: expr, ?$ctx: expr) => { - if $ctx.acknowledged() { - $ctx.update_no_components_embeds(&$cnt).await?; - } else { - $ctx.respond($cnt).await?; - } + use crate::core::model::AcknowledgementAware; + $ctx.respond_or_update($cnt).await?; }; } @@ -66,42 +56,43 @@ macro_rules! out_upd { macro_rules! hid { ($cnt: expr, $ctx: expr) => { - $ctx.ephem($cnt).await?; + #[allow(unused_imports)] + use crate::core::model::AcknowledgementAware; + $ctx.respond_ephemeral($cnt).await?; return Ok(()); }; ($cnt: expr, ?$ctx: expr) => { - $ctx.ephem($cnt).await?; + #[allow(unused_imports)] + use crate::core::model::AcknowledgementAware; + $ctx.respond_ephemeral($cnt).await?; }; } macro_rules! hid_fol { ($cnt: expr, $ctx: expr) => { - $ctx.followup_ephem(&$cnt).await?; + #[allow(unused_imports)] + use crate::core::model::AcknowledgementAware; + $ctx.followup_ephemeral($cnt).await?; + return Ok(()); + }; + ($cnt: expr, ?$ctx: expr) => {{ + use crate::core::model::AcknowledgementAware; + $ctx.followup_ephemeral($cnt).await? + }}; +} + +macro_rules! hid_or_fol { + ($cnt: expr, $ctx: expr) => { + use crate::core::model::AcknowledgementAware; + $ctx.respond_ephemeral_or_followup($cnt).await?; return Ok(()); }; ($cnt: expr, ?$ctx: expr) => { - $ctx.followup_ephem(&$cnt).await? + use crate::core::model::AcknowledgementAware; + $ctx.respond_ephemeral_or_followup($cnt).await?; }; } -// macro_rules! hid_or_fol { -// ($cnt: expr, $ctx: expr) => { -// if $ctx.acknowledged() { -// $ctx.followup_ephem(&$cnt).await?; -// return Ok(()); -// } -// $ctx.ephem($cnt).await?; -// return Ok(()); -// }; -// ($cnt: expr, ?$ctx: expr) => { -// if $ctx.acknowledged() { -// $ctx.followup_ephem(&$cnt).await?; -// } else { -// $ctx.ephem($cnt).await?; -// } -// }; -// } - macro_rules! generate_hid_variants { ($($name: ident => $emoji: ident),+$(,)?) => { $( @@ -138,30 +129,30 @@ macro_rules! generate_hid_fol_variants { } } -// macro_rules! generate_hid_or_fol_variants { -// ($($name: ident => $emoji: ident),+$(,)?) => { -// $( -// macro_rules! $name { -// ($cnt: expr, $ctx: expr) => { -// use crate::core::consts::exit_code; -// hid_or_fol!(format!("{} {}", exit_code::$emoji, $cnt), $ctx); -// }; -// ($cnt: expr, ?$ctx: expr) => { -// use crate::core::consts::exit_code; -// hid_or_fol!(format!("{} {}", exit_code::$emoji, $cnt), ?$ctx); -// }; -// } -// )+ - -// pub(crate) use {$($name,)+}; -// } -// } +macro_rules! generate_hid_or_fol_variants { + ($($name: ident => $emoji: ident),+$(,)?) => { + $( + macro_rules! $name { + ($cnt: expr, $ctx: expr) => { + use crate::core::r#const::exit_code; + crate::command::macros::hid_or_fol!(format!("{} {}", exit_code::$emoji, $cnt), $ctx); + }; + ($cnt: expr, ?$ctx: expr) => { + use crate::core::r#const::exit_code; + crate::command::macros::hid_or_fol!(format!("{} {}", exit_code::$emoji, $cnt), ?$ctx); + }; + } + )+ + + pub(crate) use {$($name,)+}; + } +} generate_hid_variants! { note => NOTICE, sus => DUBIOUS, caut => WARNING, - what => NOT_FOUND, + // what => NOT_FOUND, bad => INVALID, nope => PROHIBITED, cant => FORBIDDEN, @@ -181,16 +172,16 @@ generate_hid_fol_variants! { // crit_fol => UNKNOWN_ERROR } -// generate_hid_or_fol_variants! { -// note_or_fol => NOTICE, -// dub_or_fol => DUBIOUS, -// caut_or_fol => WARNING, -// miss_or_fol => NOT_FOUND, -// bad_or_fol => INVALID, -// nope_or_fol => PROHIBITED, -// cant_or_fol => FORBIDDEN, -// err_or_fol => KNOWN_ERROR, -// crit_or_fol => UNKNOWN_ERROR -// } +generate_hid_or_fol_variants! { + // note_or_fol => NOTICE, + // dub_or_fol => DUBIOUS, + // caut_or_fol => WARNING, + what_or_fol => NOT_FOUND, + bad_or_fol => INVALID, + nope_or_fol => PROHIBITED, + cant_or_fol => FORBIDDEN, + // err_or_fol => KNOWN_ERROR, + crit_or_fol => UNKNOWN_ERROR +} -pub(crate) use {hid, hid_fol, out, out_or_fol, out_or_upd, out_upd}; +pub(crate) use {hid, hid_fol, hid_or_fol, out, out_or_fol, out_or_upd, out_upd}; diff --git a/lyra/src/command/model/ctx.rs b/lyra/src/command/model/ctx.rs index 84df11c..8c7a929 100644 --- a/lyra/src/command/model/ctx.rs +++ b/lyra/src/command/model/ctx.rs @@ -6,6 +6,7 @@ mod modal; use std::{marker::PhantomData, sync::Arc}; +use tokio::sync::oneshot; use twilight_cache_inmemory::{model::CachedMember, InMemoryCache, Reference}; use twilight_gateway::{Latency, MessageSender}; use twilight_http::Client as HttpClient; @@ -88,6 +89,7 @@ where sender: MessageSender, data: Option, acknowledged: bool, + acknowledgement: Option>, kind: PhantomData Of>, location: PhantomData In>, } @@ -104,6 +106,7 @@ impl TryFrom> for Ctx { sender: value.sender, data: value.data, acknowledged: value.acknowledged, + acknowledgement: value.acknowledgement, kind: value.kind, location: PhantomData:: GuildMarker>, }) @@ -120,6 +123,7 @@ impl Ctx { location: self.location, data: None, acknowledged: false, + acknowledgement: None, kind: PhantomData:: ModalMarker>, } } @@ -128,12 +132,11 @@ impl Ctx { &self.latency } - pub const fn acknowledged(&self) -> bool { - self.acknowledged - } - pub fn acknowledge(&mut self) { self.acknowledged = true; + if let Some(tx) = std::mem::take(&mut self.acknowledgement) { + let _ = tx.send(()); + } } pub fn db(&self) -> &sqlx::Pool { diff --git a/lyra/src/command/model/ctx/command_data.rs b/lyra/src/command/model/ctx/command_data.rs index 56869e4..9d8f50a 100644 --- a/lyra/src/command/model/ctx/command_data.rs +++ b/lyra/src/command/model/ctx/command_data.rs @@ -1,5 +1,6 @@ use std::{hint::unreachable_unchecked, marker::PhantomData, sync::Arc}; +use tokio::sync::oneshot; use twilight_gateway::{Latency, MessageSender}; use twilight_model::{ application::interaction::application_command::{ @@ -26,6 +27,7 @@ impl Ctx { bot: OwnedBotState, latency: Latency, sender: MessageSender, + acknowledgement: oneshot::Sender<()>, ) -> Self { Self { data: Some(PartialInteractionData::Command(PartialCommandData::new( @@ -36,6 +38,7 @@ impl Ctx { latency, sender, acknowledged: false, + acknowledgement: Some(acknowledgement), kind: PhantomData:: T>, location: PhantomData, } diff --git a/lyra/src/command/model/ctx/message.rs b/lyra/src/command/model/ctx/message.rs index fbe68d0..9238020 100644 --- a/lyra/src/command/model/ctx/message.rs +++ b/lyra/src/command/model/ctx/message.rs @@ -8,10 +8,10 @@ use crate::{core::model::MessageResponse, error::command::FollowupError}; use super::{ AppCtxKind, AppCtxMarker, ComponentMarker, Ctx, Kind, Location, ModalMarker, RespondResult, + UnitRespondResult, }; type MessageRespondResult = RespondResult; -type MessageFollowupResult = Result; pub trait RespondVia: Kind {} impl RespondVia for AppCtxMarker {} @@ -32,20 +32,7 @@ impl Ctx { Ok(response?) } - pub async fn respond(&mut self, content: impl Into + Send) -> MessageRespondResult { - let data = Self::base_response_data_builder().content(content).build(); - self.respond_with(Some(data)).await - } - - pub async fn update_no_components_embeds(&self, content: &str) -> MessageFollowupResult { - Ok(self - .interface() - .await? - .update_no_components_embeds(content) - .await?) - } - - pub async fn respond_embeds_only( + pub async fn respond_embeds( &mut self, embeds: impl IntoIterator + Send, ) -> MessageRespondResult { @@ -65,7 +52,33 @@ impl Ctx { self.respond_with(Some(data)).await } - pub async fn ephem(&mut self, content: impl Into + Send) -> MessageRespondResult { + pub async fn defer(&mut self) -> UnitRespondResult { + self.acknowledge(); + Ok(self.interface().await?.defer().await?) + } +} + +impl crate::core::model::AcknowledgementAware for Ctx { + type FollowupError = FollowupError; + type RespondError = crate::error::command::RespondError; + type RespondOrFollowupError = crate::error::command::RespondOrFollowupError; + + fn acknowledged(&self) -> bool { + self.acknowledged + } + + async fn respond( + &mut self, + content: impl Into + Send, + ) -> Result { + let data = Self::base_response_data_builder().content(content).build(); + self.respond_with(Some(data)).await + } + + async fn respond_ephemeral( + &mut self, + content: impl Into + Send, + ) -> MessageRespondResult { let data = Self::base_response_data_builder() .content(content) .flags(MessageFlags::EPHEMERAL) @@ -73,11 +86,28 @@ impl Ctx { self.respond_with(Some(data)).await } - pub async fn followup(&self, content: &str) -> MessageFollowupResult { + async fn update( + &self, + content: impl Into + Send, + ) -> Result { + Ok(self + .interface() + .await? + .update_no_components_embeds(content) + .await?) + } + + async fn followup( + &self, + content: impl Into + Send, + ) -> Result { Ok(self.interface().await?.followup(content).await?) } - pub async fn followup_ephem(&self, content: &str) -> MessageFollowupResult { - Ok(self.interface().await?.followup_ephem(content).await?) + async fn followup_ephemeral( + &self, + content: impl Into + Send, + ) -> Result { + Ok(self.interface().await?.followup_ephemeral(content).await?) } } diff --git a/lyra/src/component/config/access/view.rs b/lyra/src/component/config/access/view.rs index c12dd5f..4758a6a 100644 --- a/lyra/src/component/config/access/view.rs +++ b/lyra/src/component/config/access/view.rs @@ -31,7 +31,7 @@ impl BotSlashCommand for View { ); let embed = embed.validate()?.build(); - ctx.respond_embeds_only([embed]).await?; + ctx.respond_embeds([embed]).await?; Ok(()) } } diff --git a/lyra/src/component/connection/join.rs b/lyra/src/component/connection/join.rs index 5acfdd7..c470de7 100644 --- a/lyra/src/component/connection/join.rs +++ b/lyra/src/component/connection/join.rs @@ -18,7 +18,7 @@ use twilight_model::{ use crate::{ command::{ check, - macros::{bad, cant, nope, note, note_fol, out, sus_fol}, + macros::{bad, cant, nope, note, note_fol, out_or_fol, sus_fol}, model::{BotSlashCommand, CtxKind, GuildCtx, RespondViaMessage}, require::{self, InVoiceCachedVoiceState}, SlashCtx, @@ -328,7 +328,7 @@ async fn handle_response( let (joined, empty) = match response { Response::Joined { voice, empty } => { let stage = matches!(voice.kind, JoinedChannelType::Stage); - out!( + out_or_fol!( stage_fmt(&format!("🖇️ {}", voice.id.mention()), stage), ?ctx ); @@ -336,7 +336,7 @@ async fn handle_response( } Response::Moved { from, to, empty } => { let stage = matches!(to.kind, JoinedChannelType::Stage); - out!( + out_or_fol!( stage_fmt( &format!("️📎🖇️ ~~{}~~ ➜ __{}__", from.mention(), to.id.mention()), stage, diff --git a/lyra/src/component/queue/play.rs b/lyra/src/component/queue/play.rs index fc0edc3..b6af833 100644 --- a/lyra/src/component/queue/play.rs +++ b/lyra/src/component/queue/play.rs @@ -26,7 +26,7 @@ use twilight_util::builder::command::CommandBuilder; use crate::{ command::{ - macros::{bad, crit, out_or_fol, what}, + macros::{bad, bad_or_fol, crit_or_fol, out_or_fol, what_or_fol}, model::{BotAutocomplete, BotMessageCommand, BotSlashCommand, GuildCtx, RespondViaMessage}, require, util, AutocompleteCtx, MessageCtx, SlashCtx, }, @@ -323,6 +323,7 @@ async fn play( ctx: &mut GuildCtx, queries: impl IntoIterator> + Send, ) -> Result<(), play::Error> { + ctx.defer().await?; let load_ctx = LoadTrackContext::new_via(ctx); match load_ctx.process_many(queries).await { Ok(results) => { @@ -401,13 +402,13 @@ async fn play( Err(e) => match e { LoadTrackProcessManyError::Query(query) => match query { QueryError::LoadFailed(LoadFailedError(query)) => { - crit!(format!("Failed to load tracks for query: `{}`", query), ctx); + crit_or_fol!(format!("Failed to load tracks for query: `{}`", query), ctx); } QueryError::NoMatches(query) => { - what!(format!("No matches found for query: `{}`", query), ctx); + what_or_fol!(format!("No matches found for query: `{}`", query), ctx); } QueryError::SearchResult(query) => { - bad!( + bad_or_fol!( format!( "Given query is not a URL: `{}`. Try using the command's autocomplete to search for tracks.", query diff --git a/lyra/src/core/model.rs b/lyra/src/core/model.rs index b706796..cde596a 100644 --- a/lyra/src/core/model.rs +++ b/lyra/src/core/model.rs @@ -24,8 +24,8 @@ use twilight_standby::Standby; use crate::{error::core::DeserializeBodyFromHttpError, lavalink::Lavalink, LavalinkAware}; pub use self::interaction::{ - Client as InteractionClient, Interface as InteractionInterface, MessageResponse, - UnitFollowupResult, UnitRespondResult, + AcknowledgementAware, Client as InteractionClient, Interface as InteractionInterface, + MessageResponse, UnitFollowupResult, UnitRespondResult, }; pub struct Config { diff --git a/lyra/src/core/model/interaction.rs b/lyra/src/core/model/interaction.rs index 6d40d90..6f64f8a 100644 --- a/lyra/src/core/model/interaction.rs +++ b/lyra/src/core/model/interaction.rs @@ -90,13 +90,15 @@ impl Interface<'_> { self.inner.0.update_response(self.interaction_token()) } - pub async fn update_no_components_embeds(&self, content: &str) -> MessageFollowupResult { - Ok(self - .update() + pub async fn update_no_components_embeds( + &self, + content: impl Into + Send, + ) -> MessageRespondResult { + self.update() .components(None) .embeds(None) - .content(Some(content)) - .await?) + .content(Some(&content.into())) + .await } pub async fn update_message_embeds_only( @@ -107,7 +109,15 @@ impl Interface<'_> { Ok(self.update_message_with(Some(data)).await?) } - pub async fn ephem(&self, content: impl Into + Send) -> MessageRespondResult { + pub async fn respond(&self, content: impl Into + Send) -> MessageRespondResult { + let data = Self::base_response_data_builder().content(content).build(); + self.respond_with(Some(data)).await + } + + pub async fn respond_ephemeral( + &self, + content: impl Into + Send, + ) -> MessageRespondResult { let data = Self::base_response_data_builder() .content(content) .flags(MessageFlags::EPHEMERAL) @@ -115,22 +125,25 @@ impl Interface<'_> { self.respond_with(Some(data)).await } - pub async fn followup(&self, content: &str) -> MessageFollowupResult { + pub async fn followup(&self, content: impl Into + Send) -> MessageFollowupResult { Ok(self .inner .0 .create_followup(self.interaction_token()) - .content(content) + .content(&content.into()) .await?) } - pub async fn followup_ephem(&self, content: &str) -> MessageFollowupResult { + pub async fn followup_ephemeral( + &self, + content: impl Into + Send, + ) -> MessageFollowupResult { Ok(self .inner .0 .create_followup(self.interaction_token()) .flags(MessageFlags::EPHEMERAL) - .content(content) + .content(&content.into()) .await?) } @@ -190,6 +203,36 @@ impl Interface<'_> { Ok(()) } + async fn defer_as(&self, ephemeral: bool) -> UnitRespondResult { + let mut data = Self::base_response_data_builder(); + if ephemeral { + data = data.flags(MessageFlags::EPHEMERAL); + } + + self.inner + .0 + .create_response( + self.interaction_id, + self.interaction_token(), + &InteractionResponse { + kind: InteractionResponseType::DeferredChannelMessageWithSource, + data: data.build().into(), + }, + ) + .await?; + Ok(()) + } + + #[inline] + pub async fn defer(&self) -> UnitRespondResult { + self.defer_as(false).await + } + + #[inline] + pub async fn defer_ephem(&self) -> UnitRespondResult { + self.defer_as(true).await + } + pub async fn update_followup( &self, message_id: Id, @@ -204,6 +247,109 @@ impl Interface<'_> { } } +pub trait AcknowledgementAware { + type FollowupError; + type RespondError; + type RespondOrFollowupError: From + From; + + fn acknowledged(&self) -> bool; + async fn respond( + &mut self, + content: impl Into + Send, + ) -> Result; + async fn respond_ephemeral( + &mut self, + content: impl Into + Send, + ) -> Result; + async fn update( + &self, + content: impl Into + Send, + ) -> Result; + async fn followup( + &self, + content: impl Into + Send, + ) -> Result; + async fn followup_ephemeral( + &self, + content: impl Into + Send, + ) -> Result; + + async fn respond_or_update( + &mut self, + content: impl Into + Send, + ) -> Result { + if self.acknowledged() { + return self.update(&content.into()).await; + } + self.respond(content).await + } + async fn respond_or_followup( + &mut self, + content: impl Into + Send, + ) -> Result { + if self.acknowledged() { + return Ok(self.followup(&content.into()).await?); + } + + Ok(self.respond(content).await?) + } + async fn respond_ephemeral_or_followup( + &mut self, + content: impl Into + Send, + ) -> Result { + if self.acknowledged() { + return Ok(self.followup_ephemeral(&content.into()).await?); + } + + Ok(self.respond_ephemeral(content).await?) + } +} + +impl AcknowledgementAware for (Interface<'_>, bool) { + type FollowupError = crate::error::core::FollowupError; + type RespondError = twilight_http::Error; + type RespondOrFollowupError = crate::error::core::FollowupError; + + fn acknowledged(&self) -> bool { + self.1 + } + + async fn respond_ephemeral( + &mut self, + content: impl Into + Send, + ) -> Result { + self.0.respond_ephemeral(content).await + } + + async fn respond( + &mut self, + content: impl Into + Send, + ) -> Result { + self.0.respond(content).await + } + + async fn update( + &self, + content: impl Into + Send, + ) -> Result { + self.0.update_no_components_embeds(content).await + } + + async fn followup( + &self, + content: impl Into + Send, + ) -> Result { + self.0.followup(content).await + } + + async fn followup_ephemeral( + &self, + content: impl Into + Send, + ) -> Result { + self.0.followup_ephemeral(content).await + } +} + impl<'a> Client<'a> { pub const fn new(client: twilight_http::client::InteractionClient<'a>) -> Self { Self(client) diff --git a/lyra/src/error/command.rs b/lyra/src/error/command.rs index 0df9ad3..43598db 100644 --- a/lyra/src/error/command.rs +++ b/lyra/src/error/command.rs @@ -18,6 +18,13 @@ pub enum FollowupError { Followup(#[from] super::core::FollowupError), } +#[derive(thiserror::Error, Debug)] +#[error("creating a response or followup failed: {}", 0)] +pub enum RespondOrFollowupError { + Respond(#[from] RespondError), + Followup(#[from] FollowupError), +} + #[derive(thiserror::Error, Debug)] #[error("command failed: {}", .0)] pub enum Error { @@ -243,6 +250,13 @@ impl<'a> Fe<'a> { } } + const fn from_respond_or_followup(error: &'a RespondOrFollowupError) -> Self { + match error { + RespondOrFollowupError::Respond(e) => Self::from_respond(e), + RespondOrFollowupError::Followup(e) => Self::from_followup(e), + } + } + const fn from_prompt_for_confirmation(error: &'a util::PromptForConfirmationError) -> Self { match error { util::PromptForConfirmationError::StandbyCanceled(_) => Self::StandbyCanceled, @@ -342,8 +356,8 @@ impl<'a> Fe<'a> { super::component::connection::join::HandleResponseError::DeserializeBody(_) => { Self::DeserializeBody } - super::component::connection::join::HandleResponseError::Respond(e) => { - Self::from_respond(e) + super::component::connection::join::HandleResponseError::RespondOrFollowup(e) => { + Self::from_respond_or_followup(e) } super::component::connection::join::HandleResponseError::Followup(e) => { Self::from_followup(e) @@ -490,7 +504,9 @@ impl<'a> Fe<'a> { Self::from_require_unsuppressed_error(e) } super::component::queue::play::Error::Respond(e) => Self::from_respond(e), - super::component::queue::play::Error::Followup(e) => Self::from_followup(e), + super::component::queue::play::Error::RespondOrFollowup(e) => { + Self::from_respond_or_followup(e) + } super::component::queue::play::Error::AutoJoinOrCheckInVoiceWithUser(e) => { Self::from_auto_join_or_check_in_voice_with_user(e) } diff --git a/lyra/src/error/component/connection.rs b/lyra/src/error/component/connection.rs index 4338109..b2d3c5e 100644 --- a/lyra/src/error/component/connection.rs +++ b/lyra/src/error/component/connection.rs @@ -63,9 +63,9 @@ pub mod join { #[error(transparent)] pub enum HandleResponseError { Cache(#[from] crate::error::Cache), - Respond(#[from] crate::error::command::RespondError), DeserializeBody(#[from] twilight_http::response::DeserializeBodyError), Followup(#[from] crate::error::command::FollowupError), + RespondOrFollowup(#[from] crate::error::command::RespondOrFollowupError), } #[derive(thiserror::Error, Debug)] @@ -152,9 +152,9 @@ pub mod join { HandleResponseError::Cache(e) => { Self::Other(ResidualError::HandleResponse(HandleResponseError::Cache(e))) } - HandleResponseError::Respond(e) => Self::Other(ResidualError::HandleResponse( - HandleResponseError::Respond(e), - )), + HandleResponseError::RespondOrFollowup(e) => Self::Other( + ResidualError::HandleResponse(HandleResponseError::RespondOrFollowup(e)), + ), HandleResponseError::DeserializeBody(e) => Self::Other( ResidualError::HandleResponse(HandleResponseError::DeserializeBody(e)), ), diff --git a/lyra/src/error/component/queue.rs b/lyra/src/error/component/queue.rs index 12d5898..c74b226 100644 --- a/lyra/src/error/component/queue.rs +++ b/lyra/src/error/component/queue.rs @@ -21,7 +21,7 @@ pub mod play { pub enum Error { RequireUnsuppressed(#[from] crate::error::command::require::UnsuppressedError), Respond(#[from] crate::error::command::RespondError), - Followup(#[from] crate::error::command::FollowupError), + RespondOrFollowup(#[from] crate::error::command::RespondOrFollowupError), AutoJoinOrCheckInVoiceWithUser( #[from] crate::error::command::util::AutoJoinOrCheckInVoiceWithUserError, ), diff --git a/lyra/src/gateway/interaction.rs b/lyra/src/gateway/interaction.rs index 836859e..d26f273 100644 --- a/lyra/src/gateway/interaction.rs +++ b/lyra/src/gateway/interaction.rs @@ -1,5 +1,6 @@ use std::{hint::unreachable_unchecked, sync::Arc}; +use tokio::sync::oneshot; use twilight_gateway::{Latency, MessageSender}; use twilight_mention::Mention; use twilight_model::{ @@ -13,7 +14,10 @@ use twilight_model::{ use super::model::Process; use crate::{ command::{ - macros::{bad, cant, caut, crit, err, hid, nope, note, out_upd, sus, sus_fol}, + macros::{ + bad, bad_or_fol, cant_or_fol, caut, crit, crit_or_fol, err, hid, nope, nope_or_fol, + note, out_upd, sus, sus_fol, + }, model::NonPingInteraction, require, util::MessageLinkAware, @@ -34,7 +38,7 @@ use crate::{ }, declare::{CommandExecuteError, Fuunacee}, util::AutoJoinSuppressedError, - Error as CommandError, Fe, RespondError, + Error as CommandError, Fe, }, gateway::{ProcessError, ProcessResult}, AutoJoinAttemptFailed as AutoJoinAttemptFailedError, @@ -101,6 +105,7 @@ impl Context { let inner_guild_id = self.inner.guild_id; // SAFETY: interaction type is not `Ping`, so `channel` is present let channel_id = unsafe { self.inner.channel_id_unchecked() }; + let (tx, mut rx) = oneshot::channel::<()>(); let result = match data.kind { CommandType::ChatInput => { @@ -110,11 +115,11 @@ impl Context { bot.clone(), self.latency, self.sender, + tx, ) .execute(*data) .await } - CommandType::User => todo!(), CommandType::Message => { MessageCtx::from_partial_data( self.inner, @@ -122,10 +127,12 @@ impl Context { bot.clone(), self.latency, self.sender, + tx, ) .execute(*data) .await } + CommandType::User => todo!(), _ => unimplemented!(), }; @@ -143,6 +150,7 @@ impl Context { return Ok(()); }; + let acknowledged = rx.try_recv().is_ok(); match source.flatten_until_user_not_allowed_as() { Fuunacee::UserNotAllowed => { nope!("You are not allowed to use commands in this context.", i); @@ -153,7 +161,7 @@ impl Context { // so the unflattened source error must be `CommandExecuteError::Command(_)` unsafe { unreachable_unchecked() } }; - match_error(error, name, i).await + match_error(error, name, acknowledged, i).await } _ => { crit!(format!( @@ -172,12 +180,14 @@ impl Context { }; let name = data.name.clone().into(); + let (tx, _) = oneshot::channel::<()>(); let Err(source) = ::from_partial_data( self.inner, &data, self.bot, self.latency, self.sender, + tx, ) .execute(*data) .await @@ -217,13 +227,17 @@ impl Context { async fn match_error( error: CommandError, command_name: Box, + acknowledged: bool, i: InteractionInterface<'_>, ) -> Result<(), ProcessError> { match error.flatten_as() { Fe::Cache => { tracing::warn!("cache error: {:#?}", error); - crit!("Something isn't working at the moment, try again later.", i); + crit_or_fol!( + "Something isn't working at the moment, try again later.", + (i, acknowledged) + ); } Fe::UserNotDj => { nope!("You need to be a ***DJ*** to do that.", i); @@ -246,12 +260,12 @@ async fn match_error( ); } Fe::InVoiceWithoutUser(e) => { - nope!( + nope_or_fol!( format!( "You are not with the bot in {}; You need to be a ***DJ*** to do that.", e.0.mention(), ), - i + (i, acknowledged) ); } Fe::InVoiceWithSomeoneElse(e) => { @@ -260,9 +274,11 @@ async fn match_error( Fe::InVoiceWithoutSomeoneElse(e) => { bad!(format!("Not enough people are in {}.", e.0.mention()), i); } - Fe::Suppressed(e) => Ok(match_suppressed(e, i).await?), + Fe::Suppressed(e) => Ok(match_suppressed(e, (i, acknowledged)).await?), Fe::AutoJoinSuppressed(e) => Ok(match_autojoin_suppressed(e, i).await?), - Fe::AutoJoinAttemptFailed(e) => Ok(match_autojoin_attempt_failed(e, i).await?), + Fe::AutoJoinAttemptFailed(e) => { + Ok(match_autojoin_attempt_failed(e, (i, acknowledged)).await?) + } Fe::Stopped => todo!(), Fe::NotPlaying => { bad!("Currently not playing anything.", i); @@ -316,14 +332,14 @@ async fn match_error( async fn match_suppressed( error: &SuppressedError, - i: InteractionInterface<'_>, -) -> UnitRespondResult { + mut ia: (InteractionInterface<'_>, bool), +) -> UnitFollowupResult { match error { SuppressedError::Muted => { - bad!("Currently server muted.", i); + bad_or_fol!("Currently server muted.", ia); } SuppressedError::NotSpeaker => { - bad!("Not currently a speaker in this stage channel.", i); + bad_or_fol!("Not currently a speaker in this stage channel.", ia); } } } @@ -350,33 +366,33 @@ async fn match_autojoin_suppressed( async fn match_autojoin_attempt_failed( error: &AutoJoinAttemptFailedError, - i: InteractionInterface<'_>, -) -> Result<(), RespondError> { + mut ia: (InteractionInterface<'_>, bool), +) -> UnitFollowupResult { match error { AutoJoinAttemptFailedError::UserNotInVoice(_) => { let join = InteractionClient::mention_command::(); - bad!( + bad_or_fol!( format!( "Please join a voice channel, or use {} to connect to a channel.", join ), - i + ia ); } AutoJoinAttemptFailedError::UserNotAllowed(_) => { - nope!("Attempting to join your currently connected channel failed as you are not allowed to use the bot here.", i); + nope_or_fol!("Attempting to join your currently connected channel failed as you are not allowed to use the bot here.", ia); } AutoJoinAttemptFailedError::Forbidden(e) => { - cant!( + cant_or_fol!( format!( "Attempting to join {} failed due to insufficient permissions.", e.0.mention() ), - i + ia ); } AutoJoinAttemptFailedError::UserNotStageManager(_) => { - nope!("Attempting to join your currently connected stage failed as you are not a **Stage Manager**.", i); + nope_or_fol!("Attempting to join your currently connected stage failed as you are not a **Stage Manager**.", ia); } } } diff --git a/lyra/src/lavalink/model.rs b/lyra/src/lavalink/model.rs index c5a5465..e506413 100644 --- a/lyra/src/lavalink/model.rs +++ b/lyra/src/lavalink/model.rs @@ -483,7 +483,7 @@ impl HttpAware for ClientData { } impl ClientData { - pub fn new(http: Arc) -> Self { + pub const fn new(http: Arc) -> Self { Self { http } } } diff --git a/lyra_ext/src/iter/multi_interleave.rs b/lyra_ext/src/iter/multi_interleave.rs index fe5f5ab..3937722 100644 --- a/lyra_ext/src/iter/multi_interleave.rs +++ b/lyra_ext/src/iter/multi_interleave.rs @@ -19,7 +19,7 @@ impl MultiInterleave where I: Iterator, { - fn new(iterators: Box<[I]>) -> Self { + const fn new(iterators: Box<[I]>) -> Self { Self { iterators, current: 0,