diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..ab33d3a --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,16 @@ +[target.x86_64-pc-windows-msvc] +# LLD linker +# +# You may need to install it: +# +# ``` +# cargo install -f cargo-binutils +# rustup component add llvm-tools +# ``` +linker = "rust-lld.exe" +# Nightly +rustflags = [ + "-Zshare-generics=y", + "-Zthreads=0", + "-Ctarget-cpu=native" +] \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index def3678..373fbe0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,6 +44,21 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" +[[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.14" @@ -139,6 +154,18 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + [[package]] name = "base64" version = "0.22.1" @@ -157,12 +184,27 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.6.0" @@ -181,6 +223,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.5", +] + [[package]] name = "clap" version = "4.5.13" @@ -227,18 +284,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" -[[package]] -name = "confy" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45b1f4c00870f07dc34adcac82bb6a72cc5aabca8536ba1797e01df51d2ce9a0" -dependencies = [ - "directories", - "serde", - "thiserror", - "toml", -] - [[package]] name = "core-foundation" version = "0.9.4" @@ -255,6 +300,15 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.4.2" @@ -265,24 +319,23 @@ dependencies = [ ] [[package]] -name = "directories" -version = "5.0.1" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "dirs-sys", + "generic-array", + "typenum", ] [[package]] -name = "dirs-sys" -version = "0.4.1" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.48.0", + "block-buffer", + "crypto-common", ] [[package]] @@ -438,6 +491,16 @@ dependencies = [ "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -457,6 +520,25 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[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", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "h2" version = "0.4.5" @@ -468,7 +550,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -508,6 +590,17 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[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.1.0" @@ -519,6 +612,17 @@ dependencies = [ "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 = "http-body" version = "1.0.0" @@ -526,7 +630,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http", + "http 1.1.0", ] [[package]] @@ -537,8 +641,8 @@ checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes", "futures-core", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -548,12 +652,42 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +[[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.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "hyper" version = "1.3.1" @@ -563,9 +697,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.0", "httparse", "itoa", "pin-project-lite", @@ -574,6 +708,20 @@ dependencies = [ "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 0.14.30", + "rustls", + "tokio", + "tokio-rustls", +] + [[package]] name = "hyper-tls" version = "0.6.0" @@ -582,7 +730,7 @@ checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", "http-body-util", - "hyper", + "hyper 1.3.1", "hyper-util", "native-tls", "tokio", @@ -599,9 +747,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", - "http-body", - "hyper", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.3.1", "pin-project-lite", "socket2", "tokio", @@ -610,6 +758,29 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +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 = "idna" version = "0.5.0" @@ -636,6 +807,25 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.0" @@ -728,12 +918,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" [[package]] -name = "libredox" -version = "0.1.3" +name = "libmimalloc-sys" +version = "0.1.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44" dependencies = [ - "bitflags 2.5.0", + "cc", "libc", ] @@ -755,6 +945,15 @@ version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "mimalloc" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633" +dependencies = [ + "libmimalloc-sys", +] + [[package]] name = "mime" version = "0.3.17" @@ -817,6 +1016,26 @@ dependencies = [ "libc", ] +[[package]] +name = "oauth2" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f" +dependencies = [ + "base64 0.13.1", + "chrono", + "getrandom", + "http 0.2.12", + "rand", + "reqwest 0.11.27", + "serde", + "serde_json", + "serde_path_to_error", + "sha2", + "thiserror", + "url", +] + [[package]] name = "object" version = "0.35.0" @@ -832,6 +1051,17 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "open" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a877bf6abd716642a53ef1b89fb498923a4afca5c754f9050b4d081c05c4b3" +dependencies = [ + "is-wsl", + "libc", + "pathdiff", +] + [[package]] name = "openssl" version = "0.10.64" @@ -877,10 +1107,10 @@ dependencies = [ ] [[package]] -name = "option-ext" -version = "0.2.0" +name = "pathdiff" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" [[package]] name = "percent-encoding" @@ -926,6 +1156,15 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro2" version = "1.0.85" @@ -955,14 +1194,33 @@ dependencies = [ ] [[package]] -name = "redox_users" -version = "0.4.5" +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ "getrandom", - "libredox", - "thiserror", ] [[package]] @@ -1014,6 +1272,47 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-rustls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg 0.50.0", +] + [[package]] name = "reqwest" version = "0.12.4" @@ -1021,17 +1320,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" dependencies = [ "async-compression", - "base64", + "base64 0.22.1", "bytes", "encoding_rs", "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.0", "http-body-util", - "hyper", + "hyper 1.3.1", "hyper-tls", "hyper-util", "ipnet", @@ -1042,7 +1341,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile", + "rustls-pemfile 2.1.2", "serde", "serde_json", "serde_urlencoded", @@ -1056,7 +1355,22 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", + "winreg 0.52.0", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", ] [[package]] @@ -1078,13 +1392,34 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[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-pemfile" version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" dependencies = [ - "base64", + "base64 0.22.1", "rustls-pki-types", ] @@ -1094,6 +1429,16 @@ version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +[[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 = "ryu" version = "1.0.18" @@ -1109,6 +1454,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "security-framework" version = "2.11.0" @@ -1164,11 +1519,12 @@ dependencies = [ ] [[package]] -name = "serde_spanned" -version = "0.6.6" +name = "serde_path_to_error" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0" +checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6" dependencies = [ + "itoa", "serde", ] @@ -1184,6 +1540,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "simd-json" version = "0.13.10" @@ -1231,6 +1598,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 = "static_assertions" version = "1.1.0" @@ -1354,6 +1727,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-util" version = "0.7.11" @@ -1367,40 +1750,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.8.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335" -dependencies = [ - "serde", - "serde_spanned", - "toml_datetime", - "toml_edit", -] - -[[package]] -name = "toml_datetime" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_edit" -version = "0.22.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21c7aaf97f1bd9ca9d4f9e73b0a6c74bd5afef56f2bc931943a6e1c37e04e38" -dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "winnow", -] - [[package]] name = "tower" version = "0.4.13" @@ -1456,6 +1805,18 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "twitch" version = "0.1.0" +dependencies = [ + "anyhow", + "log", + "oauth2", + "open", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "unicode-bidi" @@ -1478,6 +1839,12 @@ dependencies = [ "tinyvec", ] +[[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.0" @@ -1487,6 +1854,7 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -1527,7 +1895,7 @@ dependencies = [ "env_logger", "log", "quick-xml", - "reqwest", + "reqwest 0.12.4", "serde", ] @@ -1537,10 +1905,11 @@ version = "0.2.0" dependencies = [ "anyhow", "clap", - "confy", "env_logger", "log", + "mimalloc", "serde", + "twitch", "vmix", "youtube", ] @@ -1636,6 +2005,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 = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -1776,12 +2160,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" [[package]] -name = "winnow" -version = "0.6.12" +name = "winreg" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41ff33f391015ecab21cd092389215eb265ef9496a9a07b6bee7d3529831deda" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "memchr", + "cfg-if", + "windows-sys 0.48.0", ] [[package]] @@ -1801,7 +2186,7 @@ dependencies = [ "anyhow", "env_logger", "log", - "reqwest", + "reqwest 0.12.4", "serde", "simd-json", ] @@ -1812,6 +2197,7 @@ version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ + "byteorder", "zerocopy-derive", ] diff --git a/Cargo.toml b/Cargo.toml index 3ea1884..1f7511b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,13 +5,14 @@ edition = "2021" [dependencies] clap = { version = "4.5.13", features = ["derive"] } -confy = "0.6.1" +mimalloc = "0.1.43" serde = { workspace = true } env_logger = { workspace = true } log = { workspace = true } anyhow = { workspace = true } vmix = { path = "vmix" } youtube = { path = "youtube" } +twitch = { path = "twitch" } [workspace] members = [ @@ -25,4 +26,11 @@ serde = { version = "1.0.203", features = ["derive"] } env_logger = "0.11.3" log = "0.4.21" anyhow = "1.0.86" -oauth2 = "4.4.2" \ No newline at end of file +oauth2 = "4.4.2" + +# Optimize all dependencies even in debug builds (does not affect workspace packages): +[profile.dev.package."*"] +opt-level = "s" + +[profile.release] +panic = "abort" # This leads to better optimizations and smaller binaries (and is the default in Wasm anyways). \ No newline at end of file diff --git a/README.md b/README.md index e6bcc8b..def651b 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -A simple cli app to automate vMix over its HTTP api, intended to be used in TouchPortal or similar apps \ No newline at end of file +A simple cli app to automate vMix with Twitch and YouTube events + diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..5d56faf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly" diff --git a/src/config.rs b/src/config.rs deleted file mode 100644 index 593c833..0000000 --- a/src/config.rs +++ /dev/null @@ -1,43 +0,0 @@ -use anyhow::Result; -use serde::{Deserialize, Serialize}; - -use crate::SwitchCommands; -use vmix::Input; - -#[derive(Serialize, Deserialize, Debug)] -pub struct Config { - version: u8, - pub endpoint: String, - pub inputs: Inputs, -} - -impl Default for Config { - fn default() -> Self { - Self { - version: 1, - endpoint: "127.0.0.1:8088".into(), - inputs: Inputs { - vals: vec![ - (SwitchCommands::Start, Input::Number(1)), - (SwitchCommands::Break, Input::Number(2)), - (SwitchCommands::Game, Input::Number(3)), - (SwitchCommands::End, Input::Number(4)), - ], - }, - } - } -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct Inputs { - vals: Vec<(SwitchCommands, Input)>, -} - -impl Inputs { - pub fn at(&self, cmd: SwitchCommands) -> Result<&Input> { - let val = &self.vals[cmd as usize]; - - assert_eq!(cmd, val.0); - Ok(&val.1) - } -} diff --git a/src/main.rs b/src/main.rs index 61d6fca..f4db461 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,20 @@ +use twitch; use vmix; use youtube; -mod config; use anyhow::{Context, Result}; use clap::{Parser, Subcommand}; -use log::info; +// use log::info; use serde::{Deserialize, Serialize}; +use mimalloc::MiMalloc; + use std::fs::File; use std::io::Write; +#[global_allocator] +static GLOBAL: MiMalloc = MiMalloc; + #[derive(Parser)] #[command(version, about, long_about = None)] struct Cli { @@ -28,20 +33,6 @@ enum Commands { #[command(subcommand)] input: DumpCommands, }, - /// Switch to a given input - Switch { - #[command(subcommand)] - input: SwitchCommands, - }, - /// Increment a counter in a title - Inc { - /// The title - #[arg(short, long)] - title: vmix::Input, - /// The index of the text to increment - #[arg(short, long)] - idx: Option, - }, /// Run alerts Alerts { #[command(subcommand)] @@ -49,20 +40,6 @@ enum Commands { }, } -#[derive( - Subcommand, Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, -)] -enum SwitchCommands { - /// Switch to the starting input, and begin streaming - Start, - /// Switch to the break input - Break, - /// Switch to the game input - Game, - /// Switch to the ending input - End, -} - #[derive(Subcommand, Serialize, Deserialize, Debug)] enum DumpCommands { /// Dump the raw XML state from vMix @@ -86,6 +63,8 @@ enum DumpCommands { #[arg(short, long)] id: String, }, + /// Dump the Twitch OAuth2 token + TwitchToken, } #[derive(Subcommand, Serialize, Deserialize, Debug)] @@ -95,34 +74,27 @@ enum AlertCommands { /// Twitch Alerts Twitch, } +const VMIX_ENDPOINT: &str = "127.0.0.1:8088"; +const TWITCH_CLIENT_ID: &str = "rbt9n9wzhjxett8r99q2i15nc7enqx"; fn main() -> Result<()> { env_logger::init(); let cli = Cli::parse(); - info!( - "Config: {:?}", - confy::get_configuration_file_path("vmix-controller", None) - .with_context(|| "Bad configuration file")? - ); - let cfg: config::Config = confy::load("vmix-controller", None)?; - - // let mut vmix = vmix::client::Client::new(&cfg.endpoint)?; - match &cli.command { Commands::Dump { input } => match input { - &DumpCommands::VmixInputs => { - let mut vmix = vmix::client::Client::new(&cfg.endpoint)?; + DumpCommands::VmixInputs => { + let mut vmix = vmix::client::Client::new(VMIX_ENDPOINT)?; println!("\nInputs: {:#?}", vmix.inputs()); } - &DumpCommands::VmixTitles => { - let mut vmix = vmix::client::Client::new(&cfg.endpoint)?; + DumpCommands::VmixTitles => { + let mut vmix = vmix::client::Client::new(VMIX_ENDPOINT)?; println!("\nTitles: {:#?}", vmix.titles()); } - &DumpCommands::VmixXml => { - let mut vmix = vmix::client::Client::new(&cfg.endpoint)?; + DumpCommands::VmixXml => { + let mut vmix = vmix::client::Client::new(VMIX_ENDPOINT)?; File::create("last_state.xml")?.write_all(vmix.xml()?.as_bytes())?; println!("Parsed State: {:#?}", vmix.state()?); @@ -139,39 +111,22 @@ fn main() -> Result<()> { println!("Parsed Chat: {:#?}", yt.get_chat(id, None)?); } - }, - Commands::Inc { title, idx } => { - let mut vmix = vmix::client::Client::new(&cfg.endpoint)?; - let text = vmix.get_text(title, *idx)?; - let val: u32 = text.parse()?; - vmix.set_text(title, *idx, (val + 1).to_string())?; - } - - Commands::Switch { input } => { - let vmix = vmix::client::Client::new(&cfg.endpoint)?; - match input { - &SwitchCommands::Start => { - // Switch to start - vmix.quick_play(cfg.inputs.at(*input)?)?; - - // Start streaming - info!("Starting streaming"); - if cli.debug { - return Ok(()); // Don't stream in debug mode - } - - vmix.start_streaming()?; - } - _ => { - vmix.quick_play(cfg.inputs.at(*input)?)?; - } + DumpCommands::TwitchToken => { + let twitch = twitch::client::Client::new(TWITCH_CLIENT_ID); + + println!("Auth: {:#?}", twitch.auth()?); } - } + }, - Commands::Alerts { input } => { - todo!() - } + Commands::Alerts { input } => match input { + AlertCommands::Twitch => { + todo!() + } + AlertCommands::Youtube => { + todo!() + } + }, } Ok(()) } diff --git a/twitch/Cargo.toml b/twitch/Cargo.toml index a3d5071..9c4ae0e 100644 --- a/twitch/Cargo.toml +++ b/twitch/Cargo.toml @@ -4,3 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] +oauth2 = { workspace = true } +anyhow = { workspace = true } +log = { workspace = true } +open = "5.3.0" diff --git a/twitch/src/client.rs b/twitch/src/client.rs new file mode 100644 index 0000000..4de7447 --- /dev/null +++ b/twitch/src/client.rs @@ -0,0 +1,84 @@ +use anyhow::{Context, Result}; +use oauth2::{basic::BasicClient, url::Url, AuthUrl, AuthorizationCode, ClientId, CsrfToken, TokenResponse}; +use std::io::{BufRead, BufReader, Write}; +use std::net::TcpListener; +use log::info; + +pub struct Client { + client: BasicClient, +} + +impl Client { + pub fn new(client_id: &str) -> Self { + let client = BasicClient::new( + ClientId::new(client_id.to_string()), + None, + AuthUrl::new("https://id.twitch.tv/oauth2/authorize".to_string()).expect("Redirect URL is valid"), + None, + ); + Self { client } + } + + pub fn auth(&self) -> Result{ + let (auth_url, csrf_token) = self + .client + .authorize_url(CsrfToken::new_random) + .use_implicit_flow() + .url(); + + // println!("Opening authorization link in browser"); + // open::that(auth_url.as_str())?; + println!("Open this URL in your browser:\n{auth_url}\n"); + + let (code, state) = { + // A very naive implementation of the redirect server. + let listener = TcpListener::bind("127.0.0.1:3000").unwrap(); + + // The server will terminate itself after collecting the first code. + let Some(mut stream) = listener.incoming().flatten().next() else { + panic!("listener terminated without accepting a connection"); + }; + + let mut reader = BufReader::new(&stream); + + let mut request_line = String::new(); + reader.read_line(&mut request_line).unwrap(); + + let redirect_url = request_line.split_whitespace().nth(1).unwrap(); + let url = Url::parse(&("http://localhost:3000".to_string() + redirect_url)).unwrap(); + + let code = url + .query_pairs() + .find(|(key, _)| key == "code") + .map(|(_, code)| AuthorizationCode::new(code.into_owned())) + .unwrap(); + + let state = url + .query_pairs() + .find(|(key, _)| key == "state") + .map(|(_, state)| CsrfToken::new(state.into_owned())) + .unwrap(); + + let message = "You can close this window now."; + let response = format!( + "HTTP/1.1 200 OK\r\ncontent-length: {}\r\n\r\n{}", + message.len(), + message + ); + stream.write_all(response.as_bytes()).unwrap(); + + (code, state) + }; + + assert_eq!(state.secret(), csrf_token.secret(), "CSRF Tokens must match!"); + + Ok(code) + // let token_result = self.client + // .exchange_code(code) + // .request(oauth2::reqwest::http_client)?; + // + // + // + // Ok(token_result.) + } +} diff --git a/twitch/src/lib.rs b/twitch/src/lib.rs index b93cf3f..3935517 100644 --- a/twitch/src/lib.rs +++ b/twitch/src/lib.rs @@ -1,14 +1 @@ -pub fn add(left: u64, right: u64) -> u64 { - left + right -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } -} +pub mod client; \ No newline at end of file