diff --git a/.github/workflows/check-test-and-lint.yaml b/.github/workflows/check-test-and-lint.yaml deleted file mode 100644 index 46d338c..0000000 --- a/.github/workflows/check-test-and-lint.yaml +++ /dev/null @@ -1,69 +0,0 @@ -on: - pull_request: - push: - paths: - - "src/**" - - ".github/workflows/check-test-and-lint.yaml" - -name: Check, Test and Lint - -jobs: - check: - name: Check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - uses: actions-rs/cargo@v1 - with: - command: check - - test: - name: Test Suite - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - uses: actions-rs/cargo@v1 - with: - command: test - - fmt: - name: Rustfmt - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - profile: minimal - toolchain: stable - override: true - - run: rustup component add rustfmt - - uses: actions-rs/cargo@v1 - with: - command: fmt - args: --all -- --check - - clippy: - name: Clippy - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - components: clippy - override: true - - uses: actions-rs/clippy-check@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - args: --all-features - name: Clippy Output diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..222d26a --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,69 @@ +on: + push: + branches: [main] + pull_request: + +name: CI + +jobs: + check: + name: Check ${{ matrix.os }}, ${{ matrix.rust }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + rust: [stable, 1.82.0, nightly] + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + - run: cargo check + + test: + name: Test Suite ${{ matrix.os }}, ${{ matrix.rust }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + rust: [stable, 1.82.0, nightly] + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + - run: cargo test + + fmt: + name: Rustfmt ${{ matrix.os }}, ${{ matrix.rust }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + rust: [stable, 1.82.0, nightly] + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + components: rustfmt + - run: cargo fmt --all -- --check + + clippy: + name: Clippy ${{ matrix.os }}, ${{ matrix.rust }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + rust: [stable, 1.82.0, nightly] + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ matrix.rust }} + components: clippy + - run: cargo clippy -- -D warnings diff --git a/.github/workflows/publish-crate.yaml b/.github/workflows/publish-crate.yaml index c8f77e5..9bb5177 100644 --- a/.github/workflows/publish-crate.yaml +++ b/.github/workflows/publish-crate.yaml @@ -3,10 +3,10 @@ on: branches: - main paths: - - 'src/**' - - '**/Cargo.lock' - - '**/Cargo.toml' - + - "src/**" + - "**/Cargo.lock" + - "**/Cargo.toml" + name: Publish crate jobs: @@ -16,11 +16,10 @@ jobs: PROJECT_NAME: aletheia runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master with: toolchain: stable - override: true - - uses: katyo/publish-crates@v1 + - uses: katyo/publish-crates@v2 with: - registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }} \ No newline at end of file + registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 38cb671..7e718aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) +## [1.0.0] - 2025-07-02 + +### Changed +- [**BREAKING CHANGE**] `GuardianContentClient` no longer needs to be mutable. To account for this change, requests must be built with the `.build_request()` method to be called on the client. An example can be found in the `README.md` file. +The motivation for this change is to be able to share the client between multiple threads without resorting to synchronisation primitives. +- The client no longer prints to stderr if the Guardian Content API responds with an error. The client now returns an `Error` variant depending on the type of error, so that downstream consumers can deal with the errors as they wish. +- Removed the `aletheia::Result` type. +- Upgraded several dependencies. + +### Added +- Added MSRV to the project + +### Fixed +- The `pages` field in the `SearchResponse` struct is now of type `Option` (previously `Option`) to account for the API responding with `-1` when setting the page size to `0` on the client. + ## [0.1.6] - 2022-12-28 ### Added diff --git a/Cargo.lock b/Cargo.lock index f24e600..b9dad01 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,9 +2,24 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aletheia" -version = "0.1.6" +version = "1.0.0" dependencies = [ "chrono", "reqwest", @@ -16,6 +31,12 @@ dependencies = [ "tokio", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -25,79 +46,92 @@ dependencies = [ "libc", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" -version = "1.0.1" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "backtrace" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] [[package]] name = "base64" -version = "0.13.0" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "1.3.2" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" [[package]] name = "bumpalo" -version = "3.8.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytes" -version = "1.1.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.0.72" +version = "1.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "serde", - "time", "wasm-bindgen", - "winapi", -] - -[[package]] -name = "codespan-reporting" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" -dependencies = [ - "termcolor", - "unicode-width", + "windows-link", ] [[package]] name = "core-foundation" -version = "0.9.2" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ "core-foundation-sys", "libc", @@ -105,62 +139,51 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "cxx" -version = "1.0.85" +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5add3fc1717409d029b20c5b6903fc0c0b02fa6741d820054f4a2efa5e5816fd" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ - "cc", - "cxxbridge-flags", - "cxxbridge-macro", - "link-cplusplus", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "cxx-build" -version = "1.0.85" +name = "encoding_rs" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4c87959ba14bc6fbc61df77c3fcfe180fc32b93538c4f1031dd802ccb5f2ff0" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ - "cc", - "codespan-reporting", - "once_cell", - "proc-macro2", - "quote", - "scratch", - "syn", + "cfg-if", ] [[package]] -name = "cxxbridge-flags" -version = "1.0.85" +name = "equivalent" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69a3e162fde4e594ed2b07d0f83c6c67b745e7f28ce58c6df5e6b6bef99dfb59" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] -name = "cxxbridge-macro" -version = "1.0.85" +name = "errno" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e7e2adeb6a0d4a282e581096b06e1791532b7d576dcde5ccd9382acf55db8e6" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ - "proc-macro2", - "quote", - "syn", + "libc", + "windows-sys 0.60.2", ] [[package]] -name = "encoding_rs" -version = "0.8.30" +name = "fastrand" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df" -dependencies = [ - "cfg-if", -] +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fnv" @@ -185,46 +208,45 @@ checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] name = "form_urlencoded" -version = "1.0.1" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" dependencies = [ - "matches", "percent-encoding", ] [[package]] name = "futures-channel" -version = "0.3.25" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", ] [[package]] name = "futures-core" -version = "0.3.25" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-sink" -version = "0.3.25" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.25" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.25" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-task", @@ -234,26 +256,44 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.3" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", - "wasi", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + [[package]] name = "h2" -version = "0.3.9" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f072413d126e57991455e0a922b31e4c8ba7c2ffbebf6b78b4f8521397d65cd" +checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", "http", "indexmap", "slab", @@ -264,263 +304,379 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.15.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" [[package]] name = "heck" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "http" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ - "libc", + "bytes", + "fnv", + "itoa", ] [[package]] -name = "http" -version = "0.2.5" +name = "http-body" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "fnv", - "itoa 0.4.8", + "http", ] [[package]] -name = "http-body" -version = "0.4.4" +name = "http-body-util" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", + "futures-core", "http", + "http-body", "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" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" -version = "0.14.16" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "h2", "http", "http-body", "httparse", - "httpdate", - "itoa 0.4.8", + "itoa", "pin-project-lite", - "socket2", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + [[package]] name = "hyper-tls" -version = "0.5.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ "bytes", + "http-body-util", "hyper", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", ] [[package]] name = "iana-time-zone" -version = "0.1.53" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", - "winapi", + "windows-core", ] [[package]] name = "iana-time-zone-haiku" -version = "0.1.1" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ - "cxx", - "cxx-build", + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", ] [[package]] name = "idna" -version = "0.2.3" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "indexmap" -version = "1.9.2" +name = "idna_adapter" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885e79c1fc4b10f0e172c475f458b7f7b93061064d98c3293e98c5ba0c8b399" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ - "autocfg", - "hashbrown", + "icu_normalizer", + "icu_properties", ] [[package]] -name = "instant" -version = "0.1.12" +name = "indexmap" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" dependencies = [ - "cfg-if", + "equivalent", + "hashbrown", ] [[package]] name = "ipnet" -version = "2.3.1" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] -name = "itoa" -version = "0.4.8" +name = "iri-string" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] [[package]] name = "itoa" -version = "1.0.1" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" -version = "0.3.55" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] [[package]] -name = "lazy_static" -version = "1.4.0" +name = "libc" +version = "0.2.174" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] -name = "libc" -version = "0.2.139" +name = "linux-raw-sys" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] -name = "link-cplusplus" -version = "1.0.8" +name = "litemap" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" -dependencies = [ - "cc", -] +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" -version = "0.4.5" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ + "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "matches" -version = "0.1.9" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "memchr" -version = "2.4.1" +version = "2.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" [[package]] name = "mime" -version = "0.3.16" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] -name = "mio" -version = "0.7.14" +name = "miniz_oxide" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ - "libc", - "log", - "miow", - "ntapi", - "winapi", + "adler2", ] [[package]] -name = "miow" -version = "0.3.7" +name = "mio" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ - "winapi", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", ] [[package]] name = "native-tls" -version = "0.2.8" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -532,77 +688,68 @@ dependencies = [ "tempfile", ] -[[package]] -name = "ntapi" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" -dependencies = [ - "winapi", -] - -[[package]] -name = "num-integer" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" -version = "0.2.14" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] -name = "num_cpus" -version = "1.13.1" +name = "object" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ - "hermit-abi", - "libc", + "memchr", ] [[package]] name = "once_cell" -version = "1.9.0" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "openssl" -version = "0.10.38" +version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ "bitflags", "cfg-if", "foreign-types", "libc", "once_cell", + "openssl-macros", "openssl-sys", ] +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "openssl-probe" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.72" +version = "0.9.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e46109c383602735fa0a2e48dd2b7c892b048e1bf69e5c3b1d804b7d9c203cb" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" dependencies = [ - "autocfg", "cc", "libc", "pkg-config", @@ -611,40 +758,38 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.11.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ - "instant", "lock_api", "parking_lot_core", ] [[package]] name = "parking_lot_core" -version = "0.8.5" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", - "instant", "libc", "redox_syscall", "smallvec", - "winapi", + "windows-targets 0.52.6", ] [[package]] name = "percent-encoding" -version = "2.1.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.7" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -654,166 +799,190 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.24" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] -name = "ppv-lite86" -version = "0.2.15" +name = "potential_utf" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] [[package]] name = "proc-macro2" -version = "1.0.49" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a8eca9f9c4ffde41714334dee777596264c7825420f521abc92b5b5deb63a5" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] -name = "rand" -version = "0.8.4" +name = "r-efi" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core", -] +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] name = "redox_syscall" -version = "0.2.10" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ "bitflags", ] -[[package]] -name = "remove_dir_all" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" -dependencies = [ - "winapi", -] - [[package]] name = "reqwest" -version = "0.11.8" +version = "0.12.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c4e0a76dc12a116108933f6301b95e83634e0c47b0afbed6abbaa0601e99258" +checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" dependencies = [ "base64", "bytes", "encoding_rs", "futures-core", - "futures-util", + "h2", "http", "http-body", + "http-body-util", "hyper", + "hyper-rustls", "hyper-tls", - "ipnet", + "hyper-util", "js-sys", - "lazy_static", "log", "mime", "native-tls", "percent-encoding", "pin-project-lite", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "tokio", "tokio-native-tls", + "tower", + "tower-http", + "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "winreg", ] [[package]] -name = "rustversion" -version = "1.0.6" +name = "ring" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" - +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[package]] -name = "ryu" -version = "1.0.9" +name = "rustc-demangle" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" +checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" [[package]] -name = "schannel" -version = "0.1.19" +name = "rustix" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "lazy_static", - "winapi", + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.59.0", ] [[package]] -name = "scopeguard" -version = "1.1.0" +name = "rustls" +version = "0.23.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] [[package]] -name = "scratch" -version = "1.0.3" +name = "rustls-pki-types" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "security-framework" -version = "2.4.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags", "core-foundation", @@ -824,9 +993,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.4.2" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -834,18 +1003,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.151" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fed41fc1a24994d044e6db6935e69511a1153b52c15eb42493b26fa87feba0" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.151" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "255abe9a125a985c05190d687b320c12f9b1f0b99445e608c21ba0782c719ad8" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -854,69 +1023,82 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.91" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c235533714907a8c2464236f5c4b2a17262ef1bd71f38f35ea592c8da6883" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ - "itoa 1.0.1", + "itoa", + "memchr", "ryu", "serde", ] [[package]] name = "serde_urlencoded" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 0.4.8", + "itoa", "ryu", "serde", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" -version = "1.4.0" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ "libc", ] [[package]] name = "slab" -version = "0.4.5" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" [[package]] name = "smallvec" -version = "1.7.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" [[package]] name = "socket2" -version = "0.4.2" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", - "winapi", + "windows-sys 0.52.0", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "strum" -version = "0.24.1" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +checksum = "f64def088c51c9510a8579e3c5d67c65349dcf755e5479ad3d010aa6454e2c32" [[package]] name = "strum_macros" -version = "0.24.3" +version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +checksum = "c77a8c5abcaf0f9ce05d62342b7d298c346515365c36b673df4ebe3ced01fde8" dependencies = [ "heck", "proc-macro2", @@ -925,11 +1107,17 @@ dependencies = [ "syn", ] +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" -version = "1.0.107" +version = "2.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" dependencies = [ "proc-macro2", "quote", @@ -937,98 +1125,112 @@ dependencies = [ ] [[package]] -name = "tempfile" -version = "3.2.0" +name = "sync_wrapper" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" dependencies = [ - "cfg-if", - "libc", - "rand", - "redox_syscall", - "remove_dir_all", - "winapi", + "futures-core", ] [[package]] -name = "termcolor" -version = "1.1.3" +name = "synstructure" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ - "winapi-util", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "thiserror" -version = "1.0.38" +name = "system-configuration" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "thiserror-impl", + "bitflags", + "core-foundation", + "system-configuration-sys", ] [[package]] -name = "thiserror-impl" -version = "1.0.38" +name = "system-configuration-sys" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" dependencies = [ - "proc-macro2", - "quote", - "syn", + "core-foundation-sys", + "libc", ] [[package]] -name = "time" -version = "0.1.44" +name = "tempfile" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ - "libc", - "wasi", - "winapi", + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys 0.59.0", ] [[package]] -name = "tinyvec" -version = "1.5.1" +name = "thiserror" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "tinyvec_macros", + "thiserror-impl", ] [[package]] -name = "tinyvec_macros" -version = "0.1.0" +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tinystr" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] [[package]] name = "tokio" -version = "1.15.0" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbbf1c778ec206785635ce8ad57fe52b3009ae9e0c9f574a728f3049d3e55838" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ + "backtrace", "bytes", "libc", - "memchr", "mio", - "num_cpus", - "once_cell", "parking_lot", "pin-project-lite", "signal-hook-registry", + "socket2", "tokio-macros", - "winapi", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "1.7.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b557f72f448c511a979e2564e55d74e6c4432fc96ff4f6241bc6bded342643b7" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", @@ -1037,99 +1239,136 @@ dependencies = [ [[package]] name = "tokio-native-tls" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-util" -version = "0.6.9" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" dependencies = [ "bytes", "futures-core", "futures-sink", - "log", "pin-project-lite", "tokio", ] +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + [[package]] name = "tower-service" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.29" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ - "cfg-if", "pin-project-lite", "tracing-core", ] [[package]] name = "tracing-core" -version = "0.1.21" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" dependencies = [ - "lazy_static", + "once_cell", ] [[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" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" - -[[package]] -name = "unicode-normalization" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" -dependencies = [ - "tinyvec", -] +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] -name = "unicode-width" -version = "0.1.10" +name = "untrusted" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.2.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", ] +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "vcpkg" version = "0.2.15" @@ -1138,38 +1377,47 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "want" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" dependencies = [ - "log", "try-lock", ] [[package]] name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] [[package]] name = "wasm-bindgen" -version = "0.2.78" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.78" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", - "lazy_static", "log", "proc-macro2", "quote", @@ -1179,21 +1427,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.28" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.78" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1201,9 +1450,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.78" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", @@ -1214,56 +1463,343 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.78" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" -version = "0.3.55" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", ] [[package]] -name = "winapi" -version = "0.3.9" +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "proc-macro2", + "quote", + "syn", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows-link" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] -name = "winapi-util" -version = "0.1.5" +name = "windows-registry" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" +dependencies = [ + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ - "winapi", + "bitflags", ] [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "writeable" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] -name = "winreg" -version = "0.7.0" +name = "yoke" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ - "winapi", + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] diff --git a/Cargo.toml b/Cargo.toml index a49903b..05e27d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "aletheia" -version = "0.1.6" +version = "1.0.0" edition = "2021" description = "A client library for the Guardian's content API" license = "MIT" @@ -10,11 +10,11 @@ keywords = ["guardian", "api", "client", "library", "http"] categories = ["api-bindings", "parsing", "web-programming::http-client"] [dependencies] -chrono = { version = "0.4", features = ["serde"] } +chrono = { version = "0.4.41", features = ["serde"] } tokio = { version = "1", features = ["full"] } -reqwest = { version = "0.11", features = ["json"] } -serde = { version = "1.0.151", features = ["derive"] } -serde_json = { version = "1.0.91", features = ["raw_value"] } -strum = "0.24.1" -strum_macros = "0.24.3" -thiserror = "1.0.38" +reqwest = { version = "0.12.22", features = ["json"] } +serde = { version = "1.0.219", features = ["derive"] } +serde_json = { version = "1.0.140", features = ["raw_value"] } +strum = "0.27.1" +strum_macros = "0.27.1" +thiserror = "2.0.12" diff --git a/README.md b/README.md index 2b4cbc1..4a45529 100644 --- a/README.md +++ b/README.md @@ -4,40 +4,51 @@ Aletheia is an HTTP client library for [the Guardian](https://www.theguardian.com)'s [content API](https://open-platform.theguardian.com) written in Rust. +[![Crates.io][crates-badge]][crates-url] +[![Build Status][actions-badge]][actions-url] + +[crates-badge]: https://img.shields.io/crates/v/aletheia.svg +[crates-url]: https://crates.io/crates/aletheia +[actions-badge]: https://github.com/marsavar/aletheia/workflows/CI/badge.svg +[actions-url]: https://github.com/marsavar/aletheia/actions?query=workflow%3ACI+branch%3Amain + ## How to use it Aletheia requires Tokio as a dependency to execute asynchronous code.\ Simply add `aletheia` and `tokio` to the list of dependencies in your `Cargo.toml` file. ```toml [dependencies] -aletheia = "0.1.6" +aletheia = "1.0.0" tokio = { version = "1", features = ["full"] } ``` -You also need an API key to be able to make requests. -Keys can be requested [here](https://open-platform.theguardian.com/access/). +You also need an API key to be able to make requests. +Keys can be requested [here](https://open-platform.theguardian.com/access/). ## Example -Let's say you were interested in finding five film, play or album reviews with a rating of 5 stars +Let's say you were interested in finding five film, play or album reviews with a rating of 5 stars containing the word "politics" published from January to December 2022. The code would look something like the example below, and would consist of three steps: 1) Constructing the HTTP client 2) Building the query 3) Parsing the response [*](#debug) + ```rust use aletheia::enums::*; -use aletheia::{GuardianContentClient, Result}; +use aletheia::error::Error; +use aletheia::GuardianContentClient; #[tokio::main] -async fn main() -> Result<()> { +async fn main() -> Result<(), Error> { // The client is constructed by passing your API key // as the only parameter - let mut client = GuardianContentClient::new("your-api-key"); + let client = GuardianContentClient::new("YOUR_API_KEY"); // Query parameters are built incrementally let response = client + .build_request() .search("politics") .date_from(2022, 1, 1) .date_to(2022, 12, 31) @@ -98,4 +109,4 @@ println!("{response:#?}"); or by using the `dbg!` macro: ```rust dbg!(response); -``` \ No newline at end of file +``` diff --git a/clippy.toml b/clippy.toml new file mode 100644 index 0000000..c3aa642 --- /dev/null +++ b/clippy.toml @@ -0,0 +1 @@ +msrv = "1.82.0" diff --git a/src/enums.rs b/src/enums.rs index 725f02a..a91fdf1 100644 --- a/src/enums.rs +++ b/src/enums.rs @@ -93,12 +93,39 @@ pub enum Block<'a> { BodyPublishedSince(i64), } -#[derive(Clone, Display, Debug, Deserialize, Eq, PartialEq)] +#[derive(Clone, Display, Default, Debug, Deserialize, Eq, PartialEq)] #[strum(serialize_all = "kebab-case")] pub enum Endpoint { + #[default] Content, Tags, Sections, Editions, SingleItem, } + +/// Whether a trait matches the `All` variant +pub(crate) trait IsAll { + fn is_all(&self) -> bool; +} + +macro_rules! impl_is_all { + ($enum_type:ident) => { + impl IsAll for $enum_type { + fn is_all(&self) -> bool { + matches!(self, $enum_type::All) + } + } + }; + ($enum_type:ident <$lifetime:lifetime>) => { + impl<$lifetime> IsAll for $enum_type<$lifetime> { + fn is_all(&self) -> bool { + matches!(self, $enum_type::All) + } + } + }; +} + +impl_is_all!(Block<'a>); +impl_is_all!(Field); +impl_is_all!(Tag); diff --git a/src/error.rs b/src/error.rs index fb14803..e2849a7 100644 --- a/src/error.rs +++ b/src/error.rs @@ -6,4 +6,10 @@ use thiserror::Error; pub enum Error { #[error(transparent)] ClientError(#[from] reqwest::Error), + #[error(transparent)] + JoinError(#[from] tokio::task::JoinError), + #[error("Missing query parameter: {0}")] + MissingQueryParameter(&'static str), + #[error("API error: {0}")] + ApiError(String), } diff --git a/src/lib.rs b/src/lib.rs index 12d9d9f..0957e40 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -11,16 +11,17 @@ //! //! //! # Example -//! ``` -//! use std::error::Error; -//! use aletheia::{GuardianContentClient, Result}; +//! ```ignore +//! use aletheia::error::Error; +//! use aletheia::GuardianContentClient; //! use aletheia::enums::{Field, OrderBy, OrderDate}; //! //! #[tokio::main] -//! async fn main() -> Result<()> { -//! let mut client = GuardianContentClient::new("your-api-key"); +//! async fn main() -> Result<(), Error> { +//! let client = GuardianContentClient::new("YOUR_API_KEY"); //! //! let response = client +//! .build_request() //! .search("Elections") //! .page_size(10) //! .show_fields(vec![Field::Byline, Field::LastModified]) @@ -44,15 +45,11 @@ use crate::enums::*; use crate::error::Error; use crate::structs::*; use reqwest::header::{HeaderMap, HeaderValue}; -use reqwest::Client; +use reqwest::{Client, Url}; use std::collections::HashMap; use std::string::ToString; -const GUARDIAN_CONTENT_API: &str = "https://content.guardianapis.com"; - -/// A wrapper around Rust's [`core::result::Result`] which -/// defaults to `aletheia`'s own [`Error`] type. -pub type Result = core::result::Result; +const GUARDIAN_CONTENT_API_URL: &str = "https://content.guardianapis.com"; /// The main asynchronous client used to build requests to send to the Guardian's /// content API. This client maintains a private internal asynchronous client @@ -61,62 +58,37 @@ pub type Result = core::result::Result; pub struct GuardianContentClient { http_client: reqwest::Client, api_key: String, - base_url: String, + base_url: Url, +} + +#[derive(Debug, Clone)] +pub struct GuardianRequestBuilder { + http_client: Client, + base_url: Url, + api_key: String, request: HashMap, endpoint: Endpoint, } -impl GuardianContentClient { - /// Constructor for the client. - /// The constructor takes an API key which is then stored internally - /// in the struct. The client then uses the builder pattern - /// to add query parameters to the request. The query-building - /// methods as well as the terminal operation take a mutable borrow - /// of self. This allows the client not to be consumed after a request. - /// As a result, the client should be initialised with the `mut` keyword. - /// - /// API keys for the Guardian's content API can be requested at - /// - /// - /// # Example - /// ```ignore - /// let mut client = aletheia::GuardianContentClient::new("api-key-here"); - /// ``` - pub fn new(api_key: &str) -> GuardianContentClient { - Self { - http_client: Client::new(), - base_url: String::from(GUARDIAN_CONTENT_API), - api_key: String::from(api_key), - request: HashMap::new(), - endpoint: Endpoint::Content, - } - } - - fn add_api_key_to_headers(&self) -> HeaderMap { - let mut headers = HeaderMap::new(); - if !self.api_key.is_empty() { - headers.insert("api-key", HeaderValue::from_str(&self.api_key).unwrap()); - } - headers - } - +impl GuardianRequestBuilder { /// Specify the Guardian API endpoint to target. /// /// Can be one of: /// - [`Endpoint::Content`] (default): returns all pieces of content in the API. /// - [`Endpoint::Tags`]: returns all tags in the API. All Guardian content is manually - /// categorised using these tags, of which there are more than 50,000. + /// categorised using these tags, of which there are more than 50,000. /// - [`Endpoint::Sections`]: returns all sections in the API. /// - [`Endpoint::Editions`]: returns all editions in the API. Editions are the different /// front pages of the Guardian site (currently, there are editions for the United - /// Kingdom, the United States and Australia). + /// Kingdom, the United States and Australia). /// - [`Endpoint::SingleItem`]: returns all the data for a given single item id. - /// Here the term 'item' refers to either a piece of content, a tag, or a section. - /// The item endpoint matches the paths on theguardian.com. + /// Here the term 'item' refers to either a piece of content, a tag, or a section. + /// The item endpoint matches the paths on theguardian.com. /// /// # Example 1 /// ```ignore /// let response = client + /// .build_request() /// .endpoint(Endpoint::Tags) /// .search("food") /// .send() @@ -126,12 +98,13 @@ impl GuardianContentClient { /// # Example 2 /// ```ignore /// let response = client + /// .build_request() /// .endpoint(Endpoint::SingleItem) /// .search("books/2022/jan/01/2022-in-books-highlights-for-the-year-ahead") /// .send() /// .await?; /// ``` - pub fn endpoint(&mut self, endpoint: Endpoint) -> &mut GuardianContentClient { + pub fn endpoint(mut self, endpoint: Endpoint) -> Self { self.endpoint = endpoint; self } @@ -157,11 +130,12 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .send() /// .await?; /// ``` - pub fn search(&mut self, q: &str) -> &mut GuardianContentClient { + pub fn search(mut self, q: &str) -> Self { self.request.insert(String::from("q"), q.to_string()); self } @@ -175,13 +149,14 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .page(10) /// .send() /// .await?; /// ``` /// - pub fn page(&mut self, page: u32) -> &mut GuardianContentClient { + pub fn page(mut self, page: u32) -> GuardianRequestBuilder { self.request.insert(String::from("page"), page.to_string()); self } @@ -195,12 +170,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .page_size(20) /// .send() /// .await?; /// ``` - pub fn page_size(&mut self, page: u8) -> &mut GuardianContentClient { + pub fn page_size(mut self, page: u8) -> GuardianRequestBuilder { self.request .insert(String::from("page-size"), page.to_string()); self @@ -216,12 +192,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .order_by(OrderBy::Oldest) /// .send() /// .await?; /// ``` - pub fn order_by(&mut self, order_by: OrderBy) -> &mut GuardianContentClient { + pub fn order_by(mut self, order_by: OrderBy) -> GuardianRequestBuilder { self.request .insert(String::from("order-by"), order_by.to_string()); self @@ -237,12 +214,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .order_by(OrderDate::NewspaperEdition) /// .send() /// .await?; /// ``` - pub fn order_date(&mut self, order_date: OrderDate) -> &mut GuardianContentClient { + pub fn order_date(mut self, order_date: OrderDate) -> GuardianRequestBuilder { self.request .insert(String::from("order-date"), order_date.to_string()); self @@ -265,12 +243,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .show_fields(vec![Field::StarRating, Field::ShortUrl]) /// .send() /// .await?; /// ``` - pub fn show_fields(&mut self, show_fields: Vec) -> &mut GuardianContentClient { + pub fn show_fields(mut self, show_fields: Vec) -> GuardianRequestBuilder { let field_sequence = crate::helpers::generate_sequence(show_fields); self.request .insert(String::from("show-fields"), field_sequence); @@ -294,12 +273,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .show_tags(vec![Tag::Contributor, Tag::Type, Tag::Tone]) /// .send() /// .await?; /// ``` - pub fn show_tags(&mut self, show_tags: Vec) -> &mut GuardianContentClient { + pub fn show_tags(mut self, show_tags: Vec) -> GuardianRequestBuilder { let tag_sequence = crate::helpers::generate_sequence(show_tags); self.request.insert(String::from("show-tags"), tag_sequence); self @@ -320,12 +300,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .query_fields(vec![Field::Body]) /// .send() /// .await?; /// ``` - pub fn query_fields(&mut self, query_fields: Vec) -> &mut GuardianContentClient { + pub fn query_fields(mut self, query_fields: Vec) -> GuardianRequestBuilder { let field_sequence = crate::helpers::generate_sequence(query_fields); self.request .insert(String::from("query-fields"), field_sequence); @@ -337,16 +318,15 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .date_from(2020, 1, 1) /// .send() /// .await?; /// ``` - pub fn date_from(&mut self, year: i32, month: u32, day: u32) -> &mut GuardianContentClient { - self.request.insert( - String::from("from-date"), - format!("{}-{}-{}", year, month, day), - ); + pub fn date_from(mut self, year: i32, month: u32, day: u32) -> GuardianRequestBuilder { + self.request + .insert(String::from("from-date"), format!("{year}-{month}-{day}")); self } @@ -361,6 +341,7 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .datetime_from(2020, 1, 1, 12, 0, 0, 2) /// .send() @@ -368,7 +349,7 @@ impl GuardianContentClient { /// ``` #[allow(clippy::too_many_arguments)] pub fn datetime_from( - &mut self, + mut self, year: i32, month: u32, day: u32, @@ -376,7 +357,7 @@ impl GuardianContentClient { min: u32, sec: u32, timezone: i32, - ) -> &mut GuardianContentClient { + ) -> GuardianRequestBuilder { let formatted_datetime = crate::helpers::datetime(year, month, day, hour, min, sec, timezone); @@ -392,17 +373,16 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .date_from(2008, 1, 1) /// .date_to(2010, 12, 31) /// .send() /// .await?; /// ``` - pub fn date_to(&mut self, year: i32, month: u32, day: u32) -> &mut GuardianContentClient { - self.request.insert( - String::from("to-date"), - format!("{}-{}-{}", year, month, day), - ); + pub fn date_to(mut self, year: i32, month: u32, day: u32) -> GuardianRequestBuilder { + self.request + .insert(String::from("to-date"), format!("{year}-{month}-{day}")); self } @@ -417,6 +397,7 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .datetime_to(2016, 1, 1, 12, 0, 0, 5) /// .send() @@ -424,7 +405,7 @@ impl GuardianContentClient { /// ``` #[allow(clippy::too_many_arguments)] pub fn datetime_to( - &mut self, + mut self, year: i32, month: u32, day: u32, @@ -432,7 +413,7 @@ impl GuardianContentClient { min: u32, sec: u32, timezone: i32, - ) -> &mut GuardianContentClient { + ) -> GuardianRequestBuilder { let formatted_datetime = crate::helpers::datetime(year, month, day, hour, min, sec, timezone); @@ -456,6 +437,7 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .date_from(2015, 1, 1) /// .date_to(2018, 12, 31) @@ -463,7 +445,7 @@ impl GuardianContentClient { /// .send() /// .await?; /// ``` - pub fn use_date(&mut self, use_date: UseDate) -> &mut GuardianContentClient { + pub fn use_date(mut self, use_date: UseDate) -> GuardianRequestBuilder { self.request .insert(String::from("use-date"), use_date.to_string()); self @@ -474,12 +456,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .show_section(true) /// .send() /// .await?; /// ``` - pub fn show_section(&mut self, show_section: bool) -> &mut GuardianContentClient { + pub fn show_section(mut self, show_section: bool) -> GuardianRequestBuilder { self.request .insert(String::from("show-section"), show_section.to_string()); self @@ -490,12 +473,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .section("football") /// .send() /// .await?; /// ``` - pub fn section(&mut self, section: &str) -> &mut GuardianContentClient { + pub fn section(mut self, section: &str) -> GuardianRequestBuilder { self.request .insert(String::from("section"), section.to_string()); self @@ -506,12 +490,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .reference("isbn/9780718178949") /// .send() /// .await?; /// ``` - pub fn reference(&mut self, reference: &str) -> &mut GuardianContentClient { + pub fn reference(mut self, reference: &str) -> GuardianRequestBuilder { self.request .insert(String::from("reference"), reference.to_string()); self @@ -522,12 +507,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .reference_type("isbn") /// .send() /// .await?; /// ``` - pub fn reference_type(&mut self, reference_type: &str) -> &mut GuardianContentClient { + pub fn reference_type(mut self, reference_type: &str) -> GuardianRequestBuilder { self.request .insert(String::from("reference-type"), reference_type.to_string()); self @@ -538,12 +524,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .tag("technology/apple") /// .send() /// .await?; /// ``` - pub fn tag(&mut self, tag: &str) -> &mut GuardianContentClient { + pub fn tag(mut self, tag: &str) -> GuardianRequestBuilder { self.request.insert(String::from("tag"), tag.to_string()); self } @@ -553,12 +540,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .ids("world/2022/jan/01/funeral-of-desmond-tutu-takes-place-in-cape-town") /// .send() /// .await?; /// ``` - pub fn ids(&mut self, ids: &str) -> &mut GuardianContentClient { + pub fn ids(mut self, ids: &str) -> GuardianRequestBuilder { self.request.insert(String::from("ids"), ids.to_string()); self } @@ -568,12 +556,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .production_office("UK") /// .send() /// .await?; /// ``` - pub fn production_office(&mut self, production_office: &str) -> &mut GuardianContentClient { + pub fn production_office(mut self, production_office: &str) -> GuardianRequestBuilder { self.request.insert( String::from("production-office"), production_office.to_string(), @@ -587,12 +576,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .lang("en") /// .send() /// .await?; /// ``` - pub fn lang(&mut self, lang: &str) -> &mut GuardianContentClient { + pub fn lang(mut self, lang: &str) -> GuardianRequestBuilder { self.request.insert(String::from("lang"), lang.to_string()); self } @@ -603,12 +593,13 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .search("Elections") /// .star_rating(5) /// .send() /// .await?; /// ``` - pub fn star_rating(&mut self, star_rating: u8) -> &mut GuardianContentClient { + pub fn star_rating(mut self, star_rating: u8) -> GuardianRequestBuilder { self.request .insert(String::from("star-rating"), star_rating.to_string()); self @@ -620,6 +611,7 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .endpoint(Endpoint::Tags) /// .search("Elections") /// .tag_type("tv-and-radio/us-television") @@ -627,7 +619,7 @@ impl GuardianContentClient { /// .await?; /// /// ``` - pub fn tag_type(&mut self, r#type: &str) -> &mut GuardianContentClient { + pub fn tag_type(mut self, r#type: &str) -> GuardianRequestBuilder { self.request .insert(String::from("type"), r#type.to_string()); self @@ -653,13 +645,14 @@ impl GuardianContentClient { /// # Example /// ```ignore /// let response = client + /// .build_request() /// .endpoint(Endpoint::Tags) /// .search("Elections") /// .show_blocks(Block::BodyPublishedSince(1556529318000)) /// .send() /// .await?; /// ``` - pub fn show_blocks(&mut self, show_blocks: Vec) -> &mut GuardianContentClient { + pub fn show_blocks(mut self, show_blocks: Vec) -> GuardianRequestBuilder { let block_sequence = crate::helpers::generate_blocks(show_blocks); self.request .insert(String::from("show-blocks"), block_sequence); @@ -669,28 +662,50 @@ impl GuardianContentClient { /// Terminal operation that sends a GET request to the Guardian API. /// Once this function is called, all the query parameters constructed /// via the building methods are dropped. - pub async fn send(&mut self) -> Result { + pub async fn send(&mut self) -> Result { + let mut headers = HeaderMap::new(); + if !self.api_key.is_empty() { + headers.insert("api-key", HeaderValue::from_str(&self.api_key).unwrap()); + } + let endpoint = match self.endpoint { Endpoint::Content => String::from("search"), Endpoint::Tags => self.endpoint.to_string(), Endpoint::Sections => self.endpoint.to_string(), Endpoint::Editions => self.endpoint.to_string(), - Endpoint::SingleItem => self.request.get("q").unwrap().to_string(), + Endpoint::SingleItem => self + .request + .get("q") + .ok_or(Error::MissingQueryParameter("q"))? + .to_owned(), }; let queries = Vec::from_iter(self.request.iter()); + let mut url = self.base_url.clone(); + url.path_segments_mut().unwrap().push(&endpoint); + let search = self .http_client - .get(format!("{}/{}", self.base_url, endpoint)) - .headers(self.add_api_key_to_headers()) + .get(url) + .headers(headers) .query(&queries) .send() .await? .json::() .await?; - crate::helpers::std_err(&search.message, &search.response); + if let Some(err) = search.message { + return Err(Error::ApiError(err)); + } + + if let Some(response_content) = &search.response { + if response_content.status.as_deref() == Some("error") { + if let Some(message) = &response_content.message { + return Err(Error::ApiError(message.to_owned())); + } + } + } self.request.clear(); @@ -701,44 +716,90 @@ impl GuardianContentClient { } } -mod helpers { - use crate::enums::Block; - use crate::SearchResponse; - use chrono::{FixedOffset, LocalResult, TimeZone}; - use std::fmt::Display; - - pub(crate) fn std_err(message: &Option, response: &Option) { - if message.is_some() { - eprintln!("Error: {}", message.as_ref().unwrap()) +impl GuardianContentClient { + /// Constructor for the client. + /// The constructor takes an API key which is then stored internally + /// in the struct. The client then uses the builder pattern + /// to add query parameters to the request. The query-building + /// methods as well as the terminal operation take a mutable borrow + /// of self. This allows the client not to be consumed after a request. + /// As a result, the client should be initialised with the `mut` keyword. + /// + /// API keys for the Guardian's content API can be requested at + /// + /// + /// # Example + /// ```ignore + /// let client = aletheia::GuardianContentClient::new("YOUR_API_KEY"); + /// ``` + pub fn new(api_key: &str) -> GuardianContentClient { + Self { + http_client: Client::new(), + // Safety: it's ok to unwrap here since we are passing a valid URL string + base_url: Url::parse(GUARDIAN_CONTENT_API_URL).unwrap(), + api_key: String::from(api_key), } + } - if response.is_some() { - let response_content = response.as_ref().unwrap(); - if response_content.status.is_some() - && response_content.status.as_ref().unwrap() == "error" - && response_content.message.is_some() - { - eprintln!("Error: {}", response_content.message.as_ref().unwrap()); - } + /// Start building a new request. + /// This method returns `GuardianRequestBuilder`, which allows you to + /// build queries using the builder pattern. + /// + /// # Example + /// ```ignore + /// let client = aletheia::GuardianContentClient::new("YOUR_API_KEY"); + /// let response = client + /// .build_request() + /// .search("Elections") + /// .datetime_from(2020, 1, 1, 12, 0, 0, 2) + /// .send() + /// .await?; + /// ``` + pub fn build_request(&self) -> GuardianRequestBuilder { + GuardianRequestBuilder { + http_client: self.http_client.clone(), + base_url: self.base_url.clone(), + api_key: self.api_key.clone(), + request: HashMap::new(), + endpoint: Endpoint::default(), } } +} + +mod helpers { + use crate::enums::{Block, IsAll}; + use crate::SearchResponse; + use chrono::{FixedOffset, LocalResult, TimeZone}; + use std::fmt::Display; pub(crate) fn generate_sequence(items: Vec) -> String where - T: Display, + T: Display + IsAll, { - let items_to_strings = items - .into_iter() - .map(|item| item.to_string()) - .collect::>(); - if items_to_strings.contains(&String::from("all")) { - String::from("all") - } else { - items_to_strings.join(",") + let mut sequence = String::new(); + let mut first = true; + + for item in items { + if item.is_all() { + return "all".to_owned(); + } + + if !first { + sequence.push(','); + } else { + first = false; + } + sequence.push_str(&item.to_string()); } + + sequence } pub(crate) fn generate_blocks(items: Vec) -> String { + if items.contains(&Block::All) { + return "all".to_owned(); + } + let items_to_strings = items .into_iter() .map(|item| match item { @@ -746,24 +807,20 @@ mod helpers { Block::Body => item.to_string(), Block::All => item.to_string(), Block::BodyLatest => String::from("body:latest"), - Block::BodyLatestWith(n) => format!("body:latest:{}", n), + Block::BodyLatestWith(n) => format!("body:latest:{n}"), Block::BodyOldest => String::from("body:latest"), - Block::BodyOldestWith(n) => format!("body:oldest:{}", n), - Block::BodyBlockId(id) => format!("body:{}", id), - Block::BodyAroundBlockId(id) => format!("body:around:{}", id), + Block::BodyOldestWith(n) => format!("body:oldest:{n}"), + Block::BodyBlockId(id) => format!("body:{id}"), + Block::BodyAroundBlockId(id) => format!("body:around:{id}"), Block::BodyAroundBlockIdWith(id, n) => { - format!("body:around:{}:{}", String::from(id), n) + format!("body:around:{id}:{n}") } Block::BodyKeyEvents => String::from("body:key-events"), - Block::BodyPublishedSince(n) => format!("body:published-since:{}", n), + Block::BodyPublishedSince(n) => format!("body:published-since:{n}"), }) .collect::>(); - if items_to_strings.contains(&String::from("all")) { - String::from("all") - } else { - items_to_strings.join(",") - } + items_to_strings.join(",") } pub(crate) fn datetime( diff --git a/src/structs.rs b/src/structs.rs index dd03e11..ea3af1c 100644 --- a/src/structs.rs +++ b/src/structs.rs @@ -1,6 +1,6 @@ //! Structs for deserializing the Guardian's content API responses. //! -//! Many of these structs have been autogenerated +//! Many of these structs were autogenerated //! by Thrift with manual tweaks using existing //! Thrift definitions. @@ -23,7 +23,7 @@ pub struct SearchResponse { pub start_index: Option, pub page_size: Option, pub current_page: Option, - pub pages: Option, + pub pages: Option, pub order_by: Option, pub results: Option>, pub message: Option, diff --git a/src/tests.rs b/src/tests.rs index e90c93a..9d22af6 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,95 +1,116 @@ #[cfg(test)] mod tests { + use reqwest::Url; + use crate::{ enums::{Endpoint, Field, OrderBy, OrderDate, UseDate}, + error::Error, GuardianContentClient, }; - fn setup() -> GuardianContentClient { + fn client_setup() -> GuardianContentClient { GuardianContentClient::new("test-api-key") } #[test] fn test_api_key() { - let client = setup(); + let client = client_setup(); assert_eq!(client.api_key, "test-api-key"); } #[test] fn test_base_url() { - let client = setup(); - assert_eq!(client.base_url, "https://content.guardianapis.com"); + let client = client_setup(); + assert_eq!( + client.base_url, + Url::parse("https://content.guardianapis.com").unwrap() + ); + + let client = client_setup().build_request(); assert_eq!(client.endpoint, Endpoint::Content); } #[test] fn test_other_endpoints() { - let mut client = setup(); - client.endpoint(Endpoint::Sections); + let client = client_setup().build_request().endpoint(Endpoint::Sections); assert_eq!(client.endpoint, Endpoint::Sections); - client.endpoint(Endpoint::Editions); + + let client = client_setup().build_request().endpoint(Endpoint::Editions); assert_eq!(client.endpoint, Endpoint::Editions); - client.endpoint(Endpoint::Tags); + + let client = client_setup().build_request().endpoint(Endpoint::Tags); assert_eq!(client.endpoint, Endpoint::Tags); - client.endpoint(Endpoint::SingleItem); + + let client = client_setup() + .build_request() + .endpoint(Endpoint::SingleItem); assert_eq!(client.endpoint, Endpoint::SingleItem); } #[test] fn test_search() { - let mut client = setup(); - client.search("politics"); + let client = client_setup().build_request().search("politics"); assert_eq!(client.request.get("q").unwrap(), "politics") } #[test] fn test_page() { - let mut client = setup(); - client.page(10); + let client = client_setup().build_request().page(10); assert_eq!(client.request.get("page").unwrap(), "10") } #[test] fn test_page_size() { - let mut client = setup(); - client.page_size(20); + let client = client_setup().build_request().page_size(20); assert_eq!(client.request.get("page-size").unwrap(), "20") } #[test] fn test_order_by() { - let mut client = setup(); - client.order_by(OrderBy::Oldest); + let client = client_setup().build_request().order_by(OrderBy::Oldest); assert_eq!(client.request.get("order-by").unwrap(), "oldest"); - client.order_by(OrderBy::Newest); + + let client = client_setup().build_request().order_by(OrderBy::Newest); assert_eq!(client.request.get("order-by").unwrap(), "newest"); - client.order_by(OrderBy::Relevance); + + let client = client_setup().build_request().order_by(OrderBy::Relevance); assert_eq!(client.request.get("order-by").unwrap(), "relevance") } #[test] fn test_order_date() { - let mut client = setup(); - client.order_date(OrderDate::Published); + let client = client_setup() + .build_request() + .order_date(OrderDate::Published); assert_eq!(client.request.get("order-date").unwrap(), "published"); - client.order_date(OrderDate::NewspaperEdition); + + let client = client_setup() + .build_request() + .order_date(OrderDate::NewspaperEdition); assert_eq!( client.request.get("order-date").unwrap(), "newspaper-edition" ); - client.order_date(OrderDate::LastModified); + + let client = client_setup() + .build_request() + .order_date(OrderDate::LastModified); assert_eq!(client.request.get("order-date").unwrap(), "last-modified") } #[test] fn test_show_fields() { - let mut client = setup(); - client.show_fields(vec![Field::ShortUrl, Field::Byline, Field::StarRating]); + let client = client_setup().build_request().show_fields(vec![ + Field::ShortUrl, + Field::Byline, + Field::StarRating, + ]); assert_eq!( client.request.get("show-fields").unwrap(), "shortUrl,byline,starRating" ); - client.show_fields(vec![ + + let client = client_setup().build_request().show_fields(vec![ Field::ShortUrl, Field::Byline, Field::StarRating, @@ -100,8 +121,7 @@ mod tests { #[test] fn test_show_tags() { - let mut client = setup(); - client.show_tags(vec![ + let client = client_setup().build_request().show_tags(vec![ crate::enums::Tag::Blog, crate::enums::Tag::Contributor, ]); @@ -110,8 +130,9 @@ mod tests { #[test] fn test_query_fields() { - let mut client = setup(); - client.query_fields(vec![Field::ProductionOffice]); + let client = client_setup() + .build_request() + .query_fields(vec![Field::ProductionOffice]); assert_eq!( client.request.get("query-fields").unwrap(), "productionOffice" @@ -120,22 +141,21 @@ mod tests { #[test] fn test_date_from() { - let mut client = setup(); - client.date_from(2020, 1, 1); + let client = client_setup().build_request().date_from(2020, 1, 1); assert_eq!(client.request.get("from-date").unwrap(), "2020-1-1"); } #[test] fn test_date_to() { - let mut client = setup(); - client.date_to(2020, 1, 1); + let client = client_setup().build_request().date_to(2020, 1, 1); assert_eq!(client.request.get("to-date").unwrap(), "2020-1-1"); } #[test] fn test_datetime_from() { - let mut client = setup(); - client.datetime_from(2021, 12, 31, 0, 0, 0, 5); + let client = client_setup() + .build_request() + .datetime_from(2021, 12, 31, 0, 0, 0, 5); assert_eq!( client.request.get("from-date").unwrap(), "2021-12-31T00:00:00+05:00" @@ -144,8 +164,9 @@ mod tests { #[test] fn test_datetime_to() { - let mut client = setup(); - client.datetime_to(2021, 12, 31, 0, 0, 0, -5); + let client = client_setup() + .build_request() + .datetime_to(2021, 12, 31, 0, 0, 0, -5); assert_eq!( client.request.get("to-date").unwrap(), "2021-12-31T00:00:00-05:00" @@ -154,9 +175,10 @@ mod tests { #[test] fn test_datetime_from_wrong_offset() { - let mut client = setup(); - // Invalid offset - client.datetime_from(2021, 12, 31, 0, 0, 0, 1024); + let client = client_setup() + .build_request() + // Invalid offset + .datetime_from(2021, 12, 31, 0, 0, 0, 1024); assert_eq!( client.request.get("from-date").unwrap(), "2021-12-31T00:00:00+00:00" @@ -165,17 +187,19 @@ mod tests { #[test] fn test_datetime_from_wrong_ymd_hms() { - let mut client = setup(); - // Invalid YMD - client.datetime_from(2021, 13, 40, 0, 999, 0, 5); + let client = client_setup() + .build_request() + // Invalid YMD + .datetime_from(2021, 13, 40, 0, 999, 0, 5); assert_eq!(client.request.get("from-date"), None); } #[test] fn test_datetime_to_wrong_offset() { - let mut client = setup(); - // Invalid offset - client.datetime_to(2021, 12, 31, 0, 0, 0, 999); + let client = client_setup() + .build_request() + // Invalid offset + .datetime_to(2021, 12, 31, 0, 0, 0, 999); assert_eq!( client.request.get("to-date").unwrap(), "2021-12-31T00:00:00+00:00" @@ -184,44 +208,44 @@ mod tests { #[test] fn test_datetime_to_wrong_ymd_hms() { - let mut client = setup(); - // Invalid YMD - client.datetime_to(2021, 13, 40, 0, 999, 0, 5); + let client = client_setup() + .build_request() + // Invalid YMD + .datetime_to(2021, 13, 40, 0, 999, 0, 5); assert_eq!(client.request.get("to-date"), None); } #[test] fn test_use_date() { - let mut client = setup(); - client.use_date(UseDate::FirstPublication); + let client = client_setup() + .build_request() + .use_date(UseDate::FirstPublication); assert_eq!(client.request.get("use-date").unwrap(), "first-publication"); } #[test] fn test_show_section() { - let mut client = setup(); - client.show_section(true); + let client = client_setup().build_request().show_section(true); assert_eq!(client.request.get("show-section").unwrap(), "true"); } #[test] fn test_section() { - let mut client = setup(); - client.section("food"); + let client = client_setup().build_request().section("food"); assert_eq!(client.request.get("section").unwrap(), "food"); } #[test] fn test_reference() { - let mut client = setup(); - client.reference("isbn"); + let client = client_setup().build_request().reference("isbn"); assert_eq!(client.request.get("reference").unwrap(), "isbn"); } #[test] fn test_reference_type() { - let mut client = setup(); - client.reference_type("isbn/123456789012"); + let client = client_setup() + .build_request() + .reference_type("isbn/123456789012"); assert_eq!( client.request.get("reference-type").unwrap(), "isbn/123456789012" @@ -230,15 +254,15 @@ mod tests { #[test] fn test_tag() { - let mut client = setup(); - client.tag("technology/apple"); + let client = client_setup().build_request().tag("technology/apple"); assert_eq!(client.request.get("tag").unwrap(), "technology/apple"); } #[test] fn test_ids() { - let mut client = setup(); - client.ids("world/2022/jan/01/funeral-of-desmond-tutu-takes-place-in-cape-town"); + let client = client_setup() + .build_request() + .ids("world/2022/jan/01/funeral-of-desmond-tutu-takes-place-in-cape-town"); assert_eq!( client.request.get("ids").unwrap(), "world/2022/jan/01/funeral-of-desmond-tutu-takes-place-in-cape-town" @@ -247,29 +271,27 @@ mod tests { #[test] fn test_production_office() { - let mut client = setup(); - client.production_office("aus"); + let client = client_setup().build_request().production_office("aus"); assert_eq!(client.request.get("production-office").unwrap(), "aus"); } #[test] fn test_lang() { - let mut client = setup(); - client.lang("fr"); + let client = client_setup().build_request().lang("fr"); assert_eq!(client.request.get("lang").unwrap(), "fr"); } #[test] fn test_star_rating() { - let mut client = setup(); - client.star_rating(3); + let client = client_setup().build_request().star_rating(3); assert_eq!(client.request.get("star-rating").unwrap(), "3"); } #[test] fn test_tag_type() { - let mut client = setup(); - client.tag_type("tv-and-radio/us-television"); + let client = client_setup() + .build_request() + .tag_type("tv-and-radio/us-television"); assert_eq!( client.request.get("type").unwrap(), "tv-and-radio/us-television" @@ -278,21 +300,23 @@ mod tests { #[test] fn test_show_blocks() { - let mut client = setup(); - client.show_blocks(vec![crate::enums::Block::BodyAroundBlockIdWith( - "123456789", - 10, - )]); + let client = client_setup().build_request().show_blocks(vec![ + crate::enums::Block::BodyAroundBlockIdWith("123456789", 10), + ]); assert_eq!( client.request.get("show-blocks").unwrap(), "body:around:123456789:10" ); - client.show_blocks(vec![crate::enums::Block::BodyPublishedSince(123456)]); + + let client = client_setup() + .build_request() + .show_blocks(vec![crate::enums::Block::BodyPublishedSince(123456)]); assert_eq!( client.request.get("show-blocks").unwrap(), "body:published-since:123456" ); - client.show_blocks(vec![ + + let client = client_setup().build_request().show_blocks(vec![ crate::enums::Block::BodyPublishedSince(123456), crate::enums::Block::BodyKeyEvents, ]); @@ -301,4 +325,18 @@ mod tests { "body:published-since:123456,body:key-events" ); } + + #[tokio::test] + async fn test_error_missing_parameter() { + let result = client_setup() + .build_request() + .endpoint(Endpoint::SingleItem) + .send() + .await; + + assert!(result.is_err()); + + let err = result.err().unwrap(); + assert!(matches!(err, Error::MissingQueryParameter("q"))); + } }