diff --git a/Cargo.lock b/Cargo.lock index ca93e67..830913b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,19 +3,25 @@ version = 3 [[package]] -name = "aho-corasick" -version = "0.7.15" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" dependencies = [ "memchr", ] [[package]] name = "ansi_term" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ "winapi", ] @@ -26,6 +32,33 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "async-trait" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-tungstenite" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7cc5408453d37e2b1c6f01d8078af1da58b6cfa6a80fa2ede3bd2b9a6ada9c4" +dependencies = [ + "futures-io", + "futures-util", + "log", + "pin-project", + "tokio", + "tokio-rustls 0.22.0", + "tungstenite 0.11.1", + "webpki-roots 0.20.0", +] + [[package]] name = "atty" version = "0.2.14" @@ -43,6 +76,12 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "base64" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" + [[package]] name = "base64" version = "0.13.0" @@ -51,9 +90,9 @@ checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "block-buffer" @@ -75,16 +114,34 @@ dependencies = [ ] [[package]] -name = "byteorder" -version = "1.4.2" +name = "bumpalo" +version = "3.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" +checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "bytes" -version = "1.0.1" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040" +checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "cc" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" [[package]] name = "cfg-if" @@ -101,16 +158,16 @@ dependencies = [ "libc", "num-integer", "num-traits 0.2.14", - "serde 1.0.124", - "time", + "serde 1.0.130", + "time 0.1.44", "winapi", ] [[package]] name = "clap" -version = "2.33.3" +version = "2.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" dependencies = [ "ansi_term", "atty", @@ -141,7 +198,7 @@ dependencies = [ "lazy_static", "nom", "rust-ini", - "serde 1.0.124", + "serde 1.0.130", "serde-hjson", "serde_json", "toml", @@ -149,16 +206,35 @@ dependencies = [ ] [[package]] -name = "cpuid-bool" -version = "0.1.2" +name = "core-foundation" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8aebca1129a03dc6dc2b127edd729435bbc4a37e1d5f4d7513165089ceb02634" +checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] [[package]] name = "crc32fast" -version = "1.2.1" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" dependencies = [ "cfg-if", ] @@ -195,12 +271,48 @@ dependencies = [ "generic-array", ] +[[package]] +name = "encoding_rs" +version = "0.8.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.0.1" @@ -223,9 +335,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.13" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f55667319111d593ba876406af7c409c0ebb44dc4be6132a783ccf163ea14c1" +checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e" dependencies = [ "futures-channel", "futures-core", @@ -237,9 +349,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.13" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c2dd2df839b57db9ab69c2c9d8f3e8c81984781937fe2807dc6dcf3b2ad2939" +checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27" dependencies = [ "futures-core", "futures-sink", @@ -247,37 +359,40 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.13" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15496a72fabf0e62bdc3df11a59a3787429221dd0710ba8ef163d6f7a9112c94" +checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445" [[package]] name = "futures-io" -version = "0.3.13" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71c2c65c57704c32f5241c1223167c2c3294fd34ac020c807ddbe6db287ba59" +checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11" [[package]] name = "futures-sink" -version = "0.3.13" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85754d98985841b7d4f5e8e6fbfa4a4ac847916893ec511a2917ccd8525b8bb3" +checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af" [[package]] name = "futures-task" -version = "0.3.13" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa189ef211c15ee602667a6fcfe1c1fd9e07d42250d2156382820fba33c9df80" +checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12" [[package]] name = "futures-util" -version = "0.3.13" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1812c7ab8aedf8d6f2701a43e1243acdbcc2b36ab26e2ad421eb99ac963d96d1" +checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -311,7 +426,7 @@ dependencies = [ "geoffrey_models", "log", "rand 0.8.4", - "serde 1.0.124", + "serde 1.0.130", "serde_json", "simple_logger", "structopt", @@ -319,6 +434,22 @@ dependencies = [ "warp", ] +[[package]] +name = "geoffrey_bot" +version = "0.1.0" +dependencies = [ + "async-trait", + "config", + "geoffrey_models", + "reqwest", + "serde 1.0.130", + "serde_json", + "serde_plain", + "serenity", + "structopt", + "tokio", +] + [[package]] name = "geoffrey_db" version = "0.1.0" @@ -327,7 +458,7 @@ dependencies = [ "geoffrey_models", "lazy_static", "log", - "serde 1.0.124", + "serde 1.0.130", "serde_json", "simple_logger", "sled", @@ -338,7 +469,7 @@ name = "geoffrey_models" version = "0.1.0" dependencies = [ "chrono", - "serde 1.0.124", + "serde 1.0.130", "serde_json", ] @@ -355,9 +486,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ "cfg-if", "libc", @@ -366,11 +497,11 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.1" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d832b01df74254fe364568d6ddc294443f61cbec82816b60904303af87efae78" +checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55" dependencies = [ - "bytes", + "bytes 1.1.0", "fnv", "futures-core", "futures-sink", @@ -385,24 +516,24 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.9.1" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" [[package]] name = "headers" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0b7591fb62902706ae8e7aaff416b1b0fa2c0fd0878b46dc13baa3712d8a855" +checksum = "a4c4eb0471fcb85846d8b0690695ef354f9afb11cb03cac2e1d7c9253351afb0" dependencies = [ - "base64", + "base64 0.13.0", "bitflags", - "bytes", + "bytes 1.1.0", "headers-core", "http", + "httpdate", "mime", "sha-1", - "time", ] [[package]] @@ -416,62 +547,63 @@ dependencies = [ [[package]] name = "heck" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cbf45460356b7deeb5e3415b5563308c0a9b057c85e12b06ad551f98d0a6ac" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" dependencies = [ "unicode-segmentation", ] [[package]] name = "hermit-abi" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" dependencies = [ "libc", ] [[package]] name = "http" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7245cd7449cc792608c3c8a9eaf69bd4eabbabf802713748fd739c98b82f0747" +checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" dependencies = [ - "bytes", + "bytes 1.1.0", "fnv", "itoa", ] [[package]] name = "http-body" -version = "0.4.0" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2861bd27ee074e5ee891e8b539837a9430012e249d7f0ca2d795650f579c1994" +checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" dependencies = [ - "bytes", + "bytes 1.1.0", "http", + "pin-project-lite", ] [[package]] name = "httparse" -version = "1.3.5" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "615caabe2c3160b313d52ccc905335f4ed5f10881dd63dc5699d47e90be85691" +checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" [[package]] name = "httpdate" -version = "0.3.2" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" +checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.4" +version = "0.14.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e946c2b1349055e0b72ae281b238baf1a3ea7307c7e9f9d64673bdd9c26ac7" +checksum = "436ec0091e4f20e655156a30a0df3770fe2900aa301e548e08446ec794b6953c" dependencies = [ - "bytes", + "bytes 1.1.0", "futures-channel", "futures-core", "futures-util", @@ -481,7 +613,7 @@ dependencies = [ "httparse", "httpdate", "itoa", - "pin-project", + "pin-project-lite", "socket2", "tokio", "tower-service", @@ -490,10 +622,36 @@ dependencies = [ ] [[package]] -name = "idna" -version = "0.2.2" +name = "hyper-rustls" +version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89829a5d69c23d348314a7ac337fe39173b61149a9864deabd260983aed48c21" +checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" +dependencies = [ + "http", + "hyper", + "rustls 0.20.2", + "tokio", + "tokio-rustls 0.23.1", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes 1.1.0", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" dependencies = [ "matches", "unicode-bidi", @@ -502,9 +660,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "1.6.2" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" dependencies = [ "autocfg", "hashbrown", @@ -512,27 +670,42 @@ dependencies = [ [[package]] name = "input_buffer" -version = "0.4.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f97967975f448f1a7ddb12b0bc41069d09ed6a1c161a92687e057325db35d413" +checksum = "19a8a95243d5a0398cae618ec29477c6e3cb631152be5c19481f80bc71559754" dependencies = [ - "bytes", + "bytes 0.5.6", ] [[package]] name = "instant" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ "cfg-if", ] [[package]] -name = "itoa" -version = "0.4.7" +name = "ipnet" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736" +checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "js-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +dependencies = [ + "wasm-bindgen", +] [[package]] name = "lazy_static" @@ -555,9 +728,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.107" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbe5e23404da5b4f555ef85ebed98fb4083e55a00c317800bc2a50ede9f3d219" +checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" [[package]] name = "linked-hash-map" @@ -585,21 +758,21 @@ dependencies = [ [[package]] name = "matches" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "memchr" -version = "2.3.4" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] name = "memoffset" -version = "0.6.1" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" dependencies = [ "autocfg", ] @@ -621,10 +794,20 @@ dependencies = [ ] [[package]] -name = "mio" -version = "0.7.9" +name = "miniz_oxide" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5dede4e2065b3842b8b0af444119f3aa331cc7cc2dd20388bfb0f5d5a38823a" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "mio" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" dependencies = [ "libc", "log", @@ -635,19 +818,18 @@ dependencies = [ [[package]] name = "miow" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a33c1b55807fbed163481b5ba66db4b2fa6cde694a5027be10fb724206c5897" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" dependencies = [ - "socket2", "winapi", ] [[package]] name = "multipart" -version = "0.17.1" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d050aeedc89243f5347c3e237e3e13dc76fbe4ae3742a57b94dc14f69acf76d4" +checksum = "00dec633863867f29cb39df64a397cdf4a6354708ddd7759f70c7fb51c5f9182" dependencies = [ "buf_redux", "httparse", @@ -655,12 +837,30 @@ dependencies = [ "mime", "mime_guess", "quick-error", - "rand 0.7.3", + "rand 0.8.4", "safemem", "tempfile", "twoway", ] +[[package]] +name = "native-tls" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "nom" version = "5.1.2" @@ -721,9 +921,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af8b08b04175473088b46763e51ee54da5f9a164bc162f615b91bc179dbf15a3" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" [[package]] name = "opaque-debug" @@ -731,6 +931,39 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-sys", +] + +[[package]] +name = "openssl-probe" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" + +[[package]] +name = "openssl-sys" +version = "0.9.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73" +dependencies = [ + "autocfg", + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "parking_lot" version = "0.11.2" @@ -764,18 +997,18 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" [[package]] name = "pin-project" -version = "1.0.5" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96fa8ebb90271c4477f144354485b8068bd8f6b78b428b01ba892ca26caf0b63" +checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.0.5" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758669ae3558c6f74bd2a18b41f7ac0b5a195aea6639d6a9b5e5d1ad5ba24c0b" +checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" dependencies = [ "proc-macro2", "quote", @@ -784,9 +1017,9 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e1f259c92177c30a4c9d177246edd0a3568b25756a977d0632cf8fa37e905" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" [[package]] name = "pin-utils" @@ -795,10 +1028,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "ppv-lite86" -version = "0.2.10" +name = "pkg-config" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f" + +[[package]] +name = "ppv-lite86" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" [[package]] name = "proc-macro-error" @@ -826,9 +1065,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.24" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e0704ee1a7e00d7bb417d0770ea303c1bccbabf0ef1667dae92b5967f5f8a71" +checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" dependencies = [ "unicode-xid", ] @@ -841,9 +1080,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" dependencies = [ "proc-macro2", ] @@ -868,9 +1107,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" dependencies = [ "libc", - "rand_chacha 0.3.0", - "rand_core 0.6.2", - "rand_hc 0.3.0", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", ] [[package]] @@ -885,12 +1124,12 @@ dependencies = [ [[package]] name = "rand_chacha" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core 0.6.2", + "rand_core 0.6.3", ] [[package]] @@ -904,11 +1143,11 @@ dependencies = [ [[package]] name = "rand_core" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" dependencies = [ - "getrandom 0.2.2", + "getrandom 0.2.3", ] [[package]] @@ -922,11 +1161,11 @@ dependencies = [ [[package]] name = "rand_hc" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" dependencies = [ - "rand_core 0.6.2", + "rand_core 0.6.3", ] [[package]] @@ -940,9 +1179,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.4.6" +version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a26af418b574bd56588335b3a3659a65725d4e636eb1016c2f9e3b38c7cc759" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ "aho-corasick", "memchr", @@ -964,6 +1203,63 @@ dependencies = [ "winapi", ] +[[package]] +name = "reqwest" +version = "0.11.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bea77bc708afa10e59905c3d4af7c8fd43c9214251673095ff8b14345fcbc5" +dependencies = [ + "base64 0.13.0", + "bytes 1.1.0", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "lazy_static", + "log", + "mime", + "mime_guess", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls 0.20.2", + "rustls-pemfile", + "serde 1.0.130", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-native-tls", + "tokio-rustls 0.23.1", + "tokio-util", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.21.1", + "winreg", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + [[package]] name = "rust-ini" version = "0.13.0" @@ -971,10 +1267,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" [[package]] -name = "ryu" -version = "1.0.5" +name = "rustls" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64 0.13.0", + "log", + "ring", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d37e5e2290f3e040b594b1a9e04377c2c671f1a1cfd9bfdef82106ac1c113f84" +dependencies = [ + "log", + "ring", + "sct 0.7.0", + "webpki 0.22.0", +] + +[[package]] +name = "rustls-pemfile" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eebeaeb360c87bfb72e84abdb3447159c0eaececf1bef2aecd65a8be949d1c9" +dependencies = [ + "base64 0.13.0", +] + +[[package]] +name = "ryu" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" [[package]] name = "safemem" @@ -982,6 +1312,16 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" +[[package]] +name = "schannel" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +dependencies = [ + "lazy_static", + "winapi", +] + [[package]] name = "scoped-tls" version = "1.0.0" @@ -994,6 +1334,49 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "sct" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "security-framework" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "serde" version = "0.8.23" @@ -1002,9 +1385,9 @@ checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" [[package]] name = "serde" -version = "1.0.124" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd761ff957cb2a45fbb9ab3da6512de9de55872866160b23c25f1a841e99d29f" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" dependencies = [ "serde_derive", ] @@ -1023,9 +1406,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.124" +version = "1.0.130" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1800f7693e94e186f5e25a28291ae1570da908aff7d97a095dec1e56ff99069b" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" dependencies = [ "proc-macro2", "quote", @@ -1034,13 +1417,22 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.64" +version = "1.0.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "799e97dc9fdae36a5c8b8f2cae9ce2ee9fdce2058c57a93e6099d919fd982f79" +checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527" dependencies = [ "itoa", "ryu", - "serde 1.0.124", + "serde 1.0.130", +] + +[[package]] +name = "serde_plain" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95455e7e29fada2052e72170af226fbe368a4ca33dee847875325d9fdb133858" +dependencies = [ + "serde 1.0.130", ] [[package]] @@ -1052,49 +1444,72 @@ dependencies = [ "form_urlencoded", "itoa", "ryu", - "serde 1.0.124", + "serde 1.0.130", +] + +[[package]] +name = "serenity" +version = "0.10.9" +source = "git+https://github.com/serenity-rs/serenity.git#a8b4e2f9ef8bee24f967944f184d77789b4a9be8" +dependencies = [ + "async-trait", + "async-tungstenite", + "base64 0.13.0", + "bitflags", + "bytes 1.1.0", + "chrono", + "flate2", + "futures", + "percent-encoding", + "reqwest", + "serde 1.0.130", + "serde_json", + "tokio", + "tracing", + "typemap_rev", + "url", ] [[package]] name = "sha-1" -version = "0.9.4" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfebf75d25bd900fd1e7d11501efab59bc846dbc76196839663e6637bba9f25f" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer", "cfg-if", - "cpuid-bool", + "cpufeatures", "digest", "opaque-debug", ] [[package]] name = "signal-hook-registry" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16f1d0fef1604ba8f7a073c7e701f213e056707210e9020af4528e0101ce11a6" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" dependencies = [ "libc", ] [[package]] name = "simple_logger" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7de33c687404ec3045d4a0d437580455257c0436f858d702f244e7d652f9f07" +checksum = "205596cf77a15774e5601c5ef759f4211ac381c0855a1f1d5e24a46f60f93e9a" dependencies = [ "atty", - "chrono", "colored", "log", + "time 0.3.5", "winapi", ] [[package]] name = "slab" -version = "0.4.2" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" [[package]] name = "sled" @@ -1114,21 +1529,26 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "socket2" -version = "0.3.19" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "122e570113d28d773067fab24266b66753f6ea915758651696b6e35e49f88d6e" +checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" dependencies = [ - "cfg-if", "libc", "winapi", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "static_assertions" version = "1.1.0" @@ -1143,9 +1563,9 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" [[package]] name = "structopt" -version = "0.3.21" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5277acd7ee46e63e5168a80734c9f6ee81b1367a7d8772a2d765df2a3705d28c" +checksum = "40b9788f4202aa75c240ecc9c15c65185e6a39ccdeb0fd5d008b98825464c87c" dependencies = [ "clap", "lazy_static", @@ -1154,9 +1574,9 @@ dependencies = [ [[package]] name = "structopt-derive" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ba9cdfda491b814720b6b06e0cac513d922fc407582032e8706e9f137976f90" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" dependencies = [ "heck", "proc-macro-error", @@ -1167,9 +1587,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.61" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed22b90a0e734a23a7610f4283ac9e5acfb96cbb30dfefa540d66f866f1c09c5" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" dependencies = [ "proc-macro2", "quote", @@ -1199,6 +1619,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.1.44" @@ -1211,10 +1651,27 @@ dependencies = [ ] [[package]] -name = "tinyvec" -version = "1.1.1" +name = "time" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317cca572a0e89c3ce0ca1f1bdc9369547fe318a683418e42ac8f59d14701023" +checksum = "41effe7cfa8af36f439fac33861b66b049edc6f9a32331e2312660529c1c24ad" +dependencies = [ + "itoa", + "libc", + "time-macros", +] + +[[package]] +name = "time-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25eb0ca3468fc0acc11828786797f6ef9aa1555e4a211a60d64cc8e4d1be47d6" + +[[package]] +name = "tinyvec" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" dependencies = [ "tinyvec_macros", ] @@ -1227,12 +1684,12 @@ checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" [[package]] name = "tokio" -version = "1.3.0" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d56477f6ed99e10225f38f9f75f872f29b8b8bd8c0b946f63345bb144e9eeda" +checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144" dependencies = [ "autocfg", - "bytes", + "bytes 1.1.0", "libc", "memchr", "mio", @@ -1247,9 +1704,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "1.1.0" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf7b11a536f46a809a8a9f0bb4237020f70ecbf115b842360afb127ea2fda57" +checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e" dependencies = [ "proc-macro2", "quote", @@ -1257,10 +1714,42 @@ dependencies = [ ] [[package]] -name = "tokio-stream" -version = "0.1.4" +name = "tokio-native-tls" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c535f53c0cfa1acace62995a8994fc9cc1f12d202420da96ff306ee24d576469" +checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls 0.19.1", + "tokio", + "webpki 0.21.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4baa378e417d780beff82bf54ceb0d195193ea6a00c14e22359e7f39456b5689" +dependencies = [ + "rustls 0.20.2", + "tokio", + "webpki 0.22.0", +] + +[[package]] +name = "tokio-stream" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50145484efff8818b5ccd256697f36863f587da82cf8b409c53adf1e840798e3" dependencies = [ "futures-core", "pin-project-lite", @@ -1269,24 +1758,24 @@ dependencies = [ [[package]] name = "tokio-tungstenite" -version = "0.13.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1a5f475f1b9d077ea1017ecbc60890fda8e54942d680ca0b1d2b47cfa2d861b" +checksum = "511de3f85caf1c98983545490c3d09685fa8eb634e57eec22bb4db271f46cbd8" dependencies = [ "futures-util", "log", "pin-project", "tokio", - "tungstenite", + "tungstenite 0.14.0", ] [[package]] name = "tokio-util" -version = "0.6.4" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec31e5cc6b46e653cf57762f36f71d5e6386391d88a72fd6db4508f8f676fb29" +checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" dependencies = [ - "bytes", + "bytes 1.1.0", "futures-core", "futures-sink", "log", @@ -1300,7 +1789,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" dependencies = [ - "serde 1.0.124", + "serde 1.0.130", ] [[package]] @@ -1311,33 +1800,35 @@ checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" [[package]] name = "tracing" -version = "0.1.25" +version = "0.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ebdc2bb4498ab1ab5f5b73c5803825e60199229ccba0698170e3be0e7f959f" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" dependencies = [ "cfg-if", "log", "pin-project-lite", + "tracing-attributes", "tracing-core", ] [[package]] -name = "tracing-core" -version = "0.1.17" +name = "tracing-attributes" +version = "0.1.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50de3927f93d202783f4513cda820ab47ef17f624b03c096e86ef00c67e6b5f" +checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" dependencies = [ - "lazy_static", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "tracing-futures" -version = "0.2.5" +name = "tracing-core" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" dependencies = [ - "pin-project", - "tracing", + "lazy_static", ] [[package]] @@ -1348,19 +1839,38 @@ checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" [[package]] name = "tungstenite" -version = "0.12.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ada8297e8d70872fa9a551d93250a9f407beb9f37ef86494eb20012a2ff7c24" +checksum = "f0308d80d86700c5878b9ef6321f020f29b1bb9d5ff3cab25e75e23f3a492a23" dependencies = [ - "base64", + "base64 0.12.3", "byteorder", - "bytes", + "bytes 0.5.6", "http", "httparse", "input_buffer", "log", + "rand 0.7.3", + "sha-1", + "url", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0b2d8558abd2e276b0a8df5c05a2ec762609344191e5fd23e292c910e9165b5" +dependencies = [ + "base64 0.13.0", + "byteorder", + "bytes 1.1.0", + "http", + "httparse", + "log", "rand 0.8.4", "sha-1", + "thiserror", "url", "utf-8", ] @@ -1375,10 +1885,16 @@ dependencies = [ ] [[package]] -name = "typenum" -version = "1.13.0" +name = "typemap_rev" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "ed5b74f0a24b5454580a79abb6994393b09adf0ab8070f15827cb666255de155" + +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" [[package]] name = "unicase" @@ -1391,45 +1907,48 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.4" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5" -dependencies = [ - "matches", -] +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" [[package]] name = "unicode-normalization" -version = "0.1.17" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07fbfce1c8a97d547e8b5334978438d9d6ec8c20e38f56d4a4374d181493eaef" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.7.1" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0d2e7be6ae3a5fa87eed5fb451aff96f2573d2694942e40543ae0bbe19c796" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" [[package]] name = "unicode-width" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" [[package]] name = "unicode-xid" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" [[package]] name = "url" -version = "2.2.1" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ccd964113622c8e9322cfac19eb1004a07e636c545f325da085d5cdde6f1f8b" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" dependencies = [ "form_urlencoded", "idna", @@ -1439,9 +1958,15 @@ dependencies = [ [[package]] name = "utf-8" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "vec_map" @@ -1451,9 +1976,9 @@ checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" -version = "0.9.2" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" [[package]] name = "want" @@ -1467,12 +1992,13 @@ dependencies = [ [[package]] name = "warp" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dafd0aac2818a94a34df0df1100a7356c493d8ede4393875fd0b5c51bb6bc80" +checksum = "3cef4e1e9114a4b7f1ac799f16ce71c14de5778500c5450ec6b7b920c55b587e" dependencies = [ - "bytes", - "futures", + "bytes 1.1.0", + "futures-channel", + "futures-util", "headers", "http", "hyper", @@ -1483,7 +2009,7 @@ dependencies = [ "percent-encoding", "pin-project", "scoped-tls", - "serde 1.0.124", + "serde 1.0.130", "serde_json", "serde_urlencoded", "tokio", @@ -1492,7 +2018,6 @@ dependencies = [ "tokio-util", "tower-service", "tracing", - "tracing-futures", ] [[package]] @@ -1507,6 +2032,120 @@ version = "0.10.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +[[package]] +name = "wasm-bindgen" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" + +[[package]] +name = "web-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f20dea7535251981a9670857150d571846545088359b28e4951d350bdaf179f" +dependencies = [ + "webpki 0.21.4", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki 0.21.4", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1529,6 +2168,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "winreg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +dependencies = [ + "winapi", +] + [[package]] name = "yaml-rust" version = "0.4.5" diff --git a/Cargo.toml b/Cargo.toml index 92b767e..7022159 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,5 +2,6 @@ members = [ "geoffrey_models", "geoffrey_db", - "geoffrey_api" + "geoffrey_api", + "geoffrey_bot" ] \ No newline at end of file diff --git a/bot_config.toml b/bot_config.toml new file mode 100644 index 0000000..3d8afd6 --- /dev/null +++ b/bot_config.toml @@ -0,0 +1,7 @@ +[api] +token = "0Bxpl0N4wBYHtgfwdtnaFPblQKa4Em9wIAGp6q0TV5X6M2HzuPsjfcCKxXddDny2" +base_url = "http://localhost:8080/" + +[discord] +token = "OTExNDQ1MDY3MTMzMjQ3NDk4.YZhfXQ.idsLVIgipSU1SJUnG_vkhZgFOMg" +app_id = 911445067133247498 \ No newline at end of file diff --git a/geoffrey_bot/Cargo.toml b/geoffrey_bot/Cargo.toml new file mode 100644 index 0000000..c6eab4e --- /dev/null +++ b/geoffrey_bot/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "geoffrey_bot" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serenity = { git="https://github.com/serenity-rs/serenity.git", default-features = false, features = ["client", "gateway", "rustls_backend", "model", "unstable_discord_api", "cache"] } +tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } +reqwest = { version = "0.11.6", features = ["json"]} +geoffrey_models = { path = "../geoffrey_models" } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +serde_plain = "1.0.0" +async-trait = "0.1.51" +config = "0.11.0" +structopt = "0.3.21" diff --git a/geoffrey_bot/src/commands/add_item.rs b/geoffrey_bot/src/commands/add_item.rs new file mode 100644 index 0000000..72ddd57 --- /dev/null +++ b/geoffrey_bot/src/commands/add_item.rs @@ -0,0 +1,129 @@ +use crate::commands::bot_command::{BotCommand, CommandError}; +use async_trait::async_trait; +use geoffrey_models::models::locations::Location; +use geoffrey_models::models::parameters::add_item_params::AddItemParams; +use reqwest::Method; +use serenity::client::Context; +use serenity::model::interactions::application_command::{ + ApplicationCommand, ApplicationCommandInteraction, ApplicationCommandOptionType, +}; +use serenity::model::prelude::application_command::ApplicationCommandInteractionDataOptionValue; + +pub struct AddItemCommand; + +#[async_trait] +impl BotCommand for AddItemCommand { + type ApiParams = AddItemParams; + type ApiResp = Location; + + fn command_name() -> String { + "add_item".to_string() + } + + fn request_type() -> Method { + Method::POST + } + + async fn create_app_command(ctx: &Context) -> Result { + let command = ApplicationCommand::create_global_application_command(&ctx.http, |command| { + command + .name(Self::command_name()) + .description("Add a item to a shop.") + .create_option(|option| { + option + .name("item_name") + .description("Name of the item to sell.") + .kind(ApplicationCommandOptionType::String) + .required(true) + }) + .create_option(|option| { + option + .name("price") + .description("Price to list them item at.") + .kind(ApplicationCommandOptionType::Integer) + .required(true) + .min_int_value(0) + }) + .create_option(|option| { + option + .name("quantity") + .description("Number of items to sell for price") + .kind(ApplicationCommandOptionType::Integer) + .required(true) + .min_int_value(1) + }) + .create_option(|option| { + option + .name("shop") + .description("Shop to list the item at") + .kind(ApplicationCommandOptionType::String) + .required(true) + }) + }) + .await?; + + Ok(command) + } + + async fn process_arguments( + command_interaction: ApplicationCommandInteraction, + ) -> Result { + let options = command_interaction.data.options; + + let mut item_name = String::default(); + let mut price = 0; + let mut quanity = 0; + let mut shop = String::default(); + + if let Some(option) = options.get(0) { + let option = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option { + item_name = s.clone(); + } else { + return Err(CommandError::ArgumentParse("item_name".to_string())); + } + } + + if let Some(option) = options.get(1) { + let option = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::Integer(p)) = option { + price = *p; + } else { + return Err(CommandError::ArgumentParse("price".to_string())); + } + } + + if let Some(option) = options.get(2) { + let option = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::Integer(q)) = option { + quanity = *q; + } else { + return Err(CommandError::ArgumentParse("quantity".to_string())); + } + } + + if let Some(option) = options.get(3) { + let option = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option { + shop = s.clone(); + } else { + return Err(CommandError::ArgumentParse("shop".to_string())); + } + } + + Ok(Self::ApiParams::new( + item_name, + price as u32, + quanity as u32, + shop, + )) + } + + fn build_response(resp: Self::ApiResp) -> String { + format!("{} has been updated", resp.name) + } +} diff --git a/geoffrey_bot/src/commands/add_location.rs b/geoffrey_bot/src/commands/add_location.rs new file mode 100644 index 0000000..d17e509 --- /dev/null +++ b/geoffrey_bot/src/commands/add_location.rs @@ -0,0 +1,174 @@ +use crate::commands::bot_command::{BotCommand, CommandError}; +use async_trait::async_trait; +use geoffrey_models::models::locations::{Location, LocationType}; +use geoffrey_models::models::parameters::add_location_params::AddLocationParams; +use geoffrey_models::models::{Dimension, Position}; +use reqwest::Method; +use serenity::client::Context; +use serenity::model::interactions::application_command::{ + ApplicationCommand, ApplicationCommandInteraction, ApplicationCommandInteractionDataOption, + ApplicationCommandOptionType, +}; +use serenity::model::prelude::application_command::ApplicationCommandInteractionDataOptionValue; +use std::str::FromStr; + +pub struct AddLocationCommand; + +fn option_to_i64(option: &ApplicationCommandInteractionDataOption) -> Option { + let option = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::Integer(s)) = option { + Some(*s) + } else { + None + } +} + +#[async_trait] +impl BotCommand for AddLocationCommand { + type ApiParams = AddLocationParams; + type ApiResp = Location; + + fn command_name() -> String { + "add_location".to_string() + } + + fn request_type() -> Method { + Method::POST + } + + async fn create_app_command(ctx: &Context) -> Result { + let command = ApplicationCommand::create_global_application_command(&ctx.http, |command| { + command + .name(Self::command_name()) + .description("Add a location to Geoffrey.") + .create_option(|option| { + option + .name("type") + .description("Location type") + .kind(ApplicationCommandOptionType::String) + .required(true) + .add_string_choice(LocationType::Base, LocationType::Base) + .add_string_choice(LocationType::Shop, LocationType::Shop) + .add_string_choice(LocationType::Attraction, LocationType::Attraction) + .add_string_choice(LocationType::Town, LocationType::Town) + .add_string_choice(LocationType::Farm, LocationType::Farm) + .add_string_choice(LocationType::Market, LocationType::Market) + }) + .create_option(|option| { + option + .name("name") + .description("Name of the location") + .kind(ApplicationCommandOptionType::String) + .required(true) + }) + .create_option(|option| { + option + .name("x") + .description("X coordinate of the shop") + .kind(ApplicationCommandOptionType::Integer) + .required(true) + }) + .create_option(|option| { + option + .name("y") + .description("Y coordinate of the shop") + .kind(ApplicationCommandOptionType::Integer) + .required(true) + }) + .create_option(|option| { + option + .name("z") + .description("Z coordinate of the shop") + .kind(ApplicationCommandOptionType::Integer) + .required(true) + }) + .create_option(|option| { + option + .name("dimension") + .description("Dimension of the shop, default is Overworld") + .kind(ApplicationCommandOptionType::String) + .add_string_choice(Dimension::Overworld, Dimension::Overworld) + .add_string_choice(Dimension::Nether, Dimension::Nether) + .add_string_choice(Dimension::TheEnd, Dimension::TheEnd) + .required(false) + }) + .create_option(|option| { + option + .name("portal_x") + .description("X Coordinate of the portal in the nether") + .kind(ApplicationCommandOptionType::Integer) + .required(false) + }) + .create_option(|option| { + option + .name("portal_z") + .description("Z Coordinate of the portal in the nether") + .kind(ApplicationCommandOptionType::Integer) + .required(false) + }) + }) + .await?; + + Ok(command) + } + + async fn process_arguments( + command_interaction: ApplicationCommandInteraction, + ) -> Result { + let options = command_interaction.data.options; + let mut name = String::new(); + let mut loc_type = LocationType::Base; + let x; + let _y; + let z; + let dimension; + + if let Some(option) = options.get(0) { + let option = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option { + loc_type = LocationType::from_str(s).unwrap(); + } else { + return Err(CommandError::ArgumentParse("loc_type".to_string())); + } + } + + if let Some(option) = options.get(1) { + let option = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option { + name = s.clone(); + } else { + return Err(CommandError::ArgumentParse("name".to_string())); + } + } + + x = option_to_i64(&options[2]).unwrap() as i32; + _y = option_to_i64(&options[3]).unwrap() as i32; + z = option_to_i64(&options[4]).unwrap() as i32; + + if let Some(option) = options.get(5) { + let option = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option { + dimension = Dimension::from_str(s.as_str()).unwrap(); + } else { + return Err(CommandError::ArgumentParse("dimension".to_string())); + } + } else { + dimension = Dimension::default(); + } + + Ok(Self::ApiParams::new( + name, + Position::new(x, z, dimension), + loc_type, + None, + )) + } + + fn build_response(resp: Self::ApiResp) -> String { + format!("{} has been added to Geoffrey.", resp.name) + } +} diff --git a/geoffrey_bot/src/commands/bot_command.rs b/geoffrey_bot/src/commands/bot_command.rs new file mode 100644 index 0000000..f92a480 --- /dev/null +++ b/geoffrey_bot/src/commands/bot_command.rs @@ -0,0 +1,166 @@ +use crate::context::GeoffreyContext; +use async_trait::async_trait; +use geoffrey_models::models::parameters::CommandRequest; +use geoffrey_models::models::player::UserID; +use geoffrey_models::models::response::api_error::GeoffreyAPIError; +use geoffrey_models::models::response::APIResponse; +use reqwest::Error; +use serde::de::DeserializeOwned; +use serde::Serialize; +use serenity::model::prelude::application_command::{ + ApplicationCommand, ApplicationCommandInteraction, +}; +use serenity::prelude::{Context, SerenityError}; +use std::fmt::{Display, Formatter}; + +#[derive(Debug)] +pub enum CommandError { + ArgumentParse(String), + GeoffreyApi(GeoffreyAPIError), + Serenity(serenity::Error), + Reqwest(reqwest::Error), +} + +impl Display for CommandError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let s = match self { + CommandError::ArgumentParse(s) => format!("Unable to parse argument '{}'", s), + CommandError::GeoffreyApi(err) => format!("Got error from GeoffreyAPI: {}", err), + CommandError::Serenity(err) => format!("Serenity Error: {}", err), + CommandError::Reqwest(err) => format!("Reqwest Error: {}", err), + }; + + write!(f, "{}", s) + } +} + +impl From for CommandError { + fn from(err: GeoffreyAPIError) -> Self { + Self::GeoffreyApi(err) + } +} + +impl From for CommandError { + fn from(err: SerenityError) -> Self { + Self::Serenity(err) + } +} + +impl From for CommandError { + fn from(err: Error) -> Self { + Self::Reqwest(err) + } +} + +#[async_trait] +pub trait BotCommand { + type ApiParams: CommandRequest; + type ApiResp: Serialize + DeserializeOwned + Send; + + fn command_name() -> String; + + fn request_type() -> reqwest::Method; + + fn command_url(base_string: &str) -> String { + let slash = if !base_string.ends_with('/') { "/" } else { "" }; + + format!("{}{}command/{}/", base_string, slash, Self::command_name()) + } + + async fn run_api_query( + ctx: &GeoffreyContext, + params: Self::ApiParams, + ) -> Result, CommandError> { + let command_url = Self::command_url(&ctx.cfg.api.base_url); + let resp: APIResponse = ctx + .http_client + .request(Self::request_type(), command_url) + .json(¶ms) + .send() + .await? + .json() + .await?; + + Ok(resp) + } + + fn get_err_resp(err: CommandError) -> String { + if let Some(resp) = Self::custom_err_resp(&err) { + resp + } else { + match err { + CommandError::GeoffreyApi(err) => match err { + GeoffreyAPIError::PlayerNotRegistered => { + "You need to register before using this command!".to_string() + } + GeoffreyAPIError::EntryNotFound => { + "Couldn't find that, maybe look for something that exists?".to_string() + } + GeoffreyAPIError::PermissionInsufficient => { + "Looks like you don't have permission for that.".to_string() + } + GeoffreyAPIError::EntryNotUnique => { + "Slow down, I already know that thing. Try a new name.".to_string() + } + GeoffreyAPIError::DatabaseError(_) => "How the heck u mess that up".to_string(), + GeoffreyAPIError::TokenNotAuthorized => "WHO ARE YOU????".to_string(), + GeoffreyAPIError::MultipleLocationsMatch => { + "I couldn't match a single location, narrow down your search".to_string() + } + GeoffreyAPIError::ParameterInvalid(err) => { + format!( + "Welp, you some how messed up the {} parameter, great job", + err + ) + } + }, + _ => { + println!("GeoffreyBot an unhandled error: {}", err); + format!("OOPSIE WOOPSIE!! Uwu We made a fucky wucky!! A wittle fucko boingo! The admins at our \ + headquarters are working VEWY HAWD to fix this! (Error in command {})", Self::command_name()) + } + } + } + } + + fn custom_err_resp(_: &CommandError) -> Option { + None + } + + async fn create_app_command(ctx: &Context) -> Result; + + async fn process_arguments( + command_interaction: ApplicationCommandInteraction, + ) -> Result; + + async fn run_command( + ctx: &GeoffreyContext, + user_id: UserID, + command_interact: ApplicationCommandInteraction, + ) -> Result { + let mut args = Self::process_arguments(command_interact).await?; + + args.set_token(ctx.cfg.api.token.clone()); + args.set_user_id(user_id); + + let resp = Self::run_api_query(ctx, args).await?; + + match resp { + APIResponse::Response(resp) => Ok(Self::build_response(resp)), + APIResponse::Error { error: err, .. } => Err(CommandError::GeoffreyApi(err)), + } + } + + async fn command( + ctx: &GeoffreyContext, + user_id: UserID, + command_interact: ApplicationCommandInteraction, + ) -> String { + match Self::run_command(ctx, user_id, command_interact).await { + Ok(msg) => msg, + Err(e) => Self::get_err_resp(e), + } + } + + fn build_response(resp: Self::ApiResp) -> String; +} diff --git a/geoffrey_bot/src/commands/find.rs b/geoffrey_bot/src/commands/find.rs new file mode 100644 index 0000000..adf365e --- /dev/null +++ b/geoffrey_bot/src/commands/find.rs @@ -0,0 +1,74 @@ +use crate::commands::bot_command::{BotCommand, CommandError}; +use async_trait::async_trait; +use geoffrey_models::models::locations::Location; +use geoffrey_models::models::parameters::find_params::FindParams; +use reqwest::Method; +use serenity::client::Context; +use serenity::model::interactions::application_command::{ + ApplicationCommand, ApplicationCommandInteraction, ApplicationCommandOptionType, +}; +use serenity::model::prelude::application_command::ApplicationCommandInteractionDataOptionValue; +use std::fmt::Write; + +pub struct FindCommand; + +#[async_trait] +impl BotCommand for FindCommand { + type ApiParams = FindParams; + type ApiResp = Vec; + + fn command_name() -> String { + "find".to_string() + } + + fn request_type() -> Method { + Method::GET + } + + async fn create_app_command(ctx: &Context) -> Result { + let command = ApplicationCommand::create_global_application_command(&ctx.http, |command| { + command + .name(Self::command_name()) + .description("Find a location in Geoffrey.") + .create_option(|option| { + option + .name("query") + .description("The location name or player to lookup") + .kind(ApplicationCommandOptionType::String) + .required(true) + }) + }) + .await?; + + Ok(command) + } + + async fn process_arguments( + command_interaction: ApplicationCommandInteraction, + ) -> Result { + let options = command_interaction.data.options; + + if let Some(option) = options.get(0) { + let query = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = query { + return Ok(FindParams::new(s.clone())); + } + } + + Err(CommandError::ArgumentParse("query".to_string())) + } + + fn build_response(resp: Self::ApiResp) -> String { + if resp.is_empty() { + "No locations match that query, try better next time ding dong".to_string() + } else { + let mut resp_str = String::new(); + writeln!(resp_str, "The following locations match:").unwrap(); + for loc in resp { + writeln!(resp_str, "**{}**, {}", loc.name, loc.position).unwrap(); + } + resp_str + } + } +} diff --git a/geoffrey_bot/src/commands/mod.rs b/geoffrey_bot/src/commands/mod.rs new file mode 100644 index 0000000..01e5822 --- /dev/null +++ b/geoffrey_bot/src/commands/mod.rs @@ -0,0 +1,28 @@ +pub mod add_item; +pub mod add_location; +pub mod bot_command; +pub mod find; +pub mod selling; + +use crate::commands::add_item::AddItemCommand; +use crate::commands::add_location::AddLocationCommand; +use crate::commands::bot_command::{BotCommand, CommandError}; +use crate::commands::find::FindCommand; +use crate::commands::selling::SellingCommand; +use serenity::model::interactions::application_command::ApplicationCommand; +use serenity::prelude::*; + +pub async fn create_commands(ctx: &Context) -> Result, CommandError> { + let mut commands: Vec = Vec::new(); + + for command in ApplicationCommand::get_global_application_commands(&ctx.http).await? { + ApplicationCommand::delete_global_application_command(&ctx.http, command.id).await?; + } + + commands.push(FindCommand::create_app_command(ctx).await?); + commands.push(SellingCommand::create_app_command(ctx).await?); + commands.push(AddLocationCommand::create_app_command(ctx).await?); + commands.push(AddItemCommand::create_app_command(ctx).await?); + + Ok(commands) +} diff --git a/geoffrey_bot/src/commands/selling.rs b/geoffrey_bot/src/commands/selling.rs new file mode 100644 index 0000000..3c07c0c --- /dev/null +++ b/geoffrey_bot/src/commands/selling.rs @@ -0,0 +1,127 @@ +use crate::commands::bot_command::{BotCommand, CommandError}; +use async_trait::async_trait; +use geoffrey_models::models::parameters::selling_params::{ItemSort, Order, SellingParams}; +use geoffrey_models::models::response::selling_listing::SellingListing; +use reqwest::Method; +use serenity::client::Context; +use serenity::model::interactions::application_command::{ + ApplicationCommand, ApplicationCommandInteraction, ApplicationCommandOptionType, +}; +use serenity::model::prelude::application_command::ApplicationCommandInteractionDataOptionValue; +use std::fmt::Write; +use std::str::FromStr; + +pub struct SellingCommand; + +#[async_trait] +impl BotCommand for SellingCommand { + type ApiParams = SellingParams; + type ApiResp = Vec; + + fn command_name() -> String { + "selling".to_string() + } + + fn request_type() -> Method { + Method::GET + } + + async fn create_app_command(ctx: &Context) -> Result { + let command = ApplicationCommand::create_global_application_command(&ctx.http, |command| { + command + .name(Self::command_name()) + .description("Find items for sale.") + .create_option(|option| { + option + .name("query") + .description("Item to find") + .kind(ApplicationCommandOptionType::String) + .required(true) + }) + .create_option(|option| { + option + .name("sort") + .description("How to sort items") + .kind(ApplicationCommandOptionType::String) + .add_string_choice(ItemSort::Price, ItemSort::Price) + .add_string_choice(ItemSort::Restock, ItemSort::Restock) + .required(false) + }) + .create_option(|option| { + option + .name("order") + .description("Order of the item Search") + .kind(ApplicationCommandOptionType::String) + .add_string_choice(Order::Low, Order::Low) + .add_string_choice(Order::High, Order::High) + .required(false) + }) + }) + .await?; + + Ok(command) + } + + async fn process_arguments( + command_interaction: ApplicationCommandInteraction, + ) -> Result { + let options = command_interaction.data.options; + let mut query = String::new(); + let mut sort = None; + let mut order = None; + + if let Some(option) = options.get(0) { + let option = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option { + query = s.clone(); + } else { + return Err(CommandError::ArgumentParse("query".to_string())); + } + } + + if let Some(option) = options.get(1) { + let option = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option { + sort = Some(ItemSort::from_str(s).unwrap()); + } else { + return Err(CommandError::ArgumentParse("sort".to_string())); + } + } + + if let Some(option) = options.get(2) { + let option = option.resolved.as_ref(); + + if let Some(ApplicationCommandInteractionDataOptionValue::String(s)) = option { + order = Some(Order::from_str(s).unwrap()); + } else { + return Err(CommandError::ArgumentParse("order".to_string())); + } + } + + Ok(SellingParams::new(query, sort, order)) + } + + fn build_response(resp: Self::ApiResp) -> String { + if resp.is_empty() { + "No shops were found selling that, maybe I should start selling it...".to_string() + } else { + let mut resp_str = String::new(); + writeln!(resp_str, "The items match:").unwrap(); + for item in resp { + writeln!( + resp_str, + "**{}**, {}D for {}: {} {}", + item.listing.item.name, + item.listing.count_per_price, + item.listing.count_per_price, + item.shop_name, + item.shop_loc + ) + .unwrap(); + } + resp_str + } + } +} diff --git a/geoffrey_bot/src/configs.rs b/geoffrey_bot/src/configs.rs new file mode 100644 index 0000000..5e57036 --- /dev/null +++ b/geoffrey_bot/src/configs.rs @@ -0,0 +1,30 @@ +use config::{Config, ConfigError, File}; +use serde::Deserialize; +use std::path::Path; + +#[derive(Debug, Deserialize, Clone)] +pub struct DiscordConfig { + pub token: String, + pub app_id: u64, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct ApiConfig { + pub token: String, + pub base_url: String, +} + +#[derive(Debug, Deserialize, Clone)] +pub struct GeoffreyBotConfig { + pub api: ApiConfig, + pub discord: DiscordConfig, +} + +impl GeoffreyBotConfig { + pub fn new(config_path: &Path) -> Result { + let mut cfg = Config::new(); + cfg.merge(File::from(config_path.to_path_buf()))?; + + cfg.try_into() + } +} diff --git a/geoffrey_bot/src/context.rs b/geoffrey_bot/src/context.rs new file mode 100644 index 0000000..e4f869d --- /dev/null +++ b/geoffrey_bot/src/context.rs @@ -0,0 +1,12 @@ +use crate::configs::GeoffreyBotConfig; +use serenity::prelude::TypeMapKey; + +#[derive(Debug, Clone)] +pub struct GeoffreyContext { + pub http_client: reqwest::Client, + pub cfg: GeoffreyBotConfig, +} + +impl TypeMapKey for GeoffreyContext { + type Value = GeoffreyContext; +} diff --git a/geoffrey_bot/src/main.rs b/geoffrey_bot/src/main.rs new file mode 100644 index 0000000..58cb8d0 --- /dev/null +++ b/geoffrey_bot/src/main.rs @@ -0,0 +1,130 @@ +mod commands; +mod configs; +mod context; + +use crate::commands::add_item::AddItemCommand; +use crate::commands::add_location::AddLocationCommand; +use crate::commands::bot_command::BotCommand; +use crate::commands::create_commands; +use crate::commands::find::FindCommand; +use crate::commands::selling::SellingCommand; +use crate::configs::GeoffreyBotConfig; +use crate::context::GeoffreyContext; +use geoffrey_models::models::player::UserID; +use serenity::utils::{content_safe, ContentSafeOptions}; +use serenity::{ + async_trait, + model::{ + gateway::Ready, + interactions::{Interaction, InteractionResponseType}, + }, + prelude::*, +}; +use std::path::PathBuf; +use structopt::StructOpt; + +#[derive(Debug, StructOpt, Clone)] +#[structopt(name = "GeoffreyBot", about = "Geoffrey Discord Bot")] +struct Args { + #[structopt(env = "GEOFFREY_BOT_CONFIG", parse(from_os_str))] + config: PathBuf, +} + +struct HttpClient; + +impl TypeMapKey for HttpClient { + type Value = serenity::client::Client; +} + +struct Handler; + +#[async_trait] +impl EventHandler for Handler { + async fn ready(&self, ctx: Context, ready: Ready) { + println!("{} is connected!", ready.user.name); + let commands = create_commands(&ctx).await.unwrap(); + + println!("The following commands have been registered:"); + + for command in commands { + println!( + "{}: {} - {:?}", + command.name, command.description, command.options + ); + } + } + + async fn interaction_create(&self, ctx: Context, interaction: Interaction) { + let data = ctx.data.read().await; + let geoffrey_ctx = data.get::().unwrap(); + + if let Interaction::ApplicationCommand(command) = interaction { + let user_id = UserID::DiscordUUID { + discord_uuid: command.user.id.0, + }; + + let msg = match command.data.name.as_str() { + "find" => FindCommand::command(geoffrey_ctx, user_id, command.clone()).await, + "selling" => SellingCommand::command(geoffrey_ctx, user_id, command.clone()).await, + "add_location" => { + AddLocationCommand::command(geoffrey_ctx, user_id, command.clone()).await + } + "add_item" => AddItemCommand::command(geoffrey_ctx, user_id, command.clone()).await, + _ => "not implemented :(".to_string(), + }; + + let msg = content_safe(&ctx.cache, &msg, &ContentSafeOptions::default()).await; + + command + .create_interaction_response(&ctx.http, |resp| { + resp.kind(InteractionResponseType::ChannelMessageWithSource) + .interaction_response_data(|message| message.content(msg)) + }) + .await + .unwrap(); + } else if let Interaction::Autocomplete(auto_complete) = interaction { + auto_complete + .create_autocomplete_response(&ctx.http, |resp| resp) + .await + .unwrap() + } else if let Interaction::MessageComponent(msg) = interaction { + msg.create_interaction_response(&ctx.http, |resp| resp) + .await + .unwrap() + } else if let Interaction::Ping(_) = interaction { + println!("Ping recv'ed"); + } + } +} + +#[tokio::main] +async fn main() { + let args: Args = Args::from_args(); + + let cfg = match GeoffreyBotConfig::new(args.config.as_path()) { + Ok(cfg) => cfg, + Err(e) => { + println!("Error opening config: {}", e); + return; + } + }; + + let mut client = Client::builder(cfg.discord.token.clone()) + .event_handler(Handler) + .application_id(cfg.discord.app_id) + .await + .expect("Error creating Geoffrey client"); + + { + let mut data = client.data.write().await; + + data.insert::(GeoffreyContext { + http_client: reqwest::Client::new(), + cfg, + }) + } + + if let Err(why) = client.start().await { + println!("Client error: {:?}", why); + } +} diff --git a/geoffrey_models/src/models/locations/mod.rs b/geoffrey_models/src/models/locations/mod.rs index 22123f0..c30bbd9 100644 --- a/geoffrey_models/src/models/locations/mod.rs +++ b/geoffrey_models/src/models/locations/mod.rs @@ -8,6 +8,8 @@ use crate::models::locations::town::{Town, TownDb}; use crate::models::player::Player; use crate::models::{Position, Tunnel}; use crate::GeoffreyDatabaseModel; +use std::fmt::{Display, Formatter}; +use std::str::FromStr; pub mod farm; pub mod market; @@ -37,6 +39,39 @@ impl From for LocationType { } } +impl Display for LocationType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let name = match self { + LocationType::Base => "Base", + LocationType::Shop => "Shop", + LocationType::Attraction => "Attraction", + LocationType::Town => "Town", + LocationType::Farm => "Farm", + LocationType::Market => "Market", + }; + + write!(f, "{}", name) + } +} + +impl FromStr for LocationType { + type Err = String; + + fn from_str(s: &str) -> Result { + let t = match s.to_lowercase().as_str() { + "base" => LocationType::Base, + "shop" => LocationType::Shop, + "attraction" => LocationType::Attraction, + "town" => LocationType::Town, + "farm" => LocationType::Farm, + "market" => LocationType::Market, + &_ => return Err(format!("Location type invalid: '{}'", s)), + }; + + Ok(t) + } +} + #[derive(Serialize, Deserialize, Debug, Clone)] pub enum LocationDataDb { Base, diff --git a/geoffrey_models/src/models/mod.rs b/geoffrey_models/src/models/mod.rs index d4ee6d5..c0dcc8e 100644 --- a/geoffrey_models/src/models/mod.rs +++ b/geoffrey_models/src/models/mod.rs @@ -1,4 +1,6 @@ use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; +use std::str::FromStr; pub mod item; pub mod locations; @@ -21,6 +23,31 @@ impl Default for Dimension { } } +impl Display for Dimension { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let display_name = match self { + Dimension::Overworld => "Overworld", + Dimension::Nether => "Nether", + Dimension::TheEnd => "The End", + }; + write!(f, "{}", display_name) + } +} + +impl FromStr for Dimension { + type Err = String; + + fn from_str(s: &str) -> Result { + let s = s.to_lowercase(); + Ok(match s.as_str() { + "o" | "overworld" => Dimension::Overworld, + "n" | "nether" => Dimension::Nether, + "e" | "end" | "the end" => Dimension::TheEnd, + _ => return Err(format!("Unable to parse {} as dimension", s)), + }) + } +} + #[derive(Serialize, Deserialize, Debug, Copy, Clone)] pub enum Direction { North, @@ -29,6 +56,19 @@ pub enum Direction { West, } +impl Display for Direction { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let display_name = match self { + Direction::North => "North", + Direction::East => "East", + Direction::South => "South", + Direction::West => "West", + }; + + write!(f, "{}", display_name) + } +} + #[derive(Default, Serialize, Deserialize, Debug, Copy, Clone)] pub struct Position { pub x: i32, @@ -42,6 +82,12 @@ impl Position { } } +impl Display for Position { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{} @ (x={}, z={}) ", self.dimension, self.x, self.y) + } +} + #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Tunnel { direction: Direction, diff --git a/geoffrey_models/src/models/parameters/add_item_params.rs b/geoffrey_models/src/models/parameters/add_item_params.rs index 7b2bb19..2dc8605 100644 --- a/geoffrey_models/src/models/parameters/add_item_params.rs +++ b/geoffrey_models/src/models/parameters/add_item_params.rs @@ -12,6 +12,19 @@ pub struct AddItemParams { pub shop: String, } +impl AddItemParams { + pub fn new(item_name: String, price: u32, quantity: u32, shop: String) -> Self { + Self { + token: Default::default(), + user_id: Default::default(), + item_name, + price, + quantity, + shop, + } + } +} + impl CommandRequest for AddItemParams { fn token(&self) -> String { self.token.clone() @@ -20,4 +33,12 @@ impl CommandRequest for AddItemParams { fn user_id(&self) -> Option { Some(self.user_id.clone()) } + + fn set_token(&mut self, token: String) { + self.token = token; + } + + fn set_user_id(&mut self, user_id: UserID) { + self.user_id = user_id; + } } diff --git a/geoffrey_models/src/models/parameters/add_location_params.rs b/geoffrey_models/src/models/parameters/add_location_params.rs index f037c49..7cc4a5c 100644 --- a/geoffrey_models/src/models/parameters/add_location_params.rs +++ b/geoffrey_models/src/models/parameters/add_location_params.rs @@ -14,6 +14,24 @@ pub struct AddLocationParams { pub tunnel: Option, } +impl AddLocationParams { + pub fn new( + name: String, + position: Position, + loc_type: LocationType, + tunnel: Option, + ) -> Self { + Self { + token: Default::default(), + user_id: Default::default(), + name, + position, + loc_type, + tunnel, + } + } +} + impl CommandRequest for AddLocationParams { fn token(&self) -> String { self.token.clone() @@ -22,4 +40,12 @@ impl CommandRequest for AddLocationParams { fn user_id(&self) -> Option { Some(self.user_id.clone()) } + + fn set_user_id(&mut self, user_id: UserID) { + self.user_id = user_id; + } + + fn set_token(&mut self, token: String) { + self.token = token; + } } diff --git a/geoffrey_models/src/models/parameters/add_token_params.rs b/geoffrey_models/src/models/parameters/add_token_params.rs index f550b22..198836c 100644 --- a/geoffrey_models/src/models/parameters/add_token_params.rs +++ b/geoffrey_models/src/models/parameters/add_token_params.rs @@ -1,5 +1,4 @@ use crate::models::parameters::CommandRequest; -use crate::models::player::UserID; use crate::models::token::Permissions; use serde::{Deserialize, Serialize}; @@ -9,12 +8,21 @@ pub struct AddTokenParams { pub permissions: Vec, } +impl AddTokenParams { + fn new(permissions: Vec) -> Self { + Self { + token: Default::default(), + permissions, + } + } +} + impl CommandRequest for AddTokenParams { fn token(&self) -> String { self.token.clone() } - fn user_id(&self) -> Option { - None + fn set_token(&mut self, token: String) { + self.token = token; } } diff --git a/geoffrey_models/src/models/parameters/find_params.rs b/geoffrey_models/src/models/parameters/find_params.rs index f1dd514..d8d972c 100644 --- a/geoffrey_models/src/models/parameters/find_params.rs +++ b/geoffrey_models/src/models/parameters/find_params.rs @@ -7,8 +7,21 @@ pub struct FindParams { pub query: String, } +impl FindParams { + pub fn new(query: String) -> Self { + Self { + token: Default::default(), + query, + } + } +} + impl CommandRequest for FindParams { fn token(&self) -> String { self.token.clone() } + + fn set_token(&mut self, token: String) { + self.token = token; + } } diff --git a/geoffrey_models/src/models/parameters/mod.rs b/geoffrey_models/src/models/parameters/mod.rs index 276d2ae..d484cd8 100644 --- a/geoffrey_models/src/models/parameters/mod.rs +++ b/geoffrey_models/src/models/parameters/mod.rs @@ -12,12 +12,17 @@ use serde::de::DeserializeOwned; use serde::Serialize; use std::fmt::Debug; -pub trait CommandRequest: Serialize + DeserializeOwned + Debug + Clone + Send + 'static { +pub trait CommandRequest: + Serialize + DeserializeOwned + Debug + Clone + Send + 'static + Sync +{ fn token(&self) -> String; fn user_id(&self) -> Option { None } + fn set_token(&mut self, token: String); + fn set_user_id(&mut self, _: UserID) {} + fn check_permission( &self, player: &Player, diff --git a/geoffrey_models/src/models/parameters/register_params.rs b/geoffrey_models/src/models/parameters/register_params.rs index 16b9c9a..a6f36aa 100644 --- a/geoffrey_models/src/models/parameters/register_params.rs +++ b/geoffrey_models/src/models/parameters/register_params.rs @@ -9,8 +9,26 @@ pub struct RegisterParameters { pub username: String, } +impl RegisterParameters { + pub fn new(username: String) -> Self { + RegisterParameters { + token: Default::default(), + new_user_id: Default::default(), + username, + } + } +} + impl CommandRequest for RegisterParameters { fn token(&self) -> String { self.token.clone() } + + fn set_user_id(&mut self, user_id: UserID) { + self.new_user_id = user_id; + } + + fn set_token(&mut self, token: String) { + self.token = token; + } } diff --git a/geoffrey_models/src/models/parameters/selling_params.rs b/geoffrey_models/src/models/parameters/selling_params.rs index 65621a1..e0c5758 100644 --- a/geoffrey_models/src/models/parameters/selling_params.rs +++ b/geoffrey_models/src/models/parameters/selling_params.rs @@ -1,6 +1,8 @@ use crate::models::parameters::CommandRequest; use crate::models::player::UserID; use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; +use std::str::FromStr; #[derive(Debug, Serialize, Deserialize, Clone)] pub enum ItemSort { @@ -8,12 +10,62 @@ pub enum ItemSort { Restock, } +impl Display for ItemSort { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let s = match self { + ItemSort::Price => "Price", + ItemSort::Restock => "Restock Time", + }; + + write!(f, "{}", s) + } +} + +impl FromStr for ItemSort { + type Err = String; + + fn from_str(s: &str) -> Result { + let sort = match s.to_lowercase().as_str() { + "price" => ItemSort::Price, + "restock" => ItemSort::Restock, + &_ => return Err(format!("Unknown sort '{}'", s)), + }; + + Ok(sort) + } +} + #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub enum Order { High, Low, } +impl Display for Order { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let s = match self { + Order::High => "High", + Order::Low => "Low", + }; + + write!(f, "{}", s) + } +} + +impl FromStr for Order { + type Err = String; + + fn from_str(s: &str) -> Result { + let order = match s.to_lowercase().as_str() { + "high" => Order::High, + "low" => Order::Low, + &_ => return Err(format!("Unknown sorting '{}'", s)), + }; + + Ok(order) + } +} + #[derive(Debug, Serialize, Deserialize, Clone)] pub struct SellingParams { pub token: String, @@ -22,6 +74,17 @@ pub struct SellingParams { pub order: Option, } +impl SellingParams { + pub fn new(query: String, sort: Option, order: Option) -> Self { + Self { + token: Default::default(), + query, + sort, + order, + } + } +} + impl CommandRequest for SellingParams { fn token(&self) -> String { self.token.clone() @@ -30,4 +93,8 @@ impl CommandRequest for SellingParams { fn user_id(&self) -> Option { None } + + fn set_token(&mut self, token: String) { + self.token = token; + } } diff --git a/geoffrey_models/src/models/player.rs b/geoffrey_models/src/models/player.rs index c1b3cc9..f8e3119 100644 --- a/geoffrey_models/src/models/player.rs +++ b/geoffrey_models/src/models/player.rs @@ -6,6 +6,13 @@ use serde::{Deserialize, Serialize}; pub enum UserID { DiscordUUID { discord_uuid: u64 }, MinecraftUUID { mc_uuid: String }, + None, +} + +impl Default for UserID { + fn default() -> Self { + Self::None + } } #[derive(Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq)]