diff --git a/Cargo.lock b/Cargo.lock index 7c5fc4b..e939c77 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,21 +1,21 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +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 = "aho-corasick" @@ -43,43 +43,43 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" dependencies = [ "serde", ] [[package]] name = "async-trait" -version = "0.1.80" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.93", ] [[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 = "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 0.52.6", ] [[package]] @@ -102,9 +102,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -117,9 +117,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.10.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" dependencies = [ "memchr", "serde", @@ -145,24 +145,24 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] @@ -182,9 +182,12 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.98" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c270e7540d725e65ac7f1b212ac8ce349719624d7bcff99f8e2e488e8cf03f" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -193,23 +196,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "chrono" -version = "0.4.38" +name = "cfg_aliases" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] name = "command_attr" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88da8d7e9fe6f30d8e3fcf72d0f84102b49de70fece952633e8439e89bdc7631" +checksum = "6fcc89439e1bb4e19050a9586a767781a3060000d2f3296fd2a40597ad9421c5" dependencies = [ "proc-macro2", "quote", @@ -228,15 +237,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" dependencies = [ "libc", ] @@ -252,18 +261,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crypto-common" @@ -275,6 +284,16 @@ dependencies = [ "typenum", ] +[[package]] +name = "ctrlc" +version = "3.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" +dependencies = [ + "nix", + "windows-sys 0.59.0", +] + [[package]] name = "dashmap" version = "5.5.3" @@ -282,7 +301,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ "cfg-if", - "hashbrown", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -316,10 +335,27 @@ dependencies = [ ] [[package]] -name = "encoding_rs" -version = "0.8.34" +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.93", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] @@ -332,12 +368,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[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]] @@ -351,15 +387,15 @@ dependencies = [ [[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 = "flate2" -version = "1.0.30" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" dependencies = [ "crc32fast", "miniz_oxide", @@ -382,9 +418,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -396,9 +432,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -406,44 +442,44 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.93", ] [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -484,20 +520,32 @@ checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.13.3+wasi-0.2.2", + "windows-targets 0.52.6", ] [[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 = "h2" @@ -524,6 +572,12 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + [[package]] name = "hermit-abi" version = "0.3.9" @@ -543,9 +597,9 @@ dependencies = [ [[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", @@ -565,9 +619,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -577,9 +631,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ "bytes", "futures-channel", @@ -615,9 +669,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -637,43 +691,173 @@ dependencies = [ ] [[package]] -name = "idna" -version = "0.5.0" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.93", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] name = "indexmap" -version = "2.2.6" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.2", ] [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[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 = "js-sys" -version = "0.3.69" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -691,18 +875,18 @@ checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" [[package]] name = "libc" -version = "0.2.155" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -711,6 +895,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" version = "0.4.12" @@ -723,24 +913,24 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "luau0-src" -version = "0.10.2+luau635" +version = "0.11.2+luau653" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8bd6bc70c84fdd4e89b71b528f7ab7db7b97adf759faa8dbe15c5011468e290" +checksum = "02313a53daf1fae25e82f7e7ca56180b72d1f08c514426672877cd957298201c" dependencies = [ "cc", ] [[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 = "mime" @@ -750,9 +940,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -775,45 +965,45 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87dfd01fe195c66b572b37921ad8803d010623c0aca821bea2302239d155cdae" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "1.0.1" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ - "hermit-abi", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] [[package]] name = "mlua" -version = "0.9.9" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d111deb18a9c9bd33e1541309f4742523bfab01d276bfa9a27519f6de9c11dc7" +checksum = "d3f763c1041eff92ffb5d7169968a327e1ed2ebfe425dac0ee5a35f29082534b" dependencies = [ "bstr", + "either", "futures-util", "libloading", "mlua-sys", "num-traits", - "once_cell", + "parking_lot", "rustc-hash", ] [[package]] name = "mlua-sys" -version = "0.6.2" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab7a5b4756b8177a2dfa8e0bbcde63bd4000afbc4ab20cbb68d114a25470f29" +checksum = "63a11d485edf0f3f04a508615d36c7d50d299cf61a7ee6d3e2530651e0a31771" dependencies = [ "cc", "cfg-if", @@ -821,13 +1011,26 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.6.0", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "nopalmo" version = "0.1.0" dependencies = [ + "ctrlc", "mlua", "num_cpus", - "rand", + "rand 0.9.0", "regex", "serenity", "sqlite", @@ -873,18 +1076,18 @@ 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.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "overload" @@ -894,9 +1097,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[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", @@ -912,7 +1115,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -923,9 +1126,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -935,9 +1138,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 = "powerfmt" @@ -947,15 +1150,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 = "proc-macro2" -version = "1.0.83" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b33eb56c327dec362a9e55b3ad14f9d2f0904fb5a5b03b513ab5465399e9f43" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] @@ -966,16 +1172,16 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "memchr", "unicase", ] [[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", ] @@ -987,8 +1193,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.0", + "zerocopy 0.8.17", ] [[package]] @@ -998,7 +1215,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.0", ] [[package]] @@ -1007,23 +1234,33 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_core" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff" +dependencies = [ + "getrandom 0.3.1", + "zerocopy 0.8.17", ] [[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 2.5.0", + "bitflags 2.6.0", ] [[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", @@ -1033,9 +1270,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", @@ -1044,9 +1281,9 @@ 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 = "reqwest" @@ -1100,7 +1337,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", "spin", "untrusted", @@ -1115,21 +1352,21 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1153,7 +1390,7 @@ dependencies = [ "log", "ring", "rustls-pki-types", - "rustls-webpki 0.102.4", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] @@ -1169,9 +1406,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" [[package]] name = "rustls-webpki" @@ -1185,9 +1422,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.4" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -1237,18 +1474,18 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.202" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] @@ -1264,22 +1501,23 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.93", ] [[package]] name = "serde_json" -version = "1.0.117" +version = "1.0.134" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1298,14 +1536,14 @@ dependencies = [ [[package]] name = "serenity" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "880a04106592d0a8f5bdacb1d935889bfbccb4a14f7074984d9cd857235d34ac" +checksum = "3d72ec4323681bf9a3cabe40fd080abc2435859b502a1b5aa9bf693f125bfa76" dependencies = [ "arrayvec", "async-trait", "base64 0.22.1", - "bitflags 2.5.0", + "bitflags 2.6.0", "bytes", "chrono", "command_attr", @@ -1353,6 +1591,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -1394,9 +1638,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[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", @@ -1436,6 +1680,12 @@ dependencies = [ "sqlite3-src", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "static_assertions" version = "1.1.0" @@ -1444,9 +1694,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[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" @@ -1461,9 +1711,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.65" +version = "2.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2863d96a84c6439701d7a38f9de935ec562c8832cc55d1dde0f513b52fad106" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" dependencies = [ "proc-macro2", "quote", @@ -1476,6 +1726,17 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.93", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -1505,34 +1766,35 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" [[package]] name = "tempfile" -version = "3.10.1" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.93", ] [[package]] @@ -1547,9 +1809,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", @@ -1568,34 +1830,29 @@ 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", ] [[package]] -name = "tinyvec" -version = "1.6.0" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "tinyvec_macros", + "displaydoc", + "zerovec", ] -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "tokio" -version = "1.39.2" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -1617,7 +1874,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.93", ] [[package]] @@ -1654,14 +1911,14 @@ dependencies = [ "tokio", "tokio-rustls 0.25.0", "tungstenite", - "webpki-roots 0.26.1", + "webpki-roots 0.26.7", ] [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -1672,15 +1929,15 @@ dependencies = [ [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "log", "pin-project-lite", @@ -1690,20 +1947,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.93", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -1722,9 +1979,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "chrono", "nu-ansi-term", @@ -1737,9 +1994,9 @@ dependencies = [ [[package]] name = "triomphe" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" [[package]] name = "try-lock" @@ -1756,10 +2013,10 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.1.0", + "http 1.2.0", "httparse", "log", - "rand", + "rand 0.8.5", "rustls 0.22.4", "rustls-pki-types", "sha1", @@ -1782,13 +2039,13 @@ checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "typesize" -version = "0.1.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb704842c709bc76f63e99e704cb208beeccca2abbabd0d9aec02e48ca1cee0f" +checksum = "549e54551d85ba6718a95333d9bc4367f69793d7aba638de30f8d25a1f554a1d" dependencies = [ "chrono", "dashmap", - "hashbrown", + "hashbrown 0.14.5", "mini-moka", "parking_lot", "secrecy", @@ -1800,44 +2057,26 @@ dependencies = [ [[package]] name = "typesize-derive" -version = "0.1.7" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "905e88c2a4cc27686bd57e495121d451f027e441388a67f773be729ad4be1ea8" +checksum = "fd9fc0ad9e03a2b0c2e2a0eafaecccef2121829e1ab6ce9c9d790e6c6766bd1c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.93", ] [[package]] name = "unicase" -version = "2.7.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "untrusted" @@ -1847,9 +2086,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -1863,6 +2102,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "uwl" version = "0.6.0" @@ -1877,9 +2128,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[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 = "walkdir" @@ -1907,47 +2158,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] -name = "wasm-bindgen" -version = "0.2.92" +name = "wasi" +version = "0.13.3+wasi-0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.93", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1955,28 +2216,28 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.65", + "syn 2.0.93", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wasm-streams" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" dependencies = [ "futures-util", "js-sys", @@ -1987,9 +2248,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" dependencies = [ "js-sys", "wasm-bindgen", @@ -2003,9 +2264,9 @@ checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webpki-roots" -version = "0.26.1" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -2028,11 +2289,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -2047,7 +2308,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", ] [[package]] @@ -2065,7 +2326,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -2085,18 +2355,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.5", - "windows_aarch64_msvc 0.52.5", - "windows_i686_gnu 0.52.5", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc 0.52.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 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2107,9 +2377,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -2119,9 +2389,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -2131,15 +2401,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.5" +version = "0.52.6" 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" @@ -2149,9 +2419,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -2161,9 +2431,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -2173,9 +2443,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -2185,9 +2455,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.5" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winreg" @@ -2200,7 +2470,136 @@ dependencies = [ ] [[package]] -name = "zeroize" -version = "1.7.0" +name = "wit-bindgen-rt" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.93", + "synstructure", +] + +[[package]] +name = "zerocopy" +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.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa91407dacce3a68c56de03abe2760159582b846c6a4acd2f456618087f12713" +dependencies = [ + "zerocopy-derive 0.8.17", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.93", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06718a168365cad3d5ff0bb133aad346959a2074bd4a85c121255a11304a8626" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.93", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.93", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.93", +] diff --git a/Cargo.toml b/Cargo.toml index c6744c0..d9f4ea2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,13 +8,14 @@ tokio = { version = "1.37.0", features = ["full"] } tracing = "0.1.40" tracing-subscriber = { version = "0.3.18", features = ["chrono"] } -mlua = { version = "0.9.9", features = ["async", "luau"] } -serenity = "0.12.1" +mlua = { version = "0.10.3", features = ["async", "luau"] } +serenity = "0.12.4" num_cpus = "1.16.0" -rand = "0.8.5" +rand = "0.9.0" regex = "1.10.4" sqlite = { version = "0.36.1", features = ["bundled"] } +ctrlc = "3.4.5" [features] diff --git a/lua/help.lua b/lua/help.lua index e740fba..b09ff4d 100644 --- a/lua/help.lua +++ b/lua/help.lua @@ -1,18 +1,18 @@ -COMMAND["help"] = { +Metadata = { + name = "help", -- the main required string used to call the command aliases = { "h" }, -- other strings that you can run the command from pretty_name = "Help", -- the name of the command as it shows up in menues and other commands that use its pretty name - name = "help", -- the main required string used to call the command - command_category = commandCategory.info, -- this can be any string, but the bot provides a few categories already help = "Shows you helpful information for the bot. Seems you already know how to use it. :loafplink:", + + command_category = commandCategory.info, -- this can be any string, but the bot provides a few categories already timeout = nil, -- time in milliseconds that the user must wait before running the command again hidden = false, -- whether or not other commands should acknowledge its existance, for example we dont want dev commands showing up in the help info for regular users, regardless if they can use them or not permissions = nil, -- which discord permissions they need to run the command - - FUNC = function(context, message, guildid) - for t in COMMAND do - print("Help info for command " + t) - end - end } -COMMAND["help"].FUNC() \ No newline at end of file + +function Command(context, message, guildid) + for t in COMMAND do + print("Help info for command " + t) + end +end diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..31578d3 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "stable" \ No newline at end of file diff --git a/rustfmt.toml b/rustfmt.toml index 218e203..1abdef1 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1 +1,33 @@ -hard_tabs = true +# i use tabs so stop bugging me and go elsewhere already + +hard_tabs=true +binop_separator="Back" +condense_wildcard_suffixes = true +empty_item_single_line = false +enum_discrim_align_threshold = 30 +struct_field_align_threshold = 30 +short_array_element_width_threshold = 30 +inline_attribute_width = 50 +fn_params_layout = "Compressed" +fn_single_line = true +format_code_in_doc_comments = true +format_macro_matchers = true +hex_literal_case = "Upper" +imports_indent = "Visual" +imports_layout = "Vertical" +# indent_style = "Visual" +match_arm_blocks = false +match_block_trailing_comma = true +max_width = 160 +imports_granularity = "Item" +newline_style = "Unix" +normalize_doc_attributes = true +overflow_delimited_expr = true +reorder_impl_items = true +# group_imports = "StdExternalCrate" +space_after_colon = false +# trailing_comma = "Always" +type_punctuation_density = "Compressed" +use_field_init_shorthand = true +use_try_shorthand = true +where_single_line = true diff --git a/src/arguments.rs b/src/arguments.rs index af1b0a8..eed1204 100644 --- a/src/arguments.rs +++ b/src/arguments.rs @@ -1,14 +1,13 @@ -use std::{collections::HashMap, sync::Arc}; +use std::collections::HashMap; #[derive(Debug, Clone, PartialEq, Default)] pub struct ArgumentStorage(HashMap); impl ArgumentStorage { - pub fn new() -> Self { - Self::default() - } + pub fn new() -> Self { Self::default() } - pub fn add_argument() {} + pub fn add_argument() { + } } // #[derive(Debug, Clone, PartialEq, Default)] @@ -84,4 +83,3 @@ impl ArgumentStorage { // Value(String), // Argument(usize), // } - diff --git a/src/bot.rs b/src/bot.rs index e7e22c0..1558cd3 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -1,18 +1,34 @@ -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, Condvar, OnceLock}; +use std::sync::atomic::AtomicBool; +use std::sync::Arc; +use std::sync::OnceLock; -use crate::commands::{self, COMMANDS}; -use crate::{constants, tasks, CARG_NO_DISCORD}; -use serenity::all::{ActivityData, Context, GuildId}; -use serenity::all::{EventHandler, GatewayIntents, ShardManager}; +use serenity::all::ActivityData; +use serenity::all::Context; +use serenity::all::EventHandler; +use serenity::all::GatewayIntents; +use serenity::all::GuildId; +use serenity::all::ShardManager; use serenity::model::channel::Message; use serenity::model::gateway::Ready; use serenity::Client; -use tracing::{error, info, warn}; -pub static DO_SHUTDOWN: (AtomicBool, Condvar) = (AtomicBool::new(false), Condvar::new()); // atombool and condvar combo to ensure maximum coverage when the bot needs to power off +use tracing::error; +use tracing::info; +use tracing::warn; +use crate::commands::COMMANDS; +use crate::commands::{self}; +use crate::constants; +use crate::tasks; +use crate::CMD_ARGS; + +pub static DO_SHUTDOWN: AtomicBool = AtomicBool::new(false); + +// TODO remove from static memory pub static SHARD_MANAGER: OnceLock> = OnceLock::new(); +// cant remember why this was here, it isnt used anywhere else so ill just remove it for now +//pub static BOT_STARTED: AtomicBool = AtomicBool::new(false); + pub struct BotHandler; unsafe impl Sync for BotHandler {} @@ -26,65 +42,59 @@ impl EventHandler for BotHandler { return; } + // TODO remove regular expressions let prefix_regex = format!( r"^({}|{}|<@{}>)\s?", constants::COMMAND_PREFIX, - "NPO_PFX", + constants::CONSTANT_PREFIX, ctx.cache.current_user().id ); - let cmd_regex = format!(r"{}[A-Za-z0-9_\-]+", prefix_regex); + let cmd_regex = format!(r"{prefix_regex}[A-Za-z0-9_\-]+"); - let result = match regex::Regex::new(cmd_regex.as_str()) - .unwrap() - .find(&msg.content) - { - Some(result) => result, - None => return, // silently exit because not every message is meant for the bot + let Ok(result) = regex::Regex::new(cmd_regex.as_str()) else { + error!("The following regex function has failed to compile, this should not be possible. `{prefix_regex}`"); + return; }; - if DO_SHUTDOWN.0.load(Ordering::SeqCst) { + let Some(result) = result.find(&msg.content) else { + return; // message not meant for us :( + }; + + if DO_SHUTDOWN.load(std::sync::atomic::Ordering::SeqCst) { let _ = msg .channel_id - .say( - &ctx.http, - "Sorry! Your request was cancelled because the bot is shutting down.", - ) + .say(&ctx.http, "Sorry! Your request was cancelled because the bot is shutting down.") .await; return; } - let target_cmd_name = regex::Regex::new(prefix_regex.as_str()) - .unwrap() - .replace(result.as_str(), "") - .to_string(); + let Ok(target_cmd_name) = regex::Regex::new(prefix_regex.as_str()) else { + error!("The following regex function has failed to compile, this should not be possible. `{prefix_regex}`"); + return; + }; + let target_cmd_name = dbg!(target_cmd_name.replace(result.as_str(), "").to_string()); - msg.reply(&ctx.http, target_cmd_name.to_string()) - .await - .unwrap(); + let _ = msg.reply(&ctx.http, target_cmd_name.to_string()).await; - if let Some(command) = COMMANDS.read().await.get(&target_cmd_name) { - if let Some(guild_id) = msg.guild_id { - if let Some(run_guild_command) = &command.run_guild_command { - match run_guild_command { - commands::CommandFnKind::Lua(_) => todo!(), - commands::CommandFnKind::Rust(cmd) => (cmd)(ctx, msg, Some(guild_id)), - } - } - } else { - if let Some(run_dm_command) = &command.run_dm_command { - match run_dm_command { - commands::CommandFnKind::Lua(_) => todo!(), - commands::CommandFnKind::Rust(cmd) => (cmd)(ctx, msg, None), - } - } + if let Some(command) = dbg!(COMMANDS.read().await).get(&target_cmd_name) { + match (msg.guild_id, &command.run_guild_command, &command.run_dm_command) { + //(Some(gid), Some(commands::CommandFnKind::Lua(())), _) => todo!(), + (Some(gid), Some(commands::CommandFnKind::Rust(gcmd)), _) => (gcmd)(ctx, msg, Some(gid)), + //(None, _, Some(commands::CommandFnKind::Lua(()))) => todo!(), + (None, _, Some(commands::CommandFnKind::Rust(dcmd))) => (dcmd)(ctx, msg, None), + _ => (), } } } /// Runs once for every shard once its ready async fn ready(&self, ctx: Context, ready: Ready) { - info!("Shart `{}` is connected!", ready.shard.unwrap().id); - ctx.set_activity(Some(ActivityData::custom("Initializing."))) + let Some(shart) = ready.shard else { + error!("Bot ready function called while shards are not ready, this should be impossible."); + return; + }; + info!("Shart `{}` is connected!", shart.id); + ctx.set_activity(Some(ActivityData::custom("Initializing."))); } /// Runs once when all shards are ready @@ -122,18 +132,18 @@ pub async fn start() { | GatewayIntents::GUILD_MESSAGES | GatewayIntents::MESSAGE_CONTENT; - if *CARG_NO_DISCORD.get().unwrap() { + if CMD_ARGS.nodiscord { warn!("ABORTING CONNECTING TO DISCORD, BYE BYE!"); } else { - let mut client = match Client::builder(&token, intents) - .event_handler(BotHandler) - .await - { + let mut client = match Client::builder(token, intents).event_handler(BotHandler).await { Ok(client) => client, Err(err) => panic!("Error starting client connection: `{err}`"), }; - SHARD_MANAGER.set(client.shard_manager.clone()).unwrap(); + // just ignore the response, its impossible to fail here anyway + let _ = SHARD_MANAGER.set(client.shard_manager.clone()); + + //BOT_STARTED.store(true, std::sync::atomic::Ordering::SeqCst); if let Err(why) = client.start_shards(2).await { error!("Client error: {why:?}"); @@ -142,4 +152,3 @@ pub async fn start() { warn!("BOT EXITING"); } - diff --git a/src/commands.rs b/src/commands.rs index 935cdab..0f5a03e 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -1,19 +1,28 @@ -use std::{collections::HashMap, fmt::Debug, sync::LazyLock, time::Duration}; +use std::collections::HashMap; +use std::fmt::Debug; +use std::sync::LazyLock; +use std::time::Duration; + +use serenity::all::Context; +use serenity::all::GuildId; +use serenity::all::Message; +use serenity::all::Permissions; -use serenity::all::{Context, GuildId, Message, Permissions}; use tokio::sync::RwLock; use crate::arguments::ArgumentStorage; +use crate::constants::CAT_HID; -pub static COMMANDS: LazyLock>> = - LazyLock::new(|| RwLock::new(HashMap::new())); +pub static COMMANDS: LazyLock>> = LazyLock::new(|| RwLock::new(HashMap::new())); +#[derive(Debug)] pub enum CommandFnKind { Lua(()), Rust(fn(Context, Message, Option)), } -pub struct Command { +#[derive(Debug)] +pub struct BotCommand { pub run_dm_command: Option, pub run_guild_command: Option, pub aliases: Vec, @@ -26,7 +35,7 @@ pub struct Command { pub hidden: bool, pub arguments: ArgumentStorage, - pub required_caller_discord_permissions: ::serenity::all::Permissions, + pub required_caller_discord_permissions: serenity::all::Permissions, #[cfg(feature = "nsfw_features")] pub is_nsfw: bool, @@ -34,7 +43,7 @@ pub struct Command { pub premium_kind: usize, } -impl Command { +impl BotCommand { pub fn new(name: String) -> Self { Self { run_dm_command: None, @@ -54,18 +63,22 @@ impl Command { premium_kind: 0, } } + pub fn dm_command(mut self, dm_command: CommandFnKind) -> Self { self.run_dm_command = Some(dm_command); self } + pub fn guild_command(mut self, guild_command: CommandFnKind) -> Self { self.run_guild_command = Some(guild_command); self } + pub fn pretty_name(mut self, pretty_name: String) -> Self { self.pretty_name = Some(pretty_name); self } + // pub fn name(mut self, name: String) -> Self { // self.name = name; // self @@ -74,22 +87,27 @@ impl Command { self.aliases.push(alias); self } + pub fn aliases(mut self, aliases: &mut Vec) -> Self { self.aliases.append(aliases); self } + pub fn category(mut self, category: String) -> Self { self.command_category = Some(category); self } + pub fn help(mut self, help: String) -> Self { self.help = Some(help); self } + pub fn timeout(mut self, timeout: Duration) -> Self { self.timeout = Some(timeout); self } + // pub fn argument(mut self, argument: Argument) -> Self { // self.arguments.add(argument); // self @@ -100,38 +118,38 @@ impl Command { } } -unsafe impl Sync for Command {} -unsafe impl Send for Command {} +unsafe impl Sync for BotCommand {} +unsafe impl Send for BotCommand {} -impl Debug for Command { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let mut binding = f.debug_struct("Command"); - binding - .field( - "run_dm_command", - &::std::any::type_name_of_val(&self.run_dm_command), - ) - .field( - "run_guild_command", - &::std::any::type_name_of_val(&self.run_guild_command), - ) - .field("aliases", &self.aliases) - .field("name", &self.name) - .field("pretty_name", &self.pretty_name) - .field("command_type", &self.command_category) - .field("help", &self.help) - .field("hidden", &self.hidden) - // .field("usage", &self.usage) - .field("timeout", &self.timeout) - .field("arguments", &self.arguments) - .field("permissions", &self.required_caller_discord_permissions); - #[cfg(feature = "nsfw_features")] - binding.field("is_nsfw", &self.is_nsfw); - #[cfg(feature = "premium_features")] - binding.field("premium_kind", &self.premium_kind); - binding.finish() - } -} +//impl Debug for BotCommand { +// fn fmt(&self, f:&mut std::fmt::Formatter<'_>) -> std::fmt::Result { +// let mut binding = f.debug_struct("Command"); +// binding +// .field( +// "run_dm_command", +// &::std::any::type_name_of_val(&self.run_dm_command), +// ) +// .field( +// "run_guild_command", +// &::std::any::type_name_of_val(&self.run_guild_command), +// ) +// .field("aliases", &self.aliases) +// .field("name", &self.name) +// .field("pretty_name", &self.pretty_name) +// .field("command_type", &self.command_category) +// .field("help", &self.help) +// .field("hidden", &self.hidden) +// // .field("usage", &self.usage) +// .field("timeout", &self.timeout) +// .field("arguments", &self.arguments) +// .field("permissions", &self.required_caller_discord_permissions); +// #[cfg(feature = "nsfw_features")] +// binding.field("is_nsfw", &self.is_nsfw); +// #[cfg(feature = "premium_features")] +// binding.field("premium_kind", &self.premium_kind); +// binding.finish() +// } +//} // impl Default for Command { // fn default() -> Self { @@ -139,3 +157,55 @@ impl Debug for Command { // } // } +/// The last set of commands, these are used by the hoster of the engine. +pub fn insert_lua(_lua: &mlua::Lua) { + // commands.insert( + // "stop".to_owned(), + // Command::new("stop".to_owned()) + // .alias("svs".to_owned()) + // .category(CAT_HID.to_owned()) + // .hidden(true) + // .dm_command(CommandFnKind::Rust(stop_command)) + // .guild_command(CommandFnKind::Rust(stop_command)) + // .pretty_name("Stop the bot".to_owned()) + // .help("Stops the bot. Does nothing unless you are a developer.".to_owned()), + // ); +} + +/// Cannot use any command names of stock commands, but gets to pick before lua commands are loaded. +pub fn insert_rust() { + // COMMANDS.blocking_write().insert( + // "stop2".to_owned(), + // BotCommand::new("stop".to_owned()) + // .alias("svs".to_owned()) + // .category(CAT_HID.to_owned()) + // .hidden(true) + // .dm_command(CommandFnKind::Rust(stop_command)) + // .guild_command(CommandFnKind::Rust(stop_command)) + // .pretty_name("Stop the bot".to_owned()) + // .help("Stops the bot. Does nothing unless you are a developer.".to_owned()), + // ); +} + +/// Will never fail, gets first pick of command names and properties. It is up to the maintainer to make damn sure this works. +pub async fn insert_stock() { + let shutdown_command = |_, msg: Message, _| { + // hardcode my id for now + if crate::databases::get_db().is_dev(msg.author.id) { + return; + } + crate::shutdown_handler(); + }; + + COMMANDS.write().await.insert( + "stop".to_owned(), + BotCommand::new("stop".to_owned()) + .alias("svs".to_owned()) + .category(CAT_HID.to_owned()) + .hidden(true) + .dm_command(CommandFnKind::Rust(shutdown_command)) + .guild_command(CommandFnKind::Rust(shutdown_command)) + .pretty_name("Stop the bot".to_owned()) + .help("Stops the bot. Does nothing unless you are a developer.".to_owned()), + ); +} diff --git a/src/constants.rs b/src/constants.rs index d0d93e9..4e0e909 100644 --- a/src/constants.rs +++ b/src/constants.rs @@ -1,12 +1,60 @@ +#![allow(unused)] + pub const VERSION: u16 = 0; -pub const CAT_DEV: &'static str = "Dev"; -pub const CAT_FUN: &'static str = "Fun"; -pub const CAT_MOD: &'static str = "Moderation"; -pub const CAT_GEN: &'static str = "General"; -pub const CAT_INF: &'static str = "Info"; -pub const CAT_HID: &'static str = "Hidden"; +// This variable should never change for any reason, it will be used to identify this instance of the bot +//pub const BOT_INTERNAL: &str = "npobot"; +/// Should be limited to lowercase alphanumeric characters with periods, dashes, and underscores only +/// If you want to stylize the bot name use the fancy version +pub const BOT_NAME: &str = "nopalmo"; +pub const BOT_NAME_FANCY: &str = "Nopalmo"; -pub const COMMAND_PREFIX: &'static str = ";"; -// pub const SHORT_ARGUMENT_PREFIX: &'static str = "-"; -// pub const LONG_ARGUMENT_PREFIX: &'static str = "--"; +pub const CAT_DEV: &str = "Dev"; +pub const CAT_FUN: &str = "Fun"; +pub const CAT_MOD: &str = "Moderation"; +pub const CAT_GEN: &str = "General"; +pub const CAT_INF: &str = "Info"; +pub const CAT_HID: &str = "Hidden"; + +pub const EMOJI_THUMB_UP: &str = "<:thumbsup:1339301449645166665>"; + +pub const CONSTANT_PREFIX: &str = "NPO_PFX"; +pub const COMMAND_PREFIX: &str = ";"; +pub const SHORT_ARGUMENT_PREFIX: &str = "-"; +pub const LONG_ARGUMENT_PREFIX: &str = "--"; + +pub const HELP_STRING: &str = r" +Nopalmo command help page: + +Description: + Lorem Ipsum Dolar Sit Amet... + +Arguments: + nodiscord Skips connecting to discord + Eventually this will connect to a simulated discord instance + + dbuser The username to be used when connecting to a database type that requires one + dbpass The password used like dbuser + dbaddress The network address of the desired database + dbport The port to use with dbaddress + dbpath The path to a unix socket to substitute an address or the path to an SQLite database file + dbkind The kind of database we will be using + + use_cli Enables a CLI management interface for the bot + use_gui The GUI version of the CLI + + lua_engine_count The number of lua execution engines to create, This defaults to the number of cores the computer has + This allows executing multiple lua tasks at once, including user commands and timer tasks + + connect_remote Connect to a remote instance of the bot + host_remote Host an instance of the bot for remote connections + remote_address The remote address of the bot, or the address you wish to host the bot on + remote_port The port used like remote_address + remote_key The path or literal value of the key required to authenticate with the bot on a remote connection + remote_key_type Decides the key type for remote connections + +Remote Connections: + Remote access is disabled by default and must be enabled via the `connect_remote` or `host_remote` flags + A key is required for remote connections, if you just need something quick use the `password` key type, the password must be the same for both server and client + The key can be managed by the database as well, and the key type `database` will disable the `remote_key` variable and instead load authentication information from the server +"; \ No newline at end of file diff --git a/src/databases/access.rs b/src/databases/access.rs new file mode 100644 index 0000000..d441754 --- /dev/null +++ b/src/databases/access.rs @@ -0,0 +1,11 @@ +use std::process::exit; + +use tracing::error; + +pub fn create_interface() -> Result<(), Box> { + //warn!("You must provide both a username and password via `dbuser` and `dbpass`"); + //exit(-1); + + error!("Sorry! this database kind is not implemented right now."); + exit(-1); +} diff --git a/src/databases/mariadb.rs b/src/databases/mariadb.rs new file mode 100644 index 0000000..d441754 --- /dev/null +++ b/src/databases/mariadb.rs @@ -0,0 +1,11 @@ +use std::process::exit; + +use tracing::error; + +pub fn create_interface() -> Result<(), Box> { + //warn!("You must provide both a username and password via `dbuser` and `dbpass`"); + //exit(-1); + + error!("Sorry! this database kind is not implemented right now."); + exit(-1); +} diff --git a/src/databases/mod.rs b/src/databases/mod.rs new file mode 100644 index 0000000..8efada9 --- /dev/null +++ b/src/databases/mod.rs @@ -0,0 +1,60 @@ +use std::{ + fmt::Debug, + panic::Location, + sync::{Arc, OnceLock}, +}; + +use serenity::all::UserId; + +use crate::errors::DatabaseStoredError; + +pub mod access; +pub mod mariadb; +pub mod postgres; +pub mod sqlite; + +#[derive(Debug)] +pub enum DBKind { + Access, + SQLite, + MariaDB, + PostgreSQL, +} + +static DATABASE_ACCESSOR: OnceLock>> = OnceLock::new(); + +/// # Panics +/// This function will panic if used after the database has already been set +/// +/// You should not worry about this as this function only ever gets called once at the start of the program and you are doing something wrong if you need to call this a second time +pub fn set_db(dba: Box) { + assert!(DATABASE_ACCESSOR.set(Arc::new(dba)).is_ok(), "attempted to set database accessor after init"); +} + +/// # Panics +/// This function will panic if used before the database has been set +/// +/// You should not worry about this as this function only ever gets called after the database has been set and you are doing something wrong if you are calling this before the database is live +pub fn get_db() -> Arc> { + #[allow(clippy::expect_used)] + DATABASE_ACCESSOR.get().expect("attempted to get database before init").clone() +} + +/// This trait will provide a very high level interface to all supported databases +/// Its implementations should also sanitize all inputs regardless of what type +/// The implementation may be multithreaded/multiconnection, but for sqlite it is limited to a single thread/locked direct access to the connection via a mutex +/// If you need more performance use a different database type +pub trait DatabaseAccessor: Sync + Send { + // TODO make a db upgrade table + + fn get_db_version(&self); + + fn check_db_health(&self); + fn fix_db_health(&self); + + fn is_dev(&self, user_id: UserId) -> bool; + + fn set_dev(&self, user_id: UserId); + + fn store_error(&self, err: &DatabaseStoredError); +} diff --git a/src/databases/postgres.rs b/src/databases/postgres.rs new file mode 100644 index 0000000..d441754 --- /dev/null +++ b/src/databases/postgres.rs @@ -0,0 +1,11 @@ +use std::process::exit; + +use tracing::error; + +pub fn create_interface() -> Result<(), Box> { + //warn!("You must provide both a username and password via `dbuser` and `dbpass`"); + //exit(-1); + + error!("Sorry! this database kind is not implemented right now."); + exit(-1); +} diff --git a/src/databases/sqlite.rs b/src/databases/sqlite.rs new file mode 100644 index 0000000..7439201 --- /dev/null +++ b/src/databases/sqlite.rs @@ -0,0 +1,72 @@ +use std::{ + fmt::Debug, + sync::{Arc, Mutex}, +}; + +use sqlite::Connection; +use tracing::{error, info}; + +use crate::{errors::DatabaseStoredError, CMD_ARGS}; + +use super::DatabaseAccessor; + +struct SQLiteDatabase { + connection: Mutex, /*>*/ +} + +impl SQLiteDatabase { + //fn lock(&self) { + + //} +} + +impl Debug for SQLiteDatabase { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SQLiteDatabase")/*.field("connection", &"")*/.finish() + } +} + +impl DatabaseAccessor for SQLiteDatabase { + fn get_db_version(&self) { + todo!() + } + + fn check_db_health(&self) { + todo!() + } + + fn fix_db_health(&self) { + todo!() + } + + fn is_dev(&self, user_id: serenity::all::UserId) -> bool { + todo!() + } + + fn set_dev(&self, user_id: serenity::all::UserId) { + todo!() + } + + fn store_error(&self, err: &DatabaseStoredError) { + todo!() + } +} + +/// # Panics +/// This function will panic if used after the database has already been set +/// +/// You should not worry about this as this function only ever gets called once at the start of the program and you are doing something wrong if you need to call this a second time +pub fn create_interface() -> Result<(), Box> { + info!("Loading SQLite."); + if let Some(db_path) = CMD_ARGS.dbpath.clone() { + let connection = sqlite::open(&db_path).map_err(|err| format!("Could not open file {db_path:?} with error: {err}"))?; + + super::set_db(Box::new(SQLiteDatabase { + connection: /*Arc::new(*/Mutex::new(connection)/*)*/, + })); + + Ok(()) + } else { + Err("You must provide a path using `dbpath` for sqlite to function!".into()) + } +} diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..1ef1f83 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,40 @@ +use std::{ + fmt::Display, + panic::Location, + time::{SystemTime, UNIX_EPOCH}, +}; + +use crate::databases; + +#[derive(Debug)] +pub struct DatabaseStoredError { + epoch: u64, + caller: std::panic::Location<'static>, + cause: String, +} + +impl Display for DatabaseStoredError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("") + } +} + +impl std::error::Error for DatabaseStoredError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + None + } +} + +impl DatabaseStoredError { + #[track_caller] + pub fn new(cause: impl ToString) -> Self { + let caller = *Location::caller(); + let cause = cause.to_string(); + #[allow(clippy::unwrap_used)] // Since epoch is 0, now cannot be less than 0 as the datatype is unsigned, making this unwrap impossible to fail. + let epoch = SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs(); + + let err = Self { epoch, caller, cause }; + databases::get_db().store_error(&err); + err + } +} diff --git a/src/lua.rs b/src/lua.rs index e4a28ca..c4bd642 100644 --- a/src/lua.rs +++ b/src/lua.rs @@ -1,7 +1,25 @@ -use mlua::{Lua, LuaOptions, Result, StdLib, Table, Value, Variadic}; -use tracing::{debug, error, info, trace, warn}; +// FIXME remove later, used for now while in active development +#![allow(clippy::unwrap_used)] -use crate::constants::{CAT_DEV, CAT_FUN, CAT_GEN, CAT_INF, CAT_MOD, VERSION}; +use mlua::Lua; +use mlua::LuaOptions; +use mlua::Result; +use mlua::StdLib; +use mlua::Table; +use mlua::Value; +use mlua::Variadic; +use tracing::debug; +use tracing::error; +use tracing::info; +use tracing::trace; +use tracing::warn; + +use crate::constants::CAT_DEV; +use crate::constants::CAT_FUN; +use crate::constants::CAT_GEN; +use crate::constants::CAT_INF; +use crate::constants::CAT_MOD; +use crate::constants::VERSION; // if there is a better way please tell me or replace this garbage pub fn value_to_string(value: Value) -> String { @@ -12,22 +30,25 @@ pub fn value_to_string(value: Value) -> String { Value::Integer(int) => int.to_string(), Value::Number(num) => num.to_string(), Value::Vector(vec) => vec.to_string(), - Value::String(string2) => String::from_utf8_lossy(string2.as_bytes()).to_string(), + Value::String(string2) => string2.to_string_lossy(), Value::Table(table) => format!("{table:?}"), // could probably handle this one better but whatever Value::Function(function) => { let info = function.info(); format!( "`{}` at `{}`", info.name.map_or_else(|| "Unnamed".to_owned(), |val| val), - info.line_defined - .map_or_else(|| "Unknown location".to_owned(), |val| val.to_string()), + info.line_defined.map_or_else(|| "Unknown location".to_owned(), |val| val.to_string()), ) - } + }, Value::Thread(thread) => { format!("`{}`:`{:?}`", thread.to_pointer() as usize, thread.status()) - } + }, Value::UserData(userdata) => format!("`{userdata:?}`"), Value::Error(err) => err.to_string(), + Value::Buffer(buffer) => format!("{buffer:?}"), + // TODO figure out a better way to figure out what the reference is + // or just leave it as is because if youre converting a generic value ref to a string, what else were you expecting to happen + Value::Other(value_ref) => format!("{value_ref:?}"), } } @@ -39,40 +60,41 @@ pub fn initialize() -> Result { // may need debug to set limitations to the runtime such as execution time and iteration count let lua = Lua::new_with( StdLib::BIT | StdLib::BUFFER | StdLib::MATH | StdLib::STRING | StdLib::TABLE | StdLib::UTF8, - LuaOptions::new() - .catch_rust_panics(true) - .thread_pool_size(num_cpus::get()), + LuaOptions::new().catch_rust_panics(true).thread_pool_size(num_cpus::get()), )?; // .expect("Lua could not initialize properly"); // set max to 2mb - info!("Previous memory limit `{}`", lua.set_memory_limit(2 * 1024 * 1024)?); + let limit = 2 * 1024 * 1024; + info!("Setting memory limit to `{limit}` The previous limit was: `{}`", lua.set_memory_limit(limit)?); + + // TODO make a mapping file that is processed at compile time that dictates what gets mapped where inside the lua engines + // This can be used to easily modify what is present in the sandbox and where it is/how to use it + // Once this mapping file is stable make a plugin or editor that can use the mapping file and associated type information + // To give syntax highlighting and autofill information, as well as documentation let globals = lua.globals(); globals.set("NP_VERSION", VERSION)?; - clean_global( - #[cfg(not(debug_assertions))] - &lua, - &globals, - ); + // TODO asserts should be handled differently + // allows us to assert things in debug mode, and keep the asserts in release without hard crashing + //#[cfg(not(debug_assertions))] + //{ + //let assert = lua.create_function(|_lua, ()| Ok(())).unwrap(); + //globals.set("assert", assert).unwrap(); + //} + + clean_global(&globals); prepare_global(&lua, &globals); set_logging(&lua, &globals); - drop(globals); - Ok(lua) } -fn clean_global(#[cfg(not(debug_assertions))] lua: &Lua, globals: &Table) { - // allows us to assert things in debug mode, and keep the asserts in release without hard crashing - #[cfg(not(debug_assertions))] - { - let assert = lua.create_function(|_lua, ()| Ok(())).unwrap(); - globals.set("assert", assert).unwrap(); - } +/// Remove definitions that either A: should not be present in a sandbox, or B: we supply an alternative for to better suit the program +fn clean_global(globals: &Table) { // disabling this for now as mlua should do a decent job of collecting itself, and if not we can manage it in rust, no need for the users to worry about it globals.raw_remove("collectgarbage").unwrap(); // keep error as lua needs trace errors instead of rust like return types (its easier to keep things the way they are so we dont confuse newcomers) @@ -85,6 +107,7 @@ fn clean_global(#[cfg(not(debug_assertions))] lua: &Lua, globals: &Table) { globals.raw_remove("print").unwrap(); } +/// Fill global with our new definitions meant to either extend functionality or suppliment things we have removed fn prepare_global(lua: &Lua, globals: &Table) { let command_category_table = lua.create_table().unwrap(); command_category_table.set("dev", CAT_DEV).unwrap(); @@ -92,24 +115,26 @@ fn prepare_global(lua: &Lua, globals: &Table) { command_category_table.set("fun", CAT_FUN).unwrap(); command_category_table.set("general", CAT_GEN).unwrap(); command_category_table.set("moderation", CAT_MOD).unwrap(); - globals - .set("commandCategory", command_category_table) - .unwrap(); + globals.set("commandCategory", command_category_table).unwrap(); let sys_table = lua.create_table().unwrap(); - #[allow(clippy::deprecated_cfg_attr)] // shut up clippy thats unstable - #[cfg_attr(rustfmt, rustfmt_skip)] // wish this was comment based but whatever - { - sys_table.set("registerCommand", lua.create_function(rust_lua_functions::register_command).unwrap()).unwrap(); - sys_table.set("executeCommand", lua.create_function(rust_lua_functions::execute_command).unwrap()).unwrap(); - sys_table.set("luaValueToString", lua.create_function(rust_lua_functions::lua_value_to_string).unwrap()).unwrap(); - } + + sys_table + .set("registerCommand", lua.create_function(rust_lua_functions::register_command).unwrap()) + .unwrap(); + sys_table + .set("executeCommand", lua.create_function(rust_lua_functions::execute_command).unwrap()) + .unwrap(); + sys_table + .set("luaValueToString", lua.create_function(rust_lua_functions::lua_value_to_string).unwrap()) + .unwrap(); globals.set("sys", sys_table).unwrap(); } fn set_logging(lua: &Lua, globals: &Table) { // i wish i could loop these but i cant instantiate macros + // TODO maybe i can wrap each log tool in a function and use function pointers let log_table = lua.create_table().unwrap(); let trace = lua .create_function(|_lua, strings: Variadic| { @@ -181,15 +206,17 @@ fn set_logging(lua: &Lua, globals: &Table) { mod rust_lua_functions { use mlua::prelude::LuaResult; - use mlua::{ExternalError, Lua, Value, Variadic}; + use mlua::ExternalError; + use mlua::Lua; + use mlua::Value; + use mlua::Variadic; use tracing::info; use crate::lua::value_to_string; pub fn execute_command(_lua: &Lua, mut arg_values: Variadic) -> LuaResult<()> { - let command_name = match arg_values.get(0).cloned() { - Some(name) => name, - None => return Err("executeCommand requires a command name to execute! please supply a valid command name as the first argument.".into_lua_err()), + let Some(command_name) = arg_values.first().cloned() else { + return Err("executeCommand requires a command name to execute! please supply a valid command name as the first argument.".into_lua_err()); }; let mut command_args = vec![]; @@ -198,45 +225,23 @@ mod rust_lua_functions { match value { Value::String(string) => { command_args.push(string.to_string_lossy().to_string()); - } - Value::Nil => { - return Err( - "Nil argument provided! executeCommand accepts no nil arguments" - .into_lua_err(), - ) - } - Value::Table(_) => { - return Err("Direct run commands are not supported yet.".into_lua_err()) - } - _ => return Err( - "Invalid type used! Only `String` and `Table` are supported by executeCommand" - .into_lua_err(), - ), + }, + Value::Nil => return Err("Nil argument provided! executeCommand accepts no nil arguments".into_lua_err()), + Value::Table(_) => return Err("Direct run commands are not supported yet.".into_lua_err()), + _ => return Err("Invalid type used! Only `String` and `Table` are supported by executeCommand".into_lua_err()), } } - info!( - "Running lua command `{}` with args `{:?}`", - value_to_string(command_name), - command_args - ); + info!("Running lua command `{}` with args `{:?}`", value_to_string(command_name), command_args); Ok(()) } pub fn register_command(_lua: &Lua, arg_values: Variadic) -> LuaResult<()> { - let table = match arg_values.get(0) { + let table = match arg_values.first() { Some(Value::Table(table)) => table, - Some(Value::Nil) | None => { - return Err( - "Nil argument provided! registerCommand accepts no nil arguments" - .into_lua_err(), - ) - } + Some(Value::Nil) | None => return Err("Nil argument provided! registerCommand accepts no nil arguments".into_lua_err()), _ => { - return Err( - "Invalid type used! Only `Table` is supported by registerCommand" - .into_lua_err(), - ); - } + return Err("Invalid type used! Only `Table` is supported by registerCommand".into_lua_err()); + }, }; info!("{:?}", table); @@ -353,4 +358,3 @@ mod rust_lua_functions { // } // } // } - diff --git a/src/main.rs b/src/main.rs index ddd81ee..02b82ff 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,148 +3,247 @@ #![deny(clippy::pedantic)] #![allow(clippy::unreadable_literal)] #![allow(clippy::needless_pass_by_value)] +#![allow(clippy::unused_async)] mod arguments; mod bot; mod commands; mod constants; +mod databases; +mod errors; mod lua; mod tasks; use std::process::exit; -use std::sync::atomic::Ordering; +use std::sync::mpsc::Sender; +use std::sync::LazyLock; use std::sync::OnceLock; -use serenity::all::{Context, GuildId}; -use serenity::model::channel::Message; +use tracing::debug; +use tracing::error; +use tracing::info; use tracing::metadata::LevelFilter; +use tracing::warn; -use tracing::{error, info}; +use constants::HELP_STRING; -use commands::{Command, CommandFnKind, COMMANDS}; -use constants::CAT_HID; +use databases::DBKind; -pub static CARG_NO_DISCORD: OnceLock = OnceLock::new(); +#[derive(Debug, Clone)] +pub struct CmdArgs { + // TODO bool_bucket: u8, + pub nodiscord: bool, + pub dbuser: Option, + pub dbpass: Option, + pub dbaddress: Option, + pub dbport: Option, + pub dbpath: Option, + pub dbkind: Option, + pub use_cli: bool, + pub lua_engine_count: Option, + pub connect_remote: bool, + pub remote_address: Option, + pub remote_port: Option, + pub remote_key: Option, + pub remote_key_type: Option, +} -#[tokio::main] -async fn main() { - if let Err(err) = tracing::subscriber::set_global_default( - tracing_subscriber::fmt() - .with_max_level(LevelFilter::INFO) - .finish(), - ) { - eprintln!("Encountered an error while initializing logging! `{err}`"); - exit(1); - }; - info!("Logging initialized."); +/// In most cases this would just be a once lock or similar +/// however i dont like needing to unwrap it everywhere in the program after i know for a fact it was already initialized +/// at the start of execution and will never be written to again +/// +/// So we just force the once lock when we want to load the args like we would for a once lock +pub static CMD_ARGS: LazyLock = LazyLock::new(get_cmd_args); +/// A simple no questions asked way to shut down the bot gracefully +// maybe we should include a reason enum that includes other info? no that should be handled wherever the message is sent from +// TODO custom panic handler? +pub static SHUTDOWN_SENDER: OnceLock> = OnceLock::new(); + +#[allow(clippy::missing_panics_doc)] +pub fn shutdown_handler() { + static SHUTDOWN_COUNT: std::sync::atomic::AtomicU8 = std::sync::atomic::AtomicU8::new(1); + if SHUTDOWN_COUNT.fetch_add(1, std::sync::atomic::Ordering::SeqCst) >= 3 { + warn!("3 exit events have piled up. Forcing exit."); + std::process::exit(-1); + } + #[allow(clippy::unwrap_used)] // it is impossible for this to be an error + if let Err(err) = SHUTDOWN_SENDER.get().unwrap().send(()) { + error!("Failed to send shutdown signal: {err}"); + } +} + +pub fn get_cmd_args() -> CmdArgs { info!("Grabbing commandline input."); + let mut nodiscord = false; - for i in std::env::args() { - #[allow(clippy::single_match)] // here for convienience when adding additional flags - match i.as_str() { - "nodiscord" => nodiscord = true, - _ => {} + let mut dbuser = None; + let mut dbpass = None; + let mut dbaddress = None; + let mut dbport = None; + let mut dbpath = None; + let mut dbkind = None; + let mut use_cli = false; + let mut lua_engine_count = None; + let mut connect_remote = false; + let mut remote_address = None; + let mut remote_port = None; + let mut remote_key = None; + let mut remote_key_type = None; + + let mut args = std::env::args().peekable(); + + // The first arg is the path to the executable on all systems that i know of + // But this is not always guaranteed, however this program does not expect file paths as the first element so we can safely skip it if the path exists + // We could check this to see if it matches our environment executable path but that needs too much error handling for something like this + if let Some(argpath) = args.peek() { + if std::path::PathBuf::from(argpath).exists() { + args.next(); } } - if let Err(err) = CARG_NO_DISCORD.set(nodiscord) { - error!("Encountered an error while setting the `nodiscord` flag! `{err}`"); - exit(1); + + while let Some(item) = args.next() { + match item.to_lowercase().trim() { + // Execution args + "help" | "-h" | "--help" | "-help" | "/help" | "/h" | "?" | "/?" => { + info!("{HELP_STRING}"); + exit(0); + }, + // Data args + "nodiscord" => nodiscord = true, + "dbuser" => dbuser = args.next(), + "dbpass" => dbpass = args.next(), + "dbaddress" => dbaddress = args.next(), + "dbport" => dbport = args.next(), + "dbpath" => dbpath = args.next(), + "dbkind" => dbkind = args.next(), + "use_cli" => use_cli = true, + "lua_engine_count" => lua_engine_count = args.next(), + "connect_remote" => connect_remote = true, + "remote_address" => remote_address = args.next(), + "remote_port" => remote_port = args.next(), + "remote_key" => remote_key = args.next(), + "remote_key_type" => remote_key_type = args.next(), + value => warn!("Unknown or misplaced value: {value}"), // TODO move help argument here? + } + } + + CmdArgs { + nodiscord, + dbuser, + dbpass, + dbaddress, + dbport, + dbpath, + dbkind, + use_cli, + lua_engine_count, + connect_remote, + remote_address, + remote_port, + remote_key, + remote_key_type, + } +} + +// TODO remove async from the main function and restrict its usage to just the discord bot +// We can manually manage worker threads everywhere else, especially with the lua engines +#[tokio::main] +async fn main() { + // why do we need to set global default again? + tracing_subscriber::fmt() + .compact() + .with_timer(tracing_subscriber::fmt::time::uptime()) + .with_ansi(true) + .with_level(true) + .with_file(cfg!(debug_assertions)) + .with_line_number(cfg!(debug_assertions)) + .with_thread_names(cfg!(debug_assertions)) + .with_max_level(if cfg!(debug_assertions) { LevelFilter::DEBUG } else { LevelFilter::INFO }) + .init(); + info!("Logging initialized."); + + // Manually init the lazy lock + LazyLock::force(&CMD_ARGS); + debug!("{:?}", *CMD_ARGS); + + let (shutdown_tx, shutdown_rx) = std::sync::mpsc::channel(); + #[allow(clippy::unwrap_used)] // it is impossible for this to be an error + SHUTDOWN_SENDER.set(shutdown_tx.clone()).unwrap(); + #[allow(clippy::unwrap_used)] // it is impossible for this to be an error + tasks::SHUTDOWN_RECEIVER.set(tokio::sync::Mutex::new(shutdown_rx)).unwrap(); + + if let Err(err) = ctrlc::set_handler(shutdown_handler) { + error!("Error setting Ctrl-C handler: {err}"); + } + + let dbkind = if let Some(arg) = &CMD_ARGS.dbkind { + info!("Loading database accessor."); + match arg.to_lowercase().trim() { + "access" => DBKind::Access, + "postgresql" => DBKind::PostgreSQL, + "sqlite" => DBKind::SQLite, + "mariadb" => DBKind::MariaDB, + _ => { + error!("Invalid database kind! Choose one of `sqlite` `mariadb` `postgresql` `access`"); + exit(-1); + }, + } + } else { + warn!("You must select a database kind with `dbkind`"); + exit(-1); }; + if let Err(err) = match dbkind { + DBKind::Access => databases::access::create_interface(), + DBKind::MariaDB => databases::mariadb::create_interface(), + DBKind::PostgreSQL => databases::postgres::create_interface(), + DBKind::SQLite => databases::sqlite::create_interface(), + } { + error!("Could not start database {dbkind:?} with error: {err}"); + exit(-1); + } + + // TODO if the db is new fill it with data + // TODO if the db health check fails or is old attempt backup and upgrade + info!("Loading stock commands."); - insert_stock().await; + commands::insert_stock().await; info!("Loading rust dynamic commands."); - insert_rust(); + commands::insert_rust(); - info!("Initializing Lua runtime."); - let lua = match lua::initialize() { - Ok(lua) => lua, - Err(err) => { - error!("Encountered an error while initializing lua! `{err}`"); - exit(1); - }, - }; // may not need to be mutable, but its fine for now + // TODO lua mpmc with N lua engines, use the fire and forget strategy, lua engines should handle their own errors! and using a custom panic hook they should be replaced on death! - if let Err(err) = lua - .load(include_str!("../lua/loader.lua")) - .set_name("loader.lua") - .exec() - { - error!("Encountered an error while running loader.lua: {err}"); - }; + // TODO lua::init_lua(); + //info!("Loading lua commandlets."); + //insert_lua(&lua); - info!("Loading lua commandlets."); - insert_lua(&lua); + // old - if let Err(err) = lua.sandbox(true) { - error!("Encountered an error while setting the lua runtime to sandbox mode! `{err}`"); - exit(1); - }; + //info!("Initializing Lua runtime."); + //let lua = match lua::initialize() { + // Ok(lua) => lua, + // Err(err) => { + // error!("Encountered an error while initializing lua! `{err}`"); + // exit(1); + // }, + //}; + + //if let Err(err) = lua.load(include_str!("../lua/loader.lua")).set_name("loader.lua").exec() { + // error!("Encountered an error while running loader.lua: {err}"); + //} + + //info!("Loading lua commandlets."); + //insert_lua(&lua); + + //if let Err(err) = lua.sandbox(true) { + // error!("Encountered an error while setting the lua runtime to sandbox mode! `{err}`"); + // exit(1); + //} + + if CMD_ARGS.use_cli { + // TODO create cli interface for bot + } bot::start().await; } - -/// The last set of commands, these are used by the hoster of the engine. -pub fn insert_lua(_lua: &mlua::Lua) { - // commands.insert( - // "stop".to_owned(), - // Command::new("stop".to_owned()) - // .alias("svs".to_owned()) - // .category(CAT_HID.to_owned()) - // .hidden(true) - // .dm_command(CommandFnKind::Rust(stop_command)) - // .guild_command(CommandFnKind::Rust(stop_command)) - // .pretty_name("Stop the bot".to_owned()) - // .help("Stops the bot. Does nothing unless you are a developer.".to_owned()), - // ); -} - -/// Cannot use any command names of stock commands, but gets to pick before lua commands are loaded. -pub fn insert_rust() { - // commands.insert( - // "stop".to_owned(), - // Command::new("stop".to_owned()) - // .alias("svs".to_owned()) - // .category(CAT_HID.to_owned()) - // .hidden(true) - // .dm_command(CommandFnKind::Rust(stop_command)) - // .guild_command(CommandFnKind::Rust(stop_command)) - // .pretty_name("Stop the bot".to_owned()) - // .help("Stops the bot. Does nothing unless you are a developer.".to_owned()), - // ); -} - -/// Will never fail, gets first pick of command names and properties. It is up to the maintainer to make damn sure this works. -pub async fn insert_stock() { - COMMANDS.write().await.insert( - "stop".to_owned(), - Command::new("stop".to_owned()) - .alias("svs".to_owned()) - .category(CAT_HID.to_owned()) - .hidden(true) - .dm_command(CommandFnKind::Rust(stop_command)) - .guild_command(CommandFnKind::Rust(stop_command)) - .pretty_name("Stop the bot".to_owned()) - .help("Stops the bot. Does nothing unless you are a developer.".to_owned()), - ); -} - -fn stop_command(_: Context, msg: Message, _: Option) { - // hardcode my id for now - if msg.author.id != 380045419381784576 { - return; - } - bot::DO_SHUTDOWN.0.store(true, Ordering::SeqCst); - bot::DO_SHUTDOWN.1.notify_all(); - - let handle = tokio::runtime::Handle::current(); - let _eg = handle.enter(); - - handle.spawn(async { - // this is literally impossible to fail as the SHARD_MANAGER is required to exist for this function to ever run - #[allow(clippy::unwrap_used)] - bot::SHARD_MANAGER.get().unwrap().shutdown_all().await; - }); -} - diff --git a/src/tasks.rs b/src/tasks.rs index 936fff3..0fe1685 100644 --- a/src/tasks.rs +++ b/src/tasks.rs @@ -1,17 +1,31 @@ -use crate::{bot::SHARD_MANAGER, constants}; -use std::{ - sync::{Arc, LazyLock}, - time::Duration, -}; +use std::collections::hash_map::HashMap; +use std::sync::Arc; +use std::sync::LazyLock; +use std::sync::OnceLock; +use std::time::Duration; -use ::std::collections::hash_map::HashMap; -use rand::{distributions::uniform::SampleRange, rngs::OsRng}; -use serenity::all::{ActivityData, Cache, Context, ShardId, ShardRunnerInfo}; -use tokio::{sync::Mutex, task::JoinHandle}; +use rand::Rng; +use rand::SeedableRng; + +use serenity::all::ActivityData; +use serenity::all::Cache; +use serenity::all::Context; +use serenity::all::ShardId; +use serenity::all::ShardRunnerInfo; + +use tokio::sync::Mutex; +use tokio::task::JoinHandle; + +use tracing::error; use tracing::info; +use tracing::warn; -static TASK_HANDLES: LazyLock>> = - LazyLock::new(|| Arc::new(Mutex::new(TaskContainer::default()))); +use crate::bot::SHARD_MANAGER; +use crate::constants; + +// TODO remove SHUTDOWN_RECEIVER from static memory +pub static SHUTDOWN_RECEIVER: OnceLock>> = OnceLock::new(); +static TASK_HANDLES: LazyLock>> = LazyLock::new(|| Arc::new(Mutex::new(TaskContainer::default()))); #[derive(Debug, Default)] pub struct TaskContainer { @@ -21,24 +35,64 @@ pub struct TaskContainer { pub async fn start_tasks(ctx: Context) { info!("Starting MISC tasks."); - info!("Starting activity switcher task."); + info!("Starting activity switcher task..."); + let Some(sharts) = SHARD_MANAGER.get() else { + error!("Could not obtain the shard manager."); + return; + }; TASK_HANDLES .lock() .await .misc - .push(tokio::spawn(status_timer( - SHARD_MANAGER.get().unwrap().runners.clone(), - ctx.cache, - ))); + .push(tokio::spawn(status_timer(sharts.runners.clone(), ctx.cache))); + info!("Starting forum task..."); + TASK_HANDLES.lock().await.misc.push(tokio::spawn(forum_checker())); + info!("Starting shutdown monitor task..."); + TASK_HANDLES.lock().await.misc.push(tokio::spawn(shutdown_monitor())); info!("MISC tasks started."); + + warn!("Task health checker is currently unimplemented!"); + warn!("If a task panics we will not be able to restart it or fix any issues!"); } -pub async fn status_timer( - shard_runners: Arc>>, - cache: Arc, -) { - let mut rand = OsRng::default(); +async fn forum_checker() { + let mut interval = tokio::time::interval(Duration::from_millis(16)); + + loop { + interval.tick().await; + } +} + +pub async fn check_forum() {} + +async fn shutdown_monitor() { + // TODO tokio interval waiting may be more efficient than just a recv on an std mpsc + // tokio mpsc may be better than both as the std mpsc may halt the tokio task + // without letting it yeild properly + + //let mut interval = tokio::time::interval(Duration::from_millis(16)); + #[allow(clippy::unwrap_used)] // it is impossible for this to be an error + let lock = SHUTDOWN_RECEIVER.get().unwrap().lock().await; + //loop { + if lock.recv().is_ok() { + warn!("The bot is shutting down now!"); + + crate::bot::DO_SHUTDOWN.store(true, std::sync::atomic::Ordering::SeqCst); + + // TODO wait till all existing actions are completed or timeout + + // impossible to fail + #[allow(clippy::unwrap_used)] + crate::bot::SHARD_MANAGER.get().unwrap().shutdown_all().await; + //break; + } + //interval.tick().await; + //} +} + +async fn status_timer(shard_runners: Arc>>, cache: Arc) { + // TODO make this a vec and able to be updated from external sources like lua engines, maybe static let activities = [ ActivityData::watching("my developer eat a watermelon whole."), ActivityData::watching(format!( @@ -50,13 +104,12 @@ pub async fn status_timer( ActivityData::listening("Infected Mushroom"), ]; let mut interval = tokio::time::interval(Duration::from_secs(20 * 60)); - + let mut rand = rand::rngs::SmallRng::from_os_rng(); + loop { - let activity = SampleRange::sample_single(0..activities.len() - 1, &mut rand); + let activity = rand.random_range(0..activities.len() - 1); for (_shard_id, shard_info) in shard_runners.lock().await.iter() { - shard_info - .runner_tx - .set_activity(Some(activities[activity].clone())); + shard_info.runner_tx.set_activity(Some(activities[activity].clone())); } interval.tick().await;