diff --git a/.env.example b/.env.example index 4085678..b29eca2 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,6 @@ # Logging (env_logger) ----------------------------------------------------------------------------------- -RUST_LOG="rotom_discord_bot=debug" +RUST_LOG="cipher_discord_bot=debug" # Discord ------------------------------------------------------------------------------------------------ diff --git a/Cargo.lock b/Cargo.lock index 778f8eb..67d97ea 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,6 +32,21 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anstream" version = "0.6.18" @@ -82,6 +97,15 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +dependencies = [ + "serde", +] + [[package]] name = "async-trait" version = "0.1.85" @@ -90,7 +114,7 @@ checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -122,7 +146,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -164,7 +188,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn", + "syn 2.0.96", ] [[package]] @@ -203,6 +227,12 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "bytecount" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" + [[package]] name = "byteorder" version = "1.5.0" @@ -215,6 +245,37 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" +[[package]] +name = "camino" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", +] + [[package]] name = "cc" version = "1.2.10" @@ -241,6 +302,56 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[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.6", +] + +[[package]] +name = "cipher_core" +version = "0.1.0" +dependencies = [ + "async-trait", +] + +[[package]] +name = "cipher_database" +version = "0.1.0" +dependencies = [ + "async-trait", + "cipher_core", + "diesel", + "diesel-async", + "diesel_migrations", + "thiserror 2.0.11", +] + +[[package]] +name = "cipher_discord_bot" +version = "0.1.0" +dependencies = [ + "cipher_core", + "cipher_database", + "clap 4.5.27", + "dotenvy", + "env_logger", + "humantime", + "log", + "poise", + "secrecy 0.10.3", + "serenity", + "thiserror 2.0.11", + "tokio", +] + [[package]] name = "clang-sys" version = "1.8.1" @@ -298,7 +409,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -331,6 +442,33 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +[[package]] +name = "command_attr" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fcc89439e1bb4e19050a9586a767781a3060000d2f3296fd2a40597ad9421c5" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cpufeatures" version = "0.2.16" @@ -436,7 +574,7 @@ dependencies = [ "proc-macro2", "quote", "strsim 0.11.1", - "syn", + "syn 2.0.96", ] [[package]] @@ -447,9 +585,29 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn", + "syn 2.0.96", ] +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", + "serde", +] + +[[package]] +name = "data-encoding" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e60eed09d8c01d3cee5b7d30acb059b76614c918fa0f992e0dd6eeb10daad6f" + [[package]] name = "deranged" version = "0.3.11" @@ -457,6 +615,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -505,7 +675,7 @@ dependencies = [ "dsl_auto_type", "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -525,7 +695,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" dependencies = [ - "syn", + "syn 2.0.96", ] [[package]] @@ -547,7 +717,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -570,7 +740,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -579,6 +749,15 @@ 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", +] + [[package]] name = "env_filter" version = "0.1.3" @@ -608,12 +787,37 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "error-chain" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc" +dependencies = [ + "version_check", +] + [[package]] name = "fallible-iterator" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + [[package]] name = "flate2" version = "1.0.35" @@ -645,6 +849,20 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -661,6 +879,12 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + [[package]] name = "futures-macro" version = "0.3.31" @@ -669,7 +893,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -690,15 +914,27 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -717,7 +953,19 @@ 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]] @@ -732,12 +980,37 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.7.1", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "hashbrown" version = "0.15.2" @@ -773,12 +1046,118 @@ dependencies = [ "digest", ] +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "icu_collections" version = "1.5.0" @@ -894,7 +1273,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -944,6 +1323,12 @@ dependencies = [ "hashbrown 0.15.2", ] +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + [[package]] name = "is_terminal_polyfill" version = "1.70.1" @@ -999,6 +1384,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "levenshtein" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760" + [[package]] name = "libc" version = "0.2.169" @@ -1012,7 +1403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -1025,6 +1416,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + [[package]] name = "litemap" version = "0.7.4" @@ -1093,6 +1490,37 @@ dependencies = [ "quote", ] +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "mini-moka" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c325dfab65f261f386debee8b0969da215b3fa0037e74c8a1234db7ba986d803" +dependencies = [ + "crossbeam-channel", + "crossbeam-utils", + "dashmap", + "skeptic", + "smallvec", + "tagptr", + "triomphe", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -1115,7 +1543,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -1276,7 +1704,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -1330,7 +1758,7 @@ checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -1351,6 +1779,35 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" +[[package]] +name = "poise" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1819d5a45e3590ef33754abce46432570c54a120798bdbf893112b4211fa09a6" +dependencies = [ + "async-trait", + "derivative", + "futures-util", + "parking_lot", + "poise_macros", + "regex", + "serenity", + "tokio", + "tracing", +] + +[[package]] +name = "poise_macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fa2c123c961e78315cd3deac7663177f12be4460f5440dbf62a7ed37b1effea" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.96", +] + [[package]] name = "postgres-protocol" version = "0.6.7" @@ -1413,6 +1870,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "pulldown-cmark" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" +dependencies = [ + "bitflags 2.8.0", + "memchr", + "unicase", +] + [[package]] name = "quote" version = "1.0.38" @@ -1449,7 +1917,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] @@ -1491,37 +1959,62 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] -name = "rotom_core" -version = "0.1.0" +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "async-trait", -] - -[[package]] -name = "rotom_database" -version = "0.1.0" -dependencies = [ - "async-trait", - "diesel", - "diesel-async", - "diesel_migrations", - "rotom_core", - "thiserror 2.0.11", -] - -[[package]] -name = "rotom_discord_bot" -version = "0.1.0" -dependencies = [ - "clap 4.5.27", - "dotenvy", - "env_logger", + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", "log", - "rotom_core", - "rotom_database", - "secrecy", - "thiserror 2.0.11", + "mime", + "mime_guess", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.12", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", "tokio", + "tokio-rustls 0.24.1", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots 0.25.4", + "winreg", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.15", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", ] [[package]] @@ -1536,12 +2029,102 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.8.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki 0.101.7", + "sct", +] + +[[package]] +name = "rustls" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" +dependencies = [ + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-pki-types" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" + [[package]] name = "ryu" version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "saturating" version = "0.1.0" @@ -1563,6 +2146,26 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "serde", + "zeroize", +] + [[package]] name = "secrecy" version = "0.10.3" @@ -1572,6 +2175,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "semver" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" +dependencies = [ + "serde", +] + [[package]] name = "serde" version = "1.0.217" @@ -1581,6 +2193,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde_cow" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7bbbec7196bfde255ab54b65e34087c0849629280028238e67ee25d6a4b7da" +dependencies = [ + "serde", +] + [[package]] name = "serde_derive" version = "1.0.217" @@ -1589,7 +2210,7 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -1613,6 +2234,55 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serenity" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d72ec4323681bf9a3cabe40fd080abc2435859b502a1b5aa9bf693f125bfa76" +dependencies = [ + "arrayvec", + "async-trait", + "base64 0.22.1", + "bitflags 2.8.0", + "bytes", + "chrono", + "command_attr", + "dashmap", + "flate2", + "futures", + "fxhash", + "levenshtein", + "mime_guess", + "parking_lot", + "percent-encoding", + "reqwest", + "secrecy 0.8.0", + "serde", + "serde_cow", + "serde_json", + "static_assertions", + "time", + "tokio", + "tokio-tungstenite", + "tracing", + "typemap_rev", + "typesize", + "url", + "uwl", +] + [[package]] name = "sha1" version = "0.10.6" @@ -1656,6 +2326,21 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" +[[package]] +name = "skeptic" +version = "0.13.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d23b015676c90a0f01c197bfdc786c20342c73a0afdda9025adb0bc42940a8" +dependencies = [ + "bytecount", + "cargo_metadata", + "error-chain", + "glob", + "pulldown-cmark", + "tempfile", + "walkdir", +] + [[package]] name = "slab" version = "0.4.9" @@ -1681,6 +2366,12 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1732,6 +2423,17 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.96" @@ -1743,6 +2445,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "synstructure" version = "0.13.1" @@ -1751,7 +2459,48 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "tempfile" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91" +dependencies = [ + "cfg-if", + "fastrand", + "getrandom 0.3.1", + "once_cell", + "rustix", + "windows-sys 0.59.0", ] [[package]] @@ -1795,7 +2544,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -1806,7 +2555,7 @@ checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -1891,7 +2640,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -1920,6 +2669,43 @@ dependencies = [ "whoami", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.4", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +dependencies = [ + "futures-util", + "log", + "rustls 0.22.4", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.25.0", + "tungstenite", + "webpki-roots 0.26.7", +] + [[package]] name = "tokio-util" version = "0.7.13" @@ -1967,6 +2753,77 @@ dependencies = [ "winnow", ] +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", +] + +[[package]] +name = "triomphe" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.2.0", + "httparse", + "log", + "rand", + "rustls 0.22.4", + "rustls-pki-types", + "sha1", + "thiserror 1.0.69", + "url", + "utf-8", +] + [[package]] name = "twox-hash" version = "1.6.3" @@ -1978,12 +2835,53 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "typemap_rev" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74b08b0c1257381af16a5c3605254d529d3e7e109f3c62befc5d168968192998" + [[package]] name = "typenum" version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "typesize" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20304d891be0766f52123746c721d1190b953e874f9eccf29067a64c1a0ae16c" +dependencies = [ + "chrono", + "dashmap", + "hashbrown 0.14.5", + "mini-moka", + "parking_lot", + "secrecy 0.8.0", + "serde_json", + "time", + "typesize-derive", + "url", +] + +[[package]] +name = "typesize-derive" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "536b6812192bda8551cfa0e52524e328c6a951b48e66529ee4522d6c721243d6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.96", +] + +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + [[package]] name = "unicode-bidi" version = "0.3.18" @@ -2011,6 +2909,12 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.4" @@ -2020,8 +2924,15 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + [[package]] name = "utf16_iter" version = "1.0.5" @@ -2046,6 +2957,12 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "744018581f9a3454a9e15beb8a33b017183f1e7c0cd170232a2d1453b23a51c4" +[[package]] +name = "uwl" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4bf03e0ca70d626ecc4ba6b0763b934b6f2976e8c744088bb3c1d646fbb1ad0" + [[package]] name = "vcpkg" version = "0.2.15" @@ -2058,12 +2975,40 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasite" version = "0.1.0" @@ -2078,6 +3023,7 @@ checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", "once_cell", + "rustversion", "wasm-bindgen-macro", ] @@ -2091,10 +3037,23 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn", + "syn 2.0.96", "wasm-bindgen-shared", ] +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasm-bindgen-macro" version = "0.2.100" @@ -2113,7 +3072,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2127,6 +3086,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "web-sys" version = "0.3.77" @@ -2137,6 +3109,21 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "webpki-roots" +version = "0.26.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "whoami" version = "1.5.2" @@ -2179,13 +3166,31 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + [[package]] name = "windows-sys" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -2194,7 +3199,22 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -2203,28 +3223,46 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -2237,24 +3275,48 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -2270,6 +3332,25 @@ dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags 2.8.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -2302,7 +3383,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", "synstructure", ] @@ -2324,7 +3405,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] @@ -2344,7 +3425,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", "synstructure", ] @@ -2373,7 +3454,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.96", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index aaab1f2..6a7d3ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ resolver = "2" members = [ - "rotom_core", - "rotom_database", "rotom_discord_bot", + "cipher_core", + "cipher_database", + "cipher_discord_bot", ] diff --git a/README.md b/README.md index 4fcb86b..fb3978c 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# rotom \ No newline at end of file +# cipher diff --git a/rotom_core/Cargo.toml b/cipher_core/Cargo.toml similarity index 80% rename from rotom_core/Cargo.toml rename to cipher_core/Cargo.toml index b63dd04..5a778dc 100644 --- a/rotom_core/Cargo.toml +++ b/cipher_core/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "rotom_core" +name = "cipher_core" version = "0.1.0" edition = "2021" diff --git a/rotom_core/src/lib.rs b/cipher_core/src/lib.rs similarity index 100% rename from rotom_core/src/lib.rs rename to cipher_core/src/lib.rs diff --git a/rotom_core/src/repository/mod.rs b/cipher_core/src/repository/mod.rs similarity index 76% rename from rotom_core/src/repository/mod.rs rename to cipher_core/src/repository/mod.rs index 6014f82..016f2e7 100644 --- a/rotom_core/src/repository/mod.rs +++ b/cipher_core/src/repository/mod.rs @@ -1,3 +1,5 @@ +use std::fmt::Display; + use user_repository::UserRepository; pub mod user_repository; @@ -22,3 +24,12 @@ where #[derive(Debug)] pub struct RepositoryError(pub E); + +impl Display for RepositoryError +where + E: Display, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} diff --git a/rotom_core/src/repository/user_repository.rs b/cipher_core/src/repository/user_repository.rs similarity index 100% rename from rotom_core/src/repository/user_repository.rs rename to cipher_core/src/repository/user_repository.rs diff --git a/rotom_database/Cargo.toml b/cipher_database/Cargo.toml similarity index 90% rename from rotom_database/Cargo.toml rename to cipher_database/Cargo.toml index ca10854..793d38f 100644 --- a/rotom_database/Cargo.toml +++ b/cipher_database/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "rotom_database" +name = "cipher_database" version = "0.1.0" edition = "2021" @@ -8,7 +8,7 @@ async-trait = "0.1.85" diesel = { version = "2.2.6", default-features = false } diesel-async = { version = "0.5.2", features = ["bb8"] } diesel_migrations = "2.2.0" -rotom_core = { path = "../rotom_core" } +cipher_core = { path = "../cipher_core" } thiserror = "2.0.11" [features] diff --git a/rotom_database/build.rs b/cipher_database/build.rs similarity index 100% rename from rotom_database/build.rs rename to cipher_database/build.rs diff --git a/rotom_database/diesel_mysql.toml b/cipher_database/diesel_mysql.toml similarity index 100% rename from rotom_database/diesel_mysql.toml rename to cipher_database/diesel_mysql.toml diff --git a/rotom_database/diesel_postgres.toml b/cipher_database/diesel_postgres.toml similarity index 100% rename from rotom_database/diesel_postgres.toml rename to cipher_database/diesel_postgres.toml diff --git a/rotom_database/diesel_sqlite.toml b/cipher_database/diesel_sqlite.toml similarity index 100% rename from rotom_database/diesel_sqlite.toml rename to cipher_database/diesel_sqlite.toml diff --git a/rotom_database/migrations/mysql/.keep b/cipher_database/migrations/mysql/.keep similarity index 100% rename from rotom_database/migrations/mysql/.keep rename to cipher_database/migrations/mysql/.keep diff --git a/rotom_database/migrations/mysql/2025-01-29-032332_create_users/down.sql b/cipher_database/migrations/mysql/2025-01-29-032332_create_users/down.sql similarity index 100% rename from rotom_database/migrations/mysql/2025-01-29-032332_create_users/down.sql rename to cipher_database/migrations/mysql/2025-01-29-032332_create_users/down.sql diff --git a/rotom_database/migrations/mysql/2025-01-29-032332_create_users/up.sql b/cipher_database/migrations/mysql/2025-01-29-032332_create_users/up.sql similarity index 100% rename from rotom_database/migrations/mysql/2025-01-29-032332_create_users/up.sql rename to cipher_database/migrations/mysql/2025-01-29-032332_create_users/up.sql diff --git a/rotom_database/migrations/postgres/.keep b/cipher_database/migrations/postgres/.keep similarity index 100% rename from rotom_database/migrations/postgres/.keep rename to cipher_database/migrations/postgres/.keep diff --git a/rotom_database/migrations/postgres/00000000000000_diesel_initial_setup/down.sql b/cipher_database/migrations/postgres/00000000000000_diesel_initial_setup/down.sql similarity index 100% rename from rotom_database/migrations/postgres/00000000000000_diesel_initial_setup/down.sql rename to cipher_database/migrations/postgres/00000000000000_diesel_initial_setup/down.sql diff --git a/rotom_database/migrations/postgres/00000000000000_diesel_initial_setup/up.sql b/cipher_database/migrations/postgres/00000000000000_diesel_initial_setup/up.sql similarity index 100% rename from rotom_database/migrations/postgres/00000000000000_diesel_initial_setup/up.sql rename to cipher_database/migrations/postgres/00000000000000_diesel_initial_setup/up.sql diff --git a/rotom_database/migrations/postgres/2025-01-29-032258_create_users/down.sql b/cipher_database/migrations/postgres/2025-01-29-032258_create_users/down.sql similarity index 100% rename from rotom_database/migrations/postgres/2025-01-29-032258_create_users/down.sql rename to cipher_database/migrations/postgres/2025-01-29-032258_create_users/down.sql diff --git a/rotom_database/migrations/postgres/2025-01-29-032258_create_users/up.sql b/cipher_database/migrations/postgres/2025-01-29-032258_create_users/up.sql similarity index 100% rename from rotom_database/migrations/postgres/2025-01-29-032258_create_users/up.sql rename to cipher_database/migrations/postgres/2025-01-29-032258_create_users/up.sql diff --git a/rotom_database/migrations/sqlite/.keep b/cipher_database/migrations/sqlite/.keep similarity index 100% rename from rotom_database/migrations/sqlite/.keep rename to cipher_database/migrations/sqlite/.keep diff --git a/rotom_database/migrations/sqlite/2025-01-29-032217_create_users/down.sql b/cipher_database/migrations/sqlite/2025-01-29-032217_create_users/down.sql similarity index 100% rename from rotom_database/migrations/sqlite/2025-01-29-032217_create_users/down.sql rename to cipher_database/migrations/sqlite/2025-01-29-032217_create_users/down.sql diff --git a/rotom_database/migrations/sqlite/2025-01-29-032217_create_users/up.sql b/cipher_database/migrations/sqlite/2025-01-29-032217_create_users/up.sql similarity index 100% rename from rotom_database/migrations/sqlite/2025-01-29-032217_create_users/up.sql rename to cipher_database/migrations/sqlite/2025-01-29-032217_create_users/up.sql diff --git a/rotom_database/src/lib.rs b/cipher_database/src/lib.rs similarity index 100% rename from rotom_database/src/lib.rs rename to cipher_database/src/lib.rs diff --git a/rotom_database/src/mysql/mod.rs b/cipher_database/src/mysql/mod.rs similarity index 100% rename from rotom_database/src/mysql/mod.rs rename to cipher_database/src/mysql/mod.rs diff --git a/rotom_database/src/mysql/repository/mod.rs b/cipher_database/src/mysql/repository/mod.rs similarity index 89% rename from rotom_database/src/mysql/repository/mod.rs rename to cipher_database/src/mysql/repository/mod.rs index fb9e5d7..d63ca44 100644 --- a/rotom_database/src/mysql/repository/mod.rs +++ b/cipher_database/src/mysql/repository/mod.rs @@ -1,9 +1,9 @@ use diesel_async::pooled_connection::bb8::Pool; use diesel_async::pooled_connection::bb8::PooledConnection; use diesel_async::AsyncMysqlConnection; -use rotom_core::repository::Repository; -use rotom_core::repository::RepositoryError; -use rotom_core::repository::RepositoryProvider; +use cipher_core::repository::Repository; +use cipher_core::repository::RepositoryError; +use cipher_core::repository::RepositoryProvider; use crate::BackendError; diff --git a/rotom_database/src/mysql/repository/user_repository.rs b/cipher_database/src/mysql/repository/user_repository.rs similarity index 95% rename from rotom_database/src/mysql/repository/user_repository.rs rename to cipher_database/src/mysql/repository/user_repository.rs index 2887d59..2bc4d4f 100644 --- a/rotom_database/src/mysql/repository/user_repository.rs +++ b/cipher_database/src/mysql/repository/user_repository.rs @@ -2,10 +2,10 @@ use diesel::prelude::*; use diesel_async::scoped_futures::ScopedFutureExt; use diesel_async::AsyncConnection; use diesel_async::RunQueryDsl; -use rotom_core::repository::user_repository::NewUser; -use rotom_core::repository::user_repository::User; -use rotom_core::repository::user_repository::UserRepository; -use rotom_core::repository::RepositoryError; +use cipher_core::repository::user_repository::NewUser; +use cipher_core::repository::user_repository::User; +use cipher_core::repository::user_repository::UserRepository; +use cipher_core::repository::RepositoryError; use crate::mysql::schema::users; use crate::BackendError; diff --git a/rotom_database/src/mysql/schema.rs b/cipher_database/src/mysql/schema.rs similarity index 100% rename from rotom_database/src/mysql/schema.rs rename to cipher_database/src/mysql/schema.rs diff --git a/rotom_database/src/postgres/mod.rs b/cipher_database/src/postgres/mod.rs similarity index 100% rename from rotom_database/src/postgres/mod.rs rename to cipher_database/src/postgres/mod.rs diff --git a/rotom_database/src/postgres/repository/mod.rs b/cipher_database/src/postgres/repository/mod.rs similarity index 89% rename from rotom_database/src/postgres/repository/mod.rs rename to cipher_database/src/postgres/repository/mod.rs index 805c622..ec555cb 100644 --- a/rotom_database/src/postgres/repository/mod.rs +++ b/cipher_database/src/postgres/repository/mod.rs @@ -1,9 +1,9 @@ use diesel_async::pooled_connection::bb8::Pool; use diesel_async::pooled_connection::bb8::PooledConnection; use diesel_async::AsyncPgConnection; -use rotom_core::repository::Repository; -use rotom_core::repository::RepositoryError; -use rotom_core::repository::RepositoryProvider; +use cipher_core::repository::Repository; +use cipher_core::repository::RepositoryError; +use cipher_core::repository::RepositoryProvider; use crate::BackendError; diff --git a/rotom_database/src/postgres/repository/user_repository.rs b/cipher_database/src/postgres/repository/user_repository.rs similarity index 95% rename from rotom_database/src/postgres/repository/user_repository.rs rename to cipher_database/src/postgres/repository/user_repository.rs index d92a3e9..fed0025 100644 --- a/rotom_database/src/postgres/repository/user_repository.rs +++ b/cipher_database/src/postgres/repository/user_repository.rs @@ -2,10 +2,10 @@ use diesel::prelude::*; use diesel_async::scoped_futures::ScopedFutureExt; use diesel_async::AsyncConnection; use diesel_async::RunQueryDsl; -use rotom_core::repository::user_repository::NewUser; -use rotom_core::repository::user_repository::User; -use rotom_core::repository::user_repository::UserRepository; -use rotom_core::repository::RepositoryError; +use cipher_core::repository::user_repository::NewUser; +use cipher_core::repository::user_repository::User; +use cipher_core::repository::user_repository::UserRepository; +use cipher_core::repository::RepositoryError; use crate::postgres::schema::users; use crate::BackendError; diff --git a/rotom_database/src/postgres/schema.rs b/cipher_database/src/postgres/schema.rs similarity index 100% rename from rotom_database/src/postgres/schema.rs rename to cipher_database/src/postgres/schema.rs diff --git a/rotom_database/src/sqlite/mod.rs b/cipher_database/src/sqlite/mod.rs similarity index 100% rename from rotom_database/src/sqlite/mod.rs rename to cipher_database/src/sqlite/mod.rs diff --git a/rotom_database/src/sqlite/repository/mod.rs b/cipher_database/src/sqlite/repository/mod.rs similarity index 90% rename from rotom_database/src/sqlite/repository/mod.rs rename to cipher_database/src/sqlite/repository/mod.rs index df99f8e..0198811 100644 --- a/rotom_database/src/sqlite/repository/mod.rs +++ b/cipher_database/src/sqlite/repository/mod.rs @@ -2,9 +2,9 @@ use diesel::SqliteConnection; use diesel_async::pooled_connection::bb8::Pool; use diesel_async::pooled_connection::bb8::PooledConnection; use diesel_async::sync_connection_wrapper::SyncConnectionWrapper; -use rotom_core::repository::Repository; -use rotom_core::repository::RepositoryError; -use rotom_core::repository::RepositoryProvider; +use cipher_core::repository::Repository; +use cipher_core::repository::RepositoryError; +use cipher_core::repository::RepositoryProvider; use crate::BackendError; diff --git a/rotom_database/src/sqlite/repository/user_repository.rs b/cipher_database/src/sqlite/repository/user_repository.rs similarity index 95% rename from rotom_database/src/sqlite/repository/user_repository.rs rename to cipher_database/src/sqlite/repository/user_repository.rs index 6462703..b591fce 100644 --- a/rotom_database/src/sqlite/repository/user_repository.rs +++ b/cipher_database/src/sqlite/repository/user_repository.rs @@ -2,10 +2,10 @@ use diesel::prelude::*; use diesel_async::scoped_futures::ScopedFutureExt; use diesel_async::AsyncConnection; use diesel_async::RunQueryDsl; -use rotom_core::repository::user_repository::NewUser; -use rotom_core::repository::user_repository::User; -use rotom_core::repository::user_repository::UserRepository; -use rotom_core::repository::RepositoryError; +use cipher_core::repository::user_repository::NewUser; +use cipher_core::repository::user_repository::User; +use cipher_core::repository::user_repository::UserRepository; +use cipher_core::repository::RepositoryError; use crate::sqlite::schema::users; use crate::BackendError; diff --git a/rotom_database/src/sqlite/schema.rs b/cipher_database/src/sqlite/schema.rs similarity index 100% rename from rotom_database/src/sqlite/schema.rs rename to cipher_database/src/sqlite/schema.rs diff --git a/rotom_discord_bot/Cargo.toml b/cipher_discord_bot/Cargo.toml similarity index 53% rename from rotom_discord_bot/Cargo.toml rename to cipher_discord_bot/Cargo.toml index 34dd80d..bf28553 100644 --- a/rotom_discord_bot/Cargo.toml +++ b/cipher_discord_bot/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "rotom_discord_bot" +name = "cipher_discord_bot" version = "0.1.0" edition = "2021" @@ -7,15 +7,18 @@ edition = "2021" clap = { version = "4.5.27", features = ["derive", "env"] } dotenvy = { version = "0.15.7", features = ["clap"] } env_logger = "0.11.6" +humantime = "2.1.0" log = "0.4.25" -rotom_core = { path = "../rotom_core" } -rotom_database = { path = "../rotom_database", default-features = false } +poise = "0.6.1" +cipher_core = { path = "../cipher_core" } +cipher_database = { path = "../cipher_database", default-features = false } secrecy = "0.10.3" +serenity = "0.12.4" thiserror = "2.0.11" tokio = { version = "1.43.0", features = ["full"] } [features] default = ["mysql", "postgres", "sqlite"] -mysql = ["rotom_database/mysql"] -postgres = ["rotom_database/postgres"] -sqlite = ["rotom_database/sqlite"] +mysql = ["cipher_database/mysql"] +postgres = ["cipher_database/postgres"] +sqlite = ["cipher_database/sqlite"] diff --git a/cipher_discord_bot/src/app/event_handler.rs b/cipher_discord_bot/src/app/event_handler.rs new file mode 100644 index 0000000..e9e2fed --- /dev/null +++ b/cipher_discord_bot/src/app/event_handler.rs @@ -0,0 +1,30 @@ +use cipher_core::repository::RepositoryProvider; +use serenity::all::FullEvent; + +use crate::utils; + +use super::AppData; +use super::AppError; + +pub async fn event_handler( + serenity_ctx: &serenity::client::Context, + event: &FullEvent, + framework_ctx: poise::FrameworkContext<'_, AppData, AppError>, + _data: &AppData, +) -> Result<(), AppError> { + match event { + FullEvent::Ready { data_about_bot } => { + log::info!( + "Connected as {} in {} guild(s).", + data_about_bot.user.name, + data_about_bot.guilds.len() + ); + } + FullEvent::CacheReady { guilds } => { + utils::register_in_guilds(serenity_ctx, &framework_ctx.options.commands, guilds).await; + } + _ => {} + } + + Ok(()) +} diff --git a/cipher_discord_bot/src/app/framework.rs b/cipher_discord_bot/src/app/framework.rs new file mode 100644 index 0000000..7d8ef1b --- /dev/null +++ b/cipher_discord_bot/src/app/framework.rs @@ -0,0 +1,41 @@ +use poise::Framework; +use poise::FrameworkOptions; +use cipher_core::repository::RepositoryProvider; + +use crate::commands; + +use super::event_handler; +use super::on_error; +use super::AppData; +use super::AppError; + +pub fn framework(repository_provider: R) -> Framework, AppError> +where + R: RepositoryProvider + Send + Sync + 'static, + R::BackendError: Send + Sync, + for<'a> R::Repository<'a>: Send + Sync, +{ + let commands = commands::commands(); + + let app_data = AppData { + repository_provider, + }; + + let options = FrameworkOptions::, AppError> { + commands, + on_error: |framework_error| { + Box::pin(async move { on_error::on_error(framework_error).await }) + }, + event_handler: |serenity_ctx, event, framework_ctx, data| { + Box::pin(async move { + event_handler::event_handler(serenity_ctx, event, framework_ctx, data).await + }) + }, + ..Default::default() + }; + + Framework::builder() + .options(options) + .setup(|_ctx, _ready, _framework| Box::pin(async move { Ok(app_data) })) + .build() +} diff --git a/cipher_discord_bot/src/app/mod.rs b/cipher_discord_bot/src/app/mod.rs new file mode 100644 index 0000000..93624b4 --- /dev/null +++ b/cipher_discord_bot/src/app/mod.rs @@ -0,0 +1,63 @@ +use cipher_core::repository::RepositoryError; +use cipher_core::repository::RepositoryProvider; +use secrecy::ExposeSecret; +use serenity::all::GatewayIntents; +use serenity::Client; + +use crate::cli::DiscordCredentials; + +mod event_handler; +mod framework; +mod on_error; + +#[derive(Debug, thiserror::Error)] +pub enum AppStartError { + #[error(transparent)] + SerenityError(#[from] serenity::Error), +} + +pub struct AppData { + repository_provider: R, +} + +#[derive(Debug, thiserror::Error)] +pub enum AppError { + #[error(transparent)] + SerenityError(#[from] serenity::Error), + #[error(transparent)] + RepositoryError(#[from] RepositoryError), +} + +pub type AppContext<'a, R, E> = poise::ApplicationContext<'a, AppData, AppError>; +pub type AppCommand = poise::Command, AppError>; + +pub async fn start(credentials: DiscordCredentials, repository_provider: R) -> Result<(), AppStartError> +where + R: RepositoryProvider + Send + Sync + 'static, + R::BackendError: Send + Sync, + for<'a> R::Repository<'a>: Send + Sync, +{ + let mut client = Client::builder(credentials.bot_token.expose_secret(), GatewayIntents::all()) + .framework(framework::framework(repository_provider)) + .await?; + + let shard_manager = client.shard_manager.clone(); + tokio::spawn(async move { + if let Err(err) = tokio::signal::ctrl_c().await { + log::error!("Failed to register ctrl+c handler: {}", err); + } + log::info!("Stopping."); + shard_manager.shutdown_all().await; + }); + + client.start().await.map_err(AppStartError::from) +} + +impl AppData +where + R: RepositoryProvider, +{ + pub async fn repository(&self) -> Result, RepositoryError> { + self.repository_provider.get().await + } +} diff --git a/cipher_discord_bot/src/app/on_error.rs b/cipher_discord_bot/src/app/on_error.rs new file mode 100644 index 0000000..9091ff3 --- /dev/null +++ b/cipher_discord_bot/src/app/on_error.rs @@ -0,0 +1,298 @@ +use cipher_core::repository::RepositoryError; +use cipher_core::repository::RepositoryProvider; +use poise::CreateReply; +use poise::FrameworkError; +use serenity::all::Color; +use serenity::all::CreateEmbed; +use serenity::all::Permissions; + +use super::AppData; +use super::AppError; + +struct ErrorMessage { + embed: Option, + log: Option, +} + +struct ErrorEmbed { + title: String, + description: String, +} + +struct ErrorLog { + message: String, + log_level: log::Level, +} + +impl ErrorMessage { + fn new(title: T, description: D, message: M, log_level: log::Level) -> Self + where + T: ToString, + D: ToString, + M: ToString, + { + Self { + embed: Some(ErrorEmbed { title: title.to_string(), description: description.to_string() }), + log: Some(ErrorLog { message: message.to_string(), log_level }), + } + } +} + +#[rustfmt::skip] +pub async fn on_error(framework_error: FrameworkError<'_, AppData, AppError>) +where + R: RepositoryProvider, +{ + let ctx = framework_error.ctx(); + + let error_data = ErrorMessage::from(framework_error); + + match error_data.log { + Some(ErrorLog { message, log_level: log::Level::Trace }) => log::trace!("{}", message), + Some(ErrorLog { message, log_level: log::Level::Debug }) => log::debug!("{}", message), + Some(ErrorLog { message, log_level: log::Level::Info }) => log::info!("{}", message), + Some(ErrorLog { message, log_level: log::Level::Warn }) => log::warn!("{}", message), + Some(ErrorLog { message, log_level: log::Level::Error }) => log::error!("{}", message), + None => {}, + } + + if let Some((ctx, ErrorEmbed { title, description })) = ctx.zip(error_data.embed) { + let embed = CreateEmbed::new() + .title(title) + .description(description) + .color(Color::RED); + + let reply = CreateReply::default() + .embed(embed) + .ephemeral(true); + + ctx.send(reply).await.ok(); + } +} + +impl<'a, R> From, AppError>> for ErrorMessage +where + R: RepositoryProvider, +{ + fn from(value: FrameworkError<'a, AppData, AppError>) -> ErrorMessage { + use FrameworkError as F; + + fn format_permissions(permissions: Permissions) -> String { + permissions + .iter_names() + .map(|(name, _)| format!("`{}`", name)) + .collect::>() + .join(", ") + } + + #[allow(unused)] + match value { + F::Setup { error, framework, data_about_bot, ctx, .. } => error.into(), + F::EventHandler { error, ctx, event, framework, .. } => error.into(), + F::Command { error, ctx, .. } => error.into(), + F::SubcommandRequired { ctx } => ErrorMessage::new( + "Expected Subcommand", + format!("Expected subcommand for `/{}`. Please contact a bot administrator to review the logs for further details.", ctx.command().qualified_name), + format!("expected subcommand for `/{}`. this error has likely occurred due to the application commands not being synced with discord.", ctx.command().qualified_name), + log::Level::Error, + ), + F::CommandPanic { ctx, payload, .. } => ErrorMessage::new( + "A Panic Has Occurred", + "A panic has occurred during command execution. Please contact a bot administrator to review the logs for further details.", + format!("panic in command `{}`: {}", ctx.command().qualified_name, payload.unwrap_or_else(|| "Unknown panic".to_string())), + log::Level::Error, + ), + F::ArgumentParse { error, input, ctx, .. } => ErrorMessage::new( + "Argument Parse Error", + "Failed to parse argument in command. Please contact a bot administrator to review the logs for further details.", + format!("failed to parse argument in command `{}` on input {:?}", ctx.command().qualified_name, input), + log::Level::Error, + ), + F::CommandStructureMismatch { description, ctx, .. } => ErrorMessage::new( + "Command Structure Mismatch", + "Unexpected application command structure. Please contact a bot administrator to review the logs for further details.", + format!("unexpected application command structure in command `{}`: {}", ctx.command.qualified_name, description), + log::Level::Error, + ), + F::CooldownHit { remaining_cooldown, ctx, .. } => ErrorMessage::new( + "Cooldown Hit", + format!("You can't use that command right now. Try again in {}.", humantime::format_duration(remaining_cooldown)), + format!("cooldown hit in command `{}` ({:?} remaining)", ctx.command().qualified_name, remaining_cooldown), + log::Level::Info, + ), + F::MissingBotPermissions { missing_permissions, ctx, .. } => ErrorMessage::new( + "Insufficient Bot Permissions", + format!("The bot is missing the following permissions: {}.", format_permissions(missing_permissions)), + format!("bot is missing permissions ({}) to execute command `{}`", missing_permissions, ctx.command().qualified_name), + log::Level::Info, + ), + F::MissingUserPermissions { missing_permissions, ctx, .. } => ErrorMessage::new( + "Insufficient User Permissions", + missing_permissions + .map(|p| format!("You are missing the following permissions: {}.", format_permissions(p))) + .unwrap_or_else(|| "Failed to get user permissions.".to_string()), + format!("user is or may be missing permissions ({:?}) to execute command `{}`", missing_permissions, ctx.command().qualified_name), + log::Level::Info, + ), + F::NotAnOwner { ctx, .. } => ErrorMessage::new( + "Owner Only Command", + format!("`/{}` can only be used by bot owners.", ctx.command().qualified_name), + format!("owner-only command `{}` cannot be run by non-owners", ctx.command().qualified_name), + log::Level::Info, + ), + F::GuildOnly { ctx, .. } => ErrorMessage::new( + "Guild Only Command", + format!("`/{}` can only be used in a server.", ctx.command().qualified_name), + format!("guild-only command `{}` cannot be run in DMs", ctx.command().qualified_name), + log::Level::Info, + ), + F::DmOnly { ctx, .. } => ErrorMessage::new( + "Direct Message Only Command", + format!("`/{}` can only be used in direct messages.", ctx.command().qualified_name), + format!("DM-only command `{}` cannot be run in DMs", ctx.command().qualified_name), + log::Level::Info, + ), + F::NsfwOnly { ctx, .. } => ErrorMessage::new( + "NSFW Only Command", + format!("`/{}` can only be used in channels marked as NSFW.", ctx.command().qualified_name), + format!("nsfw-only command `{}` cannot be run in non-nsfw channels", ctx.command().qualified_name), + log::Level::Info, + ), + F::CommandCheckFailed { error, ctx, .. } => error.map(Into::into).unwrap_or_else(|| ErrorMessage::new( + "Command Check Failed", + "A pre-command check failed without a reason. Please contact a bot administrator to review the logs for further details.", + format!("pre-command check for command `{}` either denied access or errored without a reason", ctx.command().qualified_name), + log::Level::Warn, + )), + F::DynamicPrefix { error, ctx, msg, .. } => ErrorMessage::new( + "Dynamic Prefix Error", + format!("Dynamic prefix callback error on message {:?}", msg.content), + format!("dynamic prefix callback error on message {:?}", msg.content), + log::Level::Error, + ), + F::UnknownCommand { ctx, msg, prefix, msg_content, framework, invocation_data, trigger, .. } => ErrorMessage::new( + "Unknown Command", + format!("Unknown command `{}`", msg_content), + format!("unknown command `{}`", msg_content), + log::Level::Error, + ), + F::UnknownInteraction { ctx, framework, interaction, .. } => ErrorMessage::new( + "Unknown Interaction", + format!("Unknown interaction `{}`", interaction.data.name), + format!("unknown interaction `{}`", interaction.data.name), + log::Level::Error, + ), + unknown_error => ErrorMessage::new( + "Unexpected Error", + "An unexpected error has occurred. Please contact a bot administrator to review the logs for further details.", + format!("unknown error: {}", unknown_error), + log::Level::Error, + ), + } + } +} + +impl From> for ErrorMessage +where + E: std::error::Error, +{ + fn from(value: AppError) -> ErrorMessage { + use AppError as A; + use serenity::Error as S; + + #[allow(unused)] + match value { + A::SerenityError(S::Decode(msg, value)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + msg, + log::Level::Error, + ), + A::SerenityError(S::Format(error)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + error, + log::Level::Error, + ), + A::SerenityError(S::Io(error)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + error, + log::Level::Error, + ), + A::SerenityError(S::Json(error)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + error, + log::Level::Error, + ), + A::SerenityError(S::Model(error)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + error, + log::Level::Error, + ), + A::SerenityError(S::ExceededLimit(_, _)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + "input exceeded a limit", + log::Level::Error, + ), + A::SerenityError(S::NotInRange(_, _, _, _)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + "input is not in the specified range", + log::Level::Error, + ), + A::SerenityError(S::Other(msg)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + msg, + log::Level::Error, + ), + A::SerenityError(S::Url(msg)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + msg, + log::Level::Error, + ), + A::SerenityError(S::Client(error)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + error, + log::Level::Error, + ), + A::SerenityError(S::Gateway(error)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + error, + log::Level::Error, + ), + A::SerenityError(S::Http(http_error)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + http_error, + log::Level::Error, + ), + A::SerenityError(S::Tungstenite(error)) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + error, + log::Level::Error, + ), + A::SerenityError(unknown_error) => ErrorMessage::new( + "Internal Error", + "Please contact a bot administrator to review the logs for further details.", + format!("unknown error: {}", unknown_error), + log::Level::Error, + ), + + A::RepositoryError(RepositoryError(error)) => ErrorMessage::new( + "Repository Backend Error", + "Please contact a bot administrator to review the logs for further details.", + format!("repository backend error: {}", error), + log::Level::Error, + ), + } + } +} diff --git a/rotom_discord_bot/src/cli/command.rs b/cipher_discord_bot/src/cli/command.rs similarity index 100% rename from rotom_discord_bot/src/cli/command.rs rename to cipher_discord_bot/src/cli/command.rs diff --git a/rotom_discord_bot/src/cli/mod.rs b/cipher_discord_bot/src/cli/mod.rs similarity index 96% rename from rotom_discord_bot/src/cli/mod.rs rename to cipher_discord_bot/src/cli/mod.rs index 6b0cb83..2dbb63c 100644 --- a/rotom_discord_bot/src/cli/mod.rs +++ b/cipher_discord_bot/src/cli/mod.rs @@ -43,7 +43,7 @@ pub fn parse() -> Result { /// because `Dotenv` disables them and `Cli` requires them to be enabled. #[derive(Debug, Parser)] #[command( - name = "rotom", + name = "cipher", about, version, long_about = None, @@ -97,9 +97,9 @@ pub enum DatabaseDialect { Sqlite, } -impl From for rotom_database::DatabaseDialect { +impl From for cipher_database::DatabaseDialect { fn from(value: DatabaseDialect) -> Self { - use rotom_database::DatabaseDialect as Dialect; + use cipher_database::DatabaseDialect as Dialect; match value { #[cfg(feature = "mysql")] DatabaseDialect::Mysql => Dialect::Mysql, diff --git a/rotom_discord_bot/src/cli/start.rs b/cipher_discord_bot/src/cli/start.rs similarity index 74% rename from rotom_discord_bot/src/cli/start.rs rename to cipher_discord_bot/src/cli/start.rs index 4647b1e..b725e0d 100644 --- a/rotom_discord_bot/src/cli/start.rs +++ b/cipher_discord_bot/src/cli/start.rs @@ -19,9 +19,9 @@ pub struct Start { #[derive(Debug, thiserror::Error)] pub enum StartError { #[error(transparent)] - RepositoryBackendError(#[from] rotom_database::BackendError), + RepositoryBackendError(#[from] cipher_database::BackendError), #[error(transparent)] - AppError(#[from] crate::app::AppError), + AppError(#[from] crate::app::AppStartError), } impl Start { @@ -34,24 +34,24 @@ impl Start { #[cfg(feature = "mysql")] crate::cli::DatabaseDialect::Mysql => { log::info!("Running any pending database migrations."); - rotom_database::mysql::run_pending_migrations(database_url)?; - let repository_provider = rotom_database::mysql::repository_provider(database_url).await?; + cipher_database::mysql::run_pending_migrations(database_url)?; + let repository_provider = cipher_database::mysql::repository_provider(database_url).await?; log::info!("Starting discord application."); crate::app::start(self.discord, repository_provider).await?; }, #[cfg(feature = "postgres")] crate::cli::DatabaseDialect::Postgres => { log::info!("Running any pending database migrations."); - rotom_database::postgres::run_pending_migrations(database_url)?; - let repository_provider = rotom_database::postgres::repository_provider(database_url).await?; + cipher_database::postgres::run_pending_migrations(database_url)?; + let repository_provider = cipher_database::postgres::repository_provider(database_url).await?; log::info!("Starting discord application."); crate::app::start(self.discord, repository_provider).await?; }, #[cfg(feature = "sqlite")] crate::cli::DatabaseDialect::Sqlite => { log::info!("Running any pending database migrations."); - rotom_database::sqlite::run_pending_migrations(database_url)?; - let repository_provider = rotom_database::sqlite::repository_provider(database_url).await?; + cipher_database::sqlite::run_pending_migrations(database_url)?; + let repository_provider = cipher_database::sqlite::repository_provider(database_url).await?; log::info!("Starting discord application."); crate::app::start(self.discord, repository_provider).await?; }, diff --git a/cipher_discord_bot/src/commands/mod.rs b/cipher_discord_bot/src/commands/mod.rs new file mode 100644 index 0000000..5256dbf --- /dev/null +++ b/cipher_discord_bot/src/commands/mod.rs @@ -0,0 +1,14 @@ +use cipher_core::repository::RepositoryProvider; + +use crate::app::AppCommand; + +mod ping; + +pub fn commands() -> Vec> +where + R: RepositoryProvider + Send + Sync + 'static, +{ + vec![ + ping::ping(), + ] +} diff --git a/cipher_discord_bot/src/commands/ping.rs b/cipher_discord_bot/src/commands/ping.rs new file mode 100644 index 0000000..cf03644 --- /dev/null +++ b/cipher_discord_bot/src/commands/ping.rs @@ -0,0 +1,22 @@ +use poise::CreateReply; +use cipher_core::repository::RepositoryProvider; +use serenity::all::CreateEmbed; + +use crate::app::AppContext; +use crate::app::AppError; +use crate::utils; + +/// Is the bot alive or dead? :thinking: +#[poise::command(slash_command)] +pub async fn ping(ctx: AppContext<'_, R, R::BackendError>) -> Result<(), AppError> { + let embed = CreateEmbed::new() + .title("Pong :ping_pong:") + .color(utils::bot_color(&ctx).await); + + let reply = CreateReply::default() + .embed(embed); + + ctx.send(reply).await?; + + Ok(()) +} diff --git a/rotom_discord_bot/src/main.rs b/cipher_discord_bot/src/main.rs similarity index 93% rename from rotom_discord_bot/src/main.rs rename to cipher_discord_bot/src/main.rs index eb4b672..143094b 100644 --- a/rotom_discord_bot/src/main.rs +++ b/cipher_discord_bot/src/main.rs @@ -1,5 +1,7 @@ mod app; mod cli; +mod commands; +mod utils; #[derive(Debug, thiserror::Error)] enum MainError { diff --git a/cipher_discord_bot/src/utils.rs b/cipher_discord_bot/src/utils.rs new file mode 100644 index 0000000..4eeccf6 --- /dev/null +++ b/cipher_discord_bot/src/utils.rs @@ -0,0 +1,35 @@ +use cipher_core::repository::RepositoryProvider; +use serenity::all::{Color, GuildId}; + +use crate::app::{AppCommand, AppContext}; + +pub async fn register_in_guilds( + serenity_ctx: &serenity::client::Context, + commands: &[AppCommand], + guilds: &[GuildId], +) +where + R: RepositoryProvider, +{ + for guild in guilds { + let result = poise::builtins::register_in_guild(serenity_ctx, commands, *guild).await; + match (guild.name(serenity_ctx), result) { + (None, Err(err)) => log::warn!("Failed to register command in guild with id {}: {}", guild.get().to_string(), err), + (None, Ok(())) => log::info!("Successfully registered commands in guild with id {}", guild.get().to_string()), + (Some(guild_name), Err(err)) => log::warn!("Failed to register command in guild with id {} ({}): {}", guild.get().to_string(), guild_name, err), + (Some(guild_name), Ok(())) => log::info!("Successfully registered commands in guild with id {} ({})", guild.get().to_string(), guild_name), + } + } +} + +pub async fn bot_color(ctx: &AppContext<'_, R, R::BackendError>) -> Color +where + R: RepositoryProvider + Send + Sync, +{ + let member = match ctx.guild_id() { + Some(guild) => guild.member(ctx, ctx.framework.bot_id).await.ok(), + None => None, + }; + + member.and_then(|m| m.colour(ctx)).unwrap_or(Color::BLURPLE) +} diff --git a/rotom_discord_bot/src/app/mod.rs b/rotom_discord_bot/src/app/mod.rs deleted file mode 100644 index cac89c4..0000000 --- a/rotom_discord_bot/src/app/mod.rs +++ /dev/null @@ -1,17 +0,0 @@ -use rotom_core::repository::RepositoryProvider; - -use crate::cli::DiscordCredentials; - -#[derive(Debug, thiserror::Error)] -pub enum AppError { - -} - -pub async fn start(_credentials: DiscordCredentials, _repository_provider: R) -> Result<(), AppError> -where - R: RepositoryProvider + Send + Sync + 'static, - R::BackendError: Send + Sync, - for<'a> R::Repository<'a>: Send + Sync, -{ - todo!() -}