diff --git a/LICENSE b/COPYING similarity index 99% rename from LICENSE rename to COPYING index 0ad25db..be3f7b2 100644 --- a/LICENSE +++ b/COPYING @@ -633,8 +633,8 @@ the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published - by the Free Software Foundation, either version 3 of the License, or + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/Cargo.lock b/Cargo.lock index fc39bd6..ec4fdc4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,29 +3,23 @@ version = 3 [[package]] -name = "aho-corasick" -version = "0.7.18" +name = "arg" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +checksum = "568bbed0b9810cd4b43c8560ff3c5d2318b29d78fc314818d156bbed7075d394" dependencies = [ - "memchr", + "arg-derive", ] [[package]] -name = "anyhow" -version = "1.0.47" +name = "arg-derive" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d9ff5d688f1c13395289f67db01d4826b46dd694e7580accdc3e8430f2d98e" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "849efc162c06e51ce911bf4fe702f62a08f3b6ebbbfc5178e86c6bae449c2c60" dependencies = [ - "hermit-abi", - "libc", - "winapi", + "quote", + "syn 1.0.109", + "tabwriter", ] [[package]] @@ -35,10 +29,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" [[package]] -name = "base64" -version = "0.13.0" +name = "bindgen" +version = "0.63.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885" +dependencies = [ + "bitflags", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 1.0.109", + "which", +] [[package]] name = "bitflags" @@ -46,12 +56,6 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" -[[package]] -name = "bumpalo" -version = "3.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" - [[package]] name = "bytes" version = "1.1.0" @@ -59,16 +63,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" [[package]] -name = "cc" -version = "1.0.72" +name = "c-main" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "797bbff8bd2bcddb7f0ee638b55398686adac15174689a86da5ffc0f51219f75" +dependencies = [ + "libc", +] [[package]] -name = "cfg-if" -version = "0.1.10" +name = "cc" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] [[package]] name = "cfg-if" @@ -77,53 +93,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "clap" -version = "3.2.20" +name = "clang-sys" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b71c3ce99b7611011217b366d923f1d0a7e07a92bb2dbf1e84508c673ca3bd" +checksum = "77ed9a53e5d4d9c573ae844bfac6872b159cb1d1585a83b29e7a64b7eef7332a" dependencies = [ - "atty", - "bitflags", - "clap_derive", - "clap_lex", - "indexmap", - "once_cell", - "strsim", - "termcolor", - "textwrap", -] - -[[package]] -name = "clap_derive" -version = "3.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - -[[package]] -name = "confy" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2913470204e9e8498a0f31f17f90a0de801ae92c8c5ac18c49af4819e6786697" -dependencies = [ - "directories", - "serde", - "toml", + "glob", + "libc", + "libloading", ] [[package]] @@ -142,20 +119,34 @@ dependencies = [ ] [[package]] -name = "core-foundation" -version = "0.9.2" +name = "curl" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +checksum = "509bd11746c7ac09ebd19f0b17782eae80aadee26237658a6b4808afb5c11a22" dependencies = [ - "core-foundation-sys", + "curl-sys", "libc", + "openssl-probe", + "openssl-sys", + "schannel", + "socket2", + "winapi", ] [[package]] -name = "core-foundation-sys" -version = "0.8.3" +name = "curl-sys" +version = "0.4.61+curl-8.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "14d05c10f541ae6f3bc5b3d923c20001f47db7d5f0b2bc6ad16490133842db79" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", + "winapi", +] [[package]] name = "dialoguer" @@ -170,94 +161,37 @@ dependencies = [ ] [[package]] -name = "directories" -version = "2.0.2" +name = "dirs" +version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551a778172a450d7fc12e629ca3b0428d00f6afa9a43da1b630d54604e97371c" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" dependencies = [ - "cfg-if 0.1.10", "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.3.6" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" dependencies = [ "libc", "redox_users", "winapi", ] +[[package]] +name = "either" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" + [[package]] name = "encode_unicode" version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" -[[package]] -name = "encoding_rs" -version = "0.8.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a74ea89a0a1b98f6332de42c95baff457ada66d1cb4030f9ff151b2041a1c746" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "env_logger" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" -dependencies = [ - "matches", - "percent-encoding", -] - -[[package]] -name = "futures-channel" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" -dependencies = [ - "futures-core", -] - [[package]] name = "futures-core" version = "0.3.18" @@ -272,15 +206,9 @@ checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.109", ] -[[package]] -name = "futures-sink" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" - [[package]] name = "futures-task" version = "0.3.18" @@ -307,41 +235,22 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "wasi", ] [[package]] -name = "h2" -version = "0.3.7" +name = "glob" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd819562fcebdac5afc5c113c3ec36f902840b70fd4fc458799c8ce4607ae55" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "hashbrown" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" - -[[package]] -name = "heck" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hermit-abi" @@ -356,114 +265,26 @@ dependencies = [ name = "hopper" version = "0.1.0" dependencies = [ - "anyhow", - "clap", - "confy", + "arg", + "c-main", "console", + "curl", "dialoguer", - "env_logger", "futures-util", "indicatif", - "log", - "reqwest", "serde", "serde_json", "tokio", -] - -[[package]] -name = "http" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" -dependencies = [ - "bytes", - "http", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" - -[[package]] -name = "httpdate" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" - -[[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.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436ec0091e4f20e655156a30a0df3770fe2900aa301e548e08446ec794b6953c" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "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", - "unicode-normalization", + "toml", + "xdg", + "yacexits", ] [[package]] name = "indexmap" -version = "1.7.0" +version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" dependencies = [ "autocfg", "hashbrown", @@ -487,30 +308,15 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] -[[package]] -name = "ipnet" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -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" version = "1.4.0" @@ -518,10 +324,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] -name = "libc" -version = "0.2.108" +name = "lazycell" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8521a1b57e76b1ec69af7599e75e38e7b7fad6610f037db8c79b127201b5d119" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libc" +version = "0.2.140" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libz-sys" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] [[package]] name = "lock_api" @@ -538,15 +372,9 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] -[[package]] -name = "matches" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" - [[package]] name = "memchr" version = "2.4.1" @@ -554,10 +382,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" [[package]] -name = "mime" -version = "0.3.16" +name = "minimal-lexical" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" @@ -582,21 +410,13 @@ dependencies = [ ] [[package]] -name = "native-tls" -version = "0.2.8" +name = "nom" +version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", + "memchr", + "minimal-lexical", ] [[package]] @@ -630,31 +450,17 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" -[[package]] -name = "openssl" -version = "0.10.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" -dependencies = [ - "bitflags", - "cfg-if 1.0.0", - "foreign-types", - "libc", - "once_cell", - "openssl-sys", -] - [[package]] name = "openssl-probe" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.71" +version = "0.9.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73" +checksum = "a95792af3c4e0153c3914df2261bedd30a98476f94dc892b67dfe1d89d433a04" dependencies = [ "autocfg", "cc", @@ -663,12 +469,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "os_str_bytes" -version = "6.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff" - [[package]] name = "parking_lot" version = "0.11.2" @@ -686,7 +486,7 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "instant", "libc", "redox_syscall", @@ -695,10 +495,10 @@ dependencies = [ ] [[package]] -name = "percent-encoding" -version = "2.1.0" +name = "peeking_take_while" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" [[package]] name = "pin-project-lite" @@ -714,9 +514,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.22" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12295df4f294471248581bc09bef3c38a5e46f1e36d6a37353621a0c6c357e1f" +checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" [[package]] name = "ppv-lite86" @@ -724,44 +524,20 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" -version = "1.0.32" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba508cc11742c0dc5c1659771673afbab7a0efab23aa17e854cbab0837ed0b43" +checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" dependencies = [ - "unicode-xid", + "unicode-ident", ] [[package]] name = "quote" -version = "1.0.10" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" dependencies = [ "proc-macro2", ] @@ -808,21 +584,22 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ "bitflags", ] [[package]] name = "redox_users" -version = "0.4.0" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" dependencies = [ "getrandom", "redox_syscall", + "thiserror", ] [[package]] @@ -831,8 +608,6 @@ version = "1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" dependencies = [ - "aho-corasick", - "memchr", "regex-syntax", ] @@ -852,39 +627,10 @@ dependencies = [ ] [[package]] -name = "reqwest" -version = "0.11.6" +name = "rustc-hash" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66d2927ca2f685faf0fc620ac4834690d29e7abb153add10f5812eef20b5e280" -dependencies = [ - "base64", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "http", - "http-body", - "hyper", - "hyper-tls", - "ipnet", - "js-sys", - "lazy_static", - "log", - "mime", - "native-tls", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "tokio", - "tokio-native-tls", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "winreg", -] +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "ryu" @@ -894,12 +640,11 @@ checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" [[package]] name = "schannel" -version = "0.1.19" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" dependencies = [ - "lazy_static", - "winapi", + "windows-sys", ] [[package]] @@ -908,47 +653,24 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" -[[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 = "1.0.130" +version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +checksum = "771d4d9c4163ee138805e12c710dd365e4f44be8be0503cb1bb9eb989425d9c9" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.130" +version = "1.0.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +checksum = "e801c1712f48475582b7696ac71e0ca34ebb30e09338425384269d9717c62cad" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.5", ] [[package]] @@ -963,17 +685,20 @@ dependencies = [ ] [[package]] -name = "serde_urlencoded" -version = "0.7.0" +name = "serde_spanned" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +checksum = "0efd8caf556a6cebd3b285caf480045fcc1ac04f6bd786b09a6f11af30c4fcf4" dependencies = [ - "form_urlencoded", - "itoa", - "ryu", "serde", ] +[[package]] +name = "shlex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" + [[package]] name = "signal-hook-registry" version = "1.4.0" @@ -997,29 +722,43 @@ checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" [[package]] name = "socket2" -version = "0.4.2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ "libc", "winapi", ] -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "syn" -version = "1.0.81" +version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2afee18b8beb5a596ecb4a2dce128c719b4ba399d34126b9e4396e3f9860966" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ "proc-macro2", "quote", - "unicode-xid", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89c2d1c76a26822187a1fbb5964e3fff108bc208f02e820ab9dac1234f6b388a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tabwriter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36205cfc997faadcc4b0b87aaef3fbedafe20d38d4959a7ca6ff803564051111" +dependencies = [ + "unicode-width", ] [[package]] @@ -1028,7 +767,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "rand", "redox_syscall", @@ -1036,15 +775,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "termcolor" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" -dependencies = [ - "winapi-util", -] - [[package]] name = "terminal_size" version = "0.1.17" @@ -1056,25 +786,24 @@ dependencies = [ ] [[package]] -name = "textwrap" -version = "0.15.0" +name = "thiserror" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" - -[[package]] -name = "tinyvec" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ - "tinyvec_macros", + "thiserror-impl", ] [[package]] -name = "tinyvec_macros" -version = "0.1.0" +name = "thiserror-impl" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.5", +] [[package]] name = "tokio" @@ -1104,88 +833,48 @@ checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e" dependencies = [ "proc-macro2", "quote", - "syn", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "log", - "pin-project-lite", - "tokio", + "syn 1.0.109", ] [[package]] name = "toml" -version = "0.5.8" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +checksum = "b403acf6f2bb0859c93c7f0d967cb4a75a7ac552100f9322faf64dc047669b21" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622" dependencies = [ "serde", ] [[package]] -name = "tower-service" -version = "0.3.1" +name = "toml_edit" +version = "0.19.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" - -[[package]] -name = "tracing" -version = "0.1.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +checksum = "dc18466501acd8ac6a3f615dd29a3438f8ca6bb3b19537138b3106e575621274" dependencies = [ - "cfg-if 1.0.0", - "pin-project-lite", - "tracing-core", + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", ] [[package]] -name = "tracing-core" -version = "0.1.21" +name = "unicode-ident" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" -dependencies = [ - "lazy_static", -] - -[[package]] -name = "try-lock" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" - -[[package]] -name = "unicode-bidi" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] +checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" [[package]] name = "unicode-width" @@ -1193,46 +882,12 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" -[[package]] -name = "unicode-xid" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" - -[[package]] -name = "url" -version = "2.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" -dependencies = [ - "form_urlencoded", - "idna", - "matches", - "percent-encoding", -] - [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "version_check" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" - -[[package]] -name = "want" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" -dependencies = [ - "log", - "try-lock", -] - [[package]] name = "wasi" version = "0.10.2+wasi-snapshot-preview1" @@ -1240,79 +895,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] -name = "wasm-bindgen" -version = "0.2.78" +name = "which" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" dependencies = [ - "cfg-if 1.0.0", - "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 1.0.0", - "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", + "either", + "libc", + "once_cell", ] [[package]] @@ -1331,15 +921,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" -[[package]] -name = "winapi-util" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" -dependencies = [ - "winapi", -] - [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -1347,12 +928,88 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] -name = "winreg" -version = "0.7.0" +name = "windows-sys" +version = "0.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" dependencies = [ - "winapi", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "winnow" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23d020b441f92996c80d94ae9166e8501e59c7bb56121189dc9eab3bd8216966" +dependencies = [ + "memchr", +] + +[[package]] +name = "xdg" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4583db5cbd4c4c0303df2d15af80f0539db703fa1c68802d4cbbd2dd0f88f6" +dependencies = [ + "dirs", +] + +[[package]] +name = "yacexits" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3afbe270dff95fe94b3a55c7e2dce91457a89b2b0dc6013814bba9806d099be" +dependencies = [ + "bindgen", + "libc", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index be435aa..a1dc83c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,18 +3,22 @@ name = "hopper" version = "0.1.0" license = "AGPL-3.0-or-later" edition = "2021" +authors = [ + "Emma Tebibyte ", + "Marceline Cramer " +] [dependencies] -anyhow = "1.0" -confy = "0.4" +arg = "0.4.1" +c-main = "1.0.1" console = "0.15.0" +curl = "0.4.44" dialoguer = "0.9.0" -env_logger = "0.9.0" futures-util = "0.3.18" indicatif = "0.15.0" -log = "0.4.14" -reqwest = { version = "0.11", features = ["json", "stream"] } serde = { version = "1", features = ["derive"] } serde_json = "1" -clap = { version = "3.2.20", features = ["derive"] } tokio = { version = "1", features = ["full"] } +toml = "0.7.3" +xdg = "2.4.1" +yacexits = "0.1.3" diff --git a/src/api.rs b/src/api.rs index 07c1cfe..e69de29 100644 --- a/src/api.rs +++ b/src/api.rs @@ -1,156 +0,0 @@ -use console::style; -use serde::Deserialize; -use std::{collections::HashMap, fmt}; - -#[derive(Deserialize, Debug)] -pub struct SearchResponse { - pub hits: Vec, - pub offset: isize, - pub limit: isize, - pub total_hits: isize, -} - -#[derive(Deserialize, Debug)] -pub struct ModResult { - pub slug: String, - pub title: String, - pub description: String, - pub categories: Vec, - pub display_categories: Vec, // NOTE this is not in the OpenAPI docs - pub client_side: String, - pub server_side: String, - pub project_type: String, // NOTE this isn't in all search results? - pub downloads: isize, - pub icon_url: String, - pub project_id: String, // TODO parse to 'local-xxxx' with reegex - pub author: String, - pub versions: Vec, - pub follows: isize, - pub date_created: String, - pub date_modified: String, - pub latest_version: String, - pub license: String, - pub gallery: Vec, -} - -impl ModResult { - pub fn format_info(&self) -> String { - let title = style(self.title.clone()).bold(); - let downloads = style(self.downloads.clone()).bold().green(); - if let Some(latest_release) = self.versions.last() { - // TODO fetch version numbers to display - let latest_release = style(latest_release).bold().blue(); - format!("{} [{}] ({} downloads)", title, latest_release, downloads) - } else { - format!("{} [no releases]", title) - } - } - - pub fn format_description(&self) -> String { - self.description.to_owned() - } - - pub fn display(&self, index: usize) { - let index = style(index).magenta(); - let info = self.format_info(); - let description = self.format_description(); - println!("{:>2} {}\n {}", index, info, description); - } -} - -#[derive(Deserialize, Debug)] -pub struct ModInfo { - pub slug: String, - pub title: String, - pub description: String, - pub categories: Vec, - pub additional_categories: Vec, // NOTE not listed in OpenAPI docs - pub client_side: String, // TODO serialize as enum - pub server_side: String, // TODO serialize as enum - pub body: String, - pub issues_url: Option, - pub source_url: Option, - pub wiki_url: Option, - pub discord_url: Option, - pub donation_urls: Option>, - pub project_type: String, - pub downloads: isize, - pub icon_url: Option, - pub id: String, // TODO serialize mod id? - pub team: String, // TODO serialize team id? - pub body_url: Option, // NOTE deprecated - pub moderator_message: Option, - pub published: String, // TODO serialize as datetime - pub updated: String, // TODO serialize as datetime - pub approved: Option, // NOTE not listed in OpenAPI docs, TODO serialize as datetime - pub followers: isize, - pub status: String, - pub license: License, - pub versions: Vec, - pub gallery: Option>, -} - -#[derive(Deserialize, Debug)] -pub struct GalleryEntry { - pub url: String, - pub featured: bool, - pub title: String, - pub description: String, - pub created: String, -} - -#[derive(Deserialize, Debug)] -pub struct License { - pub id: String, - pub name: String, - pub url: String, -} - -#[derive(Deserialize, Debug)] -pub struct DonationLink { - pub id: String, - pub platform: String, - pub url: String, -} - -#[derive(Deserialize, Debug)] -pub struct ModVersion { - pub name: String, - pub version_number: String, - pub changelog: Option, - // pub dependencies: Option>, // TODO dependency wrangling, thank you modrinth, very cool - pub game_versions: Vec, - pub version_type: String, // TODO {alpha | beta | release} - pub loaders: Vec, - pub featured: bool, - pub id: String, // version id - pub project_id: String, // mod id - pub author_id: String, // user id - pub date_published: String, // TODO serialize datetime - pub downloads: isize, - pub changelog_url: Option, // NOTE deprecated - pub files: Vec, -} - -#[derive(Deserialize, Debug)] -pub struct ModVersionFile { - pub hashes: HashMap, - pub url: String, - pub filename: String, - pub primary: bool, - pub size: isize, -} - -#[derive(Deserialize, Debug)] -pub struct Error { - pub error: String, - pub description: String, -} - -impl fmt::Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}: {}", self.error, self.description) - } -} - -impl std::error::Error for Error {} diff --git a/src/args.rs b/src/args.rs new file mode 100644 index 0000000..840a6bc --- /dev/null +++ b/src/args.rs @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2022–2023 Emma Tebibyte + * Copyright (c) 2021–2022 Marceline Cramer + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This file is part of Hopper. + * + * Hopper is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * Hopper is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License along with + * Hopper. If not, see . + */ + +use core::str::FromStr; + +use arg::Args; + +#[derive(Args, Debug)] +struct Arguments { + #[arg(short = "v")] + v: bool, + + #[arg(sub)] + sub: Command, +} + +#[derive(Args, Debug)] +struct InitArgs { + #[arg(short = "d")] + dir: Option, + + #[arg(short = "f")] + template: Option, + + #[arg(short = "m")] + mc_version: Vec, + + #[arg(short = "t", required)] + package_type: PackageType, +} + +#[derive(Args, Debug)] +struct HopArgs { + #[arg(short = "f")] + hopfile: Option, + + #[arg(short = "m")] + mc_version: Vec, + + #[arg(short = "t")] + package_type: Option, +} + +#[derive(Args, Debug)] +struct SearchArgs { + package_name: String, + + /// Overrides the download directory + #[arg(short = "d")] + dir: Option, + + /// Restricts the target Minecraft version + #[arg(short = "m")] + mc_version: Vec, + + /// Type of package to use + #[arg(short = "t")] + package_type: Option, +} + +#[derive(Args, Debug)] +enum Command { + Add(SearchArgs), + Get(SearchArgs), + Init(InitArgs), + List(HopArgs), + Remove(HopArgs), + Update(HopArgs), +} + +#[derive(Debug)] +enum PackageType { + Mod(Loader), + Pack(Loader), + Plugin(Server), + ResourcePack, +} + +#[derive(Debug)] +enum Loader { + Fabric, + Forge, + Quilt, +} + +#[derive(Debug)] +enum Server { + Bukkit, + Paper, + Purpur, + Spigot, + Sponge, +} + +#[derive(Debug)] +enum PackageParseError { + Invalid(String), +} + +impl FromStr for PackageType { + type Err = PackageParseError; + fn from_str(s: &str) -> Result { + let pieces: Vec<&str> = s.split("-").collect(); + + if pieces.len() > 2 || pieces.len() == 1 { + return Err(PackageParseError::Invalid( + format!("{}: Invalid package name.", s) + )); + } + + let (prefix, postfix) = (pieces[0], pieces[1]); + + let loader = match prefix { + "bukkit" => return Ok(PackageType::Plugin(Server::Bukkit)), + "fabric" => Loader::Fabric, + "forge" => Loader::Forge, + "paper" => return Ok(PackageType::Plugin(Server::Paper)), + "purpur" => return Ok(PackageType::Plugin(Server::Purpur)), + "quilt" => Loader::Quilt, + "resource" => return Ok(PackageType::ResourcePack), + "spigot" => return Ok(PackageType::Plugin(Server::Spigot)), + "sponge" => return Ok(PackageType::Plugin(Server::Sponge)), + _ => { + return Err(PackageParseError::Invalid( + format!("{}: Invalid package type.", prefix) + )) + }, + }; + + match postfix { + "mod" => Ok(PackageType::Mod(loader)), + "pack" => Ok(PackageType::Pack(loader)), + _ => { + Err(PackageParseError::Invalid( + format!("{}: Invalid package type.", postfix) + )) + }, + } + } +} diff --git a/src/client.rs b/src/client.rs index 37019a7..e69de29 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,166 +0,0 @@ -use crate::api::{ModInfo, ModResult, ModVersion, ModVersionFile, SearchResponse, Error as APIError}; -use crate::config::{Args, Config, PackageType, SearchArgs}; -use futures_util::StreamExt; -use log::*; -use std::cmp::min; -use std::io::Write; - -pub struct HopperClient { - config: Config, - client: reqwest::Client, -} - -impl HopperClient { - pub fn new(config: Config) -> Self { - Self { - config: config, - client: reqwest::ClientBuilder::new() - .user_agent(format!("tebibytemedia/hopper/{} (tebibyte.media)", env!("CARGO_PKG_VERSION"))) - .build() - .unwrap(), - } - } - - pub async fn search_mods(&self, search_args: &SearchArgs) -> anyhow::Result { - println!("Searching with query \"{}\"...", search_args.package_name); - - let url = format!("https://{}/v2/search", self.config.upstream.server_address); - - let mut params = vec![("query", search_args.package_name.to_owned())]; - let mut facets: Vec = Vec::new(); - if let Some(versions) = &search_args.version { - let versions_facets = versions - .iter() - .map(|e| format!("[\"versions:{}\"]", e)) - .collect::>() - .join(","); - facets.push(format!("{}", versions_facets)); - } - if let Some(package_type) = &search_args.package_type { - let package_type_facet = match package_type { - PackageType::Fabric => "[\"categories:fabric\"],[\"project_type:mod\"]", - PackageType::Forge => "[\"categories:forge\"],[\"project_type:mod\"]", - PackageType::Quilt => "[\"categories:quilt\"],[\"project_type:mod\"]", - PackageType::Resource => "[\"project_type:resourcepack\"]", - PackageType::FabricPack => "[\"project_type:modpack\"],[\"categories:fabric\"]", - PackageType::ForgePack => "[\"project_type:modpack\"],[\"categories:forge\"]", - PackageType::QuiltPack => "[\"project_type:modpack\"],[\"categories:quilt\"]", - PackageType::BukkitPlugin => "[\"project_type:mod\"],[\"categories:bukkit\"]", - PackageType::PaperPlugin => "[\"project_type:mod\"],[\"categories:paper\"]", - PackageType::PurpurPlugin => "[\"project_type:mod\"],[\"categories:purpur\"]", - PackageType::SpigotPlugin => "[\"project_type:mod\"],[\"categories:spigot\"]", - PackageType::SpongePlugin => "[\"project_type:mod\"],[\"categories:sponge\"]", - } - .to_string(); - facets.push(package_type_facet); - } - - if !facets.is_empty() { - params.push(("facets", format!("[{}]", facets.join(",")))); - } - - let url = reqwest::Url::parse_with_params(url.as_str(), ¶ms)?; - info!("GET {}", url); - let response = self.client.get(url).send().await?; - - if response.status().is_success() { - Ok(response.json::().await?) - } else { - Err(response.json::().await?.into()) - } - } - - pub async fn fetch_mod_info(&self, mod_result: &ModResult) -> anyhow::Result { - let mod_id = &mod_result.project_id; - println!( - "Fetching mod info for {} (ID: {})...", - mod_result.title, mod_id - ); - - let url = format!( - "https://{}/v2/project/{}", - self.config.upstream.server_address, mod_id - ); - info!("GET {}", url); - let response = self.client.get(url).send().await?; - - if response.status().is_success() { - Ok(response.json::().await?) - } else { - Err(response.json::().await?.into()) - } - } - - pub async fn fetch_mod_version(&self, version_id: &String) -> anyhow::Result { - println!("Fetching mod version {}...", version_id); - - let url = format!( - "https://{}/v2/version/{}", - self.config.upstream.server_address, version_id - ); - info!("GET {}", url); - let response = self.client.get(url).send().await?; - - if response.status().is_success() { - Ok(response.json::().await?) - } else { - Err(response.json::().await?.into()) - } - } - - pub async fn download_version_file( - &self, - args: &Args, - file: &ModVersionFile, - ) -> anyhow::Result<()> { - // TODO replace all uses of .unwrap() with proper error codes - let filename = &file.filename; - - // TODO make confirmation skippable with flag argument - if !args.auto_accept { - use dialoguer::Confirm; - let prompt = format!("Download to {}?", filename); - let confirm = Confirm::new() - .with_prompt(prompt) - .default(true) - .interact()?; - if !confirm { - println!("Skipping downloading {}...", filename); - return Ok(()); - } - } - let url = &file.url; - info!("GET {}", url); - let response = self.client.get(url).send().await?; - - if !response.status().is_success() { - return Err(response.json::().await?.into()) - } - - let total_size = response.content_length().unwrap(); - - // TODO better colors and styling! - // TODO square colored creeper face progress indicator (from top-left clockwise spiral in) - use indicatif::{ProgressBar, ProgressStyle}; - let pb = ProgressBar::new(total_size); - pb.set_style(ProgressStyle::default_bar().template("{msg}\n{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({bytes_per_sec}, {eta})").progress_chars("#>-")); - pb.set_message(&format!("Downloading {}", url)); - - let filename = &file.filename; - let mut file = std::fs::File::create(filename)?; - let mut downloaded: u64 = 0; - let mut stream = response.bytes_stream(); - - // TODO check hashes while streaming - while let Some(item) = stream.next().await { - let chunk = &item.unwrap(); - file.write(&chunk)?; - let new = min(downloaded + (chunk.len() as u64), total_size); - downloaded = new; - pb.set_position(new); - } - - pb.finish_with_message(&format!("Downloaded {} to {}", url, filename)); - Ok(()) - } -} diff --git a/src/config.rs b/src/config.rs index 8ba1f47..4a77ab0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,119 +1,91 @@ -use clap::{Parser, Subcommand, ValueEnum}; -use serde::{Deserialize, Serialize}; -use std::path::PathBuf; +/* + * Copyright (c) 2022–2023 Emma Tebibyte + * Copyright (c) 2021–2022 Marceline Cramer + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This file is part of Hopper. + * + * Hopper is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * Hopper is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License along with + * Hopper. If not, see . + */ -// TODO parameter to restrict target Minecraft version -#[derive(clap::Args, Clone, Debug)] -pub struct SearchArgs { - pub package_name: String, +use std::{ + collections::HashMap, + fs::File, + io::Read, +}; - /// Type of package to use - #[clap(short, long, value_enum)] - pub package_type: Option, +use serde::Deserialize; +use toml::de::ValueDeserializer; +use yacexits::{ + EX_DATAERR, + EX_UNAVAILABLE, +}; - /// Restricts the target Minecraft version - #[clap(short, long)] - pub version: Option>, -} - -// TODO use ColoredHelp by default? -#[derive(Subcommand, Clone, Debug)] -pub enum Command { - /// Adds a mod to the current instance - Add(SearchArgs), - /// Removes a mod - Remove { - package_name: String, - }, - Get(SearchArgs), - Update, - Clean, -} - -#[derive(ValueEnum, Clone, Debug)] -pub enum PackageType { - Fabric, - Forge, - Quilt, - Resource, - FabricPack, - ForgePack, - QuiltPack, - BukkitPlugin, - PaperPlugin, - PurpurPlugin, - SpigotPlugin, - SpongePlugin, -} - -// TODO move main body argument fields to substruct for ease of moving? -#[derive(Parser, Clone, Debug)] -#[clap(name = "hopper")] -pub struct Args { - /// Path to configuration file - #[clap(short, long, value_parser)] - pub config: Option, - - /// Path to mod lockfile - #[clap(short, long, value_parser)] - pub lockfile: Option, - - /// Auto-accept confirmation dialogues - #[clap(short = 'y', long = "yes")] - pub auto_accept: bool, - - #[clap(subcommand)] - pub command: Command, -} - -impl Args { - pub fn load_config(&self) -> Result { - if let Some(config_path) = &self.config { - confy::load_path(config_path) - } else { - confy::load("hopper") - } - } -} - -#[derive(Deserialize, Serialize, Debug, Clone)] -pub struct Upstream { - /// Modrinth main server address - pub server_address: String, -} - -impl Default for Upstream { - fn default() -> Self { - Self { - server_address: "api.modrinth.com".into(), - } - } -} - -#[derive(Deserialize, Serialize, Debug, Clone)] -pub struct Options { - /// Whether to reverse search results - pub reverse_search: bool, -} - -impl Default for Options { - fn default() -> Self { - Self { - reverse_search: true, - } - } -} - -#[derive(Deserialize, Serialize, Debug, Default, Clone)] +#[derive(Deserialize)] pub struct Config { - /// General settings - pub options: Options, - - /// Configuration for the upstream Modrinth server - pub upstream: Upstream, + hopfiles: Vec, + sources: HashMap, } -pub struct AppContext { - pub args: Args, - pub config: Config, +pub fn get_config() -> Result<(), (String, u32)> { + let xdg_dirs = match xdg::BaseDirectories::with_prefix("hopper") { + Ok(dirs) => dirs, + Err(err) => { + return Err(( + format!("{:?}", err), + EX_UNAVAILABLE, + )); + }, + }; + Ok(()) +} + +impl Config { + pub fn read_config(config_path: String) -> Result { + let mut buf: Vec = Vec::new(); + + let mut config_file = match File::open(&config_path) { + Ok(file) => file, + Err(_) => { + return Err(( + format!("{}: Permission denied.", &config_path), + EX_UNAVAILABLE, + )); + }, + }; + + match config_file.read_to_end(&mut buf) { + Ok(_) => {}, + Err(err) => { + return Err(( + format!("{:?}", err), + EX_DATAERR, + )); + }, + }; + + let toml = match String::from_utf8(buf) { + Ok(contents) => contents, + Err(_) => { + return Err(( + format!("Invalid configuration file."), + EX_DATAERR, + )); + }, + }; + + match Config::deserialize(ValueDeserializer::new(&toml)) { + Ok(val) => Ok(val), + Err(err) => Err((format!("{:?}", err), EX_DATAERR)), + } + } } diff --git a/src/main.rs b/src/main.rs index ec7553e..ae63b44 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,121 +1,36 @@ +/* + * Copyright (c) 2022–2023 Emma Tebibyte + * Copyright (c) 2021–2022 Marceline Cramer + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This file is part of Hopper. + * + * Hopper is free software: you can redistribute it and/or modify it under the + * terms of the GNU General Public License as published by the Free Software + * Foundation, either version 3 of the License, or (at your option) any later + * version. + * + * Hopper is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License along with + * Hopper. If not, see . + */ + +#![no_main] + mod api; +mod args; mod client; mod config; use api::*; -use clap::Parser; +use args::*; use client::*; use config::*; -fn display_search_results(ctx: &AppContext, response: &SearchResponse) { - let iter = response.hits.iter().enumerate(); - if ctx.config.options.reverse_search { - for (i, result) in iter.rev() { - result.display(i + 1); - } - } else { - for (i, result) in iter { - result.display(i + 1); - } - } -} - -// TODO implement enum for more graceful exiting -async fn select_from_results( - _ctx: &AppContext, - response: &SearchResponse, -) -> anyhow::Result> { - let input: String = dialoguer::Input::new() - .with_prompt("Mods to install (eg: 1 2 3-5)") - .interact_text()?; - - let mut selected: Vec = Vec::new(); - for token in input.split(" ") { - let terms: Vec<&str> = token.split("-").collect(); - - match terms.len() { - 1 => selected.push(terms[0].parse().expect("Token must be an integer")), - 2 => { - let terms: Vec = terms - .iter() - .map(|term| term.parse().expect("Term must be an integer")) - .collect(); - let from = terms[0]; - let to = terms[1]; - - for index in from..=to { - selected.push(index); - } - } - _ => panic!("Invalid selection token {}", token), - } - } - - selected.dedup(); - - let selected = selected - .iter() - .map(|index| { - if *index < 1 || *index > response.hits.len() { - // TODO return useful error instead of panicking - panic!("Index {} is out of bounds", index); - } - - // input is indexed from 1, but results are indexed from 0 - let index = index - 1; - - index - }) - .collect(); - - Ok(selected) -} - -async fn cmd_get(ctx: &AppContext, search_args: SearchArgs) -> anyhow::Result<()> { - let client = HopperClient::new(ctx.config.clone()); - let response = client.search_mods(&search_args).await?; - - if response.hits.is_empty() { - // TODO formatting - println!("No results; nothing to do..."); - return Ok(()); - } - - display_search_results(ctx, &response); - let selected = select_from_results(ctx, &response).await?; - - if selected.is_empty() { - // TODO formatting - println!("No packages selected; nothing to do..."); - return Ok(()); - } - - for selection in selected.iter() { - let to_get = &response.hits[*selection]; - let mod_info = client.fetch_mod_info(to_get).await?; - - // TODO allow the user to select multiple versions - if let Some(version_id) = mod_info.versions.first() { - println!("fetching version {}", version_id); - - let version = client.fetch_mod_version(version_id).await?; - for file in version.files.iter() { - client.download_version_file(&ctx.args, file).await?; - } - } - } - - Ok(()) -} - #[tokio::main] -async fn main() -> anyhow::Result<()> { - env_logger::init(); - let args = Args::parse(); - let config = args.load_config()?; - let ctx = AppContext { args, config }; - match ctx.args.to_owned().command { - Command::Get(search_args) => cmd_get(&ctx, search_args).await, - _ => unimplemented!("unimplemented subcommand"), - } +#[no_mangle] +async fn rust_main(args: c_main::Args) { + let argv: Vec<&str> = args.into_iter().collect(); }