diff --git a/.github/workflows/general.yml b/.github/workflows/general.yml index 0c2a357..230c5d5 100644 --- a/.github/workflows/general.yml +++ b/.github/workflows/general.yml @@ -1,4 +1,4 @@ -name: Rust +name: Rust General concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -12,9 +12,12 @@ on: branches: - main - develop + workflow_call: env: CARGO_TERM_COLOR: always + RUSTFLAGS: -D warnings + RUSTDOCFLAGS: -D warnings jobs: test: @@ -23,6 +26,8 @@ jobs: steps: - uses: wykies/checkout@main - uses: wykies/setup-rust-toolchain@main + - name: Run examples + run: cargo test --all-features --examples - name: Run tests run: cargo test --all-features @@ -33,9 +38,10 @@ jobs: - uses: wykies/checkout@main - uses: wykies/setup-rust-toolchain@main with: + toolchain: nightly components: rustfmt - name: Enforce formatting - run: cargo fmt --check + run: cargo fmt --all --check clippy: name: Clippy @@ -46,4 +52,4 @@ jobs: with: components: clippy - name: Linting - run: cargo clippy -- -D warnings + run: cargo clippy --all-features -- -D warnings diff --git a/.github/workflows/link_check.yml b/.github/workflows/link_check.yml new file mode 100644 index 0000000..4e85ffc --- /dev/null +++ b/.github/workflows/link_check.yml @@ -0,0 +1,24 @@ +name: Links Checker + +on: + pull_request: + branches: + - main + schedule: + - cron: "12 02 4 * *" + +jobs: + link_checker: + runs-on: ubuntu-latest + steps: + - uses: wykies/checkout@main + - name: Restore lychee cache + uses: actions/cache@v4 + with: + path: .lycheecache + key: cache-lychee-${{ github.ref }} + restore-keys: cache-lychee- + - name: Run lychee + uses: lycheeverse/lychee-action@v2 + with: + args: --cache --no-progress --require-https './**/*.md' './**/*.html' './**/*.rs' \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5b27ee1..c3a30ad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -8,6 +8,8 @@ on: pull_request: branches: - main + workflow_call: + env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/semver_check.yml b/.github/workflows/semver_check.yml index b83ad5e..026deeb 100644 --- a/.github/workflows/semver_check.yml +++ b/.github/workflows/semver_check.yml @@ -8,6 +8,8 @@ on: pull_request: branches: - main + workflow_call: + env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index 00231c0..448ad3e 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -10,14 +10,14 @@ on: - develop pull_request: branches: - - main - develop + workflow_call: env: CARGO_TERM_COLOR: always jobs: - test: + test_in_browser: name: Test WASM in browser runs-on: ubuntu-latest steps: @@ -32,7 +32,7 @@ jobs: - name: Run Examples run: wasm-pack test --headless --chrome --all-features --examples - clippy: + clippy_wasm: name: Clippy WASM runs-on: ubuntu-latest steps: diff --git a/.gitignore b/.gitignore index c41cc9e..35a423d 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -/target \ No newline at end of file +/target +.lycheecache diff --git a/.vscode/settings.json b/.vscode/settings.json index 5e3029a..f8f20ed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,7 +2,7 @@ "rust-analyzer.showUnlinkedFileNotification": false, "cSpell.words": [ "jsvalue" - ] - // "code-runner.customCommand": "wasm-pack test --headless --firefox", + ], // "rust-analyzer.cargo.target": "wasm32-unknown-unknown" // Uncomment to use rust-analyzer on wasm code instead + "rust-analyzer.cargo.features": ["yield_now", "egui"] } diff --git a/Cargo.lock b/Cargo.lock index 779ad7c..6636091 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,21 +1,97 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 + +[[package]] +name = "ab_glyph" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "anyhow" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" + +[[package]] +name = "async-compression" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df895a515f70646414f4b45c0b79082783b80552b373a68283012928df56f522" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", + "zstd", + "zstd-safe", +] + +[[package]] +name = "async-trait" +version = "0.1.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "atomic-waker" @@ -25,23 +101,23 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -52,15 +128,30 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" -version = "1.3.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] -name = "bitflags" -version = "2.6.0" +name = "brotli" +version = "7.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "cc97b8f16f944bba54f0433f07e30be199b6dc2bd25937444bbad560bcea29bd" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] [[package]] name = "bumpalo" @@ -68,17 +159,28 @@ version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" -version = "1.6.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cc" -version = "1.1.6" +version = "1.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f" +checksum = "8d6dbb628b8f8555f86d0323c2eb39e3ec81901f4b83e091db8a6a76d316a333" +dependencies = [ + "jobserver", + "libc", + "shlex", +] [[package]] name = "cfg-if" @@ -87,13 +189,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "console_error_panic_hook" -version = "0.1.7" +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "cookie" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ - "cfg-if", - "wasm-bindgen", + "percent-encoding", + "time", + "version_check", +] + +[[package]] +name = "cookie_store" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9" +dependencies = [ + "cookie", + "document-features", + "idna", + "log", + "publicsuffix", + "serde", + "serde_derive", + "serde_json", + "time", + "url", ] [[package]] @@ -108,19 +235,124 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "document-features" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6969eaabd2421f8a2775cfd2471a2b634372b4a25d41e3bd647b79912850a0" +dependencies = [ + "litrs", +] + +[[package]] +name = "ecolor" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d72e9c39f6e11a2e922d04a34ec5e7ef522ea3f5a1acfca7a19d16ad5fe50f5" +dependencies = [ + "emath", +] + +[[package]] +name = "egui" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "252d52224d35be1535d7fd1d6139ce071fb42c9097773e79f7665604f5596b5e" +dependencies = [ + "ahash", + "emath", + "epaint", + "nohash-hasher", + "profiling", +] + +[[package]] +name = "either" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "emath" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4fe73c1207b864ee40aa0b0c038d6092af1030744678c60188a05c28553515d" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] +[[package]] +name = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "epaint" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5666f8d25236293c966fbb3635eac18b04ad1914e3bab55bc7d44b9980cafcac" +dependencies = [ + "ab_glyph", + "ahash", + "ecolor", + "emath", + "nohash-hasher", + "parking_lot", + "profiling", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -129,19 +361,29 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "fastrand" -version = "2.1.0" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "flate2" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] [[package]] name = "fnv" @@ -175,9 +417,9 @@ dependencies = [ [[package]] name = "futures" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -190,9 +432,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -200,15 +442,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -217,15 +459,15 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", @@ -234,21 +476,21 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -269,21 +511,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "h2" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" dependencies = [ "atomic-waker", "bytes", @@ -300,21 +544,77 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.5" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] -name = "hermit-abi" -version = "0.3.9" +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hickory-proto" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447afdcdb8afb9d0a852af6dc65d9b285ce720ed7a59e42a8bf2e931c67bc1b5" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "once_cell", + "rand", + "thiserror 1.0.69", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a2e2aba9c389ce5267d31cf1e4dace82390ae276b0b364ea55630b1fa1b44b4" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand", + "resolv-conf", + "smallvec", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "hostname" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] [[package]] name = "http" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -346,15 +646,15 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "hyper" -version = "1.4.1" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +checksum = "256fb8d4bd6413123cc9d91832d78325c48ff41677595be797d90f42969beae0" dependencies = [ "bytes", "futures-channel", @@ -372,9 +672,9 @@ dependencies = [ [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ "futures-util", "http", @@ -385,6 +685,7 @@ dependencies = [ "tokio", "tokio-rustls", "tower-service", + "webpki-roots", ] [[package]] @@ -405,9 +706,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.6" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab92f4f49ee4fb4f997c784b7a2e0fa70050211e0b6a287f898c3c9785ca956" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ "bytes", "futures-channel", @@ -418,142 +719,366 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower", "tower-service", "tracing", ] [[package]] -name = "idna" -version = "0.5.0" +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "displaydoc", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "indexmap" -version = "2.2.6" +name = "icu_locid" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ - "equivalent", - "hashbrown", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", ] [[package]] -name = "ipnet" -version = "2.9.0" +name = "icu_locid_transform" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] [[package]] -name = "itoa" -version = "1.0.11" +name = "icu_locid_transform_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" [[package]] -name = "js-sys" -version = "0.3.69" +name = "icu_normalizer" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" dependencies = [ - "wasm-bindgen", + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", ] [[package]] -name = "libc" -version = "0.2.155" +name = "icu_normalizer_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" [[package]] -name = "linux-raw-sys" -version = "0.4.14" +name = "icu_properties" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] [[package]] -name = "log" -version = "0.4.22" +name = "icu_properties_data" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" [[package]] -name = "memchr" -version = "2.7.4" +name = "icu_provider" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] [[package]] -name = "mime" -version = "0.3.17" +name = "icu_provider_macros" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "miniz_oxide" -version = "0.7.4" +name = "idna" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "adler", + "idna_adapter", + "smallvec", + "utf8_iter", ] [[package]] -name = "mio" -version = "1.0.1" +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "hermit-abi", - "libc", - "wasi", - "windows-sys 0.52.0", + "icu_normalizer", + "icu_properties", ] [[package]] -name = "native-tls" -version = "0.2.12" +name = "indexmap" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", + "equivalent", + "hashbrown", ] [[package]] -name = "object" -version = "0.36.2" +name = "ipconfig" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f203fa8daa7bb185f760ae12bd8e097f63d17041dcdcaf675ac54cdf863170e" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "memchr", + "socket2", + "widestring", + "windows-sys 0.48.0", + "winreg", ] [[package]] -name = "once_cell" -version = "1.19.0" +name = "ipnet" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] -name = "openssl" -version = "0.10.66" +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minicov" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27fe9f1cc3c22e1687f9446c2083c4c5fc7f0bcf1c7a86bdbded14985895b4b" +dependencies = [ + "cc", + "walkdir", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" dependencies = [ - "bitflags 2.6.0", + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "openssl" +version = "0.10.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +dependencies = [ + "bitflags", "cfg-if", "foreign-types", "libc", @@ -581,9 +1106,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.103" +version = "0.9.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" dependencies = [ "cc", "libc", @@ -592,36 +1117,48 @@ dependencies = [ ] [[package]] -name = "percent-encoding" -version = "2.3.1" +name = "owned_ttf_parser" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +dependencies = [ + "ttf-parser", +] [[package]] -name = "pin-project" -version = "1.1.5" +name = "parking_lot" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ - "pin-project-internal", + "lock_api", + "parking_lot_core", ] [[package]] -name = "pin-project-internal" -version = "1.1.5" +name = "parking_lot_core" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ - "proc-macro2", - "quote", - "syn", + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", ] +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -631,40 +1168,178 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" dependencies = [ "unicode-ident", ] +[[package]] +name = "profiling" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" + +[[package]] +name = "psl-types" +version = "2.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" + +[[package]] +name = "publicsuffix" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42ea446cab60335f76979ec15e12619a2165b5ae2c12166bef27d283a9fadf" +dependencies = [ + "idna", + "psl-types", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quinn" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.9", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +dependencies = [ + "bytes", + "getrandom", + "rand", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.9", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c40286217b4ba3a71d644d752e6a0b71f13f1b6a2c5311acfcbe0c2418ed904" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "redox_syscall" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +dependencies = [ + "bitflags", +] + [[package]] name = "reqwest" -version = "0.12.5" +version = "0.12.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" dependencies = [ + "async-compression", "base64", "bytes", + "cookie", + "cookie_store", "encoding_rs", "futures-core", "futures-util", "h2", + "hickory-resolver", "http", "http-body", "http-body-util", @@ -676,11 +1351,15 @@ dependencies = [ "js-sys", "log", "mime", + "mime_guess", "native-tls", "once_cell", "percent-encoding", "pin-project-lite", + "quinn", + "rustls", "rustls-pemfile", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", @@ -688,27 +1367,48 @@ dependencies = [ "system-configuration", "tokio", "tokio-native-tls", + "tokio-rustls", + "tokio-socks", + "tokio-util", + "tower", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", + "wasm-streams", "web-sys", - "winreg", + "webpki-roots", + "windows-registry", ] [[package]] name = "reqwest-cross" -version = "0.4.2" +version = "0.5.0" dependencies = [ + "anyhow", + "document-features", + "egui", "futures", "js-sys", "reqwest", + "thiserror 2.0.9", "tokio", + "tracing", "wasm-bindgen-futures", "wasm-bindgen-test", "web-sys", ] +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + [[package]] name = "ring" version = "0.17.8" @@ -730,26 +1430,33 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" + [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" dependencies = [ - "bitflags 2.6.0", + "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "5065c3f250cbd332cd894be57c40fa52387247659b14a2d6041d121547903b1b" dependencies = [ "once_cell", + "ring", "rustls-pki-types", "rustls-webpki", "subtle", @@ -758,25 +1465,27 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.7.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" +checksum = "d2bf47e6ff922db3825eb750c4e2ff784c6ff8fb9e13046ef6a1d1c5401b0b37" +dependencies = [ + "web-time", +] [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", "rustls-pki-types", @@ -789,13 +1498,22 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -804,13 +1522,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" +[[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.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.6.0", + "bitflags", "core-foundation", "core-foundation-sys", "libc", @@ -819,9 +1543,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -829,18 +1553,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.204" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", @@ -849,11 +1573,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.120" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e0d21c9a8cae1235ad58a00c11cb40d4b1e5c784f1ef2c537876ed6ffd8b7c5" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -871,97 +1596,206 @@ dependencies = [ ] [[package]] -name = "slab" -version = "0.4.9" +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c786062daee0d6db1132800e623df74274a0a87322d8e183338e01b3d98d058" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" dependencies = [ - "autocfg", + "core-foundation-sys", + "libc", ] [[package]] -name = "smallvec" -version = "1.13.2" +name = "tempfile" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" +dependencies = [ + "cfg-if", + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] [[package]] -name = "socket2" -version = "0.5.7" +name = "thiserror" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "libc", - "windows-sys 0.52.0", + "thiserror-impl 1.0.69", ] [[package]] -name = "spin" -version = "0.9.8" +name = "thiserror" +version = "2.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" +dependencies = [ + "thiserror-impl 2.0.9", +] [[package]] -name = "subtle" -version = "2.6.1" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] -name = "syn" -version = "2.0.72" +name = "thiserror-impl" +version = "2.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" dependencies = [ "proc-macro2", "quote", - "unicode-ident", + "syn", ] [[package]] -name = "sync_wrapper" -version = "1.0.1" +name = "time" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] [[package]] -name = "system-configuration" -version = "0.5.1" +name = "time-core" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] -name = "system-configuration-sys" -version = "0.5.0" +name = "time-macros" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ - "core-foundation-sys", - "libc", + "num-conv", + "time-core", ] [[package]] -name = "tempfile" -version = "3.10.1" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", + "displaydoc", + "zerovec", ] [[package]] name = "tinyvec" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8" dependencies = [ "tinyvec_macros", ] @@ -974,9 +1808,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.1" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" dependencies = [ "backtrace", "bytes", @@ -1011,20 +1845,31 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.0" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" dependencies = [ "rustls", - "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-socks" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d4770b8024672c1101b3f6733eab95b18007dbe0847a8afe341fcf79e06043f" +dependencies = [ + "either", + "futures-util", + "thiserror 1.0.69", "tokio", ] [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", @@ -1035,14 +1880,14 @@ dependencies = [ [[package]] name = "tower" -version = "0.4.13" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "pin-project", "pin-project-lite", + "sync_wrapper", "tokio", "tower-layer", "tower-service", @@ -1050,31 +1895,43 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", ] @@ -1086,25 +1943,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] -name = "unicode-bidi" -version = "0.3.15" +name = "ttf-parser" +version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31" [[package]] -name = "unicode-ident" -version = "1.0.12" +name = "unicase" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] -name = "unicode-normalization" -version = "0.1.23" +name = "unicode-ident" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "untrusted" @@ -1114,21 +1968,49 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -1146,23 +2028,23 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", "syn", @@ -1171,21 +2053,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.42" +version = "0.4.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1193,9 +2076,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" dependencies = [ "proc-macro2", "quote", @@ -1206,18 +2089,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.92" +version = "0.2.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" [[package]] name = "wasm-bindgen-test" -version = "0.3.42" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9bf62a58e0780af3e852044583deee40983e5886da43a271dd772379987667b" +checksum = "c61d44563646eb934577f2772656c7ad5e9c90fac78aa8013d776fcdaf24625d" dependencies = [ - "console_error_panic_hook", "js-sys", + "minicov", "scoped-tls", "wasm-bindgen", "wasm-bindgen-futures", @@ -1226,25 +2109,124 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.42" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7f89739351a2e03cb94beb799d47fb2cac01759b40ec441f7de39b00cbf7ef0" +checksum = "54171416ce73aa0b9c377b51cc3cb542becee1cd678204812e8392e5b0e4a031" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "web-sys" -version = "0.3.69" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.26.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -1263,6 +2245,15 @@ 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-targets" version = "0.48.5" @@ -1386,16 +2377,144 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winreg" -version = "0.52.0" +version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ "cfg-if", "windows-sys 0.48.0", ] +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +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 = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zstd" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.13+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml index fa53710..8b8a386 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "reqwest-cross" -version = "0.4.2" +version = "0.5.0" authors = ["One "] categories = ["web-programming::http-client", "wasm"] documentation = "https://docs.rs/reqwest-cross" @@ -13,9 +13,17 @@ description = "Wrapper around reqwest for use in both native and wasm" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[package.metadata.docs.rs] +all-features = true + [dependencies] +anyhow = "1.0.95" +document-features = "0.2.10" +egui = { version = "0.30.0", default-features = false, optional = true } futures = "0.3.28" -reqwest = { version = "0.12.3", default-features = false } +reqwest = { version = "0.12.12", default-features = false } +thiserror = "2.0.9" +tracing = "0.1.41" # For native compilation [target.'cfg(not(target_arch = "wasm32"))'.dependencies] @@ -28,18 +36,71 @@ js-sys = { version = "0.3.69", optional = true } web-sys = { version = "0.3.69", optional = true } [dev-dependencies] -reqwest = { version = "0.12.3" } wasm-bindgen-test = "0.3.34" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] tokio = { version = "1.27.0", default-features = false, features = ["macros", "rt-multi-thread"] } [[example]] -name = "loop_yield" +name = "loop_yield_custom" +required-features = ["yield_now"] + +[[example]] +name = "loop_yield_data_state" required-features = ["yield_now"] [features] -default = ["native-tokio"] +## Enables the tokio runtime and reqwest's default features. +## If default-features gets disabled do ensure you at least enable tls, unless you explicitly do not want tls support. +default = ["native-tokio", "reqwest_default"] + +## Enables reqwest's default features +reqwest_default = ["reqwest/default"] + +## Sets [tokio][tokio-url] as the runtime to use for native native-tokio = ["dep:tokio"] -yield_now = ["dep:js-sys", "web-sys"] -# If we add support for other runtimes we need to update CI to test each separately (rn tests all features together) + +## Add a function that can be called to yield to the executor. +## This is only needed if you only have one thread and need to release it to prevent a deadlock +## because you are waiting on another future (as can be the case in WASM). If you are using a +## framework such as egui this may not be necessary as they already allow for other futures to +## make progress. But one test will quickly let you know either way. If the program freezes +## after you make a request then this can help. +yield_now = ["dep:js-sys", "dep:web-sys"] + +## Add helper functions to ['DataState'] to do egui boiler plate +egui = ["dep:egui"] + +#! The following enable a subset of reqwest's features. +#! If you need a feature that we didn't include please open an issue and let us know and we'll add it. +#! In the mean while you can depend on reqwest directly with the same version as this crate and enable the feature. +#! Because features are additive it will be enabled but note that if the version goes out of sync it will cause compilation issues. + +## Enables the feature with the same name on reqwest +default-tls = ["reqwest/default-tls"] +## Enables the feature with the same name on reqwest +native-tls = ["reqwest/native-tls"] +## Enables the feature with the same name on reqwest +rustls-tls = ["reqwest/rustls-tls"] +## Enables the feature with the same name on reqwest +http2 = ["reqwest/http2"] +## Enables the feature with the same name on reqwest +json = ["reqwest/json"] +## Enables the feature with the same name on reqwest +cookies = ["reqwest/cookies"] +## Enables the feature with the same name on reqwest +hickory-dns = ["reqwest/hickory-dns"] +## Enables the feature with the same name on reqwest +multipart = ["reqwest/multipart"] +## Enables the feature with the same name on reqwest +socks = ["reqwest/socks"] +## Enables the feature with the same name on reqwest +stream = ["reqwest/stream"] +## Enables the feature with the same name on reqwest +brotli = ["reqwest/brotli"] +## Enables the feature with the same name on reqwest +deflate = ["reqwest/deflate"] +## Enables the feature with the same name on reqwest +gzip = ["reqwest/gzip"] +## Enables the feature with the same name on reqwest +zstd = ["reqwest/zstd"] diff --git a/LICENSE-APACHE b/LICENSE-APACHE index 28b2427..077b86b 100644 --- a/LICENSE-APACHE +++ b/LICENSE-APACHE @@ -1,7 +1,7 @@ Apache License Version 2.0, January 2004 - http://www.apache.org/licenses/ + https://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION @@ -193,7 +193,7 @@ you may not use this file except in compliance with the License. You may obtain a copy of the License at - http://www.apache.org/licenses/LICENSE-2.0 + https://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, diff --git a/README.md b/README.md index 8ffe89b..5263847 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ # reqwest-cross + Wrapper around [reqwest][reqwest-url] for ease of use in applications that target BOTH native and wasm but do not want to block in the calling task (eg. A UI thread). Inspired by [ehttp](https://docs.rs/ehttp/0.2.0/ehttp/) but uses [reqwest][reqwest-url] instead. Doesn't provide much value if you're only targeting one or the other because request does that pretty well, see their [wasm example](https://github.com/seanmonstar/reqwest/tree/master/examples/wasm_github_fetch). ## License All code in this repository is dual-licensed under either: -- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) -- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) +- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or ) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) at your option. This means you can select the license you prefer! @@ -19,5 +20,4 @@ Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions. - [reqwest-url]: https://docs.rs/reqwest/latest/reqwest/ diff --git a/bacon.toml b/bacon.toml new file mode 100644 index 0000000..5fccbfc --- /dev/null +++ b/bacon.toml @@ -0,0 +1,6 @@ +[jobs.test_examples] +command = ["cargo", "test", "--features=yield_now,egui", "--examples"] +need_stdout = true + +[keybindings] +e = "job:test_examples" diff --git a/examples/loop_yield.rs b/examples/loop_yield_custom.rs similarity index 88% rename from examples/loop_yield.rs rename to examples/loop_yield_custom.rs index 783ec19..b3f46b5 100644 --- a/examples/loop_yield.rs +++ b/examples/loop_yield_custom.rs @@ -1,8 +1,10 @@ // Native and WASM require different main functions but after that it should be -// the same Uses yield but yield isn't available yet for wasm_bindgen_futures so -// uses a workaround found (poll-promise might be better) +// the same. Uses yield but yield isn't available yet for wasm_bindgen_futures +// so uses a workaround found. If you're building a bigger application or have +// multiple places you need to make requests look at the +// loop_yield_data_state.rs example instead. -use reqwest_cross::fetch; +use reqwest_cross::{fetch, reqwest}; #[cfg(all(not(target_arch = "wasm32"), feature = "native-tokio"))] #[tokio::main] @@ -38,7 +40,7 @@ async fn common_code() -> Result<(), Box> { match state { State::Startup => { // Send request - let request = client.get("http://httpbin.org/get"); + let request = client.get("https://httpbin.org/get"); let (tx, rx) = futures::channel::oneshot::channel(); fetch( request, diff --git a/examples/loop_yield_data_state.rs b/examples/loop_yield_data_state.rs new file mode 100644 index 0000000..dc777a0 --- /dev/null +++ b/examples/loop_yield_data_state.rs @@ -0,0 +1,72 @@ +// Native and WASM require different main functions but after that it should be +// the same. This example demonstrates how this crate can be used with the +// DataState type. + +use anyhow::Context; +use reqwest_cross::{fetch_plus, reqwest, Awaiting, DataState}; + +#[cfg(all(not(target_arch = "wasm32"), feature = "native-tokio"))] +#[tokio::main] +async fn main() -> Result<(), Box> { + common_code().await +} + +#[cfg(target_arch = "wasm32")] +wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); +#[cfg(target_arch = "wasm32")] +fn main() { + #[wasm_bindgen_test::wasm_bindgen_test] + async fn do_fetch() -> Result<(), Box> { + common_code().await + } +} + +async fn common_code() -> Result<(), Box> { + // Allows for one iteration where we see no progress but next loop should go + // into first branch + let mut seen_no_progress = false; + + let client = reqwest::Client::new(); + let mut state = DataState::None; + + println!("Starting loop"); + + // This loop would normally be a game loop, or the executor of an immediate mode + // GUI. + loop { + if let DataState::Present(status_code) = state.as_ref() { + println!("Response received"); + assert_eq!(status_code, &200); + break; + } else { + let outcome = state.get(|| { + let req = client.get("https://httpbin.org/get"); + let response_handler = |resp: reqwest::Result| async { + resp.map(|resp| resp.status()) + .context("Request failed, got an error back") + }; + let ui_notify = || { + println!("Request Completed, this is where you would wake up your UI thread"); + }; + Awaiting(fetch_plus(req, response_handler, ui_notify)) + }); + assert!(!seen_no_progress); + if outcome.is_unable_to_make_progress() { + // We should never get into this branch again + seen_no_progress = true; + } + reqwest_cross::yield_now().await; + } + } + println!("Exited loop"); + Ok(()) +} + +#[cfg(all(test, not(target_arch = "wasm32")))] +mod tests { + + #[tokio::test] + async fn test_name() { + super::common_code().await.unwrap(); + } +} diff --git a/examples/simple_fetch.rs b/examples/simple_fetch.rs index 1dedd86..7e6f7c1 100644 --- a/examples/simple_fetch.rs +++ b/examples/simple_fetch.rs @@ -1,7 +1,7 @@ // Native and WASM require different main functions but after that it should be -// the same +// the same. This example shows how to do a simple fetch. -use reqwest_cross::fetch; +use reqwest_cross::{fetch, reqwest}; #[cfg(all(not(target_arch = "wasm32"), feature = "native-tokio"))] #[tokio::main] @@ -21,7 +21,7 @@ fn main() { async fn common_code() -> Result<(), Box> { let client = reqwest::Client::new(); - let request = client.get("http://httpbin.org/get"); + let request = client.get("https://httpbin.org/get"); let (tx, rx) = futures::channel::oneshot::channel(); fetch( diff --git a/rustfmt.toml b/rustfmt.toml index 705974a..4416699 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -1,4 +1,4 @@ # `wrap_comments` is unstable so to use you need to use nightly. # Uncomment the line below then run `cargo +nightly fmt` -# wrap_comments = true +wrap_comments = true diff --git a/src/data_state.rs b/src/data_state.rs new file mode 100644 index 0000000..feb8cba --- /dev/null +++ b/src/data_state.rs @@ -0,0 +1,228 @@ +//! Helpers for handling pending data. + +use std::fmt::{Debug, Display}; + +use anyhow::anyhow; +use futures::channel::oneshot; +use thiserror::Error; +use tracing::{error, warn}; + +/// Provides a common way to specify the bounds errors are expected to meet +pub trait ErrorBounds: Display + Send + Sync + 'static + Debug {} +impl ErrorBounds for T {} + +#[derive(Error, Debug)] +/// Represents the types of errors that can occur while using [DataState] +pub enum DataStateError { + /// Sender was dropped, request cancelled + #[error("Request sender was dropped")] + SenderDropped(oneshot::Canceled), + + /// The response received from the request was an error + #[error("Response received was an error: {0}")] + ErrorResponse(E), + + /// This variant is supplied for use by application code + #[error(transparent)] + FromE(E), +} + +#[derive(Debug)] +/// Provides a way to ensure the calling code knows if it is calling a function +/// that cannot do anything useful anymore +pub enum CanMakeProgress { + AbleToMakeProgress, + UnableToMakeProgress, +} + +/// Used to represent data that is pending being available +#[derive(Debug)] +pub struct Awaiting(pub oneshot::Receiver>); + +/// Used to store a type that is not always available and we need to keep +/// polling it to get it ready +#[derive(Debug, Default)] +pub enum DataState { + /// Represent no data present and not pending + #[default] + None, + /// Represents data has been requested and awaiting it being available + AwaitingResponse(Awaiting), // TODO 4: Add support for a timeout on waiting + /// Represents data that is available for use + Present(T), + /// Represents an error that Occurred + Failed(DataStateError), +} + +impl DataState { + #[cfg(feature = "egui")] + /// Attempts to load the data and displays appropriate UI if applicable. + /// Some branches lead to no UI being displayed, in particular when the data + /// or an error is received (On the expectation it will show next frame). + /// When in an error state the error messages will show as applicable. + /// If called an already has data present this function does nothing and + /// returns [CanMakeProgress::UnableToMakeProgress] + /// + /// If a `retry_msg` is provided then it overrides the default + /// + /// Note see [`Self::get`] for more info. + #[must_use] + pub fn egui_get( + &mut self, + ui: &mut egui::Ui, + retry_msg: Option<&str>, + fetch_fn: F, + ) -> CanMakeProgress + where + F: FnOnce() -> Awaiting, + { + match self { + DataState::None => { + ui.spinner(); + let is_able_to_make_progress = self.get(fetch_fn).is_able_to_make_progress(); + debug_assert!( + is_able_to_make_progress, + "Should only be calling get if there is a point" + ); + } + DataState::AwaitingResponse(rx) => { + if let Some(new_state) = Self::await_data(rx) { + *self = new_state; + } else { + ui.spinner(); + } + } + DataState::Present(_data) => { + // Does nothing as data is already present + return CanMakeProgress::UnableToMakeProgress; + } + DataState::Failed(e) => { + ui.colored_label(ui.visuals().error_fg_color, e.to_string()); + if ui.button(retry_msg.unwrap_or("Retry Request")).clicked() { + *self = DataState::default(); + } + } + } + CanMakeProgress::AbleToMakeProgress + } + + /// Attempts to load the data and returns if it is able to make progress. + /// + /// Note: F needs to return `AwaitingType` and not T because it needs to + /// be able to be pending if T is not ready. + #[must_use] + pub fn get(&mut self, fetch_fn: F) -> CanMakeProgress + where + F: FnOnce() -> Awaiting, + { + match self { + DataState::None => { + let rx = fetch_fn(); + *self = DataState::AwaitingResponse(rx); + CanMakeProgress::AbleToMakeProgress + } + DataState::AwaitingResponse(rx) => { + if let Some(new_state) = Self::await_data(rx) { + *self = new_state; + } + CanMakeProgress::AbleToMakeProgress + } + DataState::Present(_data) => { + // Does nothing data is already present + CanMakeProgress::UnableToMakeProgress + } + DataState::Failed(_e) => { + // Have no way to let the user know there is an error nothing we + // can do here + CanMakeProgress::UnableToMakeProgress + } + } + } + + /// Checks to see if the data is ready and if it is returns a new [`Self`] + /// otherwise None + pub fn await_data(rx: &mut Awaiting) -> Option { + Some(match rx.0.try_recv() { + Ok(recv_opt) => match recv_opt { + Some(outcome_result) => match outcome_result { + Ok(data) => DataState::Present(data), + Err(err_msg) => { + warn!(?err_msg, "Error response received instead of the data"); + DataState::Failed(DataStateError::ErrorResponse(err_msg)) + } + }, + None => { + return None; + } + }, + Err(e) => { + error!("Error receiving on channel. Sender dropped."); + DataState::Failed(DataStateError::SenderDropped(e)) + } + }) + } + + /// Returns `true` if the data state is [`Present`]. + /// + /// [`Present`]: DataState::Present + #[must_use] + pub fn is_present(&self) -> bool { + matches!(self, Self::Present(..)) + } + + /// Returns `true` if the data state is [`None`]. + /// + /// [`None`]: DataState::None + #[must_use] + pub fn is_none(&self) -> bool { + matches!(self, Self::None) + } +} + +impl AsRef> for DataState { + fn as_ref(&self) -> &DataState { + self + } +} + +impl AsMut> for DataState { + fn as_mut(&mut self) -> &mut DataState { + self + } +} + +impl From for DataStateError { + fn from(value: E) -> Self { + Self::FromE(value) + } +} + +impl From<&str> for DataStateError { + fn from(value: &str) -> Self { + value.to_string().into() + } +} + +impl From for DataStateError { + fn from(value: String) -> Self { + anyhow!(value).into() + } +} + +impl CanMakeProgress { + /// Returns `true` if the can make progress is [`AbleToMakeProgress`]. + /// + /// [`AbleToMakeProgress`]: CanMakeProgress::AbleToMakeProgress + #[must_use] + pub fn is_able_to_make_progress(&self) -> bool { + matches!(self, Self::AbleToMakeProgress) + } + + /// Returns `true` if the can make progress is [`UnableToMakeProgress`]. + /// + /// [`UnableToMakeProgress`]: CanMakeProgress::UnableToMakeProgress + #[must_use] + pub fn is_unable_to_make_progress(&self) -> bool { + matches!(self, Self::UnableToMakeProgress) + } +} diff --git a/src/lib.rs b/src/lib.rs index 4d30d77..c22367a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,7 +3,8 @@ #![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] #![cfg_attr(test, deny(warnings))] -// dox - used as documentation for duplicate wasm functions (Uncertain if this will cause problems but seen this in Reqwest) +// dox - used as documentation for duplicate wasm functions (Uncertain if this will cause problems +// but seen this in Reqwest) //! # reqwest-cross //! @@ -11,45 +12,50 @@ //! wrapper around [reqwest][reqwest-url] for ease of use in applications that //! target BOTH native and wasm and do not want to block in the calling //! task/thread, for example in a UI task/thread or game loop. This is achieved -//! by using callbacks. NOTE: At least 1 [feature flag](#feature-flags) for +//! by using callbacks. This crate provides a few options to choose from and the +//! one that fits best for you depends on what you need. A good way to get an +//! idea what level of abstraction would work for you is by looking at the +//! [examples][#examples]. I would say if you're writing a larger application +//! then [DataState] can abstract away a lot of the boiler plate. In addition I +//! would prefer [fetch_plus] over [fetch] unless you don't need the UI +//! callback and [fetch_plus] ends up as the one with more boiler plate. +//! +//! NOTE: At least 1 [feature flag](#feature-flags) for //! native MUST be set to choose which runtime to use. Currently only Tokio is //! supported but if you want to use another runtime please open an issue on //! github and we'd be happy to add it. To communicate between the callback and //! the caller you can use various approaches such as: //! +//! - The helper type in this crate [DataState] see [examples +//! folder][examples_folder] //! - channels (used in [examples](#examples)) //! - `Arc>` //! - promises and so on. //! //! # Examples //! -//! For examples of how to use this crate see [fetch] +//! For examples of how to use this crate see [fetch], [fetch_plus] and the +//! [examples folder][examples_folder] in the repo //! //! # Feature Flags +#![doc = document_features::document_features!()] //! //! Exactly 1 of the "native-*" flags MUST be enabled to select which runtime to //! use for native. If one of the other options needs to be used instead of -//! tokio then defaults must be disabled. For example: `reqwest-cross = { -//! version = "*", default-features = false, features = ["native-async-std"] }` -//! (The feature in this example does not exist at this time, only used for -//! demonstration purposes). -//! -//! - **native-tokio**: Sets [tokio][tokio-url] as the runtime to use for -//! native. (Default) +//! tokio then defaults must be disabled. //! //! # Tradeoffs //! -//! **Exposing underlying framework that actually sends the requests**: The -//! currently selected approach of exposing and using [reqwest::RequestBuilder] -//! is much more flexible than the fully isolated approach used by -//! [ehttp][ehttp-url] and is generally desirable as it allows for reuse of the -//! same [reqwest::Client] as recommended by [reqwest][reqwest-url].However, -//! since [reqwest::Client] is asynchronous it requires an available runtime. -//! For wasm the spawning of the futures is handled by -//! [wasm-bindgen-futures](https://docs.rs/wasm-bindgen-futures/latest/wasm_bindgen_futures/) +//! ## Exposing underlying framework that actually sends the requests +//! The currently selected approach of exposing and using +//! [reqwest::RequestBuilder](https://docs.rs/reqwest/latest/reqwest/struct.RequestBuilder.html) is much more flexible than the fully isolated +//! approach used by [ehttp][ehttp-url] and is generally desirable as it allows +//! for reuse of the same [reqwest::Client][reqwest_client] as recommended by +//! [reqwest][reqwest-url]. However, since [reqwest::Client][reqwest_client] is +//! asynchronous it requires an available runtime. For wasm the spawning of the +//! futures is handled by [wasm-bindgen-futures](https://docs.rs/wasm-bindgen-futures/latest/wasm_bindgen_futures/) //! but for local which runtime is specified using [feature -//! flags](#feature-flags). If the one you want is not listed please create an -//! [issue](https://github.com/c-git/reqwest-cross/issues) and I'll attempt to add it. +//! flags](#feature-flags). //! //! # How to run tokio on "secondary" thread //! @@ -62,18 +68,21 @@ //! [reqwest-url]: https://docs.rs/reqwest/latest/reqwest/ //! [ehttp-url]: https://docs.rs/ehttp/0.2.0/ehttp/ //! [tokio-url]: https://docs.rs/tokio/latest/tokio/ +//! [reqwest_client]:https://docs.rs/reqwest/latest/reqwest/struct.Client.html +//! [examples_folder]: https://github.com/c-git/reqwest-cross/tree/main/examples -#[cfg(not(target_arch = "wasm32"))] -mod native; -#[cfg(target_arch = "wasm32")] -mod wasm; -mod wrappers; +mod data_state; +mod platform; +mod traits; #[cfg(feature = "yield_now")] mod yield_; -pub use wrappers::fetch; - +pub use data_state::{Awaiting, DataState, DataStateError, ErrorBounds}; +pub use platform::{fetch, fetch_plus, spawn}; +pub use traits::{BoundedFuture, DoneHandler, ResponseHandler, UiCallBack, ValidReturn}; #[cfg(feature = "yield_now")] pub use yield_::yield_now; -pub use reqwest::Client; // Exported to make it easier to use without a second import and maintain semver +// Exported to ensure version used matches +pub use futures::channel::oneshot; +pub use reqwest; diff --git a/src/native.rs b/src/native.rs deleted file mode 100644 index 0373fe8..0000000 --- a/src/native.rs +++ /dev/null @@ -1,13 +0,0 @@ -//! Stores the code specific to native compilations - -#[cfg(not(feature = "native-tokio"))] -compile_error!("Must chose a native runtime by enabling a feature flag. Right now only tokio is supported. If you have a different runtime that you want please create an issue on github."); - -#[cfg(feature = "native-tokio")] -pub fn spawn(future: F) -where - F: 'static + Send + futures::Future, - F::Output: Send + 'static, -{ - tokio::spawn(future); -} diff --git a/src/platform.rs b/src/platform.rs new file mode 100644 index 0000000..a304129 --- /dev/null +++ b/src/platform.rs @@ -0,0 +1,62 @@ +//! Stores the wrapper functions that can be called from either native or wasm +//! code + +use tracing::error; +#[cfg(not(target_arch = "wasm32"))] +mod native; +#[cfg(target_arch = "wasm32")] +mod wasm; + +// Using * imports to bring them up to this level +use crate::{BoundedFuture, ResponseHandler, UiCallBack, ValidReturn}; +#[cfg(not(target_arch = "wasm32"))] +pub use native::*; +#[cfg(target_arch = "wasm32")] +pub use wasm::*; + +/// Wraps the call to [fetch] with the surrounding boilerplate. +/// +/// # Example +/// ```rust +/// # use reqwest_cross::fetch_plus; +/// # +/// # #[tokio::main(flavor = "current_thread")] +/// # async fn main() -> Result<(), Box> { +/// let client = reqwest::Client::new(); +/// let request = client.get("https://httpbin.org/get"); +/// let handler = |result: Result| async { +/// result.expect("Expecting Response not Error").status() +/// }; +/// let rx = fetch_plus(request, handler, || {}); +/// let status = rx.await?; //In actual use case code to prevent blocking use try_recv instead +/// assert_eq!(status, 200); +/// # Ok(()) +/// # } +/// +/// # #[cfg(target_arch = "wasm32")] +/// # fn main(){} +/// ``` +#[must_use = "receiver is needed to get the response"] +pub fn fetch_plus( + req: reqwest::RequestBuilder, + response_handler: FResponseHandler, + ui_notify: FNotify, +) -> crate::oneshot::Receiver +where + FResponseHandler: ResponseHandler, + Fut: BoundedFuture, + Ret: ValidReturn, + FNotify: UiCallBack, +{ + let (tx, rx) = crate::oneshot::channel(); + let on_done = move |resp: reqwest::Result| async { + let output = response_handler(resp).await; + match tx.send(output) { + Ok(()) => {} + Err(_output) => error!("failed to send output from handler"), + }; + ui_notify(); + }; + fetch(req, on_done); + rx +} diff --git a/src/wrappers.rs b/src/platform/native.rs similarity index 50% rename from src/wrappers.rs rename to src/platform/native.rs index 101eff7..e6fcaa1 100644 --- a/src/wrappers.rs +++ b/src/platform/native.rs @@ -1,15 +1,22 @@ -//! Stores the wrapper functions that can be called from either native or wasm -//! code +//! Stores the code specific to native compilations +// but the comments are for both because these are the ones that show on docs.rs -#[cfg(not(target_arch = "wasm32"))] -/// Performs a HTTP requests and calls the given callback when done. NB: Needs -/// to use a callback to prevent blocking on the thread that initiates the -/// fetch. Note: Instead of calling get like in the example you can use post, -/// put, etc. (See [reqwest::Client]). Also see the examples +use crate::{BoundedFuture, DoneHandler}; + +#[cfg(not(feature = "native-tokio"))] +compile_error!("Must chose a native runtime by enabling a feature flag. Right now only tokio is supported. If you have a different runtime that you want please create an issue on github."); + +/// Performs a HTTP requests and calls the given callback when done with the +/// result of the request. This is a more flexible API but requires more +/// boilerplate, see [fetch_plus][crate::fetch_plus] which wraps a lot more of +/// the boilerplate especially if you need a "wake_up" function. NB: Needs to +/// use a callback to prevent blocking on the thread that initiates the fetch. +/// Note: Instead of calling get like in the example you can use post, put, etc. +/// (See [reqwest::Client]). Also see the examples /// [folder](https://github.com/c-git/reqwest-cross/tree/main/examples) /// for more complete examples. /// -/// # Tokio example +/// # Example /// ```rust /// # use reqwest_cross::fetch; /// @@ -17,7 +24,7 @@ /// # #[tokio::main(flavor = "current_thread")] /// # async fn main() -> Result<(), Box> { /// let client = reqwest::Client::new(); -/// let request = client.get("http://httpbin.org/get"); +/// let request = client.get("https://httpbin.org/get"); /// let (tx, rx) = futures::channel::oneshot::channel(); /// /// fetch(request, move |result: Result| async { @@ -35,22 +42,8 @@ /// ``` pub fn fetch(request: reqwest::RequestBuilder, on_done: F) where - F: 'static + Send + FnOnce(reqwest::Result) -> O, - O: futures::Future + Send, -{ - let future = async move { - let result = request.send().await; - on_done(result).await; - }; - spawn(future); -} - -/// dox -#[cfg(target_arch = "wasm32")] -pub fn fetch(request: reqwest::RequestBuilder, on_done: F) -where - F: 'static + FnOnce(reqwest::Result) -> O, - O: futures::Future, + F: DoneHandler, + O: BoundedFuture<()>, { let future = async move { let result = request.send().await; @@ -59,22 +52,13 @@ where spawn(future); } -#[cfg(not(target_arch = "wasm32"))] -/// Spawns a future on the underlying runtime in a cross platform way +/// Spawns a future on the underlying runtime in a cross platform way (NB: the +/// Send bound is removed in WASM) +#[cfg(feature = "native-tokio")] pub fn spawn(future: F) where - F: futures::Future + 'static + Send, + F: 'static + Send + futures::Future, + F::Output: Send + 'static, { - crate::native::spawn(future); + tokio::spawn(future); } - -#[cfg(target_arch = "wasm32")] -/// dox -pub fn spawn(future: F) -where - F: futures::Future + 'static, -{ - crate::wasm::spawn(future); -} - -// TODO 3: Test link in documentation after pushing to main diff --git a/src/platform/wasm.rs b/src/platform/wasm.rs new file mode 100644 index 0000000..1d5a246 --- /dev/null +++ b/src/platform/wasm.rs @@ -0,0 +1,22 @@ +//! Stores the code specific to wasm compilations + +/// dox +pub fn fetch(request: reqwest::RequestBuilder, on_done: F) +where + F: 'static + FnOnce(reqwest::Result) -> O, + O: futures::Future, +{ + let future = async move { + let result = request.send().await; + on_done(result).await; + }; + spawn(future); +} + +/// dox +pub fn spawn(future: F) +where + F: futures::Future + 'static, +{ + wasm_bindgen_futures::spawn_local(future); +} diff --git a/src/traits.rs b/src/traits.rs new file mode 100644 index 0000000..1ed74a1 --- /dev/null +++ b/src/traits.rs @@ -0,0 +1,20 @@ +//! Provides an easy way for calling functions to reuse bounds of public +//! functions except [spawn][crate::spawn] for which I couldn't foresee the use +//! case. If you have a use case reach out, don't mind adding it if it adds +//! value. All these traits come with automatic impls so they are automatically +//! implemented for any function that meets the bounds functions that are +//! conditionally compiled by target +// Unable to actually include this text for docs.rs because when this module is + +// public the traits it includes do not show up as Traits at the top level of +// the crate. + +#[cfg(not(target_arch = "wasm32"))] +mod native; +#[cfg(target_arch = "wasm32")] +mod wasm; + +#[cfg(not(target_arch = "wasm32"))] +pub use native::*; +#[cfg(target_arch = "wasm32")] +pub use wasm::*; diff --git a/src/traits/native.rs b/src/traits/native.rs new file mode 100644 index 0000000..29fcaad --- /dev/null +++ b/src/traits/native.rs @@ -0,0 +1,42 @@ +use std::future::Future; + +/// An async func that accepts a [reqwest::Response] +/// and returns a generic value +pub trait ResponseHandler: + Send + 'static + FnOnce(reqwest::Result) -> Fut +where + Fut: BoundedFuture, +{ +} +impl ResponseHandler for T +where + T: Send + 'static + FnOnce(reqwest::Result) -> Fut, + Fut: BoundedFuture, +{ +} + +/// A function that receives the [reqwest::Response] +/// and returns it to the application via some means (See examples for way it +/// can be done) +pub trait DoneHandler: 'static + Send + FnOnce(reqwest::Result) -> O +where + O: BoundedFuture<()>, +{ +} +impl> DoneHandler for T where + T: 'static + Send + FnOnce(reqwest::Result) -> O +{ +} + +/// A future with the required bounds for the platform +pub trait BoundedFuture: Future + Send {} +impl BoundedFuture for T where T: Future + Send {} + +/// A function able to be used as a Call Back to notify the UI that the request +/// is ready +pub trait UiCallBack: 'static + Send + FnOnce() {} +impl UiCallBack for T where T: 'static + Send + FnOnce() {} + +/// Allowed return types +pub trait ValidReturn: Send + 'static {} +impl ValidReturn for T {} diff --git a/src/traits/wasm.rs b/src/traits/wasm.rs new file mode 100644 index 0000000..63023eb --- /dev/null +++ b/src/traits/wasm.rs @@ -0,0 +1,38 @@ +use std::future::Future; + +/// dox +pub trait ResponseHandler: + 'static + FnOnce(reqwest::Result) -> Fut +where + Fut: BoundedFuture, +{ +} +impl ResponseHandler for T +where + T: 'static + FnOnce(reqwest::Result) -> Fut, + Fut: BoundedFuture, +{ +} + +/// dox +pub trait BoundedFuture: Future {} +impl BoundedFuture for T where T: Future {} + +/// dox +pub trait DoneHandler: 'static + FnOnce(reqwest::Result) -> O +where + O: BoundedFuture<()>, +{ +} +impl> DoneHandler for T where + T: 'static + FnOnce(reqwest::Result) -> O +{ +} + +/// dox +pub trait UiCallBack: 'static + FnOnce() {} +impl UiCallBack for T where T: 'static + FnOnce() {} + +/// dox +pub trait ValidReturn: 'static {} +impl ValidReturn for T {} diff --git a/src/wasm.rs b/src/wasm.rs deleted file mode 100644 index a77aefe..0000000 --- a/src/wasm.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! Stores the code specific to wasm compilations - -pub fn spawn(future: F) -where - F: futures::Future + 'static, -{ - wasm_bindgen_futures::spawn_local(future); -} diff --git a/src/yield_.rs b/src/yield_.rs index 15ca8dc..5de2faf 100644 --- a/src/yield_.rs +++ b/src/yield_.rs @@ -1,7 +1,7 @@ /// Attempts to provide a yield for executor currently in use. /// There doesn't appear to be one available as yet for wasm_bindgen_futures so /// a workaround taken from -/// https://github.com/rustwasm/wasm-bindgen/discussions/3476 is used +/// is used pub async fn yield_now() { #[cfg(target_arch = "wasm32")] sleep_ms(1).await; diff --git a/tests/web.rs b/tests/web.rs index a12a0f6..189f7e7 100644 --- a/tests/web.rs +++ b/tests/web.rs @@ -7,7 +7,7 @@ fn main() { #[wasm_bindgen_test] async fn test_fetch() -> Result<(), Box> { let client = reqwest::Client::new(); - let request = client.get("http://httpbin.org/get"); + let request = client.get("https://httpbin.org/get"); let (tx, rx) = futures::channel::oneshot::channel(); fetch(