From 8d637b2ae159e6f0539af172cb4317a7f3556653 Mon Sep 17 00:00:00 2001 From: Magnus Bergmark Date: Wed, 14 Jun 2023 12:03:09 +0200 Subject: [PATCH] Switch to official Cloudflare API library Sadly it has a bug that prevents the "List Zones" API from working. (See https://github.com/cloudflare/cloudflare-rs/issues/198) One workaround for this is to not use "List Zones" and instead accepting a Zone ID directly. The CLI arguments now require a Zone ID or a Zone Name to be specified, and Zone Name will only be used if no Zone ID is present. We also switch over to Token-based auth for this version. --- Cargo.lock | 1291 +++++++++++---------------------------------------- Cargo.toml | 6 +- src/main.rs | 311 +++++++++---- 3 files changed, 484 insertions(+), 1124 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c7ef5a8..d424f75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,27 +3,27 @@ version = 3 [[package]] -name = "addr2line" -version = "0.19.0" +name = "aho-corasick" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ - "gimli", + "memchr", ] [[package]] -name = "adler" -version = "1.0.2" +name = "android-tzdata" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" [[package]] -name = "aho-corasick" -version = "1.0.2" +name = "android_system_properties" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ - "memchr", + "libc", ] [[package]] @@ -33,12 +33,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" [[package]] -name = "autocfg" -version = "0.1.8" +name = "anyhow" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" + +[[package]] +name = "async-trait" +version = "0.1.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" dependencies = [ - "autocfg 1.1.0", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -47,29 +55,11 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" -[[package]] -name = "backtrace" -version = "0.3.67" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" -dependencies = [ - "addr2line", - "cc", - "cfg-if 1.0.0", - "libc", - "miniz_oxide 0.6.2", - "object", - "rustc-demangle", -] - [[package]] name = "base64" -version = "0.10.1" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -dependencies = [ - "byteorder", -] +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" @@ -89,23 +79,6 @@ version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" -[[package]] -name = "byteorder" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" - -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "either", - "iovec", -] - [[package]] name = "bytes" version = "1.4.0" @@ -120,15 +93,25 @@ checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" [[package]] name = "cfg-if" -version = "0.1.10" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "cfg-if" -version = "1.0.0" +name = "chrono" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "ec837a71355b28f6556dbd569b37b3f363091c0bd4b2e735674521b4c5fd9bc5" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "time 0.1.45", + "wasm-bindgen", + "winapi", +] [[package]] name = "clap" @@ -162,7 +145,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.18", + "syn", ] [[package]] @@ -171,26 +154,26 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" -[[package]] -name = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags", -] - [[package]] name = "cloudflare" -version = "0.1.0" -source = "git+https://github.com/Mange/cloudflare-rs?branch=zone-dns-update#a416364abdc8d0281a9a56fee0d0c5d22392a257" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0778f99ea7ad39b49b758eb418da7117b93232a5f6a09f9b79a094b77ac88cc2" dependencies = [ - "log", - "reqwest 0.9.24", + "anyhow", + "async-trait", + "base64 0.13.1", + "cfg-if", + "chrono", + "http", + "percent-encoding", + "reqwest", "serde", - "serde_derive", "serde_json", - "url 1.7.2", + "serde_qs", + "serde_with", + "url", + "uuid", ] [[package]] @@ -201,35 +184,7 @@ dependencies = [ "cloudflare", "dotenv", "regex", - "reqwest 0.11.18", -] - -[[package]] -name = "cookie" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "888604f00b3db336d2af898ec3c1d5d0ddf5e6d462220f2ededc33a87ac4bbd5" -dependencies = [ - "time", - "url 1.7.2", -] - -[[package]] -name = "cookie_store" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46750b3f362965f197996c4448e4a0935e791bf7d6631bfce9ee0af3d24c919c" -dependencies = [ - "cookie", - "failure", - "idna 0.1.5", - "log", - "publicsuffix", - "serde", - "serde_json", - "time", - "try_from", - "url 1.7.2", + "reqwest", ] [[package]] @@ -249,60 +204,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] -name = "crc32fast" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "crossbeam-deque" -version = "0.7.4" +name = "darling" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" +checksum = "0558d22a7b463ed0241e993f76f09f30b126687447751a8638587b864e4b3944" dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", - "maybe-uninit", + "darling_core", + "darling_macro", ] [[package]] -name = "crossbeam-epoch" -version = "0.8.2" +name = "darling_core" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +checksum = "ab8bfa2e259f8ee1ce5e97824a3c55ec4404a0d772ca7fa96bf19f0752a046eb" dependencies = [ - "autocfg 1.1.0", - "cfg-if 0.1.10", - "crossbeam-utils", - "lazy_static", - "maybe-uninit", - "memoffset", - "scopeguard", -] - -[[package]] -name = "crossbeam-queue" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" -dependencies = [ - "cfg-if 0.1.10", - "crossbeam-utils", - "maybe-uninit", + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", ] [[package]] -name = "crossbeam-utils" -version = "0.7.2" +name = "darling_macro" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +checksum = "29a358ff9f12ec09c3e61fef9b5a9902623a695a46a917b07f269bff1445611a" dependencies = [ - "autocfg 1.1.0", - "cfg-if 0.1.10", - "lazy_static", + "darling_core", + "quote", + "syn", ] [[package]] @@ -311,25 +244,13 @@ version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" -[[package]] -name = "dtoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" - -[[package]] -name = "either" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" - [[package]] name = "encoding_rs" version = "0.8.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", ] [[package]] @@ -353,28 +274,6 @@ dependencies = [ "libc", ] -[[package]] -name = "failure" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" -dependencies = [ - "backtrace", - "failure_derive", -] - -[[package]] -name = "failure_derive" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure", -] - [[package]] name = "fastrand" version = "1.9.0" @@ -384,16 +283,6 @@ dependencies = [ "instant", ] -[[package]] -name = "flate2" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" -dependencies = [ - "crc32fast", - "miniz_oxide 0.7.1", -] - [[package]] name = "fnv" version = "1.0.7" @@ -421,37 +310,9 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" dependencies = [ - "percent-encoding 2.3.0", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "fuchsia-zircon" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" -dependencies = [ - "bitflags", - "fuchsia-zircon-sys", + "percent-encoding", ] -[[package]] -name = "fuchsia-zircon-sys" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" - -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - [[package]] name = "futures-channel" version = "0.3.28" @@ -467,16 +328,6 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" -[[package]] -name = "futures-cpupool" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4" -dependencies = [ - "futures", - "num_cpus", -] - [[package]] name = "futures-io" version = "0.3.28" @@ -511,27 +362,14 @@ dependencies = [ ] [[package]] -name = "gimli" -version = "0.27.2" +name = "getrandom" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" - -[[package]] -name = "h2" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5b34c246847f938a410a03c5458c7fee2274436675e76d8b903c08efc29c462" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" dependencies = [ - "byteorder", - "bytes 0.4.12", - "fnv", - "futures", - "http 0.1.21", - "indexmap", - "log", - "slab", - "string", - "tokio-io", + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -540,15 +378,15 @@ version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d357c7ae988e7d2182f7d7871d0b963962420b0678b0997ce7de72001aeab782" dependencies = [ - "bytes 1.4.0", + "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http 0.2.9", + "http", "indexmap", "slab", - "tokio 1.28.2", + "tokio", "tokio-util", "tracing", ] @@ -581,15 +419,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] -name = "http" -version = "0.1.21" +name = "hex" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" -dependencies = [ - "bytes 0.4.12", - "fnv", - "itoa 0.4.8", -] +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "http" @@ -597,21 +430,9 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" dependencies = [ - "bytes 1.4.0", + "bytes", "fnv", - "itoa 1.0.6", -] - -[[package]] -name = "http-body" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" -dependencies = [ - "bytes 0.4.12", - "futures", - "http 0.1.21", - "tokio-buf", + "itoa", ] [[package]] @@ -620,8 +441,8 @@ version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ - "bytes 1.4.0", - "http 0.2.9", + "bytes", + "http", "pin-project-lite", ] @@ -637,71 +458,28 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" -[[package]] -name = "hyper" -version = "0.12.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c843caf6296fc1f93444735205af9ed4e109a539005abb2564ae1d6fad34c52" -dependencies = [ - "bytes 0.4.12", - "futures", - "futures-cpupool", - "h2 0.1.26", - "http 0.1.21", - "http-body 0.1.0", - "httparse", - "iovec", - "itoa 0.4.8", - "log", - "net2", - "rustc_version", - "time", - "tokio 0.1.22", - "tokio-buf", - "tokio-executor", - "tokio-io", - "tokio-reactor", - "tokio-tcp", - "tokio-threadpool", - "tokio-timer", - "want 0.2.0", -] - [[package]] name = "hyper" version = "0.14.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" dependencies = [ - "bytes 1.4.0", + "bytes", "futures-channel", "futures-core", "futures-util", - "h2 0.3.19", - "http 0.2.9", - "http-body 0.4.5", + "h2", + "http", + "http-body", "httparse", "httpdate", - "itoa 1.0.6", + "itoa", "pin-project-lite", "socket2", - "tokio 1.28.2", + "tokio", "tower-service", "tracing", - "want 0.3.0", -] - -[[package]] -name = "hyper-tls" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f" -dependencies = [ - "bytes 0.4.12", - "futures", - "hyper 0.12.36", - "native-tls", - "tokio-io", + "want", ] [[package]] @@ -710,35 +488,42 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.4.0", - "hyper 0.14.26", + "bytes", + "hyper", "native-tls", - "tokio 1.28.2", + "tokio", "tokio-native-tls", ] [[package]] -name = "idna" -version = "0.1.5" +name = "iana-time-zone" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e" +checksum = "2fad5b825842d2b38bd206f3e81d6957625fd7f0a361e345c30e01a0ae2dd613" dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows", ] [[package]] -name = "idna" -version = "0.2.3" +name = "iana-time-zone-haiku" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", + "cc", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.4.0" @@ -755,8 +540,9 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "autocfg 1.1.0", + "autocfg", "hashbrown", + "serde", ] [[package]] @@ -765,7 +551,7 @@ 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]] @@ -779,27 +565,12 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - [[package]] name = "ipnet" version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - [[package]] name = "itoa" version = "1.0.6" @@ -815,16 +586,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "kernel32-sys" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" -dependencies = [ - "winapi 0.2.8", - "winapi-build", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -843,101 +604,24 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" -[[package]] -name = "lock_api" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4da24a77a3d8a6d4862d95f72e6fdb9c09a643ecdb402d754004a557f2bec75" -dependencies = [ - "scopeguard", -] - [[package]] name = "log" version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - [[package]] name = "memchr" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" -[[package]] -name = "memoffset" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" -dependencies = [ - "autocfg 1.1.0", -] - [[package]] name = "mime" version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "mime_guess" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" -dependencies = [ - "mime", - "unicase", -] - -[[package]] -name = "miniz_oxide" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" -dependencies = [ - "adler", -] - -[[package]] -name = "miniz_oxide" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" -dependencies = [ - "adler", -] - -[[package]] -name = "mio" -version = "0.6.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4" -dependencies = [ - "cfg-if 0.1.10", - "fuchsia-zircon", - "fuchsia-zircon-sys", - "iovec", - "kernel32-sys", - "libc", - "log", - "miow", - "net2", - "slab", - "winapi 0.2.8", -] - [[package]] name = "mio" version = "0.8.8" @@ -949,18 +633,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "miow" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d" -dependencies = [ - "kernel32-sys", - "net2", - "winapi 0.2.8", - "ws2_32-sys", -] - [[package]] name = "native-tls" version = "0.2.11" @@ -980,14 +652,12 @@ dependencies = [ ] [[package]] -name = "net2" -version = "0.2.38" +name = "num-traits" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ - "cfg-if 0.1.10", - "libc", - "winapi 0.3.9", + "autocfg", ] [[package]] @@ -1000,15 +670,6 @@ dependencies = [ "libc", ] -[[package]] -name = "object" -version = "0.30.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.18.0" @@ -1022,7 +683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69b3f656a17a6cbc115b5c7a40c616947d213ba182135b014d6051b73ab6f019" dependencies = [ "bitflags", - "cfg-if 1.0.0", + "cfg-if", "foreign-types", "libc", "once_cell", @@ -1038,7 +699,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn", ] [[package]] @@ -1059,211 +720,48 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "parking_lot" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f842b1982eb6c2fe34036a4fbfb06dd185a3f5c8edfaacdf7d1ea10b07de6252" -dependencies = [ - "lock_api", - "parking_lot_core", - "rustc_version", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall 0.1.57", - "rustc_version", - "smallvec", - "winapi 0.3.9", -] - -[[package]] -name = "percent-encoding" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831" - [[package]] name = "percent-encoding" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" - -[[package]] -name = "pin-project-lite" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkg-config" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "proc-macro2" -version = "1.0.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "publicsuffix" -version = "1.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b4ce31ff0a27d93c8de1849cf58162283752f065a90d508f1105fa6c9a213f" -dependencies = [ - "idna 0.2.3", - "url 2.4.0", -] - -[[package]] -name = "quote" -version = "1.0.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" -dependencies = [ - "autocfg 0.1.8", - "libc", - "rand_chacha", - "rand_core 0.4.2", - "rand_hc", - "rand_isaac", - "rand_jitter", - "rand_os", - "rand_pcg", - "rand_xorshift", - "winapi 0.3.9", -] - -[[package]] -name = "rand_chacha" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.3.1", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rand_hc" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "rand_isaac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" -dependencies = [ - "rand_core 0.3.1", -] +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] -name = "rand_jitter" -version = "0.1.4" +name = "pin-project-lite" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" -dependencies = [ - "libc", - "rand_core 0.4.2", - "winapi 0.3.9", -] +checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" [[package]] -name = "rand_os" -version = "0.1.3" +name = "pin-utils" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" -dependencies = [ - "cloudabi", - "fuchsia-cprng", - "libc", - "rand_core 0.4.2", - "rdrand", - "winapi 0.3.9", -] +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] -name = "rand_pcg" -version = "0.1.2" +name = "pkg-config" +version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" -dependencies = [ - "autocfg 0.1.8", - "rand_core 0.4.2", -] +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" [[package]] -name = "rand_xorshift" -version = "0.1.1" +name = "proc-macro2" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ - "rand_core 0.3.1", + "unicode-ident", ] [[package]] -name = "rdrand" -version = "0.4.0" +name = "quote" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ - "rand_core 0.3.1", + "proc-macro2", ] -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - [[package]] name = "redox_syscall" version = "0.3.5" @@ -1290,40 +788,6 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" -[[package]] -name = "reqwest" -version = "0.9.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f88643aea3c1343c804950d7bf983bd2067f5ab59db6d613a08e05572f2714ab" -dependencies = [ - "base64 0.10.1", - "bytes 0.4.12", - "cookie", - "cookie_store", - "encoding_rs", - "flate2", - "futures", - "http 0.1.21", - "hyper 0.12.36", - "hyper-tls 0.3.2", - "log", - "mime", - "mime_guess", - "native-tls", - "serde", - "serde_json", - "serde_urlencoded 0.5.5", - "time", - "tokio 0.1.22", - "tokio-executor", - "tokio-io", - "tokio-threadpool", - "tokio-timer", - "url 1.7.2", - "uuid", - "winreg 0.6.2", -] - [[package]] name = "reqwest" version = "0.11.18" @@ -1331,49 +795,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cde824a14b7c14f85caff81225f411faacc04a2013f41670f41443742b1c1c55" dependencies = [ "base64 0.21.2", - "bytes 1.4.0", + "bytes", "encoding_rs", "futures-core", "futures-util", - "h2 0.3.19", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.26", - "hyper-tls 0.5.0", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", "ipnet", "js-sys", "log", "mime", "native-tls", "once_cell", - "percent-encoding 2.3.0", + "percent-encoding", "pin-project-lite", "serde", "serde_json", - "serde_urlencoded 0.7.1", - "tokio 1.28.2", + "serde_urlencoded", + "tokio", "tokio-native-tls", "tower-service", - "url 2.4.0", + "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg 0.10.1", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver", + "winreg", ] [[package]] @@ -1405,12 +854,6 @@ dependencies = [ "windows-sys 0.42.0", ] -[[package]] -name = "scopeguard" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" - [[package]] name = "security-framework" version = "2.9.1" @@ -1434,21 +877,6 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" version = "1.0.164" @@ -1466,7 +894,7 @@ checksum = "d9735b638ccc51c28bf6914d90a2e9725b377144fc612c49a611fddd1b631d68" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn", ] [[package]] @@ -1475,21 +903,20 @@ version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ - "itoa 1.0.6", + "itoa", "ryu", "serde", ] [[package]] -name = "serde_urlencoded" -version = "0.5.5" +name = "serde_qs" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a" +checksum = "8cac3f1e2ca2fe333923a1ae72caca910b98ed0630bb35ef6f8c8517d6e81afa" dependencies = [ - "dtoa", - "itoa 0.4.8", + "percent-encoding", "serde", - "url 1.7.2", + "thiserror", ] [[package]] @@ -1499,46 +926,56 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 1.0.6", + "itoa", "ryu", "serde", ] [[package]] -name = "slab" -version = "0.4.8" +name = "serde_with" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +checksum = "07ff71d2c147a7b57362cead5e22f772cd52f6ab31cfcd9edcd7f6aeb2a0afbe" dependencies = [ - "autocfg 1.1.0", + "base64 0.13.1", + "chrono", + "hex", + "indexmap", + "serde", + "serde_json", + "serde_with_macros", + "time 0.3.22", ] [[package]] -name = "smallvec" -version = "0.6.14" +name = "serde_with_macros" +version = "2.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +checksum = "881b6f881b17d13214e5d494c939ebab463d01264ce1811e9d4ac3a882e7695f" dependencies = [ - "maybe-uninit", + "darling", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "socket2" -version = "0.4.9" +name = "slab" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ - "libc", - "winapi 0.3.9", + "autocfg", ] [[package]] -name = "string" -version = "0.2.1" +name = "socket2" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" dependencies = [ - "bytes 0.4.12", + "libc", + "winapi", ] [[package]] @@ -1549,9 +986,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" dependencies = [ "proc-macro2", "quote", @@ -1559,40 +996,37 @@ dependencies = [ ] [[package]] -name = "syn" -version = "2.0.18" +name = "tempfile" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32d41677bcbe24c20c52e7c70b0d8db04134c5d1066bf98662e2871ad200ea3e" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "autocfg", + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys 0.48.0", ] [[package]] -name = "synstructure" -version = "0.12.6" +name = "thiserror" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", + "thiserror-impl", ] [[package]] -name = "tempfile" -version = "3.6.0" +name = "thiserror-impl" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" +checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ - "autocfg 1.1.0", - "cfg-if 1.0.0", - "fastrand", - "redox_syscall 0.3.5", - "rustix", - "windows-sys 0.48.0", + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -1603,99 +1037,65 @@ checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" dependencies = [ "libc", "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", + "winapi", ] [[package]] -name = "tinyvec" -version = "1.6.0" +name = "time" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "ea9e1b3cf1243ae005d9e74085d4d542f3125458f3a81af210d901dcd7411efd" dependencies = [ - "tinyvec_macros", + "itoa", + "serde", + "time-core", + "time-macros", ] [[package]] -name = "tinyvec_macros" +name = "time-core" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] -name = "tokio" -version = "0.1.22" +name = "time-macros" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" dependencies = [ - "bytes 0.4.12", - "futures", - "mio 0.6.23", - "num_cpus", - "tokio-current-thread", - "tokio-executor", - "tokio-io", - "tokio-reactor", - "tokio-tcp", - "tokio-threadpool", - "tokio-timer", + "time-core", ] [[package]] -name = "tokio" -version = "1.28.2" +name = "tinyvec" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" dependencies = [ - "autocfg 1.1.0", - "bytes 1.4.0", - "libc", - "mio 0.8.8", - "num_cpus", - "pin-project-lite", - "socket2", - "windows-sys 0.48.0", + "tinyvec_macros", ] [[package]] -name = "tokio-buf" +name = "tinyvec_macros" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" -dependencies = [ - "bytes 0.4.12", - "either", - "futures", -] - -[[package]] -name = "tokio-current-thread" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1de0e32a83f131e002238d7ccde18211c0a5397f60cbfffcb112868c2e0e20e" -dependencies = [ - "futures", - "tokio-executor", -] - -[[package]] -name = "tokio-executor" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb2d1b8f4548dbf5e1f7818512e9c406860678f29c300cdf0ebac72d1a3a1671" -dependencies = [ - "crossbeam-utils", - "futures", -] +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] -name = "tokio-io" -version = "0.1.13" +name = "tokio" +version = "1.28.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" +checksum = "94d7b1cfd2aa4011f2de74c2c4c63665e27a71006b0a192dcd2710272e73dfa2" dependencies = [ - "bytes 0.4.12", - "futures", - "log", + "autocfg", + "bytes", + "libc", + "mio", + "num_cpus", + "pin-project-lite", + "socket2", + "windows-sys 0.48.0", ] [[package]] @@ -1705,79 +1105,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", - "tokio 1.28.2", -] - -[[package]] -name = "tokio-reactor" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09bc590ec4ba8ba87652da2068d150dcada2cfa2e07faae270a5e0409aa51351" -dependencies = [ - "crossbeam-utils", - "futures", - "lazy_static", - "log", - "mio 0.6.23", - "num_cpus", - "parking_lot", - "slab", - "tokio-executor", - "tokio-io", - "tokio-sync", -] - -[[package]] -name = "tokio-sync" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfe50152bc8164fcc456dab7891fa9bf8beaf01c5ee7e1dd43a397c3cf87dee" -dependencies = [ - "fnv", - "futures", -] - -[[package]] -name = "tokio-tcp" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98df18ed66e3b72e742f185882a9e201892407957e45fbff8da17ae7a7c51f72" -dependencies = [ - "bytes 0.4.12", - "futures", - "iovec", - "mio 0.6.23", - "tokio-io", - "tokio-reactor", -] - -[[package]] -name = "tokio-threadpool" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df720b6581784c118f0eb4310796b12b1d242a7eb95f716a8367855325c25f89" -dependencies = [ - "crossbeam-deque", - "crossbeam-queue", - "crossbeam-utils", - "futures", - "lazy_static", - "log", - "num_cpus", - "slab", - "tokio-executor", -] - -[[package]] -name = "tokio-timer" -version = "0.2.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93044f2d313c95ff1cb7809ce9a7a05735b012288a888b62d4434fd58c94f296" -dependencies = [ - "crossbeam-utils", - "futures", - "slab", - "tokio-executor", + "tokio", ] [[package]] @@ -1786,11 +1114,11 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ - "bytes 1.4.0", + "bytes", "futures-core", "futures-sink", "pin-project-lite", - "tokio 1.28.2", + "tokio", "tracing", ] @@ -1806,7 +1134,7 @@ version = "0.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "pin-project-lite", "tracing-core", ] @@ -1826,24 +1154,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" -[[package]] -name = "try_from" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "283d3b89e1368717881a9d51dad843cc435380d8109c9e47d38780a324698d8b" -dependencies = [ - "cfg-if 0.1.10", -] - -[[package]] -name = "unicase" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" -dependencies = [ - "version_check", -] - [[package]] name = "unicode-bidi" version = "0.3.13" @@ -1865,23 +1175,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "unicode-xid" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" - -[[package]] -name = "url" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a" -dependencies = [ - "idna 0.1.5", - "matches", - "percent-encoding 1.0.1", -] - [[package]] name = "url" version = "2.4.0" @@ -1889,17 +1182,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" dependencies = [ "form_urlencoded", - "idna 0.4.0", - "percent-encoding 2.3.0", + "idna", + "percent-encoding", ] [[package]] name = "uuid" -version = "0.7.4" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90dbc611eb48397705a6b0f6e917da23ae517e4d127123d2cf7674206627d32a" +checksum = "0fa2982af2eec27de306107c027578ff7f423d65f7250e40ce0fea8f45248b81" dependencies = [ - "rand", + "getrandom", + "serde", ] [[package]] @@ -1908,23 +1202,6 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "want" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6395efa4784b027708f7451087e647ec73cc74f5d9bc2e418404248d679a230" -dependencies = [ - "futures", - "log", - "try-lock", -] - [[package]] name = "want" version = "0.3.0" @@ -1953,7 +1230,7 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "wasm-bindgen-macro", ] @@ -1968,7 +1245,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.18", + "syn", "wasm-bindgen-shared", ] @@ -1978,7 +1255,7 @@ version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -2002,7 +1279,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.18", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2023,12 +1300,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "winapi" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" - [[package]] name = "winapi" version = "0.3.9" @@ -2039,12 +1310,6 @@ dependencies = [ "winapi-x86_64-pc-windows-gnu", ] -[[package]] -name = "winapi-build" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" - [[package]] name = "winapi-i686-pc-windows-gnu" version = "0.4.0" @@ -2057,6 +1322,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets", +] + [[package]] name = "windows-sys" version = "0.42.0" @@ -2180,30 +1454,11 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" -[[package]] -name = "winreg" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2986deb581c4fe11b621998a5e53361efe6b48a151178d0cd9eeffa4dc6acc9" -dependencies = [ - "winapi 0.3.9", -] - [[package]] name = "winreg" version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" dependencies = [ - "winapi 0.3.9", -] - -[[package]] -name = "ws2_32-sys" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e" -dependencies = [ - "winapi 0.2.8", - "winapi-build", + "winapi", ] diff --git a/Cargo.toml b/Cargo.toml index f2ff613..6748dd8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,10 +5,10 @@ authors = ["Magnus Bergmark "] edition = "2018" [dependencies] -cloudflare = { git = "https://github.com/Mange/cloudflare-rs", branch = "zone-dns-update" } -reqwest = { version = "0.11.18", features = ["blocking"] } -regex = "1.8.4" +cloudflare = "0.10.1" dotenv = "0.15.0" +regex = "1.8.4" +reqwest = { version = "0.11.18", features = ["blocking"] } [dependencies.clap] version = "4.3.3" diff --git a/src/main.rs b/src/main.rs index 31866e8..80d3e43 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,19 @@ -use clap::Parser; -use cloudflare::{ - zones::dns::{DnsRecord, RecordType}, - Cloudflare, -}; +use clap::{Args, Parser}; +use cloudflare::endpoints::dns::{self, DnsContent}; +use cloudflare::endpoints::zone; +use cloudflare::framework::apiclient::ApiClient; +use cloudflare::framework::auth::Credentials; +use cloudflare::framework::response::{ApiErrors, ApiFailure}; +use cloudflare::framework::{Environment, HttpApiClientConfig}; +use cloudflare::{endpoints::dns::DnsRecord, framework::HttpApiClient as CloudflareClient}; use dotenv::dotenv; use regex::Regex; use reqwest::blocking::{Client, ClientBuilder}; +use reqwest::Url; use std::collections::HashMap; +use std::net::Ipv4Addr; use std::time::Duration; -const DEFAULT_CLOUDFLARE_API_URL: &str = "https://api.cloudflare.com/client/v4/"; const IP_SERVICE_URLS: [&str; 7] = [ // HTTPS sources "https://checkip.amazonaws.com/", @@ -41,51 +45,84 @@ struct Options { #[arg(long = "dry-run", short = 'n')] dry_run: bool, - /// Talk to all available IP services and check that an absolute majority of them have the same - /// answer before making any changes. Use this if you are extra paranoid and don't want a - /// hacked or buggy service to be able to give you the wrong IP back. - #[arg(long = "verify")] - verify: bool, - - /// The Cloudflare account email. + /// The Cloudflare API token. #[arg( - long = "email", - short = 'e', - env = "CLOUDFLARE_API_EMAIL", - value_name = "EMAIL" + long = "token", + short = 't', + env = "CLOUDFLARE_API_TOKEN", + value_name = "TOKEN", + help_heading = "Cloudflare" )] - email: String, + api_token: String, - /// The Cloudflare API key. - #[arg( - long = "key", - short = 'k', - env = "CLOUDFLARE_API_KEY", - value_name = "KEY" - )] - api_key: String, - - /// The name of the zone to update ("example.com") - #[arg(env = "CLOUDFLARE_ZONE_NAME", value_name = "NAME")] - zone_name: String, + #[command(flatten)] + zone_options: ZoneOptions, /// The name of the DNS record to update ("example.com") #[arg(env = "CLOUDFLARE_DNS_RECORD", value_name = "RECORD")] dns_record: String, - /// Cloudflare API base URL. Default should work for all but the most specific cases. Note that - /// this URL *must* end with a trailing slash. + /// Custom Cloudflare API base URL. Will use Cloudflare Production if not specified. #[arg( long = "cloudflare-api-url", env = "CLOUDFLARE_API_URL", value_name = "URL", - default_value = DEFAULT_CLOUDFLARE_API_URL, + help_heading = "Cloudflare" )] - base_url: String, + base_url: Option, /// Request timeout for IP services. - #[arg(long = "ip-timeout", value_name = "SECONDS", default_value = "5")] + #[arg( + long = "ip-timeout", + value_name = "SECONDS", + default_value = "5", + help_heading = "IP" + )] ip_timeout: u16, + + /// Talk to all available IP services and check that an absolute majority of them have the same + /// answer before making any changes. Use this if you are extra paranoid and don't want a + /// hacked or buggy service to be able to give you the wrong IP back. + #[arg(long = "verify", help_heading = "IP")] + verify: bool, +} + +#[derive(Args, Debug)] +#[group(required = true, multiple = true)] +struct ZoneOptions { + /// The name of the zone to update ("6d3cf337c06d898fc4743293fda5ea3a"). + #[arg( + long = "zone-id", + env = "CLOUDFLARE_ZONE_ID", + value_name = "ID", + help_heading = "Cloudflare" + )] + id: Option, + + /// The name of the zone to update ("example.com"). If no Zone ID is set, then this name is + /// used to look up the Zone ID using the API. + #[arg( + long = "zone-name", + env = "CLOUDFLARE_ZONE_NAME", + value_name = "NAME", + help_heading = "Cloudflare" + )] + name: Option, +} + +impl Options { + fn cloudflare_credentials(&self) -> Credentials { + Credentials::UserAuthToken { + token: self.api_token.clone(), + } + } + + fn cloudflare_environment(&self) -> Environment { + match &self.base_url { + Some(url) => Environment::Custom(url.to_owned()), + None => Environment::Production, + } + } } fn main() -> Result<(), String> { @@ -98,90 +135,146 @@ fn main() -> Result<(), String> { )); } - let cloudflare = - Cloudflare::new(&options.api_key, &options.email, &options.base_url).map_err(|err| { - format!( - "Failed to initialize Cloudflare API client: {}", - format_error(err) - ) - })?; + let cloudflare = CloudflareClient::new( + options.cloudflare_credentials(), + HttpApiClientConfig::default(), + options.cloudflare_environment(), + ) + .map_err(|err| format!("Failed to initialize Cloudflare API client: {}", err))?; let zone_id = find_zone_id(&options, &cloudflare)?; + let current_record = fetch_current_dns_record(&cloudflare, &zone_id, &options.dns_record)?; - let ip = determine_external_ip(&options)?; + let external_ip = determine_external_ip(&options)?; - if current_record.content == ip { - eprintln!("Existing record is already correct. Exiting without changes."); - Ok(()) - } else { - if options.verbose { - eprintln!( - "IP difference: DNS is set to {dns}, while current IP is {current}", - dns = current_record.content, - current = ip - ); + match current_record.content { + DnsContent::A { content: ip } if ip == external_ip => { + eprintln!("Existing record is already correct. Exiting without changes."); + Ok(()) } + _ => { + if options.verbose { + eprintln!( + "IP difference: DNS is set to {dns:?}, while current IP is {current}", + dns = current_record.content, + current = external_ip + ); + } - if options.dry_run { - eprintln!("Would update DNS record to point to {}", ip); - Ok(()) - } else { - update_dns_record(&cloudflare, &zone_id, current_record, ip) + if options.dry_run { + eprintln!("Would update DNS record to point to {}", external_ip); + Ok(()) + } else { + update_dns_record(&cloudflare, &zone_id, current_record, external_ip) + } } } } -fn find_zone_id(options: &Options, cloudflare: &Cloudflare) -> Result { +fn find_zone_id(options: &Options, cloudflare: &CloudflareClient) -> Result { + if let Some(id) = &options.zone_options.id { + return Ok(id.to_owned()); + } + + let name = options + .zone_options + .name + .as_ref() + .ok_or_else(|| "Neither Zone ID or Zone Name was specified".to_string())?; + if options.verbose { eprint!("Resolving Zone ID… "); } - let zone_id = cloudflare::zones::get_zoneid(cloudflare, &options.zone_name) - .map_err(|err| format!("Failed to retreive zone ID: {}", format_error(err)))?; + let zones = cloudflare + .request(&zone::ListZones { + params: zone::ListZonesParams { + name: Some(name.to_owned()), + ..Default::default() + }, + }) + .map_err(|err| { + dbg!(&err); + format!( + "Failed to retreive zone ID: {}", + format_cloudflare_api_failure(err) + ) + })? + .result; + + let zone = zones + .into_iter() + .find(|zone| &zone.name == name) + .ok_or_else(|| { + format!( + "Failed to retrieve zone ID: No ones with name {} found", + name + ) + })?; if options.verbose { - eprintln!("OK. Found {}", zone_id); + eprintln!("OK. Found {}", zone.id); } - Ok(zone_id) + Ok(zone.id) } fn fetch_current_dns_record( - cloudflare: &Cloudflare, + cloudflare: &CloudflareClient, zone_id: &str, record_name: &str, ) -> Result { - cloudflare::zones::dns::list_dns_of_type(cloudflare, zone_id, RecordType::A) - .map_err(|err| format!("Failed to list DNS A records: {}", format_error(err))) - .and_then(|list| { - list.into_iter() - .find(|record| record.name == record_name) - .ok_or_else(|| format!("Could not find A record for {}", record_name)) - }) + let request = dns::ListDnsRecords { + zone_identifier: zone_id, + params: dns::ListDnsRecordsParams { + name: Some(record_name.to_owned()), + ..Default::default() + }, + }; + + let records = cloudflare + .request(&request) + .map_err(|err| { + format!( + "Failed to list DNS records for zone {}: {}", + zone_id, + format_cloudflare_api_failure(err) + ) + })? + .result; + + records + .into_iter() + .find(|record| record.name == record_name) + .ok_or_else(|| format!("Could not find A record for {}", record_name)) } fn update_dns_record( - cloudflare: &Cloudflare, + cloudflare: &CloudflareClient, zone_id: &str, current_record: DnsRecord, - new_ip: String, + new_ip: Ipv4Addr, ) -> Result<(), String> { - use cloudflare::zones::dns::UpdateDnsRecord; - - cloudflare::zones::dns::update_dns_entry( - cloudflare, - zone_id, - ¤t_record.id, - &UpdateDnsRecord { - record_type: current_record.record_type, - name: current_record.name.clone(), - content: new_ip, + let request = dns::UpdateDnsRecord { + zone_identifier: zone_id, + identifier: ¤t_record.id, + params: dns::UpdateDnsRecordParams { + name: ¤t_record.name, + content: DnsContent::A { content: new_ip }, ttl: None, proxied: None, }, - ) - .map_err(|err| format!("Failed to update DNS record: {}", format_error(err))) - .map(|_| ()) + }; + + cloudflare + .request(&request) + .map_err(|err| { + format!( + "Failed to update DNS record: {}", + format_cloudflare_api_failure(err) + ) + }) + .map(|_| ()) } fn http_client(options: &Options) -> Result { @@ -191,7 +284,7 @@ fn http_client(options: &Options) -> Result { .map_err(|error| format!("Failed to construct HTTP client: {}", error)) } -fn determine_external_ip(options: &Options) -> Result { +fn determine_external_ip(options: &Options) -> Result { if options.verify { determine_external_ip_with_verification(options) } else { @@ -199,7 +292,13 @@ fn determine_external_ip(options: &Options) -> Result { } } -fn determine_external_ip_without_verification(options: &Options) -> Result { +fn parse_ip(string: &str) -> Result { + string + .parse() + .map_err(|err| format!("Failed to parse IP address {}: {}", string, err)) +} + +fn determine_external_ip_without_verification(options: &Options) -> Result { let matcher: Regex = IPV4_MATCHER .parse() .expect("Programmer error: Invalid regexp"); @@ -223,7 +322,7 @@ fn determine_external_ip_without_verification(options: &Options) -> Result { eprintln!("{}", ip); - return Ok(ip.clone()); + return parse_ip(ip); } Ok(None) => { if options.verbose { @@ -244,7 +343,7 @@ fn determine_external_ip_without_verification(options: &Options) -> Result Result { +fn determine_external_ip_with_verification(options: &Options) -> Result { let matcher: Regex = IPV4_MATCHER .parse() .expect("Programmer error: Invalid regexp"); @@ -295,7 +394,7 @@ fn determine_external_ip_with_verification(options: &Options) -> Result { eprintln!("Warning: Some services disagree on IP!"); @@ -309,7 +408,7 @@ fn determine_external_ip_with_verification(options: &Options) -> Result Option { .map(|captures| captures[0].to_string()) } -fn format_error(error: cloudflare::Error) -> String { - use cloudflare::Error; - - match error { - Error::NoResultsReturned => "No results returned".into(), - Error::InvalidOptions => "Invalid options".into(), - Error::NotSuccess => "API request failed".into(), - Error::Reqwest(cause) => format!("Network error: {}", cause), - Error::Json(cause) => format!("JSON error: {}", cause), - Error::Io(cause) => format!("IO error: {}", cause), - Error::Url(cause) => format!("URL error: {}", cause), +fn format_cloudflare_api_failure(failure: ApiFailure) -> String { + match failure { + ApiFailure::Error(status, errors) => format!( + "Status code {status}:\n {errors}", + status = status, + errors = format_cloudflare_errors(errors), + ), + ApiFailure::Invalid(err) => err.to_string(), } } + +fn format_cloudflare_errors(errors: ApiErrors) -> String { + errors + .errors + .iter() + .map(|error| format!("{}: {}", error.code, error.message)) + .collect::>() + .join("\n ") +}