├── .gitignore ├── web_demo ├── .gitignore ├── favicon.ico ├── README.md └── index.html ├── Cargo.toml ├── sh ├── docs.sh └── check.sh ├── example_eframe ├── README.md ├── src │ ├── main.rs │ ├── lib.rs │ ├── web.rs │ └── app.rs ├── setup_web.sh ├── start_server.sh ├── Cargo.toml └── build_web.sh ├── rust-toolchain ├── ehttp ├── src │ ├── streaming │ │ ├── types.rs │ │ ├── web.rs │ │ ├── mod.rs │ │ └── native.rs │ ├── native.rs │ ├── lib.rs │ ├── web.rs │ ├── multipart.rs │ └── types.rs └── Cargo.toml ├── RELEASES.md ├── check.sh ├── cargo_deny.sh ├── LICENSE-MIT ├── README.md ├── CHANGELOG.md ├── .github └── workflows │ ├── deploy_web_demo.yml │ └── rust.yml ├── deny.toml ├── LICENSE-APACHE └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | **/target 2 | **/target_ra 3 | /.vscode 4 | -------------------------------------------------------------------------------- /web_demo/.gitignore: -------------------------------------------------------------------------------- 1 | example_eframe_bg.wasm 2 | example_eframe.js 3 | -------------------------------------------------------------------------------- /web_demo/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emilk/ehttp/HEAD/web_demo/favicon.ico -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = [ 3 | "ehttp", 4 | "example_eframe", 5 | ] 6 | -------------------------------------------------------------------------------- /web_demo/README.md: -------------------------------------------------------------------------------- 1 | Build the web demo using `./example_eframe/build_web.sh` and serve it with `./example_eframe/start_server.sh`. 2 | -------------------------------------------------------------------------------- /sh/docs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) 4 | cd "$script_path/.." 5 | 6 | cargo doc -p ehttp --lib --no-deps --all-features --open 7 | 8 | # cargo watch -c -x 'doc -p ehttp --lib --no-deps --all-features' 9 | -------------------------------------------------------------------------------- /example_eframe/README.md: -------------------------------------------------------------------------------- 1 | Example of using `ehttp` on web and native. 2 | 3 | ## Native usage: 4 | ``` 5 | cargo run --release -p example_eframe 6 | ``` 7 | 8 | ## Web usage: 9 | 10 | ``` sh 11 | ./setup_web.sh 12 | ./start_server.sh & 13 | ./build_web.sh --fast --open 14 | ``` 15 | -------------------------------------------------------------------------------- /example_eframe/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() -> eframe::Result<()> { 2 | env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`). 3 | 4 | eframe::run_native( 5 | "ehttp demo", 6 | Default::default(), 7 | Box::new(|_cc| Box::::default()), 8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /example_eframe/setup_web.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) 4 | cd "$script_path/.." 5 | 6 | # Pre-requisites: 7 | rustup target add wasm32-unknown-unknown 8 | 9 | # For generating JS bindings: 10 | cargo install --quiet wasm-bindgen-cli --version 0.2.89 11 | 12 | -------------------------------------------------------------------------------- /example_eframe/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Example application using [`eframe`]. 2 | 3 | mod app; 4 | 5 | pub use app::DemoApp; 6 | 7 | // ---------------------------------------------------------------------------- 8 | 9 | #[cfg(target_arch = "wasm32")] 10 | mod web; 11 | 12 | #[cfg(target_arch = "wasm32")] 13 | pub use web::*; 14 | -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | # If you see this, run "rustup self update" to get rustup 1.23 or newer. 2 | 3 | # NOTE: above comment is for older `rustup` (before TOML support was added), 4 | # which will treat the first line as the toolchain name, and therefore show it 5 | # to the user in the error, instead of "error: invalid channel name '[toolchain]'". 6 | 7 | [toolchain] 8 | channel = "1.86.0" 9 | components = [ "rustfmt", "clippy" ] 10 | targets = [ "wasm32-unknown-unknown" ] 11 | -------------------------------------------------------------------------------- /ehttp/src/streaming/types.rs: -------------------------------------------------------------------------------- 1 | use crate::types::PartialResponse; 2 | 3 | /// A piece streamed by [`crate::streaming::fetch`]. 4 | pub enum Part { 5 | /// The header of the response. 6 | /// 7 | /// The `on_data` callback receives this only once. 8 | Response(PartialResponse), 9 | 10 | /// A single chunk of the response data. 11 | /// 12 | /// If the chunk is empty, that means the `on_data` callback will not receive any more data. 13 | Chunk(Vec), 14 | } 15 | -------------------------------------------------------------------------------- /example_eframe/start_server.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) 4 | cd "$script_path/.." 5 | 6 | # Starts a local web-server that serves the contents of the `doc/` folder, 7 | 8 | echo "ensuring basic-http-server is installed…" 9 | cargo install basic-http-server 10 | 11 | echo "starting server…" 12 | echo "serving at http://localhost:8787" 13 | 14 | (cd web_demo && basic-http-server --addr 127.0.0.1:8787 .) 15 | # (cd web_demo && python3 -m http.server 8787 --bind 127.0.0.1) 16 | -------------------------------------------------------------------------------- /RELEASES.md: -------------------------------------------------------------------------------- 1 | # Release Checklist 2 | 3 | * [ ] Update `CHANGELOG.md` 4 | * [ ] Bump version numbers 5 | * [ ] `git commit -m 'Release 0.x.0 - summary'` 6 | * [ ] `cargo publish` 7 | * [ ] `git tag -a 0.x.0 -m 'Release 0.x.0 - summary'` 8 | * [ ] `git pull --tags && git tag -d latest && git tag -a latest -m 'Latest release' && git push --tags origin latest --force` 9 | * [ ] `git push && git push --tags` 10 | * [ ] Do a GitHub release: https://github.com/emilk/ehttp/releases/new 11 | * [ ] Wait for documentation to build: https://docs.rs/releases/queue 12 | * [ ] Post on Twitter 13 | -------------------------------------------------------------------------------- /example_eframe/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "example_eframe" 3 | version = "0.1.0" 4 | authors = ["Emil Ernerfeldt "] 5 | description = "Demo of ehttp for both web and native using eframe" 6 | edition = "2018" 7 | license = "MIT OR Apache-2.0" 8 | publish = false 9 | 10 | [lib] 11 | crate-type = ["cdylib", "rlib"] 12 | 13 | [dependencies] 14 | ehttp = { path = "../ehttp", features = ["streaming"] } 15 | eframe = "0.24.1" 16 | log = "0.4" 17 | 18 | # native: 19 | [target.'cfg(not(target_arch = "wasm32"))'.dependencies] 20 | env_logger = "0.10" 21 | 22 | # web: 23 | [target.'cfg(target_arch = "wasm32")'.dependencies] 24 | wasm-bindgen-futures = "0.4" 25 | -------------------------------------------------------------------------------- /sh/check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) 3 | cd "$script_path/.." 4 | set -eux 5 | 6 | # Checks all tests, lints etc. 7 | # Basically does what the CI does. 8 | 9 | cargo check --workspace --all-targets --all-features 10 | cargo test --workspace --doc 11 | cargo check --lib --target wasm32-unknown-unknown --all-features 12 | cargo clippy --workspace --all-targets --all-features -- -D warnings -W clippy::all 13 | cargo test --workspace --all-targets --all-features 14 | cargo fmt --all -- --check 15 | 16 | cargo doc --lib --no-deps --all-features 17 | cargo doc --target wasm32-unknown-unknown --lib --no-deps --all-features 18 | 19 | cargo deny check 20 | -------------------------------------------------------------------------------- /check.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # This scripts runs various CI-like checks in a convenient way. 3 | 4 | set -eu 5 | script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) 6 | cd "$script_path" 7 | set -x 8 | 9 | export RUSTFLAGS="--deny warnings" 10 | 11 | # https://github.com/ericseppanen/cargo-cranky/issues/8 12 | export RUSTDOCFLAGS="--deny warnings --deny rustdoc::missing_crate_level_docs" 13 | 14 | typos # cargo install typos-cli 15 | 16 | cargo fmt --all -- --check 17 | cargo cranky --quiet --all-targets --all-features -- --deny warnings 18 | cargo test --quiet --all-targets --all-features 19 | cargo test --quiet --doc --all-features # checks all doc-tests 20 | 21 | cargo cranky --quiet --lib --target wasm32-unknown-unknown --all-features 22 | 23 | cargo doc --quiet --no-deps --all-features 24 | cargo doc --quiet --document-private-items --no-deps --all-features 25 | 26 | cargo deny --all-features --log-level error check 27 | 28 | echo "All checks passed!" 29 | -------------------------------------------------------------------------------- /cargo_deny.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) 5 | cd "$script_path" 6 | set -x 7 | 8 | # cargo install cargo-deny 9 | cargo deny --all-features --log-level error --target aarch64-apple-darwin check 10 | cargo deny --all-features --log-level error --target i686-pc-windows-gnu check 11 | cargo deny --all-features --log-level error --target i686-pc-windows-msvc check 12 | cargo deny --all-features --log-level error --target i686-unknown-linux-gnu check 13 | cargo deny --all-features --log-level error --target wasm32-unknown-unknown check 14 | cargo deny --all-features --log-level error --target x86_64-apple-darwin check 15 | cargo deny --all-features --log-level error --target x86_64-pc-windows-gnu check 16 | cargo deny --all-features --log-level error --target x86_64-pc-windows-msvc check 17 | cargo deny --all-features --log-level error --target x86_64-unknown-linux-gnu check 18 | cargo deny --all-features --log-level error --target x86_64-unknown-linux-musl check 19 | cargo deny --all-features --log-level error --target x86_64-unknown-redox check 20 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2021 Emil Ernerfeldt 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /example_eframe/src/web.rs: -------------------------------------------------------------------------------- 1 | use eframe::wasm_bindgen::{self, prelude::*}; 2 | 3 | use crate::DemoApp; 4 | 5 | /// Our handle to the web app from JavaScript. 6 | #[derive(Clone)] 7 | #[wasm_bindgen] 8 | pub struct WebHandle { 9 | runner: eframe::WebRunner, 10 | } 11 | 12 | #[wasm_bindgen] 13 | impl WebHandle { 14 | /// Installs a panic hook, then returns. 15 | #[allow(clippy::new_without_default)] 16 | #[wasm_bindgen(constructor)] 17 | pub fn new() -> Self { 18 | // Redirect [`log`] message to `console.log` and friends: 19 | eframe::WebLogger::init(log::LevelFilter::Debug).ok(); 20 | 21 | Self { 22 | runner: eframe::WebRunner::new(), 23 | } 24 | } 25 | 26 | /// Call this once from JavaScript to start your app. 27 | #[wasm_bindgen] 28 | pub async fn start(&self, canvas_id: &str) -> Result<(), wasm_bindgen::JsValue> { 29 | self.runner 30 | .start( 31 | canvas_id, 32 | eframe::WebOptions::default(), 33 | Box::new(|_cc| Box::::default()), 34 | ) 35 | .await 36 | } 37 | 38 | #[wasm_bindgen] 39 | pub fn destroy(&self) { 40 | self.runner.destroy(); 41 | } 42 | 43 | /// The JavaScript can check whether or not your app has crashed: 44 | #[wasm_bindgen] 45 | pub fn has_panicked(&self) -> bool { 46 | self.runner.has_panicked() 47 | } 48 | 49 | #[wasm_bindgen] 50 | pub fn panic_message(&self) -> Option { 51 | self.runner.panic_summary().map(|s| s.message()) 52 | } 53 | 54 | #[wasm_bindgen] 55 | pub fn panic_callstack(&self) -> Option { 56 | self.runner.panic_summary().map(|s| s.callstack()) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ehttp: a minimal Rust HTTP client for both native and WASM 2 | 3 | [![Latest version](https://img.shields.io/crates/v/ehttp.svg)](https://crates.io/crates/ehttp) 4 | [![Documentation](https://docs.rs/ehttp/badge.svg)](https://docs.rs/ehttp) 5 | [![unsafe forbidden](https://img.shields.io/badge/unsafe-forbidden-success.svg)](https://github.com/rust-secure-code/safety-dance/) 6 | [![Build Status](https://github.com/emilk/ehttp/workflows/CI/badge.svg)](https://github.com/emilk/ehttp/actions?workflow=CI) 7 | ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) 8 | ![Apache](https://img.shields.io/badge/license-Apache-blue.svg) 9 | 10 | If you want to do HTTP requests and are targeting both native, web (WASM) and NodeJS (since v18.0), then this is the crate for you! 11 | 12 | [You can try the web demo here](https://emilk.github.io/ehttp/index.html) (works in any browser with WASM and WebGL support). Uses [`eframe`](https://github.com/emilk/egui/tree/master/crates/eframe). 13 | 14 | ## Usage 15 | ``` rust 16 | let request = ehttp::Request::get("https://www.example.com"); 17 | ehttp::fetch(request, move |result: ehttp::Result| { 18 | println!("Status code: {:?}", result.unwrap().status); 19 | }); 20 | ``` 21 | 22 | The given callback is called when the request is completed. 23 | You can communicate the results back to the main thread using something like: 24 | 25 | * Channels (e.g. [`std::sync::mpsc::channel`](https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html)). 26 | * `Arc>` 27 | * [`poll_promise::Promise`](https://docs.rs/poll-promise) 28 | * [`eventuals::Eventual`](https://docs.rs/eventuals/latest/eventuals/struct.Eventual.html) 29 | * [`tokio::sync::watch::channel`](https://docs.rs/tokio/latest/tokio/sync/watch/fn.channel.html) 30 | 31 | There is also a streaming version under `ehttp::fetch::streaming`, hidden behind the `streaming` feature flag. 32 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # egui changelog 2 | 3 | All notable changes to the `ehttp` crate will be documented in this file. 4 | 5 | 6 | ## Unreleased 7 | 8 | 9 | ## 0.6.0 - 2025-12-05 10 | * Support configurable timeouts ([#71](https://github.com/emilk/ehttp/pull/71)) 11 | * Add Node.js support ([#58](https://github.com/emilk/ehttp/pull/58)) 12 | * Include `mode` on native too ([#54](https://github.com/emilk/ehttp/pull/54)) 13 | 14 | 15 | ## 0.5.0 - 2024-02-16 16 | * Support multipart and JSON ([#47](https://github.com/emilk/ehttp/pull/47), [#49](https://github.com/emilk/ehttp/pull/49)) 17 | * Added CORS `Mode` property to `Request` on web ([#52](https://github.com/emilk/ehttp/pull/52)) 18 | * Don't add `web-sys` in native builds ([#48](https://github.com/emilk/ehttp/pull/48)) 19 | 20 | 21 | ## 0.4.0 - 2024-01-17 22 | * Allow duplicated headers in requests and responses ([#46](https://github.com/emilk/ehttp/pull/46)) 23 | * Support HEAD requests ([#45](https://github.com/emilk/ehttp/pull/45)) 24 | * Add missing web-sys feature ([#42](https://github.com/emilk/ehttp/pull/42)) 25 | * Update MSRV to 1.72.0 ([#44](https://github.com/emilk/ehttp/pull/44)) 26 | 27 | 28 | ## 0.3.1 - 2023-09-27 29 | * Improve opaque network error message on web ([#33](https://github.com/emilk/ehttp/pull/33)). 30 | 31 | 32 | ## 0.3.0 - 2023-06-15 33 | * Add `ehttp::streaming`, for streaming HTTP requests ([#28](https://github.com/emilk/ehttp/pull/28)). 34 | * Add cross-platform `fetch_async` ([#25](https://github.com/emilk/ehttp/pull/25)). 35 | * Nicer formatted error messages on web. 36 | * Implement `Clone` and `Debug` for `Request` ([#17](https://github.com/emilk/ehttp/pull/17)). 37 | 38 | 39 | ## 0.2.0 - 2022-01-15 40 | * `Response::text` and `Response::content_type` no longer allocates. 41 | * Rename `ehttp::Request::create_headers_map` to `ehttp::headers`. 42 | * `Request::post` now expects `Vec`. 43 | 44 | 45 | ## 0.1.0 - 2021-09-03 - First release 46 | -------------------------------------------------------------------------------- /.github/workflows/deploy_web_demo.yml: -------------------------------------------------------------------------------- 1 | name: Deploy web demo 2 | 3 | on: 4 | # We only run this on merges to master 5 | push: 6 | branches: ["master"] 7 | # Allows you to run this workflow manually from the Actions tab 8 | workflow_dispatch: 9 | # to only run when you do a new github release, comment out above part and uncomment the below trigger. 10 | # on: 11 | # release: 12 | # types: ["published"] 13 | 14 | 15 | permissions: 16 | contents: write # for committing to gh-pages branch 17 | 18 | # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. 19 | # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. 20 | concurrency: 21 | group: "pages" 22 | cancel-in-progress: false 23 | 24 | env: 25 | # web_sys_unstable_apis is required to enable the web_sys clipboard API which eframe web uses, 26 | # as well as by the wasm32-backend of the wgpu crate. 27 | # https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Clipboard.html 28 | # https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html 29 | RUSTFLAGS: --cfg=web_sys_unstable_apis -D warnings 30 | RUSTDOCFLAGS: -D warnings 31 | 32 | jobs: 33 | # Single deploy job since we're just deploying 34 | deploy: 35 | name: Deploy web demo 36 | 37 | runs-on: ubuntu-latest 38 | steps: 39 | - name: Checkout 40 | uses: actions/checkout@v3 41 | 42 | - uses: actions-rs/toolchain@v1 43 | with: 44 | profile: minimal 45 | target: wasm32-unknown-unknown 46 | toolchain: 1.86.0 47 | override: true 48 | 49 | - uses: Swatinem/rust-cache@v2 50 | with: 51 | prefix-key: "web-demo-" 52 | 53 | - name: "Install wasmopt / binaryen" 54 | run: | 55 | sudo apt-get update && sudo apt-get install binaryen 56 | 57 | - run: | 58 | example_eframe/build_web.sh --release 59 | 60 | - name: Deploy 61 | uses: JamesIves/github-pages-deploy-action@v4 62 | with: 63 | folder: web_demo 64 | # this option will not maintain any history of your previous pages deployment 65 | # set to false if you want all page build to be committed to your gh-pages branch history 66 | single-commit: true 67 | -------------------------------------------------------------------------------- /ehttp/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ehttp" 3 | version = "0.6.0" 4 | authors = ["Emil Ernerfeldt "] 5 | description = "Minimal HTTP client for both native and WASM" 6 | edition = "2018" 7 | rust-version = "1.86" 8 | homepage = "https://github.com/emilk/ehttp" 9 | license = "MIT OR Apache-2.0" 10 | readme = "../README.md" 11 | repository = "https://github.com/emilk/ehttp" 12 | categories = ["network-programming", "wasm", "web-programming"] 13 | keywords = ["http", "wasm", "native", "web"] 14 | include = ["../LICENSE-APACHE", "../LICENSE-MIT", "**/*.rs", "Cargo.toml"] 15 | 16 | [package.metadata.docs.rs] 17 | all-features = true 18 | 19 | [lib] 20 | 21 | 22 | [features] 23 | default = [] 24 | 25 | ## Support json fetch 26 | json = ["dep:serde", "dep:serde_json"] 27 | 28 | ## Support multipart fetch 29 | multipart = ["dep:getrandom", "dep:mime", "dep:mime_guess", "dep:rand"] 30 | 31 | ## Support `fetch_async` on native 32 | native-async = ["async-channel"] 33 | 34 | ## Support streaming fetch 35 | streaming = ["dep:wasm-streams", "dep:futures-util"] 36 | 37 | 38 | [dependencies] 39 | document-features = "0.2" 40 | 41 | # Multipart request 42 | mime = { version = "0.3", optional = true } 43 | mime_guess = { version = "2.0", optional = true } 44 | rand = { version = "0.8.5", optional = true } 45 | 46 | # Json request 47 | serde = { version = "1.0", optional = true } 48 | serde_json = { version = "1.0", optional = true } 49 | 50 | # For compiling natively: 51 | [target.'cfg(not(target_arch = "wasm32"))'.dependencies] 52 | # ureq = { version = "2.0", default-features = false, features = ["gzip", "tls_native_certs"] } 53 | ureq = "2.0" 54 | async-channel = { version = "2.0", optional = true } 55 | 56 | # For compiling to web: 57 | [target.'cfg(target_arch = "wasm32")'.dependencies] 58 | js-sys = "0.3" 59 | wasm-bindgen = "0.2.89" 60 | wasm-bindgen-futures = "0.4" 61 | 62 | # Multipart request 63 | getrandom = { version = "0.2.10", features = ["js"], optional = true } 64 | 65 | # Streaming response 66 | futures-util = { version = "0.3", optional = true } 67 | wasm-streams = { version = "0.4", optional = true } 68 | 69 | web-sys = { version = "0.3.52", features = [ 70 | "AbortSignal", 71 | "console", 72 | "Headers", 73 | "ReadableStream", 74 | "Request", 75 | "RequestInit", 76 | "RequestMode", 77 | "Response", 78 | "Window", 79 | ] } 80 | -------------------------------------------------------------------------------- /example_eframe/build_web.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -eu 3 | script_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P ) 4 | cd "$script_path/.." 5 | 6 | ./example_eframe/setup_web.sh 7 | 8 | CRATE_NAME="example_eframe" 9 | 10 | OPEN=false 11 | OPTIMIZE=false 12 | BUILD=debug 13 | BUILD_FLAGS="" 14 | WASM_OPT_FLAGS="-O2 --fast-math" 15 | 16 | while test $# -gt 0; do 17 | case "$1" in 18 | -h|--help) 19 | echo "build_demo_web.sh [--release] [--open]" 20 | echo " --open: open the result in a browser" 21 | echo " --release: Build with --release, and then run wasm-opt." 22 | exit 0 23 | ;; 24 | 25 | --open) 26 | shift 27 | OPEN=true 28 | ;; 29 | 30 | --release) 31 | shift 32 | OPTIMIZE=true 33 | BUILD="release" 34 | BUILD_FLAGS="--release" 35 | ;; 36 | 37 | *) 38 | break 39 | ;; 40 | esac 41 | done 42 | 43 | # This is required to enable the web_sys clipboard API which egui_web uses 44 | # https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Clipboard.html 45 | # https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html 46 | export RUSTFLAGS=--cfg=web_sys_unstable_apis 47 | 48 | FINAL_WASM_PATH=web_demo/${CRATE_NAME}_bg.wasm 49 | 50 | # Clear output from old stuff: 51 | rm -f "${FINAL_WASM_PATH}" 52 | 53 | echo "Building rust…" 54 | 55 | cargo build \ 56 | -p ${CRATE_NAME} \ 57 | ${BUILD_FLAGS} \ 58 | --lib \ 59 | --target wasm32-unknown-unknown 60 | 61 | echo "Generating JS bindings for wasm…" 62 | TARGET_NAME="${CRATE_NAME}.wasm" 63 | wasm-bindgen "target/wasm32-unknown-unknown/$BUILD/$TARGET_NAME" \ 64 | --out-dir web_demo --no-modules --no-typescript 65 | 66 | # to get wasm-strip: apt/brew/dnf install wabt 67 | # wasm-strip "${FINAL_WASM_PATH}" 68 | 69 | if [[ "${OPTIMIZE}" = true ]]; then 70 | echo "Optimizing wasm…" 71 | # to get wasm-opt: apt/brew/dnf install binaryen 72 | wasm-opt "${FINAL_WASM_PATH}" $WASM_OPT_FLAGS -o "${FINAL_WASM_PATH}" 73 | fi 74 | 75 | echo "Finished ${FINAL_WASM_PATH}" 76 | 77 | if [ "${OPEN}" = true ]; then 78 | if [[ "$OSTYPE" == "linux-gnu"* ]]; then 79 | # Linux, ex: Fedora 80 | xdg-open http://localhost:8787/index.html 81 | elif [[ "$OSTYPE" == "msys" ]]; then 82 | # Windows 83 | start http://localhost:8787/index.html 84 | else 85 | # Darwin/MacOS, or something else 86 | open http://localhost:8787/index.html 87 | fi 88 | fi 89 | -------------------------------------------------------------------------------- /ehttp/src/streaming/web.rs: -------------------------------------------------------------------------------- 1 | use std::ops::ControlFlow; 2 | 3 | use futures_util::Stream; 4 | use futures_util::StreamExt; 5 | use wasm_bindgen::prelude::*; 6 | 7 | use crate::web::{fetch_base, get_response_base, spawn_future, string_from_fetch_error}; 8 | use crate::Request; 9 | 10 | use super::types::Part; 11 | 12 | /// Only available when compiling for web. 13 | /// 14 | /// NOTE: `Ok(…)` is returned on network error. 15 | /// `Err` is only for failure to use the fetch API. 16 | #[cfg(feature = "streaming")] 17 | pub async fn fetch_async_streaming( 18 | request: &Request, 19 | ) -> crate::Result>> { 20 | let stream = fetch_jsvalue_stream(request) 21 | .await 22 | .map_err(string_from_fetch_error)?; 23 | Ok(stream.map(|result| result.map_err(string_from_fetch_error))) 24 | } 25 | 26 | #[cfg(feature = "streaming")] 27 | async fn fetch_jsvalue_stream( 28 | request: &Request, 29 | ) -> Result>, JsValue> { 30 | use js_sys::Uint8Array; 31 | 32 | let response = fetch_base(request).await?; 33 | let body = wasm_streams::ReadableStream::from_raw( 34 | response.body().ok_or("response has no body")?.dyn_into()?, 35 | ); 36 | 37 | // returns a `Part::Response` followed by all the chunks in `body` as `Part::Chunk` 38 | Ok( 39 | futures_util::stream::once(futures_util::future::ready(Ok(Part::Response( 40 | get_response_base(&response)?, 41 | )))) 42 | .chain( 43 | body.into_stream() 44 | .map(|value| value.map(|value| Part::Chunk(Uint8Array::new(&value).to_vec()))), 45 | ), 46 | ) 47 | } 48 | 49 | pub(crate) fn fetch_streaming( 50 | request: Request, 51 | on_data: Box) -> ControlFlow<()> + Send>, 52 | ) { 53 | spawn_future(async move { 54 | let mut stream = match fetch_jsvalue_stream(&request).await { 55 | Ok(stream) => stream, 56 | Err(e) => { 57 | on_data(Err(string_from_fetch_error(e))); 58 | return; 59 | } 60 | }; 61 | 62 | while let Some(chunk) = stream.next().await { 63 | match chunk { 64 | Ok(chunk) => { 65 | if on_data(Ok(chunk)).is_break() { 66 | return; 67 | } 68 | } 69 | Err(e) => { 70 | on_data(Err(string_from_fetch_error(e))); 71 | return; 72 | } 73 | } 74 | } 75 | 76 | on_data(Ok(Part::Chunk(vec![]))); 77 | }) 78 | } 79 | -------------------------------------------------------------------------------- /ehttp/src/streaming/mod.rs: -------------------------------------------------------------------------------- 1 | //! Streaming HTTP client for both native and WASM. 2 | //! 3 | //! Requires the `streaming` feature to be enabled. 4 | //! 5 | //! Example: 6 | //! ``` 7 | //! let your_chunk_handler = std::sync::Arc::new(|chunk: Vec| { 8 | //! if chunk.is_empty() { 9 | //! return std::ops::ControlFlow::Break(()); 10 | //! } 11 | //! 12 | //! println!("received chunk: {} bytes", chunk.len()); 13 | //! std::ops::ControlFlow::Continue(()) 14 | //! }); 15 | //! 16 | //! let url = "https://www.example.com"; 17 | //! let request = ehttp::Request::get(url); 18 | //! ehttp::streaming::fetch(request, move |result: ehttp::Result| { 19 | //! let part = match result { 20 | //! Ok(part) => part, 21 | //! Err(err) => { 22 | //! eprintln!("an error occurred while streaming `{url}`: {err}"); 23 | //! return std::ops::ControlFlow::Break(()); 24 | //! } 25 | //! }; 26 | //! 27 | //! match part { 28 | //! ehttp::streaming::Part::Response(response) => { 29 | //! println!("Status code: {:?}", response.status); 30 | //! if response.ok { 31 | //! std::ops::ControlFlow::Continue(()) 32 | //! } else { 33 | //! std::ops::ControlFlow::Break(()) 34 | //! } 35 | //! } 36 | //! ehttp::streaming::Part::Chunk(chunk) => { 37 | //! your_chunk_handler(chunk) 38 | //! } 39 | //! } 40 | //! }); 41 | //! ``` 42 | //! 43 | //! The streaming fetch works like the non-streaming fetch, but instead 44 | //! of receiving the response in full, you receive parts of the response 45 | //! as they are streamed in. 46 | 47 | use std::ops::ControlFlow; 48 | 49 | use crate::Request; 50 | 51 | /// Performs a HTTP requests and calls the given callback once for the initial response, 52 | /// and then once for each chunk in the response body. 53 | /// 54 | /// You can abort the fetch by returning [`ControlFlow::Break`] from the callback. 55 | pub fn fetch( 56 | request: Request, 57 | on_data: impl 'static + Send + Fn(crate::Result) -> ControlFlow<()>, 58 | ) { 59 | #[cfg(not(target_arch = "wasm32"))] 60 | native::fetch_streaming(request, Box::new(on_data)); 61 | 62 | #[cfg(target_arch = "wasm32")] 63 | web::fetch_streaming(request, Box::new(on_data)); 64 | } 65 | 66 | #[cfg(not(target_arch = "wasm32"))] 67 | mod native; 68 | #[cfg(not(target_arch = "wasm32"))] 69 | pub use native::fetch_streaming_blocking; 70 | 71 | #[cfg(target_arch = "wasm32")] 72 | mod web; 73 | #[cfg(target_arch = "wasm32")] 74 | pub use web::fetch_async_streaming; 75 | 76 | mod types; 77 | 78 | pub use self::types::Part; 79 | -------------------------------------------------------------------------------- /ehttp/src/streaming/native.rs: -------------------------------------------------------------------------------- 1 | use std::ops::ControlFlow; 2 | 3 | use crate::Request; 4 | 5 | use super::Part; 6 | use crate::types::PartialResponse; 7 | 8 | pub fn fetch_streaming_blocking( 9 | request: Request, 10 | on_data: Box) -> ControlFlow<()> + Send>, 11 | ) { 12 | let mut req = ureq::request(&request.method, &request.url); 13 | 14 | for (k, v) in &request.headers { 15 | req = req.set(k, v); 16 | } 17 | 18 | let resp = if request.body.is_empty() { 19 | req.call() 20 | } else { 21 | req.send_bytes(&request.body) 22 | }; 23 | 24 | let (ok, resp) = match resp { 25 | Ok(resp) => (true, resp), 26 | Err(ureq::Error::Status(_, resp)) => (false, resp), // Still read the body on e.g. 404 27 | Err(ureq::Error::Transport(err)) => { 28 | on_data(Err(err.to_string())); 29 | return; 30 | } 31 | }; 32 | 33 | let url = resp.get_url().to_owned(); 34 | let status = resp.status(); 35 | let status_text = resp.status_text().to_owned(); 36 | let mut headers = crate::Headers::default(); 37 | for key in &resp.headers_names() { 38 | if let Some(value) = resp.header(key) { 39 | headers.insert(key.to_ascii_lowercase(), value.to_owned()); 40 | } 41 | } 42 | headers.sort(); // It reads nicer, and matches web backend. 43 | 44 | let response = PartialResponse { 45 | url, 46 | ok, 47 | status, 48 | status_text, 49 | headers, 50 | }; 51 | if on_data(Ok(Part::Response(response))).is_break() { 52 | return; 53 | }; 54 | 55 | let mut reader = resp.into_reader(); 56 | loop { 57 | let mut buf = vec![0; 2048]; 58 | match reader.read(&mut buf) { 59 | Ok(n) if n > 0 => { 60 | // clone data from buffer and clear it 61 | let chunk = buf[..n].to_vec(); 62 | if on_data(Ok(Part::Chunk(chunk))).is_break() { 63 | return; 64 | }; 65 | } 66 | Ok(_) => { 67 | on_data(Ok(Part::Chunk(vec![]))); 68 | break; 69 | } 70 | Err(err) => { 71 | if request.method == "HEAD" && err.kind() == std::io::ErrorKind::UnexpectedEof { 72 | // We don't really expect a body for HEAD requests, so this is fine. 73 | on_data(Ok(Part::Chunk(vec![]))); 74 | break; 75 | } else { 76 | on_data(Err(format!("Failed to read response body: {err}"))); 77 | return; 78 | } 79 | } 80 | }; 81 | } 82 | } 83 | 84 | pub(crate) fn fetch_streaming( 85 | request: Request, 86 | on_data: Box) -> ControlFlow<()> + Send>, 87 | ) { 88 | std::thread::Builder::new() 89 | .name("ehttp".to_owned()) 90 | .spawn(move || fetch_streaming_blocking(request, on_data)) 91 | .expect("Failed to spawn ehttp thread"); 92 | } 93 | -------------------------------------------------------------------------------- /deny.toml: -------------------------------------------------------------------------------- 1 | # https://github.com/EmbarkStudios/cargo-deny 2 | # 3 | # cargo-deny checks our dependency tree for copy-left licenses, 4 | # duplicate dependencies, and rustsec advisories (https://rustsec.org/advisories). 5 | # 6 | # Install: `cargo install cargo-deny` 7 | # Check: `cargo deny check`. 8 | 9 | # Note: running just `cargo deny check` without a `--target` can result in 10 | # false positives due to https://github.com/EmbarkStudios/cargo-deny/issues/324 11 | targets = [ 12 | { triple = "aarch64-apple-darwin" }, 13 | { triple = "i686-pc-windows-gnu" }, 14 | { triple = "i686-pc-windows-msvc" }, 15 | { triple = "i686-unknown-linux-gnu" }, 16 | { triple = "wasm32-unknown-unknown" }, 17 | { triple = "x86_64-apple-darwin" }, 18 | { triple = "x86_64-pc-windows-gnu" }, 19 | { triple = "x86_64-pc-windows-msvc" }, 20 | { triple = "x86_64-unknown-linux-gnu" }, 21 | { triple = "x86_64-unknown-linux-musl" }, 22 | { triple = "x86_64-unknown-redox" }, 23 | ] 24 | 25 | [advisories] 26 | vulnerability = "deny" 27 | unmaintained = "warn" 28 | yanked = "deny" 29 | ignore = [ 30 | "RUSTSEC-2021-0019", # https://rustsec.org/advisories/RUSTSEC-2021-0019 - From xcb <- x11-clipboard <- copypasta <- egui-winit <- eframe (dev-dependency) 31 | ] 32 | 33 | [bans] 34 | multiple-versions = "deny" 35 | wildcards = "allow" # at least until https://github.com/EmbarkStudios/cargo-deny/issues/241 is fixed 36 | deny = [ 37 | { name = "openssl" }, # prefer rustls 38 | { name = "openssl-sys" }, # prefer rustls 39 | ] 40 | 41 | skip = [] 42 | skip-tree = [ 43 | { name = "eframe" }, # dev-dependency 44 | ] 45 | 46 | 47 | [licenses] 48 | unlicensed = "deny" 49 | allow-osi-fsf-free = "neither" 50 | confidence-threshold = 0.92 # We want really high confidence when inferring licenses from text 51 | copyleft = "deny" 52 | allow = [ 53 | "Apache-2.0 WITH LLVM-exception", # https://spdx.org/licenses/LLVM-exception.html 54 | "Apache-2.0", # https://tldrlegal.com/license/apache-license-2.0-(apache-2.0) 55 | "BSD-2-Clause", # https://tldrlegal.com/license/bsd-2-clause-license-(freebsd) 56 | "BSD-3-Clause", # https://tldrlegal.com/license/bsd-3-clause-license-(revised) 57 | "BSL-1.0", # https://tldrlegal.com/license/boost-software-license-1.0-explained 58 | "CC0-1.0", # https://creativecommons.org/publicdomain/zero/1.0/ 59 | "ISC", # https://tldrlegal.com/license/-isc-license 60 | "LicenseRef-UFL-1.0", # https://tldrlegal.com/license/ubuntu-font-license,-1.0 - no official SPDX, see https://github.com/emilk/egui/issues/2321 61 | "MIT", # https://tldrlegal.com/license/mit-license 62 | "MPL-2.0", # https://www.mozilla.org/en-US/MPL/2.0/FAQ/ - see Q11 63 | "OFL-1.1", # https://spdx.org/licenses/OFL-1.1.html 64 | "OpenSSL", # https://www.openssl.org/source/license.html 65 | "Unicode-DFS-2016", # https://spdx.org/licenses/Unicode-DFS-2016.html 66 | "Zlib", # https://tldrlegal.com/license/zlib-libpng-license-(zlib) 67 | ] 68 | 69 | [[licenses.clarify]] 70 | name = "webpki" 71 | expression = "ISC" 72 | license-files = [{ path = "LICENSE", hash = 0x001c7e6c }] 73 | 74 | [[licenses.clarify]] 75 | name = "rustls-webpki" 76 | expression = "ISC" 77 | license-files = [{ path = "LICENSE", hash = 0x001c7e6c }] 78 | 79 | [[licenses.clarify]] 80 | name = "ring" 81 | expression = "MIT AND ISC AND OpenSSL" 82 | license-files = [{ path = "LICENSE", hash = 0xbd0eed23 }] 83 | -------------------------------------------------------------------------------- /ehttp/src/native.rs: -------------------------------------------------------------------------------- 1 | use crate::{Request, Response}; 2 | 3 | #[cfg(feature = "native-async")] 4 | use async_channel::{Receiver, Sender}; 5 | 6 | /// Performs a HTTP request and blocks the thread until it is done. 7 | /// 8 | /// Only available when compiling for native. 9 | /// 10 | /// NOTE: `Ok(…)` is returned on network error. 11 | /// 12 | /// `Ok` is returned if we get a response, even if it's a 404. 13 | /// 14 | /// `Err` can happen for a number of reasons: 15 | /// * No internet connection 16 | /// * Connection timed out 17 | /// * DNS resolution failed 18 | /// * Firewall or proxy blocked the request 19 | /// * Server is not reachable 20 | /// * The URL is invalid 21 | /// * Server's SSL cert is invalid 22 | /// * CORS errors 23 | /// * The initial GET which returned HTML contained CSP headers to block access to the resource 24 | /// * A browser extension blocked the request (e.g. ad blocker) 25 | /// * … 26 | pub fn fetch_blocking(request: &Request) -> crate::Result { 27 | let mut req = ureq::request(&request.method, &request.url); 28 | 29 | if let Some(timeout) = request.timeout { 30 | req = req.timeout(timeout); 31 | } 32 | 33 | for (k, v) in &request.headers { 34 | req = req.set(k, v); 35 | } 36 | 37 | let resp = if request.body.is_empty() { 38 | req.call() 39 | } else { 40 | req.send_bytes(&request.body) 41 | }; 42 | 43 | let (ok, resp) = match resp { 44 | Ok(resp) => (true, resp), 45 | Err(ureq::Error::Status(_, resp)) => (false, resp), // Still read the body on e.g. 404 46 | Err(ureq::Error::Transport(err)) => return Err(err.to_string()), 47 | }; 48 | 49 | let url = resp.get_url().to_owned(); 50 | let status = resp.status(); 51 | let status_text = resp.status_text().to_owned(); 52 | let mut headers = crate::Headers::default(); 53 | for key in &resp.headers_names() { 54 | if let Some(value) = resp.header(key) { 55 | headers.insert(key, value.to_owned()); 56 | } 57 | } 58 | headers.sort(); // It reads nicer, and matches web backend. 59 | 60 | let mut reader = resp.into_reader(); 61 | let mut bytes = vec![]; 62 | use std::io::Read as _; 63 | if let Err(err) = reader.read_to_end(&mut bytes) { 64 | if request.method == "HEAD" && err.kind() == std::io::ErrorKind::UnexpectedEof { 65 | // We don't really expect a body for HEAD requests, so this is fine. 66 | } else { 67 | return Err(format!("Failed to read response body: {err}")); 68 | } 69 | } 70 | 71 | let response = Response { 72 | url, 73 | ok, 74 | status, 75 | status_text, 76 | headers, 77 | bytes, 78 | }; 79 | Ok(response) 80 | } 81 | 82 | // ---------------------------------------------------------------------------- 83 | 84 | pub(crate) fn fetch(request: Request, on_done: Box) + Send>) { 85 | std::thread::Builder::new() 86 | .name("ehttp".to_owned()) 87 | .spawn(move || on_done(fetch_blocking(&request))) 88 | .expect("Failed to spawn ehttp thread"); 89 | } 90 | 91 | #[cfg(feature = "native-async")] 92 | pub(crate) async fn fetch_async(request: Request) -> crate::Result { 93 | let (tx, rx): ( 94 | Sender>, 95 | Receiver>, 96 | ) = async_channel::bounded(1); 97 | 98 | fetch( 99 | request, 100 | Box::new(move |received| tx.send_blocking(received).unwrap()), 101 | ); 102 | rx.recv().await.map_err(|err| err.to_string())? 103 | } 104 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | on: [push, pull_request] 2 | 3 | name: CI 4 | 5 | env: 6 | # This is required to enable the web_sys clipboard API which egui_web uses 7 | # https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Clipboard.html 8 | # https://rustwasm.github.io/docs/wasm-bindgen/web-sys/unstable-apis.html 9 | RUSTFLAGS: --cfg=web_sys_unstable_apis --deny warnings 10 | RUSTDOCFLAGS: --deny warnings 11 | 12 | jobs: 13 | check_native: 14 | name: cargo check --all-features 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v2 18 | - uses: actions-rs/toolchain@v1 19 | with: 20 | profile: minimal 21 | toolchain: 1.86.0 22 | override: true 23 | - uses: actions-rs/cargo@v1 24 | with: 25 | command: check 26 | args: --all-features 27 | 28 | check_web: 29 | name: cargo check web --all-features 30 | runs-on: ubuntu-latest 31 | steps: 32 | - uses: actions/checkout@v2 33 | - uses: actions-rs/toolchain@v1 34 | with: 35 | profile: minimal 36 | toolchain: 1.86.0 37 | override: true 38 | - run: rustup target add wasm32-unknown-unknown 39 | - uses: actions-rs/cargo@v1 40 | with: 41 | command: check 42 | args: --lib --target wasm32-unknown-unknown --all-features 43 | 44 | test: 45 | name: cargo test 46 | runs-on: ubuntu-latest 47 | steps: 48 | - uses: actions/checkout@v2 49 | - uses: actions-rs/toolchain@v1 50 | with: 51 | profile: minimal 52 | toolchain: 1.86.0 53 | override: true 54 | - uses: actions-rs/cargo@v1 55 | with: 56 | command: test 57 | args: --all-features -p ehttp 58 | 59 | fmt: 60 | name: cargo fmt 61 | runs-on: ubuntu-latest 62 | steps: 63 | - uses: actions/checkout@v2 64 | - uses: actions-rs/toolchain@v1 65 | with: 66 | profile: minimal 67 | toolchain: 1.86.0 68 | override: true 69 | - run: rustup component add rustfmt 70 | - uses: actions-rs/cargo@v1 71 | with: 72 | command: fmt 73 | args: --all -- --check 74 | 75 | clippy: 76 | name: cargo clippy 77 | runs-on: ubuntu-latest 78 | steps: 79 | - uses: actions/checkout@v2 80 | - uses: actions-rs/toolchain@v1 81 | with: 82 | profile: minimal 83 | toolchain: 1.86.0 84 | override: true 85 | - run: rustup component add clippy 86 | - uses: actions-rs/cargo@v1 87 | with: 88 | command: clippy 89 | args: --all-targets --all-features -- --deny warnings -W clippy::all 90 | 91 | doc: 92 | name: cargo doc 93 | runs-on: ubuntu-latest 94 | steps: 95 | - uses: actions/checkout@v2 96 | - uses: actions-rs/toolchain@v1 97 | with: 98 | profile: minimal 99 | toolchain: 1.86.0 100 | override: true 101 | - run: cargo doc -p ehttp --lib --no-deps --all-features 102 | 103 | doc_web: 104 | name: cargo doc web 105 | runs-on: ubuntu-latest 106 | steps: 107 | - uses: actions/checkout@v2 108 | - uses: actions-rs/toolchain@v1 109 | with: 110 | profile: minimal 111 | toolchain: 1.86.0 112 | override: true 113 | - run: rustup target add wasm32-unknown-unknown 114 | - run: cargo doc -p ehttp --target wasm32-unknown-unknown --lib --no-deps --all-features 115 | 116 | cargo-deny: 117 | runs-on: ubuntu-20.04 118 | steps: 119 | - uses: actions/checkout@v2 120 | - uses: EmbarkStudios/cargo-deny-action@v1 121 | -------------------------------------------------------------------------------- /ehttp/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Minimal HTTP client for both native and WASM. 2 | //! 3 | //! Example: 4 | //! ``` 5 | //! let request = ehttp::Request::get("https://www.example.com"); 6 | //! ehttp::fetch(request, move |result: ehttp::Result| { 7 | //! println!("Status code: {:?}", result.unwrap().status); 8 | //! }); 9 | //! ``` 10 | //! 11 | //! The given callback is called when the request is completed. 12 | //! You can communicate the results back to the main thread using something like: 13 | //! 14 | //! * Channels (e.g. [`std::sync::mpsc::channel`](https://doc.rust-lang.org/std/sync/mpsc/fn.channel.html)). 15 | //! * `Arc>` 16 | //! * [`poll_promise::Promise`](https://docs.rs/poll-promise) 17 | //! * [`eventuals::Eventual`](https://docs.rs/eventuals/latest/eventuals/struct.Eventual.html) 18 | //! * [`tokio::sync::watch::channel`](https://docs.rs/tokio/latest/tokio/sync/watch/fn.channel.html) 19 | //! 20 | //! ## Feature flags 21 | #![doc = document_features::document_features!()] 22 | //! 23 | 24 | /// Performs an HTTP request and calls the given callback when done. 25 | /// 26 | /// `Ok` is returned if we get a response, even if it's a 404. 27 | /// 28 | /// `Err` can happen for a number of reasons: 29 | /// * No internet connection 30 | /// * Connection timed out 31 | /// * DNS resolution failed 32 | /// * Firewall or proxy blocked the request 33 | /// * Server is not reachable 34 | /// * The URL is invalid 35 | /// * Server's SSL cert is invalid 36 | /// * CORS errors 37 | /// * The initial GET which returned HTML contained CSP headers to block access to the resource 38 | /// * A browser extension blocked the request (e.g. ad blocker) 39 | /// * … 40 | pub fn fetch(request: Request, on_done: impl 'static + Send + FnOnce(Result)) { 41 | #[cfg(not(target_arch = "wasm32"))] 42 | native::fetch(request, Box::new(on_done)); 43 | 44 | #[cfg(target_arch = "wasm32")] 45 | web::fetch(request, Box::new(on_done)); 46 | } 47 | 48 | /// Performs an `async` HTTP request. 49 | /// 50 | /// Available on following platforms: 51 | /// - web 52 | /// - native behind the `native-async` feature. 53 | /// 54 | /// `Ok` is returned if we get a response, even if it's a 404. 55 | /// 56 | /// `Err` can happen for a number of reasons: 57 | /// * No internet connection 58 | /// * Connection timed out 59 | /// * DNS resolution failed 60 | /// * Firewall or proxy blocked the request 61 | /// * Server is not reachable 62 | /// * The URL is invalid 63 | /// * Server's SSL cert is invalid 64 | /// * CORS errors 65 | /// * The initial GET which returned HTML contained CSP headers to block access to the resource 66 | /// * A browser extension blocked the request (e.g. ad blocker) 67 | /// * … 68 | #[cfg(any(target_arch = "wasm32", feature = "native-async"))] 69 | pub async fn fetch_async(request: Request) -> Result { 70 | #[cfg(not(target_arch = "wasm32"))] 71 | return native::fetch_async(request).await; 72 | 73 | #[cfg(target_arch = "wasm32")] 74 | return web::fetch_async(&request).await; 75 | } 76 | 77 | mod types; 78 | pub use types::{Error, Headers, PartialResponse, Request, Response, Result}; 79 | 80 | #[cfg(target_arch = "wasm32")] 81 | pub use types::Mode; 82 | 83 | #[cfg(not(target_arch = "wasm32"))] 84 | mod native; 85 | #[cfg(not(target_arch = "wasm32"))] 86 | pub use native::fetch_blocking; 87 | 88 | #[cfg(target_arch = "wasm32")] 89 | mod web; 90 | #[cfg(target_arch = "wasm32")] 91 | pub use web::spawn_future; 92 | 93 | #[cfg(feature = "streaming")] 94 | pub mod streaming; 95 | 96 | #[cfg(feature = "multipart")] 97 | pub mod multipart; 98 | 99 | #[deprecated = "Use ehttp::Headers::new"] 100 | pub fn headers(headers: &[(&str, &str)]) -> Headers { 101 | Headers::new(headers) 102 | } 103 | -------------------------------------------------------------------------------- /ehttp/src/web.rs: -------------------------------------------------------------------------------- 1 | use wasm_bindgen::prelude::*; 2 | use wasm_bindgen_futures::JsFuture; 3 | 4 | use crate::types::PartialResponse; 5 | use crate::{Request, Response}; 6 | 7 | /// Binds the JavaScript `fetch` method for use in both Node.js (>= v18.0) and browser environments. 8 | #[wasm_bindgen] 9 | extern "C" { 10 | #[wasm_bindgen(js_name = fetch)] 11 | fn fetch_with_request(input: &web_sys::Request) -> js_sys::Promise; 12 | } 13 | 14 | /// Only available when compiling for web. 15 | /// 16 | /// NOTE: `Ok(…)` is returned on network error. 17 | /// 18 | /// `Err` can happen for a number of reasons: 19 | /// * No internet connection 20 | /// * Connection timed out 21 | /// * DNS resolution failed 22 | /// * Firewall or proxy blocked the request 23 | /// * Server is not reachable 24 | /// * The URL is invalid 25 | /// * Server's SSL cert is invalid 26 | /// * CORS errors 27 | /// * The initial GET which returned HTML contained CSP headers to block access to the resource 28 | /// * A browser extension blocked the request (e.g. ad blocker) 29 | /// * … 30 | pub async fn fetch_async(request: &Request) -> crate::Result { 31 | fetch_jsvalue(request) 32 | .await 33 | .map_err(string_from_fetch_error) 34 | } 35 | 36 | /// This should only be used to handle opaque exceptions thrown by the `fetch` call. 37 | pub(crate) fn string_from_fetch_error(value: JsValue) -> String { 38 | value.as_string().unwrap_or_else(|| { 39 | // TypeError means that this is an opaque `network error`, as defined by the spec: 40 | // https://fetch.spec.whatwg.org/ 41 | if value.has_type::() { 42 | web_sys::console::error_1(&value); 43 | "Failed to fetch, check the developer console for details".to_owned() 44 | } else { 45 | format!("{:#?}", value) 46 | } 47 | }) 48 | } 49 | 50 | pub(crate) async fn fetch_base(request: &Request) -> Result { 51 | let mut opts = web_sys::RequestInit::new(); 52 | opts.method(&request.method); 53 | opts.mode(request.mode.into()); 54 | 55 | if !request.body.is_empty() { 56 | let body_bytes: &[u8] = &request.body; 57 | let body_array: js_sys::Uint8Array = body_bytes.into(); 58 | let js_value: &JsValue = body_array.as_ref(); 59 | opts.body(Some(js_value)); 60 | } 61 | 62 | let js_request = web_sys::Request::new_with_str_and_init(&request.url, &opts)?; 63 | 64 | for (k, v) in &request.headers { 65 | js_request.headers().set(k, v)?; 66 | } 67 | 68 | let response = JsFuture::from(fetch_with_request(&js_request)).await?; 69 | let response: web_sys::Response = response.dyn_into()?; 70 | 71 | Ok(response) 72 | } 73 | 74 | pub(crate) fn get_response_base(response: &web_sys::Response) -> Result { 75 | // https://developer.mozilla.org/en-US/docs/Web/API/Headers 76 | // "Note: When Header values are iterated over, […] values from duplicate header names are combined." 77 | // TODO: support duplicate header names 78 | let js_headers: web_sys::Headers = response.headers(); 79 | let js_iter = js_sys::try_iter(&js_headers) 80 | .expect("headers try_iter") 81 | .expect("headers have an iterator"); 82 | 83 | let mut headers = crate::Headers::default(); 84 | for item in js_iter { 85 | let item = item.expect("headers iterator"); 86 | let array: js_sys::Array = item.into(); 87 | let v: Vec = array.to_vec(); 88 | 89 | let key = v[0] 90 | .as_string() 91 | .ok_or_else(|| JsValue::from_str("headers name"))?; 92 | let value = v[1] 93 | .as_string() 94 | .ok_or_else(|| JsValue::from_str("headers value"))?; 95 | 96 | headers.insert(key, value); 97 | } 98 | 99 | Ok(PartialResponse { 100 | url: response.url(), 101 | ok: response.ok(), 102 | status: response.status(), 103 | status_text: response.status_text(), 104 | headers, 105 | }) 106 | } 107 | 108 | /// NOTE: `Ok(…)` is returned on network error. 109 | /// `Err` is only for failure to use the fetch API. 110 | async fn fetch_jsvalue(request: &Request) -> Result { 111 | let response = fetch_base(request).await?; 112 | 113 | let array_buffer = JsFuture::from(response.array_buffer()?).await?; 114 | let uint8_array = js_sys::Uint8Array::new(&array_buffer); 115 | let bytes = uint8_array.to_vec(); 116 | 117 | let base = get_response_base(&response)?; 118 | 119 | Ok(Response { 120 | url: base.url, 121 | ok: base.ok, 122 | status: base.status, 123 | status_text: base.status_text, 124 | bytes, 125 | headers: base.headers, 126 | }) 127 | } 128 | 129 | /// Spawn an async task. 130 | /// 131 | /// A wrapper around `wasm_bindgen_futures::spawn_local`. 132 | /// Only available with the web backend. 133 | pub fn spawn_future(future: F) 134 | where 135 | F: std::future::Future + 'static, 136 | { 137 | wasm_bindgen_futures::spawn_local(future); 138 | } 139 | 140 | // ---------------------------------------------------------------------------- 141 | 142 | pub(crate) fn fetch(request: Request, on_done: Box) + Send>) { 143 | spawn_future(async move { 144 | let result = fetch_async(&request).await; 145 | on_done(result) 146 | }); 147 | } 148 | -------------------------------------------------------------------------------- /ehttp/src/multipart.rs: -------------------------------------------------------------------------------- 1 | //! Multipart HTTP request for both native and WASM. 2 | //! 3 | //! Requires the `multipart` feature to be enabled. 4 | //! 5 | //! Example: 6 | //! ``` 7 | //! use std::io::Cursor; 8 | //! use ehttp::multipart::MultipartBuilder; 9 | //! let url = "https://www.example.com"; 10 | //! let request = ehttp::Request::multipart( 11 | //! url, 12 | //! MultipartBuilder::new() 13 | //! .add_text("label", "lorem ipsum") 14 | //! .add_stream( 15 | //! &mut Cursor::new(vec![0, 0, 0, 0]), 16 | //! "4_empty_bytes", 17 | //! Some("4_empty_bytes.png"), 18 | //! None, 19 | //! ) 20 | //! .unwrap(), 21 | //! ); 22 | //! ehttp::fetch(request, |result| {}); 23 | //! ``` 24 | //! Taken from ureq_multipart 1.1.1 25 | //! 26 | 27 | use mime::Mime; 28 | use rand::Rng; 29 | 30 | use std::io::{self, Read, Write}; 31 | 32 | const BOUNDARY_LEN: usize = 29; 33 | 34 | fn random_alphanumeric(len: usize) -> String { 35 | rand::thread_rng() 36 | .sample_iter(&rand::distributions::Uniform::from(0..=9)) 37 | .take(len) 38 | .map(|num| num.to_string()) 39 | .collect() 40 | } 41 | 42 | #[derive(Debug)] 43 | /// The Builder for the multipart 44 | pub struct MultipartBuilder { 45 | boundary: String, 46 | inner: Vec, 47 | data_written: bool, 48 | } 49 | 50 | impl Default for MultipartBuilder { 51 | fn default() -> Self { 52 | Self::new() 53 | } 54 | } 55 | 56 | #[allow(dead_code)] 57 | impl MultipartBuilder { 58 | /// creates a new MultipartBuilder with empty inner 59 | pub fn new() -> Self { 60 | Self { 61 | boundary: random_alphanumeric(BOUNDARY_LEN), 62 | inner: Vec::new(), 63 | data_written: false, 64 | } 65 | } 66 | 67 | /// add text field 68 | /// 69 | /// * name field name 70 | /// * text field text value 71 | pub fn add_text(mut self, name: &str, text: &str) -> Self { 72 | self.write_field_headers(name, None, None); 73 | self.inner.extend(text.as_bytes()); 74 | self 75 | } 76 | 77 | /// add file 78 | /// 79 | /// * name file field name 80 | /// * path the sending file path 81 | #[cfg(not(target_arch = "wasm32"))] 82 | pub fn add_file>(self, name: &str, path: P) -> io::Result { 83 | fn mime_filename(path: &std::path::Path) -> (Mime, Option<&str>) { 84 | let content_type = mime_guess::from_path(path); 85 | let filename = path.file_name().and_then(|filename| filename.to_str()); 86 | (content_type.first_or_octet_stream(), filename) 87 | } 88 | 89 | let path = path.as_ref(); 90 | let (content_type, filename) = mime_filename(path); 91 | let mut file = std::fs::File::open(path)?; 92 | self.add_stream(&mut file, name, filename, Some(content_type)) 93 | } 94 | 95 | /// add some stream 96 | pub fn add_stream( 97 | mut self, 98 | stream: &mut S, 99 | name: &str, 100 | filename: Option<&str>, 101 | content_type: Option, 102 | ) -> io::Result { 103 | // This is necessary to make sure it is interpreted as a file on the server end. 104 | let content_type = Some(content_type.unwrap_or(mime::APPLICATION_OCTET_STREAM)); 105 | self.write_field_headers(name, filename, content_type); 106 | io::copy(stream, &mut self.inner)?; 107 | Ok(self) 108 | } 109 | 110 | fn write_boundary(&mut self) { 111 | if self.data_written { 112 | self.inner.write_all(b"\r\n").unwrap(); 113 | } 114 | 115 | write!( 116 | self.inner, 117 | "-----------------------------{}\r\n", 118 | self.boundary 119 | ) 120 | .unwrap() 121 | } 122 | 123 | fn write_field_headers( 124 | &mut self, 125 | name: &str, 126 | filename: Option<&str>, 127 | content_type: Option, 128 | ) { 129 | self.write_boundary(); 130 | if !self.data_written { 131 | self.data_written = true; 132 | } 133 | write!( 134 | self.inner, 135 | "Content-Disposition: form-data; name=\"{name}\"" 136 | ) 137 | .unwrap(); 138 | if let Some(filename) = filename { 139 | write!(self.inner, "; filename=\"{filename}\"").unwrap(); 140 | } 141 | if let Some(content_type) = content_type { 142 | write!(self.inner, "\r\nContent-Type: {content_type}").unwrap(); 143 | } 144 | self.inner.write_all(b"\r\n\r\n").unwrap(); 145 | } 146 | 147 | /// general multipart data 148 | /// 149 | /// # Return 150 | /// * (content_type,post_data) 151 | /// * content_type http header content type 152 | /// * post_data ureq.req.send_send_bytes(&post_data) 153 | /// 154 | pub fn finish(mut self) -> (String, Vec) { 155 | if self.data_written { 156 | self.inner.write_all(b"\r\n").unwrap(); 157 | } 158 | 159 | // always write the closing boundary, even for empty bodies 160 | write!( 161 | self.inner, 162 | "-----------------------------{}--\r\n", 163 | self.boundary 164 | ) 165 | .unwrap(); 166 | ( 167 | format!( 168 | "multipart/form-data; boundary=---------------------------{}", 169 | self.boundary 170 | ), 171 | self.inner, 172 | ) 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /web_demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ehttp example 10 | 95 | 96 | 97 | 98 | 99 | 100 |
101 |

102 | Loading… 103 |

104 |
105 |
106 | 107 | 119 | 120 | 121 | 122 | 123 | 194 | 195 | 196 | 197 | 198 | 199 | -------------------------------------------------------------------------------- /example_eframe/src/app.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | ops::ControlFlow, 3 | sync::{Arc, Mutex}, 4 | }; 5 | 6 | use eframe::egui; 7 | 8 | #[derive(Debug, PartialEq, Copy, Clone)] 9 | enum Method { 10 | Get, 11 | Head, 12 | Post, 13 | } 14 | 15 | enum Download { 16 | None, 17 | InProgress, 18 | StreamingInProgress { 19 | response: ehttp::PartialResponse, 20 | body: Vec, 21 | }, 22 | Done(ehttp::Result), 23 | } 24 | 25 | pub struct DemoApp { 26 | url: String, 27 | method: Method, 28 | request_body: String, 29 | streaming: bool, 30 | download: Arc>, 31 | } 32 | 33 | impl Default for DemoApp { 34 | fn default() -> Self { 35 | Self { 36 | url: "https://raw.githubusercontent.com/emilk/ehttp/master/README.md".to_owned(), 37 | method: Method::Get, 38 | request_body: r#"["posting some json"]"#.to_owned(), 39 | streaming: true, 40 | download: Arc::new(Mutex::new(Download::None)), 41 | } 42 | } 43 | } 44 | 45 | impl eframe::App for DemoApp { 46 | fn update(&mut self, egui_ctx: &egui::Context, _frame: &mut eframe::Frame) { 47 | egui::CentralPanel::default().show(egui_ctx, |ui| { 48 | let trigger_fetch = self.ui_url(ui); 49 | 50 | if trigger_fetch { 51 | let request = match self.method { 52 | Method::Get => ehttp::Request::get(&self.url), 53 | Method::Head => ehttp::Request::head(&self.url), 54 | Method::Post => { 55 | ehttp::Request::post(&self.url, self.request_body.as_bytes().to_vec()) 56 | } 57 | }; 58 | let download_store = self.download.clone(); 59 | *download_store.lock().unwrap() = Download::InProgress; 60 | let egui_ctx = egui_ctx.clone(); 61 | 62 | if self.streaming { 63 | // The more complicated streaming API: 64 | ehttp::streaming::fetch(request, move |part| { 65 | egui_ctx.request_repaint(); // Wake up UI thread 66 | on_fetch_part(part, &mut download_store.lock().unwrap()) 67 | }); 68 | } else { 69 | // The simple non-streaming API: 70 | ehttp::fetch(request, move |response| { 71 | *download_store.lock().unwrap() = Download::Done(response); 72 | egui_ctx.request_repaint(); // Wake up UI thread 73 | }); 74 | } 75 | } 76 | 77 | ui.separator(); 78 | 79 | let download: &Download = &self.download.lock().unwrap(); 80 | match download { 81 | Download::None => {} 82 | Download::InProgress => { 83 | ui.label("Wait for it…"); 84 | } 85 | Download::StreamingInProgress { body, .. } => { 86 | let num_bytes = body.len(); 87 | if num_bytes < 1_000_000 { 88 | ui.label(format!("{:.1} kB", num_bytes as f32 / 1e3)); 89 | } else { 90 | ui.label(format!("{:.1} MB", num_bytes as f32 / 1e6)); 91 | } 92 | } 93 | Download::Done(response) => match response { 94 | Err(err) => { 95 | ui.label(err); 96 | } 97 | Ok(response) => { 98 | response_ui(ui, response); 99 | } 100 | }, 101 | } 102 | }); 103 | } 104 | } 105 | 106 | fn on_fetch_part( 107 | part: Result, 108 | download_store: &mut Download, 109 | ) -> ControlFlow<()> { 110 | let part = match part { 111 | Err(err) => { 112 | *download_store = Download::Done(Result::Err(err)); 113 | return ControlFlow::Break(()); 114 | } 115 | Ok(part) => part, 116 | }; 117 | 118 | match part { 119 | ehttp::streaming::Part::Response(response) => { 120 | *download_store = Download::StreamingInProgress { 121 | response, 122 | body: Vec::new(), 123 | }; 124 | ControlFlow::Continue(()) 125 | } 126 | ehttp::streaming::Part::Chunk(chunk) => { 127 | if let Download::StreamingInProgress { response, mut body } = 128 | std::mem::replace(download_store, Download::None) 129 | { 130 | body.extend_from_slice(&chunk); 131 | 132 | if chunk.is_empty() { 133 | // This was the last chunk. 134 | *download_store = Download::Done(Ok(response.complete(body))); 135 | ControlFlow::Break(()) 136 | } else { 137 | // More to come. 138 | *download_store = Download::StreamingInProgress { response, body }; 139 | ControlFlow::Continue(()) 140 | } 141 | } else { 142 | ControlFlow::Break(()) // some data race - abort download. 143 | } 144 | } 145 | } 146 | } 147 | 148 | impl DemoApp { 149 | fn ui_url(&mut self, ui: &mut egui::Ui) -> bool { 150 | let mut trigger_fetch = self.ui_examples(ui); 151 | 152 | egui::Grid::new("request_parameters") 153 | .spacing(egui::Vec2::splat(4.0)) 154 | .min_col_width(70.0) 155 | .num_columns(2) 156 | .show(ui, |ui| { 157 | ui.label("URL:"); 158 | trigger_fetch |= ui.text_edit_singleline(&mut self.url).lost_focus(); 159 | ui.end_row(); 160 | 161 | ui.label("Method:"); 162 | ui.horizontal(|ui| { 163 | ui.radio_value(&mut self.method, Method::Get, "GET") 164 | .clicked(); 165 | ui.radio_value(&mut self.method, Method::Head, "HEAD") 166 | .clicked(); 167 | ui.radio_value(&mut self.method, Method::Post, "POST") 168 | .clicked(); 169 | }); 170 | ui.end_row(); 171 | 172 | if self.method == Method::Post { 173 | ui.label("POST Body:"); 174 | ui.add( 175 | egui::TextEdit::multiline(&mut self.request_body) 176 | .code_editor() 177 | .desired_rows(1), 178 | ); 179 | ui.end_row(); 180 | } 181 | 182 | ui.checkbox(&mut self.streaming, "Use streaming fetch").on_hover_text( 183 | "The ehttp::streaming API allows you to process the data piece by piece as it is received.\n\ 184 | You might need to disable caching, throttle your download speed, and/or download a large file to see the data being streamed in."); 185 | ui.end_row(); 186 | }); 187 | 188 | trigger_fetch |= ui.button("fetch ▶").clicked(); 189 | 190 | trigger_fetch 191 | } 192 | 193 | fn ui_examples(&mut self, ui: &mut egui::Ui) -> bool { 194 | let mut trigger_fetch = false; 195 | 196 | ui.horizontal(|ui| { 197 | ui.label("Examples:"); 198 | 199 | let self_url = format!( 200 | "https://raw.githubusercontent.com/emilk/ehttp/master/{}", 201 | file!() 202 | ); 203 | if ui 204 | .selectable_label( 205 | (&self.url, self.method) == (&self_url, Method::Get), 206 | "GET source code", 207 | ) 208 | .clicked() 209 | { 210 | self.url = self_url; 211 | self.method = Method::Get; 212 | trigger_fetch = true; 213 | } 214 | 215 | let wasm_file = "https://emilk.github.io/ehttp/example_eframe_bg.wasm".to_owned(); 216 | if ui 217 | .selectable_label( 218 | (&self.url, self.method) == (&wasm_file, Method::Get), 219 | "GET .wasm", 220 | ) 221 | .clicked() 222 | { 223 | self.url = wasm_file; 224 | self.method = Method::Get; 225 | trigger_fetch = true; 226 | } 227 | 228 | let pastebin_url = "https://httpbin.org/post".to_owned(); 229 | if ui 230 | .selectable_label( 231 | (&self.url, self.method) == (&pastebin_url, Method::Post), 232 | "POST to httpbin.org", 233 | ) 234 | .clicked() 235 | { 236 | self.url = pastebin_url; 237 | self.method = Method::Post; 238 | trigger_fetch = true; 239 | } 240 | }); 241 | 242 | trigger_fetch 243 | } 244 | } 245 | 246 | fn response_ui(ui: &mut egui::Ui, response: &ehttp::Response) { 247 | ui.monospace(format!("url: {}", response.url)); 248 | ui.monospace(format!( 249 | "status: {} ({})", 250 | response.status, response.status_text 251 | )); 252 | ui.monospace(format!( 253 | "content-type: {}", 254 | response.content_type().unwrap_or_default() 255 | )); 256 | ui.monospace(format!( 257 | "size: {:.1} kB", 258 | response.bytes.len() as f32 / 1000.0 259 | )); 260 | 261 | ui.separator(); 262 | 263 | egui::ScrollArea::vertical().show(ui, |ui| { 264 | egui::CollapsingHeader::new("Response headers") 265 | .default_open(false) 266 | .show(ui, |ui| { 267 | egui::Grid::new("response_headers") 268 | .spacing(egui::vec2(ui.spacing().item_spacing.x * 2.0, 0.0)) 269 | .show(ui, |ui| { 270 | for (k, v) in &response.headers { 271 | ui.label(k); 272 | ui.label(v); 273 | ui.end_row(); 274 | } 275 | }) 276 | }); 277 | 278 | ui.separator(); 279 | 280 | if let Some(text) = response.text() { 281 | let tooltip = "Click to copy the response body"; 282 | if ui.button("📋").on_hover_text(tooltip).clicked() { 283 | ui.output_mut(|o| o.copied_text = text.to_owned()); 284 | } 285 | ui.separator(); 286 | } 287 | 288 | if let Some(text) = response.text() { 289 | selectable_text(ui, text); 290 | } else { 291 | ui.monospace("[binary]"); 292 | } 293 | }); 294 | } 295 | 296 | fn selectable_text(ui: &mut egui::Ui, mut text: &str) { 297 | ui.add( 298 | egui::TextEdit::multiline(&mut text) 299 | .desired_width(f32::INFINITY) 300 | .font(egui::TextStyle::Monospace.resolve(ui.style())), 301 | ); 302 | } 303 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /ehttp/src/types.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | #[cfg(feature = "json")] 4 | use serde::Serialize; 5 | 6 | #[cfg(feature = "multipart")] 7 | use crate::multipart::MultipartBuilder; 8 | 9 | /// Headers in a [`Request`] or [`Response`]. 10 | /// 11 | /// Note that the same header key can appear twice. 12 | #[derive(Clone, Debug, Default)] 13 | pub struct Headers { 14 | /// Name-value pairs. 15 | pub headers: Vec<(String, String)>, 16 | } 17 | 18 | impl Headers { 19 | /// ``` 20 | /// use ehttp::Request; 21 | /// let request = Request { 22 | /// headers: ehttp::Headers::new(&[ 23 | /// ("Accept", "*/*"), 24 | /// ("Content-Type", "text/plain; charset=utf-8"), 25 | /// ]), 26 | /// ..Request::get("https://www.example.com") 27 | /// }; 28 | /// ``` 29 | pub fn new(headers: &[(&str, &str)]) -> Self { 30 | Self { 31 | headers: headers 32 | .iter() 33 | .map(|e| (e.0.to_owned(), e.1.to_owned())) 34 | .collect(), 35 | } 36 | } 37 | 38 | /// Will add the key/value pair to the headers. 39 | /// 40 | /// If the key already exists, it will also be kept, 41 | /// so the same key can appear twice. 42 | pub fn insert(&mut self, key: impl ToString, value: impl ToString) { 43 | self.headers.push((key.to_string(), value.to_string())); 44 | } 45 | 46 | /// Get the value of the first header with the given key. 47 | /// 48 | /// The lookup is case-insensitive. 49 | pub fn get(&self, key: &str) -> Option<&str> { 50 | let key = key.to_string().to_lowercase(); 51 | self.headers 52 | .iter() 53 | .find(|(k, _)| k.to_lowercase() == key) 54 | .map(|(_, v)| v.as_str()) 55 | } 56 | 57 | /// Get all the values that match the given key. 58 | /// 59 | /// The lookup is case-insensitive. 60 | pub fn get_all(&self, key: &str) -> impl Iterator { 61 | let key = key.to_string().to_lowercase(); 62 | self.headers 63 | .iter() 64 | .filter(move |(k, _)| k.to_lowercase() == key) 65 | .map(|(_, v)| v.as_str()) 66 | } 67 | 68 | /// Sort the headers by key. 69 | /// 70 | /// This makes the headers easier to read when printed out. 71 | /// 72 | /// `ehttp` will sort the headers in the responses. 73 | pub fn sort(&mut self) { 74 | self.headers.sort_by(|a, b| a.0.cmp(&b.0)); 75 | } 76 | } 77 | 78 | impl IntoIterator for Headers { 79 | type Item = (String, String); 80 | type IntoIter = std::vec::IntoIter; 81 | 82 | fn into_iter(self) -> Self::IntoIter { 83 | self.headers.into_iter() 84 | } 85 | } 86 | 87 | impl<'h> IntoIterator for &'h Headers { 88 | type Item = &'h (String, String); 89 | type IntoIter = std::slice::Iter<'h, (String, String)>; 90 | 91 | fn into_iter(self) -> Self::IntoIter { 92 | self.headers.iter() 93 | } 94 | } 95 | 96 | // ---------------------------------------------------------------------------- 97 | 98 | /// Determine if cross-origin requests lead to valid responses. 99 | /// 100 | /// Based on 101 | #[derive(Default, Clone, Copy, Debug)] 102 | pub enum Mode { 103 | /// If a request is made to another origin with this mode set, the result is an error. 104 | SameOrigin = 0, 105 | 106 | /// The request will not include the Origin header in a request. 107 | /// The server's response will be opaque, meaning that JavaScript code cannot access its contents 108 | NoCors = 1, 109 | 110 | /// Includes an Origin header in the request and expects the server to respond with an 111 | /// "Access-Control-Allow-Origin" header that indicates whether the request is allowed. 112 | #[default] 113 | Cors = 2, 114 | 115 | /// A mode for supporting navigation 116 | Navigate = 3, 117 | } 118 | 119 | #[cfg(target_arch = "wasm32")] 120 | impl From for web_sys::RequestMode { 121 | fn from(mode: Mode) -> Self { 122 | match mode { 123 | Mode::SameOrigin => web_sys::RequestMode::SameOrigin, 124 | Mode::NoCors => web_sys::RequestMode::NoCors, 125 | Mode::Cors => web_sys::RequestMode::Cors, 126 | Mode::Navigate => web_sys::RequestMode::Navigate, 127 | } 128 | } 129 | } 130 | 131 | /// A simple HTTP request. 132 | #[derive(Clone, Debug)] 133 | pub struct Request { 134 | /// "GET", "POST", … 135 | pub method: String, 136 | 137 | /// https://… 138 | pub url: String, 139 | 140 | /// The data you send with e.g. "POST". 141 | pub body: Vec, 142 | 143 | /// ("Accept", "*/*"), … 144 | pub headers: Headers, 145 | 146 | /// Request mode used on fetch. 147 | /// 148 | /// Used on Web to control CORS. 149 | pub mode: Mode, 150 | 151 | /// Cancel the request if it doesn't complete fast enough. 152 | pub timeout: Option, 153 | } 154 | 155 | impl Request { 156 | pub const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30); 157 | 158 | /// Create a `GET` request with the given url. 159 | #[allow(clippy::needless_pass_by_value)] 160 | pub fn get(url: impl ToString) -> Self { 161 | Self { 162 | method: "GET".to_owned(), 163 | url: url.to_string(), 164 | body: vec![], 165 | headers: Headers::new(&[("Accept", "*/*")]), 166 | mode: Mode::default(), 167 | timeout: Some(Self::DEFAULT_TIMEOUT), 168 | } 169 | } 170 | 171 | /// Create a `HEAD` request with the given url. 172 | #[allow(clippy::needless_pass_by_value)] 173 | pub fn head(url: impl ToString) -> Self { 174 | Self { 175 | method: "HEAD".to_owned(), 176 | url: url.to_string(), 177 | body: vec![], 178 | headers: Headers::new(&[("Accept", "*/*")]), 179 | mode: Mode::default(), 180 | timeout: Some(Self::DEFAULT_TIMEOUT), 181 | } 182 | } 183 | 184 | /// Create a `POST` request with the given url and body. 185 | #[allow(clippy::needless_pass_by_value)] 186 | pub fn post(url: impl ToString, body: Vec) -> Self { 187 | Self { 188 | method: "POST".to_owned(), 189 | url: url.to_string(), 190 | body, 191 | headers: Headers::new(&[ 192 | ("Accept", "*/*"), 193 | ("Content-Type", "text/plain; charset=utf-8"), 194 | ]), 195 | mode: Mode::default(), 196 | timeout: Some(Self::DEFAULT_TIMEOUT), 197 | } 198 | } 199 | 200 | /// Create a 'PUT' request with the given url and body. 201 | #[allow(clippy::needless_pass_by_value)] 202 | pub fn put(url: impl ToString, body: Vec) -> Self { 203 | Self { 204 | method: "PUT".to_owned(), 205 | url: url.to_string(), 206 | body, 207 | headers: Headers::new(&[ 208 | ("Accept", "*/*"), 209 | ("Content-Type", "text/plain; charset=utf-8"), 210 | ]), 211 | mode: Mode::default(), 212 | timeout: Some(Self::DEFAULT_TIMEOUT), 213 | } 214 | } 215 | 216 | /// Create a 'DELETE' request with the given url. 217 | pub fn delete(url: &str) -> Self { 218 | Self { 219 | method: "DELETE".to_owned(), 220 | url: url.to_string(), 221 | body: vec![], 222 | headers: Headers::new(&[("Accept", "*/*")]), 223 | mode: Mode::default(), 224 | timeout: Some(Self::DEFAULT_TIMEOUT), 225 | } 226 | } 227 | 228 | /// Multipart HTTP for both native and WASM. 229 | /// 230 | /// Requires the `multipart` feature to be enabled. 231 | /// 232 | /// Example: 233 | /// ``` 234 | /// use std::io::Cursor; 235 | /// use ehttp::multipart::MultipartBuilder; 236 | /// let url = "https://www.example.com"; 237 | /// let request = ehttp::Request::multipart( 238 | /// url, 239 | /// MultipartBuilder::new() 240 | /// .add_text("label", "lorem ipsum") 241 | /// .add_stream( 242 | /// &mut Cursor::new(vec![0, 0, 0, 0]), 243 | /// "4_empty_bytes", 244 | /// Some("4_empty_bytes.png"), 245 | /// None, 246 | /// ) 247 | /// .unwrap(), 248 | /// ); 249 | /// ehttp::fetch(request, |result| {}); 250 | /// ``` 251 | #[cfg(feature = "multipart")] 252 | pub fn multipart(url: impl ToString, builder: MultipartBuilder) -> Self { 253 | let (content_type, data) = builder.finish(); 254 | Self { 255 | method: "POST".to_string(), 256 | url: url.to_string(), 257 | body: data, 258 | headers: Headers::new(&[("Accept", "*/*"), ("Content-Type", content_type.as_str())]), 259 | mode: Mode::default(), 260 | timeout: Some(Self::DEFAULT_TIMEOUT), 261 | } 262 | } 263 | 264 | #[cfg(feature = "json")] 265 | /// Create a `POST` request with the given url and json body. 266 | #[allow(clippy::needless_pass_by_value)] 267 | pub fn json(url: impl ToString, body: &T) -> serde_json::error::Result 268 | where 269 | T: ?Sized + Serialize, 270 | { 271 | Ok(Self { 272 | method: "POST".to_owned(), 273 | url: url.to_string(), 274 | body: serde_json::to_string(body)?.into_bytes(), 275 | headers: Headers::new(&[("Accept", "*/*"), ("Content-Type", "application/json")]), 276 | mode: Mode::default(), 277 | timeout: Some(Self::DEFAULT_TIMEOUT), 278 | }) 279 | } 280 | 281 | #[cfg(feature = "json")] 282 | /// Create a 'PUT' request with the given url and json body. 283 | #[allow(clippy::needless_pass_by_value)] 284 | pub fn put_json(url: impl ToString, body: &T) -> serde_json::error::Result 285 | where 286 | T: ?Sized + Serialize, 287 | { 288 | Ok(Self { 289 | method: "PUT".to_owned(), 290 | url: url.to_string(), 291 | body: serde_json::to_string(body)?.into_bytes(), 292 | headers: Headers::new(&[("Accept", "*/*"), ("Content-Type", "application/json")]), 293 | mode: Mode::default(), 294 | timeout: Some(Self::DEFAULT_TIMEOUT), 295 | }) 296 | } 297 | 298 | pub fn with_timeout(mut self, timeout: Option) -> Self { 299 | self.timeout = timeout; 300 | self 301 | } 302 | } 303 | 304 | /// Response from a completed HTTP request. 305 | #[derive(Clone)] 306 | pub struct Response { 307 | /// The URL we ended up at. This can differ from the request url when we have followed redirects. 308 | pub url: String, 309 | 310 | /// Did we get a 2xx response code? 311 | pub ok: bool, 312 | 313 | /// Status code (e.g. `404` for "File not found"). 314 | pub status: u16, 315 | 316 | /// Status text (e.g. "File not found" for status code `404`). 317 | pub status_text: String, 318 | 319 | /// The returned headers. 320 | pub headers: Headers, 321 | 322 | /// The raw bytes of the response body. 323 | pub bytes: Vec, 324 | } 325 | 326 | impl Response { 327 | pub fn text(&self) -> Option<&str> { 328 | std::str::from_utf8(&self.bytes).ok() 329 | } 330 | 331 | #[cfg(feature = "json")] 332 | /// Convenience for getting json body 333 | pub fn json(&self) -> serde_json::Result { 334 | serde_json::from_slice(self.bytes.as_slice()) 335 | } 336 | 337 | /// Convenience for getting the `content-type` header. 338 | pub fn content_type(&self) -> Option<&str> { 339 | self.headers.get("content-type") 340 | } 341 | } 342 | 343 | impl std::fmt::Debug for Response { 344 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 345 | let Self { 346 | url, 347 | ok, 348 | status, 349 | status_text, 350 | headers, 351 | bytes, 352 | } = self; 353 | 354 | fmt.debug_struct("Response") 355 | .field("url", url) 356 | .field("ok", ok) 357 | .field("status", status) 358 | .field("status_text", status_text) 359 | .field("headers", headers) 360 | .field("bytes", &format!("{} bytes", bytes.len())) 361 | .finish_non_exhaustive() 362 | } 363 | } 364 | 365 | /// An HTTP response status line and headers used for the [`streaming`](crate::streaming) API. 366 | #[derive(Clone, Debug)] 367 | pub struct PartialResponse { 368 | /// The URL we ended up at. This can differ from the request url when we have followed redirects. 369 | pub url: String, 370 | 371 | /// Did we get a 2xx response code? 372 | pub ok: bool, 373 | 374 | /// Status code (e.g. `404` for "File not found"). 375 | pub status: u16, 376 | 377 | /// Status text (e.g. "File not found" for status code `404`). 378 | pub status_text: String, 379 | 380 | /// The returned headers. 381 | pub headers: Headers, 382 | } 383 | 384 | impl PartialResponse { 385 | pub fn complete(self, bytes: Vec) -> Response { 386 | let Self { 387 | url, 388 | ok, 389 | status, 390 | status_text, 391 | headers, 392 | } = self; 393 | Response { 394 | url, 395 | ok, 396 | status, 397 | status_text, 398 | headers, 399 | bytes, 400 | } 401 | } 402 | } 403 | 404 | /// A description of an error. 405 | /// 406 | /// This is only used when we fail to make a request. 407 | /// Any response results in `Ok`, including things like 404 (file not found). 408 | pub type Error = String; 409 | 410 | /// A type-alias for `Result`. 411 | pub type Result = std::result::Result; 412 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "ab_glyph" 7 | version = "0.2.23" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "80179d7dd5d7e8c285d67c4a1e652972a92de7475beddfb92028c76463b13225" 10 | dependencies = [ 11 | "ab_glyph_rasterizer", 12 | "owned_ttf_parser", 13 | ] 14 | 15 | [[package]] 16 | name = "ab_glyph_rasterizer" 17 | version = "0.1.8" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" 20 | 21 | [[package]] 22 | name = "accesskit" 23 | version = "0.12.1" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | checksum = "ca8410747ed85a17c4a1e9ed3f5a74d3e7bdcc876cf9a18ff40ae21d645997b2" 26 | 27 | [[package]] 28 | name = "accesskit_consumer" 29 | version = "0.16.1" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | checksum = "8c17cca53c09fbd7288667b22a201274b9becaa27f0b91bf52a526db95de45e6" 32 | dependencies = [ 33 | "accesskit", 34 | ] 35 | 36 | [[package]] 37 | name = "accesskit_macos" 38 | version = "0.10.1" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "cd3b6ae1eabbfbced10e840fd3fce8a93ae84f174b3e4ba892ab7bcb42e477a7" 41 | dependencies = [ 42 | "accesskit", 43 | "accesskit_consumer", 44 | "objc2", 45 | "once_cell", 46 | ] 47 | 48 | [[package]] 49 | name = "accesskit_unix" 50 | version = "0.6.2" 51 | source = "registry+https://github.com/rust-lang/crates.io-index" 52 | checksum = "09f46c18d99ba61ad7123dd13eeb0c104436ab6af1df6a1cd8c11054ed394a08" 53 | dependencies = [ 54 | "accesskit", 55 | "accesskit_consumer", 56 | "async-channel", 57 | "async-once-cell", 58 | "atspi", 59 | "futures-lite 1.13.0", 60 | "once_cell", 61 | "serde", 62 | "zbus", 63 | ] 64 | 65 | [[package]] 66 | name = "accesskit_windows" 67 | version = "0.15.1" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "afcae27ec0974fc7c3b0b318783be89fd1b2e66dd702179fe600166a38ff4a0b" 70 | dependencies = [ 71 | "accesskit", 72 | "accesskit_consumer", 73 | "once_cell", 74 | "paste", 75 | "static_assertions", 76 | "windows", 77 | ] 78 | 79 | [[package]] 80 | name = "accesskit_winit" 81 | version = "0.15.0" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | checksum = "88e39fcec2e10971e188730b7a76bab60647dacc973d4591855ebebcadfaa738" 84 | dependencies = [ 85 | "accesskit", 86 | "accesskit_macos", 87 | "accesskit_unix", 88 | "accesskit_windows", 89 | "winit", 90 | ] 91 | 92 | [[package]] 93 | name = "adler" 94 | version = "1.0.2" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 97 | 98 | [[package]] 99 | name = "ahash" 100 | version = "0.8.7" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" 103 | dependencies = [ 104 | "cfg-if", 105 | "once_cell", 106 | "version_check", 107 | "zerocopy", 108 | ] 109 | 110 | [[package]] 111 | name = "aho-corasick" 112 | version = "1.1.2" 113 | source = "registry+https://github.com/rust-lang/crates.io-index" 114 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 115 | dependencies = [ 116 | "memchr", 117 | ] 118 | 119 | [[package]] 120 | name = "android-activity" 121 | version = "0.4.3" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "64529721f27c2314ced0890ce45e469574a73e5e6fdd6e9da1860eb29285f5e0" 124 | dependencies = [ 125 | "android-properties", 126 | "bitflags 1.3.2", 127 | "cc", 128 | "jni-sys", 129 | "libc", 130 | "log", 131 | "ndk", 132 | "ndk-context", 133 | "ndk-sys", 134 | "num_enum 0.6.1", 135 | ] 136 | 137 | [[package]] 138 | name = "android-properties" 139 | version = "0.2.2" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" 142 | 143 | [[package]] 144 | name = "arboard" 145 | version = "3.3.0" 146 | source = "registry+https://github.com/rust-lang/crates.io-index" 147 | checksum = "aafb29b107435aa276664c1db8954ac27a6e105cdad3c88287a199eb0e313c08" 148 | dependencies = [ 149 | "clipboard-win", 150 | "log", 151 | "objc", 152 | "objc-foundation", 153 | "objc_id", 154 | "parking_lot", 155 | "thiserror", 156 | "winapi", 157 | "x11rb", 158 | ] 159 | 160 | [[package]] 161 | name = "arrayref" 162 | version = "0.3.7" 163 | source = "registry+https://github.com/rust-lang/crates.io-index" 164 | checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" 165 | 166 | [[package]] 167 | name = "arrayvec" 168 | version = "0.7.4" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" 171 | 172 | [[package]] 173 | name = "async-broadcast" 174 | version = "0.5.1" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" 177 | dependencies = [ 178 | "event-listener 2.5.3", 179 | "futures-core", 180 | ] 181 | 182 | [[package]] 183 | name = "async-channel" 184 | version = "2.1.1" 185 | source = "registry+https://github.com/rust-lang/crates.io-index" 186 | checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" 187 | dependencies = [ 188 | "concurrent-queue", 189 | "event-listener 4.0.1", 190 | "event-listener-strategy", 191 | "futures-core", 192 | "pin-project-lite", 193 | ] 194 | 195 | [[package]] 196 | name = "async-executor" 197 | version = "1.8.0" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" 200 | dependencies = [ 201 | "async-lock 3.2.0", 202 | "async-task", 203 | "concurrent-queue", 204 | "fastrand 2.0.1", 205 | "futures-lite 2.1.0", 206 | "slab", 207 | ] 208 | 209 | [[package]] 210 | name = "async-fs" 211 | version = "1.6.0" 212 | source = "registry+https://github.com/rust-lang/crates.io-index" 213 | checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" 214 | dependencies = [ 215 | "async-lock 2.8.0", 216 | "autocfg", 217 | "blocking", 218 | "futures-lite 1.13.0", 219 | ] 220 | 221 | [[package]] 222 | name = "async-io" 223 | version = "1.13.0" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" 226 | dependencies = [ 227 | "async-lock 2.8.0", 228 | "autocfg", 229 | "cfg-if", 230 | "concurrent-queue", 231 | "futures-lite 1.13.0", 232 | "log", 233 | "parking", 234 | "polling 2.8.0", 235 | "rustix 0.37.27", 236 | "slab", 237 | "socket2", 238 | "waker-fn", 239 | ] 240 | 241 | [[package]] 242 | name = "async-io" 243 | version = "2.2.2" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" 246 | dependencies = [ 247 | "async-lock 3.2.0", 248 | "cfg-if", 249 | "concurrent-queue", 250 | "futures-io", 251 | "futures-lite 2.1.0", 252 | "parking", 253 | "polling 3.3.1", 254 | "rustix 0.38.28", 255 | "slab", 256 | "tracing", 257 | "windows-sys 0.52.0", 258 | ] 259 | 260 | [[package]] 261 | name = "async-lock" 262 | version = "2.8.0" 263 | source = "registry+https://github.com/rust-lang/crates.io-index" 264 | checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" 265 | dependencies = [ 266 | "event-listener 2.5.3", 267 | ] 268 | 269 | [[package]] 270 | name = "async-lock" 271 | version = "3.2.0" 272 | source = "registry+https://github.com/rust-lang/crates.io-index" 273 | checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" 274 | dependencies = [ 275 | "event-listener 4.0.1", 276 | "event-listener-strategy", 277 | "pin-project-lite", 278 | ] 279 | 280 | [[package]] 281 | name = "async-once-cell" 282 | version = "0.5.3" 283 | source = "registry+https://github.com/rust-lang/crates.io-index" 284 | checksum = "9338790e78aa95a416786ec8389546c4b6a1dfc3dc36071ed9518a9413a542eb" 285 | 286 | [[package]] 287 | name = "async-process" 288 | version = "1.8.1" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" 291 | dependencies = [ 292 | "async-io 1.13.0", 293 | "async-lock 2.8.0", 294 | "async-signal", 295 | "blocking", 296 | "cfg-if", 297 | "event-listener 3.1.0", 298 | "futures-lite 1.13.0", 299 | "rustix 0.38.28", 300 | "windows-sys 0.48.0", 301 | ] 302 | 303 | [[package]] 304 | name = "async-recursion" 305 | version = "1.0.5" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" 308 | dependencies = [ 309 | "proc-macro2", 310 | "quote", 311 | "syn 2.0.43", 312 | ] 313 | 314 | [[package]] 315 | name = "async-signal" 316 | version = "0.2.5" 317 | source = "registry+https://github.com/rust-lang/crates.io-index" 318 | checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" 319 | dependencies = [ 320 | "async-io 2.2.2", 321 | "async-lock 2.8.0", 322 | "atomic-waker", 323 | "cfg-if", 324 | "futures-core", 325 | "futures-io", 326 | "rustix 0.38.28", 327 | "signal-hook-registry", 328 | "slab", 329 | "windows-sys 0.48.0", 330 | ] 331 | 332 | [[package]] 333 | name = "async-task" 334 | version = "4.6.0" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "e1d90cd0b264dfdd8eb5bad0a2c217c1f88fa96a8573f40e7b12de23fb468f46" 337 | 338 | [[package]] 339 | name = "async-trait" 340 | version = "0.1.76" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" 343 | dependencies = [ 344 | "proc-macro2", 345 | "quote", 346 | "syn 2.0.43", 347 | ] 348 | 349 | [[package]] 350 | name = "atomic-waker" 351 | version = "1.1.2" 352 | source = "registry+https://github.com/rust-lang/crates.io-index" 353 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 354 | 355 | [[package]] 356 | name = "atspi" 357 | version = "0.19.0" 358 | source = "registry+https://github.com/rust-lang/crates.io-index" 359 | checksum = "6059f350ab6f593ea00727b334265c4dfc7fd442ee32d264794bd9bdc68e87ca" 360 | dependencies = [ 361 | "atspi-common", 362 | "atspi-connection", 363 | "atspi-proxies", 364 | ] 365 | 366 | [[package]] 367 | name = "atspi-common" 368 | version = "0.3.0" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | checksum = "92af95f966d2431f962bc632c2e68eda7777330158bf640c4af4249349b2cdf5" 371 | dependencies = [ 372 | "enumflags2", 373 | "serde", 374 | "static_assertions", 375 | "zbus", 376 | "zbus_names", 377 | "zvariant", 378 | ] 379 | 380 | [[package]] 381 | name = "atspi-connection" 382 | version = "0.3.0" 383 | source = "registry+https://github.com/rust-lang/crates.io-index" 384 | checksum = "a0c65e7d70f86d4c0e3b2d585d9bf3f979f0b19d635a336725a88d279f76b939" 385 | dependencies = [ 386 | "atspi-common", 387 | "atspi-proxies", 388 | "futures-lite 1.13.0", 389 | "zbus", 390 | ] 391 | 392 | [[package]] 393 | name = "atspi-proxies" 394 | version = "0.3.0" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "6495661273703e7a229356dcbe8c8f38223d697aacfaf0e13590a9ac9977bb52" 397 | dependencies = [ 398 | "atspi-common", 399 | "serde", 400 | "zbus", 401 | ] 402 | 403 | [[package]] 404 | name = "autocfg" 405 | version = "1.1.0" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 408 | 409 | [[package]] 410 | name = "base64" 411 | version = "0.21.5" 412 | source = "registry+https://github.com/rust-lang/crates.io-index" 413 | checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" 414 | 415 | [[package]] 416 | name = "bitflags" 417 | version = "1.3.2" 418 | source = "registry+https://github.com/rust-lang/crates.io-index" 419 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 420 | 421 | [[package]] 422 | name = "bitflags" 423 | version = "2.4.1" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" 426 | 427 | [[package]] 428 | name = "block" 429 | version = "0.1.6" 430 | source = "registry+https://github.com/rust-lang/crates.io-index" 431 | checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" 432 | 433 | [[package]] 434 | name = "block-buffer" 435 | version = "0.10.4" 436 | source = "registry+https://github.com/rust-lang/crates.io-index" 437 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 438 | dependencies = [ 439 | "generic-array", 440 | ] 441 | 442 | [[package]] 443 | name = "block-sys" 444 | version = "0.1.0-beta.1" 445 | source = "registry+https://github.com/rust-lang/crates.io-index" 446 | checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146" 447 | dependencies = [ 448 | "objc-sys", 449 | ] 450 | 451 | [[package]] 452 | name = "block2" 453 | version = "0.2.0-alpha.6" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42" 456 | dependencies = [ 457 | "block-sys", 458 | "objc2-encode", 459 | ] 460 | 461 | [[package]] 462 | name = "blocking" 463 | version = "1.5.1" 464 | source = "registry+https://github.com/rust-lang/crates.io-index" 465 | checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" 466 | dependencies = [ 467 | "async-channel", 468 | "async-lock 3.2.0", 469 | "async-task", 470 | "fastrand 2.0.1", 471 | "futures-io", 472 | "futures-lite 2.1.0", 473 | "piper", 474 | "tracing", 475 | ] 476 | 477 | [[package]] 478 | name = "bumpalo" 479 | version = "3.14.0" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" 482 | 483 | [[package]] 484 | name = "bytemuck" 485 | version = "1.14.0" 486 | source = "registry+https://github.com/rust-lang/crates.io-index" 487 | checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" 488 | dependencies = [ 489 | "bytemuck_derive", 490 | ] 491 | 492 | [[package]] 493 | name = "bytemuck_derive" 494 | version = "1.5.0" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" 497 | dependencies = [ 498 | "proc-macro2", 499 | "quote", 500 | "syn 2.0.43", 501 | ] 502 | 503 | [[package]] 504 | name = "byteorder" 505 | version = "1.5.0" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 508 | 509 | [[package]] 510 | name = "bytes" 511 | version = "1.5.0" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 514 | 515 | [[package]] 516 | name = "calloop" 517 | version = "0.10.6" 518 | source = "registry+https://github.com/rust-lang/crates.io-index" 519 | checksum = "52e0d00eb1ea24371a97d2da6201c6747a633dc6dc1988ef503403b4c59504a8" 520 | dependencies = [ 521 | "bitflags 1.3.2", 522 | "log", 523 | "nix 0.25.1", 524 | "slotmap", 525 | "thiserror", 526 | "vec_map", 527 | ] 528 | 529 | [[package]] 530 | name = "cc" 531 | version = "1.0.83" 532 | source = "registry+https://github.com/rust-lang/crates.io-index" 533 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 534 | dependencies = [ 535 | "jobserver", 536 | "libc", 537 | ] 538 | 539 | [[package]] 540 | name = "cesu8" 541 | version = "1.1.0" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" 544 | 545 | [[package]] 546 | name = "cfg-if" 547 | version = "1.0.0" 548 | source = "registry+https://github.com/rust-lang/crates.io-index" 549 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 550 | 551 | [[package]] 552 | name = "cfg_aliases" 553 | version = "0.1.1" 554 | source = "registry+https://github.com/rust-lang/crates.io-index" 555 | checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" 556 | 557 | [[package]] 558 | name = "cgl" 559 | version = "0.3.2" 560 | source = "registry+https://github.com/rust-lang/crates.io-index" 561 | checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff" 562 | dependencies = [ 563 | "libc", 564 | ] 565 | 566 | [[package]] 567 | name = "clipboard-win" 568 | version = "4.5.0" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" 571 | dependencies = [ 572 | "error-code", 573 | "str-buf", 574 | "winapi", 575 | ] 576 | 577 | [[package]] 578 | name = "cocoa" 579 | version = "0.24.1" 580 | source = "registry+https://github.com/rust-lang/crates.io-index" 581 | checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" 582 | dependencies = [ 583 | "bitflags 1.3.2", 584 | "block", 585 | "cocoa-foundation", 586 | "core-foundation", 587 | "core-graphics", 588 | "foreign-types", 589 | "libc", 590 | "objc", 591 | ] 592 | 593 | [[package]] 594 | name = "cocoa-foundation" 595 | version = "0.1.2" 596 | source = "registry+https://github.com/rust-lang/crates.io-index" 597 | checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" 598 | dependencies = [ 599 | "bitflags 1.3.2", 600 | "block", 601 | "core-foundation", 602 | "core-graphics-types", 603 | "libc", 604 | "objc", 605 | ] 606 | 607 | [[package]] 608 | name = "color_quant" 609 | version = "1.1.0" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" 612 | 613 | [[package]] 614 | name = "combine" 615 | version = "4.6.6" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" 618 | dependencies = [ 619 | "bytes", 620 | "memchr", 621 | ] 622 | 623 | [[package]] 624 | name = "concurrent-queue" 625 | version = "2.4.0" 626 | source = "registry+https://github.com/rust-lang/crates.io-index" 627 | checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" 628 | dependencies = [ 629 | "crossbeam-utils", 630 | ] 631 | 632 | [[package]] 633 | name = "core-foundation" 634 | version = "0.9.4" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 637 | dependencies = [ 638 | "core-foundation-sys", 639 | "libc", 640 | ] 641 | 642 | [[package]] 643 | name = "core-foundation-sys" 644 | version = "0.8.6" 645 | source = "registry+https://github.com/rust-lang/crates.io-index" 646 | checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" 647 | 648 | [[package]] 649 | name = "core-graphics" 650 | version = "0.22.3" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" 653 | dependencies = [ 654 | "bitflags 1.3.2", 655 | "core-foundation", 656 | "core-graphics-types", 657 | "foreign-types", 658 | "libc", 659 | ] 660 | 661 | [[package]] 662 | name = "core-graphics-types" 663 | version = "0.1.3" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" 666 | dependencies = [ 667 | "bitflags 1.3.2", 668 | "core-foundation", 669 | "libc", 670 | ] 671 | 672 | [[package]] 673 | name = "cpufeatures" 674 | version = "0.2.11" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" 677 | dependencies = [ 678 | "libc", 679 | ] 680 | 681 | [[package]] 682 | name = "crc32fast" 683 | version = "1.3.2" 684 | source = "registry+https://github.com/rust-lang/crates.io-index" 685 | checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" 686 | dependencies = [ 687 | "cfg-if", 688 | ] 689 | 690 | [[package]] 691 | name = "crossbeam-utils" 692 | version = "0.8.18" 693 | source = "registry+https://github.com/rust-lang/crates.io-index" 694 | checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" 695 | dependencies = [ 696 | "cfg-if", 697 | ] 698 | 699 | [[package]] 700 | name = "crypto-common" 701 | version = "0.1.6" 702 | source = "registry+https://github.com/rust-lang/crates.io-index" 703 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 704 | dependencies = [ 705 | "generic-array", 706 | "typenum", 707 | ] 708 | 709 | [[package]] 710 | name = "derivative" 711 | version = "2.2.0" 712 | source = "registry+https://github.com/rust-lang/crates.io-index" 713 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 714 | dependencies = [ 715 | "proc-macro2", 716 | "quote", 717 | "syn 1.0.109", 718 | ] 719 | 720 | [[package]] 721 | name = "digest" 722 | version = "0.10.7" 723 | source = "registry+https://github.com/rust-lang/crates.io-index" 724 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 725 | dependencies = [ 726 | "block-buffer", 727 | "crypto-common", 728 | ] 729 | 730 | [[package]] 731 | name = "dispatch" 732 | version = "0.2.0" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" 735 | 736 | [[package]] 737 | name = "dlib" 738 | version = "0.5.2" 739 | source = "registry+https://github.com/rust-lang/crates.io-index" 740 | checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" 741 | dependencies = [ 742 | "libloading 0.8.1", 743 | ] 744 | 745 | [[package]] 746 | name = "document-features" 747 | version = "0.2.8" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | checksum = "ef5282ad69563b5fc40319526ba27e0e7363d552a896f0297d54f767717f9b95" 750 | dependencies = [ 751 | "litrs", 752 | ] 753 | 754 | [[package]] 755 | name = "downcast-rs" 756 | version = "1.2.0" 757 | source = "registry+https://github.com/rust-lang/crates.io-index" 758 | checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" 759 | 760 | [[package]] 761 | name = "ecolor" 762 | version = "0.24.1" 763 | source = "registry+https://github.com/rust-lang/crates.io-index" 764 | checksum = "4b7637fc2e74d17e52931bac90ff4fc061ac776ada9c7fa272f24cdca5991972" 765 | dependencies = [ 766 | "bytemuck", 767 | ] 768 | 769 | [[package]] 770 | name = "eframe" 771 | version = "0.24.1" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | checksum = "cdd73918a828c35a7efb4d7188ea973df4bffc589178ed95f521c917b03ddcfa" 774 | dependencies = [ 775 | "bytemuck", 776 | "cocoa", 777 | "egui", 778 | "egui-winit", 779 | "egui_glow", 780 | "glow", 781 | "glutin", 782 | "glutin-winit", 783 | "image", 784 | "js-sys", 785 | "log", 786 | "objc", 787 | "parking_lot", 788 | "percent-encoding", 789 | "raw-window-handle", 790 | "static_assertions", 791 | "thiserror", 792 | "wasm-bindgen", 793 | "wasm-bindgen-futures", 794 | "web-sys", 795 | "winapi", 796 | "winit", 797 | ] 798 | 799 | [[package]] 800 | name = "egui" 801 | version = "0.24.1" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "c55bcb864b764eb889515a38b8924757657a250738ad15126637ee2df291ee6b" 804 | dependencies = [ 805 | "accesskit", 806 | "ahash", 807 | "epaint", 808 | "log", 809 | "nohash-hasher", 810 | ] 811 | 812 | [[package]] 813 | name = "egui-winit" 814 | version = "0.24.1" 815 | source = "registry+https://github.com/rust-lang/crates.io-index" 816 | checksum = "3b673606b6606b12b95e3a3194d7882bf5cff302db36a520b8144c7c342e4e84" 817 | dependencies = [ 818 | "accesskit_winit", 819 | "arboard", 820 | "egui", 821 | "log", 822 | "raw-window-handle", 823 | "smithay-clipboard", 824 | "web-time", 825 | "webbrowser", 826 | "winit", 827 | ] 828 | 829 | [[package]] 830 | name = "egui_glow" 831 | version = "0.24.1" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "262151f9d57c557c02a40a46f27b9e050a6eb0b006b94dced9c6f4519a04d489" 834 | dependencies = [ 835 | "bytemuck", 836 | "egui", 837 | "glow", 838 | "log", 839 | "memoffset 0.7.1", 840 | "wasm-bindgen", 841 | "web-sys", 842 | ] 843 | 844 | [[package]] 845 | name = "ehttp" 846 | version = "0.6.0" 847 | dependencies = [ 848 | "async-channel", 849 | "document-features", 850 | "futures-util", 851 | "getrandom", 852 | "js-sys", 853 | "mime", 854 | "mime_guess", 855 | "rand", 856 | "serde", 857 | "serde_json", 858 | "ureq", 859 | "wasm-bindgen", 860 | "wasm-bindgen-futures", 861 | "wasm-streams", 862 | "web-sys", 863 | ] 864 | 865 | [[package]] 866 | name = "emath" 867 | version = "0.24.1" 868 | source = "registry+https://github.com/rust-lang/crates.io-index" 869 | checksum = "a045c6c0b44b35e98513fc1e9d183ab42881ac27caccb9fa345465601f56cce4" 870 | dependencies = [ 871 | "bytemuck", 872 | ] 873 | 874 | [[package]] 875 | name = "enumflags2" 876 | version = "0.7.8" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "5998b4f30320c9d93aed72f63af821bfdac50465b75428fce77b48ec482c3939" 879 | dependencies = [ 880 | "enumflags2_derive", 881 | "serde", 882 | ] 883 | 884 | [[package]] 885 | name = "enumflags2_derive" 886 | version = "0.7.8" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" 889 | dependencies = [ 890 | "proc-macro2", 891 | "quote", 892 | "syn 2.0.43", 893 | ] 894 | 895 | [[package]] 896 | name = "env_logger" 897 | version = "0.10.1" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" 900 | dependencies = [ 901 | "humantime", 902 | "is-terminal", 903 | "log", 904 | "regex", 905 | "termcolor", 906 | ] 907 | 908 | [[package]] 909 | name = "epaint" 910 | version = "0.24.1" 911 | source = "registry+https://github.com/rust-lang/crates.io-index" 912 | checksum = "7d1b9e000d21bab9b535ce78f9f7745be28b3f777f6c7223936561c5c7fefab8" 913 | dependencies = [ 914 | "ab_glyph", 915 | "ahash", 916 | "bytemuck", 917 | "ecolor", 918 | "emath", 919 | "log", 920 | "nohash-hasher", 921 | "parking_lot", 922 | ] 923 | 924 | [[package]] 925 | name = "equivalent" 926 | version = "1.0.1" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 929 | 930 | [[package]] 931 | name = "errno" 932 | version = "0.3.8" 933 | source = "registry+https://github.com/rust-lang/crates.io-index" 934 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 935 | dependencies = [ 936 | "libc", 937 | "windows-sys 0.52.0", 938 | ] 939 | 940 | [[package]] 941 | name = "error-code" 942 | version = "2.3.1" 943 | source = "registry+https://github.com/rust-lang/crates.io-index" 944 | checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" 945 | dependencies = [ 946 | "libc", 947 | "str-buf", 948 | ] 949 | 950 | [[package]] 951 | name = "event-listener" 952 | version = "2.5.3" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 955 | 956 | [[package]] 957 | name = "event-listener" 958 | version = "3.1.0" 959 | source = "registry+https://github.com/rust-lang/crates.io-index" 960 | checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" 961 | dependencies = [ 962 | "concurrent-queue", 963 | "parking", 964 | "pin-project-lite", 965 | ] 966 | 967 | [[package]] 968 | name = "event-listener" 969 | version = "4.0.1" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | checksum = "84f2cdcf274580f2d63697192d744727b3198894b1bf02923643bf59e2c26712" 972 | dependencies = [ 973 | "concurrent-queue", 974 | "parking", 975 | "pin-project-lite", 976 | ] 977 | 978 | [[package]] 979 | name = "event-listener-strategy" 980 | version = "0.4.0" 981 | source = "registry+https://github.com/rust-lang/crates.io-index" 982 | checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" 983 | dependencies = [ 984 | "event-listener 4.0.1", 985 | "pin-project-lite", 986 | ] 987 | 988 | [[package]] 989 | name = "example_eframe" 990 | version = "0.1.0" 991 | dependencies = [ 992 | "eframe", 993 | "ehttp", 994 | "env_logger", 995 | "log", 996 | "wasm-bindgen-futures", 997 | ] 998 | 999 | [[package]] 1000 | name = "fastrand" 1001 | version = "1.9.0" 1002 | source = "registry+https://github.com/rust-lang/crates.io-index" 1003 | checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" 1004 | dependencies = [ 1005 | "instant", 1006 | ] 1007 | 1008 | [[package]] 1009 | name = "fastrand" 1010 | version = "2.0.1" 1011 | source = "registry+https://github.com/rust-lang/crates.io-index" 1012 | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 1013 | 1014 | [[package]] 1015 | name = "fdeflate" 1016 | version = "0.3.3" 1017 | source = "registry+https://github.com/rust-lang/crates.io-index" 1018 | checksum = "209098dd6dfc4445aa6111f0e98653ac323eaa4dfd212c9ca3931bf9955c31bd" 1019 | dependencies = [ 1020 | "simd-adler32", 1021 | ] 1022 | 1023 | [[package]] 1024 | name = "flate2" 1025 | version = "1.0.28" 1026 | source = "registry+https://github.com/rust-lang/crates.io-index" 1027 | checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" 1028 | dependencies = [ 1029 | "crc32fast", 1030 | "miniz_oxide", 1031 | ] 1032 | 1033 | [[package]] 1034 | name = "foreign-types" 1035 | version = "0.3.2" 1036 | source = "registry+https://github.com/rust-lang/crates.io-index" 1037 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 1038 | dependencies = [ 1039 | "foreign-types-shared", 1040 | ] 1041 | 1042 | [[package]] 1043 | name = "foreign-types-shared" 1044 | version = "0.1.1" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 1047 | 1048 | [[package]] 1049 | name = "form_urlencoded" 1050 | version = "1.2.1" 1051 | source = "registry+https://github.com/rust-lang/crates.io-index" 1052 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 1053 | dependencies = [ 1054 | "percent-encoding", 1055 | ] 1056 | 1057 | [[package]] 1058 | name = "futures-core" 1059 | version = "0.3.30" 1060 | source = "registry+https://github.com/rust-lang/crates.io-index" 1061 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 1062 | 1063 | [[package]] 1064 | name = "futures-io" 1065 | version = "0.3.30" 1066 | source = "registry+https://github.com/rust-lang/crates.io-index" 1067 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 1068 | 1069 | [[package]] 1070 | name = "futures-lite" 1071 | version = "1.13.0" 1072 | source = "registry+https://github.com/rust-lang/crates.io-index" 1073 | checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" 1074 | dependencies = [ 1075 | "fastrand 1.9.0", 1076 | "futures-core", 1077 | "futures-io", 1078 | "memchr", 1079 | "parking", 1080 | "pin-project-lite", 1081 | "waker-fn", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "futures-lite" 1086 | version = "2.1.0" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" 1089 | dependencies = [ 1090 | "fastrand 2.0.1", 1091 | "futures-core", 1092 | "futures-io", 1093 | "parking", 1094 | "pin-project-lite", 1095 | ] 1096 | 1097 | [[package]] 1098 | name = "futures-macro" 1099 | version = "0.3.30" 1100 | source = "registry+https://github.com/rust-lang/crates.io-index" 1101 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 1102 | dependencies = [ 1103 | "proc-macro2", 1104 | "quote", 1105 | "syn 2.0.43", 1106 | ] 1107 | 1108 | [[package]] 1109 | name = "futures-sink" 1110 | version = "0.3.30" 1111 | source = "registry+https://github.com/rust-lang/crates.io-index" 1112 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 1113 | 1114 | [[package]] 1115 | name = "futures-task" 1116 | version = "0.3.30" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 1119 | 1120 | [[package]] 1121 | name = "futures-util" 1122 | version = "0.3.30" 1123 | source = "registry+https://github.com/rust-lang/crates.io-index" 1124 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 1125 | dependencies = [ 1126 | "futures-core", 1127 | "futures-io", 1128 | "futures-macro", 1129 | "futures-sink", 1130 | "futures-task", 1131 | "memchr", 1132 | "pin-project-lite", 1133 | "pin-utils", 1134 | "slab", 1135 | ] 1136 | 1137 | [[package]] 1138 | name = "generic-array" 1139 | version = "0.14.7" 1140 | source = "registry+https://github.com/rust-lang/crates.io-index" 1141 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 1142 | dependencies = [ 1143 | "typenum", 1144 | "version_check", 1145 | ] 1146 | 1147 | [[package]] 1148 | name = "gethostname" 1149 | version = "0.3.0" 1150 | source = "registry+https://github.com/rust-lang/crates.io-index" 1151 | checksum = "bb65d4ba3173c56a500b555b532f72c42e8d1fe64962b518897f8959fae2c177" 1152 | dependencies = [ 1153 | "libc", 1154 | "winapi", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "getrandom" 1159 | version = "0.2.11" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" 1162 | dependencies = [ 1163 | "cfg-if", 1164 | "js-sys", 1165 | "libc", 1166 | "wasi", 1167 | "wasm-bindgen", 1168 | ] 1169 | 1170 | [[package]] 1171 | name = "gl_generator" 1172 | version = "0.14.0" 1173 | source = "registry+https://github.com/rust-lang/crates.io-index" 1174 | checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d" 1175 | dependencies = [ 1176 | "khronos_api", 1177 | "log", 1178 | "xml-rs", 1179 | ] 1180 | 1181 | [[package]] 1182 | name = "glow" 1183 | version = "0.12.3" 1184 | source = "registry+https://github.com/rust-lang/crates.io-index" 1185 | checksum = "ca0fe580e4b60a8ab24a868bc08e2f03cbcb20d3d676601fa909386713333728" 1186 | dependencies = [ 1187 | "js-sys", 1188 | "slotmap", 1189 | "wasm-bindgen", 1190 | "web-sys", 1191 | ] 1192 | 1193 | [[package]] 1194 | name = "glutin" 1195 | version = "0.30.10" 1196 | source = "registry+https://github.com/rust-lang/crates.io-index" 1197 | checksum = "8fc93b03242719b8ad39fb26ed2b01737144ce7bd4bfc7adadcef806596760fe" 1198 | dependencies = [ 1199 | "bitflags 1.3.2", 1200 | "cfg_aliases", 1201 | "cgl", 1202 | "core-foundation", 1203 | "dispatch", 1204 | "glutin_egl_sys", 1205 | "glutin_glx_sys", 1206 | "glutin_wgl_sys", 1207 | "libloading 0.7.4", 1208 | "objc2", 1209 | "once_cell", 1210 | "raw-window-handle", 1211 | "wayland-sys 0.30.1", 1212 | "windows-sys 0.45.0", 1213 | "x11-dl", 1214 | ] 1215 | 1216 | [[package]] 1217 | name = "glutin-winit" 1218 | version = "0.3.0" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | checksum = "629a873fc04062830bfe8f97c03773bcd7b371e23bcc465d0a61448cd1588fa4" 1221 | dependencies = [ 1222 | "cfg_aliases", 1223 | "glutin", 1224 | "raw-window-handle", 1225 | "winit", 1226 | ] 1227 | 1228 | [[package]] 1229 | name = "glutin_egl_sys" 1230 | version = "0.5.1" 1231 | source = "registry+https://github.com/rust-lang/crates.io-index" 1232 | checksum = "af784eb26c5a68ec85391268e074f0aa618c096eadb5d6330b0911cf34fe57c5" 1233 | dependencies = [ 1234 | "gl_generator", 1235 | "windows-sys 0.45.0", 1236 | ] 1237 | 1238 | [[package]] 1239 | name = "glutin_glx_sys" 1240 | version = "0.4.0" 1241 | source = "registry+https://github.com/rust-lang/crates.io-index" 1242 | checksum = "1b53cb5fe568964aa066a3ba91eac5ecbac869fb0842cd0dc9e412434f1a1494" 1243 | dependencies = [ 1244 | "gl_generator", 1245 | "x11-dl", 1246 | ] 1247 | 1248 | [[package]] 1249 | name = "glutin_wgl_sys" 1250 | version = "0.4.0" 1251 | source = "registry+https://github.com/rust-lang/crates.io-index" 1252 | checksum = "ef89398e90033fc6bc65e9bd42fd29bbbfd483bda5b56dc5562f455550618165" 1253 | dependencies = [ 1254 | "gl_generator", 1255 | ] 1256 | 1257 | [[package]] 1258 | name = "hashbrown" 1259 | version = "0.14.3" 1260 | source = "registry+https://github.com/rust-lang/crates.io-index" 1261 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 1262 | 1263 | [[package]] 1264 | name = "hermit-abi" 1265 | version = "0.3.3" 1266 | source = "registry+https://github.com/rust-lang/crates.io-index" 1267 | checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" 1268 | 1269 | [[package]] 1270 | name = "hex" 1271 | version = "0.4.3" 1272 | source = "registry+https://github.com/rust-lang/crates.io-index" 1273 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 1274 | 1275 | [[package]] 1276 | name = "home" 1277 | version = "0.5.9" 1278 | source = "registry+https://github.com/rust-lang/crates.io-index" 1279 | checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" 1280 | dependencies = [ 1281 | "windows-sys 0.52.0", 1282 | ] 1283 | 1284 | [[package]] 1285 | name = "humantime" 1286 | version = "2.1.0" 1287 | source = "registry+https://github.com/rust-lang/crates.io-index" 1288 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 1289 | 1290 | [[package]] 1291 | name = "idna" 1292 | version = "0.5.0" 1293 | source = "registry+https://github.com/rust-lang/crates.io-index" 1294 | checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 1295 | dependencies = [ 1296 | "unicode-bidi", 1297 | "unicode-normalization", 1298 | ] 1299 | 1300 | [[package]] 1301 | name = "image" 1302 | version = "0.24.7" 1303 | source = "registry+https://github.com/rust-lang/crates.io-index" 1304 | checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" 1305 | dependencies = [ 1306 | "bytemuck", 1307 | "byteorder", 1308 | "color_quant", 1309 | "num-rational", 1310 | "num-traits", 1311 | "png", 1312 | ] 1313 | 1314 | [[package]] 1315 | name = "indexmap" 1316 | version = "2.1.0" 1317 | source = "registry+https://github.com/rust-lang/crates.io-index" 1318 | checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" 1319 | dependencies = [ 1320 | "equivalent", 1321 | "hashbrown", 1322 | ] 1323 | 1324 | [[package]] 1325 | name = "instant" 1326 | version = "0.1.12" 1327 | source = "registry+https://github.com/rust-lang/crates.io-index" 1328 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 1329 | dependencies = [ 1330 | "cfg-if", 1331 | "js-sys", 1332 | "wasm-bindgen", 1333 | "web-sys", 1334 | ] 1335 | 1336 | [[package]] 1337 | name = "io-lifetimes" 1338 | version = "1.0.11" 1339 | source = "registry+https://github.com/rust-lang/crates.io-index" 1340 | checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" 1341 | dependencies = [ 1342 | "hermit-abi", 1343 | "libc", 1344 | "windows-sys 0.48.0", 1345 | ] 1346 | 1347 | [[package]] 1348 | name = "is-terminal" 1349 | version = "0.4.10" 1350 | source = "registry+https://github.com/rust-lang/crates.io-index" 1351 | checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" 1352 | dependencies = [ 1353 | "hermit-abi", 1354 | "rustix 0.38.28", 1355 | "windows-sys 0.52.0", 1356 | ] 1357 | 1358 | [[package]] 1359 | name = "itoa" 1360 | version = "1.0.10" 1361 | source = "registry+https://github.com/rust-lang/crates.io-index" 1362 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 1363 | 1364 | [[package]] 1365 | name = "jni" 1366 | version = "0.21.1" 1367 | source = "registry+https://github.com/rust-lang/crates.io-index" 1368 | checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" 1369 | dependencies = [ 1370 | "cesu8", 1371 | "cfg-if", 1372 | "combine", 1373 | "jni-sys", 1374 | "log", 1375 | "thiserror", 1376 | "walkdir", 1377 | "windows-sys 0.45.0", 1378 | ] 1379 | 1380 | [[package]] 1381 | name = "jni-sys" 1382 | version = "0.3.0" 1383 | source = "registry+https://github.com/rust-lang/crates.io-index" 1384 | checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" 1385 | 1386 | [[package]] 1387 | name = "jobserver" 1388 | version = "0.1.27" 1389 | source = "registry+https://github.com/rust-lang/crates.io-index" 1390 | checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" 1391 | dependencies = [ 1392 | "libc", 1393 | ] 1394 | 1395 | [[package]] 1396 | name = "js-sys" 1397 | version = "0.3.66" 1398 | source = "registry+https://github.com/rust-lang/crates.io-index" 1399 | checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" 1400 | dependencies = [ 1401 | "wasm-bindgen", 1402 | ] 1403 | 1404 | [[package]] 1405 | name = "khronos_api" 1406 | version = "3.1.0" 1407 | source = "registry+https://github.com/rust-lang/crates.io-index" 1408 | checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" 1409 | 1410 | [[package]] 1411 | name = "lazy_static" 1412 | version = "1.4.0" 1413 | source = "registry+https://github.com/rust-lang/crates.io-index" 1414 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1415 | 1416 | [[package]] 1417 | name = "libc" 1418 | version = "0.2.151" 1419 | source = "registry+https://github.com/rust-lang/crates.io-index" 1420 | checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" 1421 | 1422 | [[package]] 1423 | name = "libloading" 1424 | version = "0.7.4" 1425 | source = "registry+https://github.com/rust-lang/crates.io-index" 1426 | checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" 1427 | dependencies = [ 1428 | "cfg-if", 1429 | "winapi", 1430 | ] 1431 | 1432 | [[package]] 1433 | name = "libloading" 1434 | version = "0.8.1" 1435 | source = "registry+https://github.com/rust-lang/crates.io-index" 1436 | checksum = "c571b676ddfc9a8c12f1f3d3085a7b163966a8fd8098a90640953ce5f6170161" 1437 | dependencies = [ 1438 | "cfg-if", 1439 | "windows-sys 0.48.0", 1440 | ] 1441 | 1442 | [[package]] 1443 | name = "libredox" 1444 | version = "0.0.2" 1445 | source = "registry+https://github.com/rust-lang/crates.io-index" 1446 | checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" 1447 | dependencies = [ 1448 | "bitflags 2.4.1", 1449 | "libc", 1450 | "redox_syscall 0.4.1", 1451 | ] 1452 | 1453 | [[package]] 1454 | name = "linux-raw-sys" 1455 | version = "0.3.8" 1456 | source = "registry+https://github.com/rust-lang/crates.io-index" 1457 | checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" 1458 | 1459 | [[package]] 1460 | name = "linux-raw-sys" 1461 | version = "0.4.12" 1462 | source = "registry+https://github.com/rust-lang/crates.io-index" 1463 | checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" 1464 | 1465 | [[package]] 1466 | name = "litrs" 1467 | version = "0.4.1" 1468 | source = "registry+https://github.com/rust-lang/crates.io-index" 1469 | checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" 1470 | 1471 | [[package]] 1472 | name = "lock_api" 1473 | version = "0.4.11" 1474 | source = "registry+https://github.com/rust-lang/crates.io-index" 1475 | checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" 1476 | dependencies = [ 1477 | "autocfg", 1478 | "scopeguard", 1479 | ] 1480 | 1481 | [[package]] 1482 | name = "log" 1483 | version = "0.4.20" 1484 | source = "registry+https://github.com/rust-lang/crates.io-index" 1485 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" 1486 | 1487 | [[package]] 1488 | name = "malloc_buf" 1489 | version = "0.0.6" 1490 | source = "registry+https://github.com/rust-lang/crates.io-index" 1491 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 1492 | dependencies = [ 1493 | "libc", 1494 | ] 1495 | 1496 | [[package]] 1497 | name = "memchr" 1498 | version = "2.7.1" 1499 | source = "registry+https://github.com/rust-lang/crates.io-index" 1500 | checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" 1501 | 1502 | [[package]] 1503 | name = "memmap2" 1504 | version = "0.5.10" 1505 | source = "registry+https://github.com/rust-lang/crates.io-index" 1506 | checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" 1507 | dependencies = [ 1508 | "libc", 1509 | ] 1510 | 1511 | [[package]] 1512 | name = "memoffset" 1513 | version = "0.6.5" 1514 | source = "registry+https://github.com/rust-lang/crates.io-index" 1515 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 1516 | dependencies = [ 1517 | "autocfg", 1518 | ] 1519 | 1520 | [[package]] 1521 | name = "memoffset" 1522 | version = "0.7.1" 1523 | source = "registry+https://github.com/rust-lang/crates.io-index" 1524 | checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" 1525 | dependencies = [ 1526 | "autocfg", 1527 | ] 1528 | 1529 | [[package]] 1530 | name = "memoffset" 1531 | version = "0.9.0" 1532 | source = "registry+https://github.com/rust-lang/crates.io-index" 1533 | checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" 1534 | dependencies = [ 1535 | "autocfg", 1536 | ] 1537 | 1538 | [[package]] 1539 | name = "mime" 1540 | version = "0.3.17" 1541 | source = "registry+https://github.com/rust-lang/crates.io-index" 1542 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 1543 | 1544 | [[package]] 1545 | name = "mime_guess" 1546 | version = "2.0.4" 1547 | source = "registry+https://github.com/rust-lang/crates.io-index" 1548 | checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" 1549 | dependencies = [ 1550 | "mime", 1551 | "unicase", 1552 | ] 1553 | 1554 | [[package]] 1555 | name = "miniz_oxide" 1556 | version = "0.7.1" 1557 | source = "registry+https://github.com/rust-lang/crates.io-index" 1558 | checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" 1559 | dependencies = [ 1560 | "adler", 1561 | "simd-adler32", 1562 | ] 1563 | 1564 | [[package]] 1565 | name = "mio" 1566 | version = "0.8.10" 1567 | source = "registry+https://github.com/rust-lang/crates.io-index" 1568 | checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" 1569 | dependencies = [ 1570 | "libc", 1571 | "log", 1572 | "wasi", 1573 | "windows-sys 0.48.0", 1574 | ] 1575 | 1576 | [[package]] 1577 | name = "ndk" 1578 | version = "0.7.0" 1579 | source = "registry+https://github.com/rust-lang/crates.io-index" 1580 | checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" 1581 | dependencies = [ 1582 | "bitflags 1.3.2", 1583 | "jni-sys", 1584 | "ndk-sys", 1585 | "num_enum 0.5.11", 1586 | "raw-window-handle", 1587 | "thiserror", 1588 | ] 1589 | 1590 | [[package]] 1591 | name = "ndk-context" 1592 | version = "0.1.1" 1593 | source = "registry+https://github.com/rust-lang/crates.io-index" 1594 | checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" 1595 | 1596 | [[package]] 1597 | name = "ndk-sys" 1598 | version = "0.4.1+23.1.7779620" 1599 | source = "registry+https://github.com/rust-lang/crates.io-index" 1600 | checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" 1601 | dependencies = [ 1602 | "jni-sys", 1603 | ] 1604 | 1605 | [[package]] 1606 | name = "nix" 1607 | version = "0.24.3" 1608 | source = "registry+https://github.com/rust-lang/crates.io-index" 1609 | checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" 1610 | dependencies = [ 1611 | "bitflags 1.3.2", 1612 | "cfg-if", 1613 | "libc", 1614 | "memoffset 0.6.5", 1615 | ] 1616 | 1617 | [[package]] 1618 | name = "nix" 1619 | version = "0.25.1" 1620 | source = "registry+https://github.com/rust-lang/crates.io-index" 1621 | checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" 1622 | dependencies = [ 1623 | "autocfg", 1624 | "bitflags 1.3.2", 1625 | "cfg-if", 1626 | "libc", 1627 | "memoffset 0.6.5", 1628 | ] 1629 | 1630 | [[package]] 1631 | name = "nix" 1632 | version = "0.26.4" 1633 | source = "registry+https://github.com/rust-lang/crates.io-index" 1634 | checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" 1635 | dependencies = [ 1636 | "bitflags 1.3.2", 1637 | "cfg-if", 1638 | "libc", 1639 | "memoffset 0.7.1", 1640 | ] 1641 | 1642 | [[package]] 1643 | name = "nohash-hasher" 1644 | version = "0.2.0" 1645 | source = "registry+https://github.com/rust-lang/crates.io-index" 1646 | checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" 1647 | 1648 | [[package]] 1649 | name = "num-integer" 1650 | version = "0.1.45" 1651 | source = "registry+https://github.com/rust-lang/crates.io-index" 1652 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 1653 | dependencies = [ 1654 | "autocfg", 1655 | "num-traits", 1656 | ] 1657 | 1658 | [[package]] 1659 | name = "num-rational" 1660 | version = "0.4.1" 1661 | source = "registry+https://github.com/rust-lang/crates.io-index" 1662 | checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" 1663 | dependencies = [ 1664 | "autocfg", 1665 | "num-integer", 1666 | "num-traits", 1667 | ] 1668 | 1669 | [[package]] 1670 | name = "num-traits" 1671 | version = "0.2.17" 1672 | source = "registry+https://github.com/rust-lang/crates.io-index" 1673 | checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" 1674 | dependencies = [ 1675 | "autocfg", 1676 | ] 1677 | 1678 | [[package]] 1679 | name = "num_enum" 1680 | version = "0.5.11" 1681 | source = "registry+https://github.com/rust-lang/crates.io-index" 1682 | checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" 1683 | dependencies = [ 1684 | "num_enum_derive 0.5.11", 1685 | ] 1686 | 1687 | [[package]] 1688 | name = "num_enum" 1689 | version = "0.6.1" 1690 | source = "registry+https://github.com/rust-lang/crates.io-index" 1691 | checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" 1692 | dependencies = [ 1693 | "num_enum_derive 0.6.1", 1694 | ] 1695 | 1696 | [[package]] 1697 | name = "num_enum_derive" 1698 | version = "0.5.11" 1699 | source = "registry+https://github.com/rust-lang/crates.io-index" 1700 | checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" 1701 | dependencies = [ 1702 | "proc-macro-crate", 1703 | "proc-macro2", 1704 | "quote", 1705 | "syn 1.0.109", 1706 | ] 1707 | 1708 | [[package]] 1709 | name = "num_enum_derive" 1710 | version = "0.6.1" 1711 | source = "registry+https://github.com/rust-lang/crates.io-index" 1712 | checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" 1713 | dependencies = [ 1714 | "proc-macro-crate", 1715 | "proc-macro2", 1716 | "quote", 1717 | "syn 2.0.43", 1718 | ] 1719 | 1720 | [[package]] 1721 | name = "objc" 1722 | version = "0.2.7" 1723 | source = "registry+https://github.com/rust-lang/crates.io-index" 1724 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 1725 | dependencies = [ 1726 | "malloc_buf", 1727 | ] 1728 | 1729 | [[package]] 1730 | name = "objc-foundation" 1731 | version = "0.1.1" 1732 | source = "registry+https://github.com/rust-lang/crates.io-index" 1733 | checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" 1734 | dependencies = [ 1735 | "block", 1736 | "objc", 1737 | "objc_id", 1738 | ] 1739 | 1740 | [[package]] 1741 | name = "objc-sys" 1742 | version = "0.2.0-beta.2" 1743 | source = "registry+https://github.com/rust-lang/crates.io-index" 1744 | checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7" 1745 | 1746 | [[package]] 1747 | name = "objc2" 1748 | version = "0.3.0-beta.3.patch-leaks.3" 1749 | source = "registry+https://github.com/rust-lang/crates.io-index" 1750 | checksum = "7e01640f9f2cb1220bbe80325e179e532cb3379ebcd1bf2279d703c19fe3a468" 1751 | dependencies = [ 1752 | "block2", 1753 | "objc-sys", 1754 | "objc2-encode", 1755 | ] 1756 | 1757 | [[package]] 1758 | name = "objc2-encode" 1759 | version = "2.0.0-pre.2" 1760 | source = "registry+https://github.com/rust-lang/crates.io-index" 1761 | checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512" 1762 | dependencies = [ 1763 | "objc-sys", 1764 | ] 1765 | 1766 | [[package]] 1767 | name = "objc_id" 1768 | version = "0.1.1" 1769 | source = "registry+https://github.com/rust-lang/crates.io-index" 1770 | checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" 1771 | dependencies = [ 1772 | "objc", 1773 | ] 1774 | 1775 | [[package]] 1776 | name = "once_cell" 1777 | version = "1.19.0" 1778 | source = "registry+https://github.com/rust-lang/crates.io-index" 1779 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 1780 | 1781 | [[package]] 1782 | name = "orbclient" 1783 | version = "0.3.47" 1784 | source = "registry+https://github.com/rust-lang/crates.io-index" 1785 | checksum = "52f0d54bde9774d3a51dcf281a5def240c71996bc6ca05d2c847ec8b2b216166" 1786 | dependencies = [ 1787 | "libredox", 1788 | ] 1789 | 1790 | [[package]] 1791 | name = "ordered-stream" 1792 | version = "0.2.0" 1793 | source = "registry+https://github.com/rust-lang/crates.io-index" 1794 | checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" 1795 | dependencies = [ 1796 | "futures-core", 1797 | "pin-project-lite", 1798 | ] 1799 | 1800 | [[package]] 1801 | name = "owned_ttf_parser" 1802 | version = "0.20.0" 1803 | source = "registry+https://github.com/rust-lang/crates.io-index" 1804 | checksum = "d4586edfe4c648c71797a74c84bacb32b52b212eff5dfe2bb9f2c599844023e7" 1805 | dependencies = [ 1806 | "ttf-parser", 1807 | ] 1808 | 1809 | [[package]] 1810 | name = "parking" 1811 | version = "2.2.0" 1812 | source = "registry+https://github.com/rust-lang/crates.io-index" 1813 | checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" 1814 | 1815 | [[package]] 1816 | name = "parking_lot" 1817 | version = "0.12.1" 1818 | source = "registry+https://github.com/rust-lang/crates.io-index" 1819 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 1820 | dependencies = [ 1821 | "lock_api", 1822 | "parking_lot_core", 1823 | ] 1824 | 1825 | [[package]] 1826 | name = "parking_lot_core" 1827 | version = "0.9.9" 1828 | source = "registry+https://github.com/rust-lang/crates.io-index" 1829 | checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" 1830 | dependencies = [ 1831 | "cfg-if", 1832 | "libc", 1833 | "redox_syscall 0.4.1", 1834 | "smallvec", 1835 | "windows-targets 0.48.5", 1836 | ] 1837 | 1838 | [[package]] 1839 | name = "paste" 1840 | version = "1.0.14" 1841 | source = "registry+https://github.com/rust-lang/crates.io-index" 1842 | checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" 1843 | 1844 | [[package]] 1845 | name = "percent-encoding" 1846 | version = "2.3.1" 1847 | source = "registry+https://github.com/rust-lang/crates.io-index" 1848 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1849 | 1850 | [[package]] 1851 | name = "pin-project-lite" 1852 | version = "0.2.13" 1853 | source = "registry+https://github.com/rust-lang/crates.io-index" 1854 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 1855 | 1856 | [[package]] 1857 | name = "pin-utils" 1858 | version = "0.1.0" 1859 | source = "registry+https://github.com/rust-lang/crates.io-index" 1860 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1861 | 1862 | [[package]] 1863 | name = "piper" 1864 | version = "0.2.1" 1865 | source = "registry+https://github.com/rust-lang/crates.io-index" 1866 | checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" 1867 | dependencies = [ 1868 | "atomic-waker", 1869 | "fastrand 2.0.1", 1870 | "futures-io", 1871 | ] 1872 | 1873 | [[package]] 1874 | name = "pkg-config" 1875 | version = "0.3.28" 1876 | source = "registry+https://github.com/rust-lang/crates.io-index" 1877 | checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" 1878 | 1879 | [[package]] 1880 | name = "png" 1881 | version = "0.17.10" 1882 | source = "registry+https://github.com/rust-lang/crates.io-index" 1883 | checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" 1884 | dependencies = [ 1885 | "bitflags 1.3.2", 1886 | "crc32fast", 1887 | "fdeflate", 1888 | "flate2", 1889 | "miniz_oxide", 1890 | ] 1891 | 1892 | [[package]] 1893 | name = "polling" 1894 | version = "2.8.0" 1895 | source = "registry+https://github.com/rust-lang/crates.io-index" 1896 | checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" 1897 | dependencies = [ 1898 | "autocfg", 1899 | "bitflags 1.3.2", 1900 | "cfg-if", 1901 | "concurrent-queue", 1902 | "libc", 1903 | "log", 1904 | "pin-project-lite", 1905 | "windows-sys 0.48.0", 1906 | ] 1907 | 1908 | [[package]] 1909 | name = "polling" 1910 | version = "3.3.1" 1911 | source = "registry+https://github.com/rust-lang/crates.io-index" 1912 | checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" 1913 | dependencies = [ 1914 | "cfg-if", 1915 | "concurrent-queue", 1916 | "pin-project-lite", 1917 | "rustix 0.38.28", 1918 | "tracing", 1919 | "windows-sys 0.52.0", 1920 | ] 1921 | 1922 | [[package]] 1923 | name = "ppv-lite86" 1924 | version = "0.2.17" 1925 | source = "registry+https://github.com/rust-lang/crates.io-index" 1926 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1927 | 1928 | [[package]] 1929 | name = "proc-macro-crate" 1930 | version = "1.3.1" 1931 | source = "registry+https://github.com/rust-lang/crates.io-index" 1932 | checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" 1933 | dependencies = [ 1934 | "once_cell", 1935 | "toml_edit", 1936 | ] 1937 | 1938 | [[package]] 1939 | name = "proc-macro2" 1940 | version = "1.0.72" 1941 | source = "registry+https://github.com/rust-lang/crates.io-index" 1942 | checksum = "a293318316cf6478ec1ad2a21c49390a8d5b5eae9fab736467d93fbc0edc29c5" 1943 | dependencies = [ 1944 | "unicode-ident", 1945 | ] 1946 | 1947 | [[package]] 1948 | name = "quote" 1949 | version = "1.0.33" 1950 | source = "registry+https://github.com/rust-lang/crates.io-index" 1951 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" 1952 | dependencies = [ 1953 | "proc-macro2", 1954 | ] 1955 | 1956 | [[package]] 1957 | name = "rand" 1958 | version = "0.8.5" 1959 | source = "registry+https://github.com/rust-lang/crates.io-index" 1960 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1961 | dependencies = [ 1962 | "libc", 1963 | "rand_chacha", 1964 | "rand_core", 1965 | ] 1966 | 1967 | [[package]] 1968 | name = "rand_chacha" 1969 | version = "0.3.1" 1970 | source = "registry+https://github.com/rust-lang/crates.io-index" 1971 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1972 | dependencies = [ 1973 | "ppv-lite86", 1974 | "rand_core", 1975 | ] 1976 | 1977 | [[package]] 1978 | name = "rand_core" 1979 | version = "0.6.4" 1980 | source = "registry+https://github.com/rust-lang/crates.io-index" 1981 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1982 | dependencies = [ 1983 | "getrandom", 1984 | ] 1985 | 1986 | [[package]] 1987 | name = "raw-window-handle" 1988 | version = "0.5.2" 1989 | source = "registry+https://github.com/rust-lang/crates.io-index" 1990 | checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" 1991 | 1992 | [[package]] 1993 | name = "redox_syscall" 1994 | version = "0.3.5" 1995 | source = "registry+https://github.com/rust-lang/crates.io-index" 1996 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 1997 | dependencies = [ 1998 | "bitflags 1.3.2", 1999 | ] 2000 | 2001 | [[package]] 2002 | name = "redox_syscall" 2003 | version = "0.4.1" 2004 | source = "registry+https://github.com/rust-lang/crates.io-index" 2005 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 2006 | dependencies = [ 2007 | "bitflags 1.3.2", 2008 | ] 2009 | 2010 | [[package]] 2011 | name = "regex" 2012 | version = "1.10.2" 2013 | source = "registry+https://github.com/rust-lang/crates.io-index" 2014 | checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" 2015 | dependencies = [ 2016 | "aho-corasick", 2017 | "memchr", 2018 | "regex-automata", 2019 | "regex-syntax", 2020 | ] 2021 | 2022 | [[package]] 2023 | name = "regex-automata" 2024 | version = "0.4.3" 2025 | source = "registry+https://github.com/rust-lang/crates.io-index" 2026 | checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" 2027 | dependencies = [ 2028 | "aho-corasick", 2029 | "memchr", 2030 | "regex-syntax", 2031 | ] 2032 | 2033 | [[package]] 2034 | name = "regex-syntax" 2035 | version = "0.8.2" 2036 | source = "registry+https://github.com/rust-lang/crates.io-index" 2037 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 2038 | 2039 | [[package]] 2040 | name = "ring" 2041 | version = "0.17.7" 2042 | source = "registry+https://github.com/rust-lang/crates.io-index" 2043 | checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" 2044 | dependencies = [ 2045 | "cc", 2046 | "getrandom", 2047 | "libc", 2048 | "spin", 2049 | "untrusted", 2050 | "windows-sys 0.48.0", 2051 | ] 2052 | 2053 | [[package]] 2054 | name = "rustix" 2055 | version = "0.37.27" 2056 | source = "registry+https://github.com/rust-lang/crates.io-index" 2057 | checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" 2058 | dependencies = [ 2059 | "bitflags 1.3.2", 2060 | "errno", 2061 | "io-lifetimes", 2062 | "libc", 2063 | "linux-raw-sys 0.3.8", 2064 | "windows-sys 0.48.0", 2065 | ] 2066 | 2067 | [[package]] 2068 | name = "rustix" 2069 | version = "0.38.28" 2070 | source = "registry+https://github.com/rust-lang/crates.io-index" 2071 | checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" 2072 | dependencies = [ 2073 | "bitflags 2.4.1", 2074 | "errno", 2075 | "libc", 2076 | "linux-raw-sys 0.4.12", 2077 | "windows-sys 0.52.0", 2078 | ] 2079 | 2080 | [[package]] 2081 | name = "rustls" 2082 | version = "0.21.10" 2083 | source = "registry+https://github.com/rust-lang/crates.io-index" 2084 | checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" 2085 | dependencies = [ 2086 | "log", 2087 | "ring", 2088 | "rustls-webpki", 2089 | "sct", 2090 | ] 2091 | 2092 | [[package]] 2093 | name = "rustls-webpki" 2094 | version = "0.101.7" 2095 | source = "registry+https://github.com/rust-lang/crates.io-index" 2096 | checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" 2097 | dependencies = [ 2098 | "ring", 2099 | "untrusted", 2100 | ] 2101 | 2102 | [[package]] 2103 | name = "ryu" 2104 | version = "1.0.16" 2105 | source = "registry+https://github.com/rust-lang/crates.io-index" 2106 | checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" 2107 | 2108 | [[package]] 2109 | name = "same-file" 2110 | version = "1.0.6" 2111 | source = "registry+https://github.com/rust-lang/crates.io-index" 2112 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 2113 | dependencies = [ 2114 | "winapi-util", 2115 | ] 2116 | 2117 | [[package]] 2118 | name = "scoped-tls" 2119 | version = "1.0.1" 2120 | source = "registry+https://github.com/rust-lang/crates.io-index" 2121 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 2122 | 2123 | [[package]] 2124 | name = "scopeguard" 2125 | version = "1.2.0" 2126 | source = "registry+https://github.com/rust-lang/crates.io-index" 2127 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 2128 | 2129 | [[package]] 2130 | name = "sct" 2131 | version = "0.7.1" 2132 | source = "registry+https://github.com/rust-lang/crates.io-index" 2133 | checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" 2134 | dependencies = [ 2135 | "ring", 2136 | "untrusted", 2137 | ] 2138 | 2139 | [[package]] 2140 | name = "sctk-adwaita" 2141 | version = "0.5.4" 2142 | source = "registry+https://github.com/rust-lang/crates.io-index" 2143 | checksum = "cda4e97be1fd174ccc2aae81c8b694e803fa99b34e8fd0f057a9d70698e3ed09" 2144 | dependencies = [ 2145 | "ab_glyph", 2146 | "log", 2147 | "memmap2", 2148 | "smithay-client-toolkit", 2149 | "tiny-skia", 2150 | ] 2151 | 2152 | [[package]] 2153 | name = "serde" 2154 | version = "1.0.193" 2155 | source = "registry+https://github.com/rust-lang/crates.io-index" 2156 | checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" 2157 | dependencies = [ 2158 | "serde_derive", 2159 | ] 2160 | 2161 | [[package]] 2162 | name = "serde_derive" 2163 | version = "1.0.193" 2164 | source = "registry+https://github.com/rust-lang/crates.io-index" 2165 | checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" 2166 | dependencies = [ 2167 | "proc-macro2", 2168 | "quote", 2169 | "syn 2.0.43", 2170 | ] 2171 | 2172 | [[package]] 2173 | name = "serde_json" 2174 | version = "1.0.109" 2175 | source = "registry+https://github.com/rust-lang/crates.io-index" 2176 | checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9" 2177 | dependencies = [ 2178 | "itoa", 2179 | "ryu", 2180 | "serde", 2181 | ] 2182 | 2183 | [[package]] 2184 | name = "serde_repr" 2185 | version = "0.1.17" 2186 | source = "registry+https://github.com/rust-lang/crates.io-index" 2187 | checksum = "3081f5ffbb02284dda55132aa26daecedd7372a42417bbbab6f14ab7d6bb9145" 2188 | dependencies = [ 2189 | "proc-macro2", 2190 | "quote", 2191 | "syn 2.0.43", 2192 | ] 2193 | 2194 | [[package]] 2195 | name = "sha1" 2196 | version = "0.10.6" 2197 | source = "registry+https://github.com/rust-lang/crates.io-index" 2198 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 2199 | dependencies = [ 2200 | "cfg-if", 2201 | "cpufeatures", 2202 | "digest", 2203 | ] 2204 | 2205 | [[package]] 2206 | name = "signal-hook-registry" 2207 | version = "1.4.1" 2208 | source = "registry+https://github.com/rust-lang/crates.io-index" 2209 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 2210 | dependencies = [ 2211 | "libc", 2212 | ] 2213 | 2214 | [[package]] 2215 | name = "simd-adler32" 2216 | version = "0.3.7" 2217 | source = "registry+https://github.com/rust-lang/crates.io-index" 2218 | checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" 2219 | 2220 | [[package]] 2221 | name = "slab" 2222 | version = "0.4.9" 2223 | source = "registry+https://github.com/rust-lang/crates.io-index" 2224 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 2225 | dependencies = [ 2226 | "autocfg", 2227 | ] 2228 | 2229 | [[package]] 2230 | name = "slotmap" 2231 | version = "1.0.7" 2232 | source = "registry+https://github.com/rust-lang/crates.io-index" 2233 | checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" 2234 | dependencies = [ 2235 | "version_check", 2236 | ] 2237 | 2238 | [[package]] 2239 | name = "smallvec" 2240 | version = "1.11.2" 2241 | source = "registry+https://github.com/rust-lang/crates.io-index" 2242 | checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" 2243 | 2244 | [[package]] 2245 | name = "smithay-client-toolkit" 2246 | version = "0.16.1" 2247 | source = "registry+https://github.com/rust-lang/crates.io-index" 2248 | checksum = "870427e30b8f2cbe64bf43ec4b86e88fe39b0a84b3f15efd9c9c2d020bc86eb9" 2249 | dependencies = [ 2250 | "bitflags 1.3.2", 2251 | "calloop", 2252 | "dlib", 2253 | "lazy_static", 2254 | "log", 2255 | "memmap2", 2256 | "nix 0.24.3", 2257 | "pkg-config", 2258 | "wayland-client", 2259 | "wayland-cursor", 2260 | "wayland-protocols", 2261 | ] 2262 | 2263 | [[package]] 2264 | name = "smithay-clipboard" 2265 | version = "0.6.6" 2266 | source = "registry+https://github.com/rust-lang/crates.io-index" 2267 | checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8" 2268 | dependencies = [ 2269 | "smithay-client-toolkit", 2270 | "wayland-client", 2271 | ] 2272 | 2273 | [[package]] 2274 | name = "socket2" 2275 | version = "0.4.10" 2276 | source = "registry+https://github.com/rust-lang/crates.io-index" 2277 | checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" 2278 | dependencies = [ 2279 | "libc", 2280 | "winapi", 2281 | ] 2282 | 2283 | [[package]] 2284 | name = "spin" 2285 | version = "0.9.8" 2286 | source = "registry+https://github.com/rust-lang/crates.io-index" 2287 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 2288 | 2289 | [[package]] 2290 | name = "static_assertions" 2291 | version = "1.1.0" 2292 | source = "registry+https://github.com/rust-lang/crates.io-index" 2293 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 2294 | 2295 | [[package]] 2296 | name = "str-buf" 2297 | version = "1.0.6" 2298 | source = "registry+https://github.com/rust-lang/crates.io-index" 2299 | checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" 2300 | 2301 | [[package]] 2302 | name = "strict-num" 2303 | version = "0.1.1" 2304 | source = "registry+https://github.com/rust-lang/crates.io-index" 2305 | checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" 2306 | 2307 | [[package]] 2308 | name = "syn" 2309 | version = "1.0.109" 2310 | source = "registry+https://github.com/rust-lang/crates.io-index" 2311 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 2312 | dependencies = [ 2313 | "proc-macro2", 2314 | "quote", 2315 | "unicode-ident", 2316 | ] 2317 | 2318 | [[package]] 2319 | name = "syn" 2320 | version = "2.0.43" 2321 | source = "registry+https://github.com/rust-lang/crates.io-index" 2322 | checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53" 2323 | dependencies = [ 2324 | "proc-macro2", 2325 | "quote", 2326 | "unicode-ident", 2327 | ] 2328 | 2329 | [[package]] 2330 | name = "tempfile" 2331 | version = "3.9.0" 2332 | source = "registry+https://github.com/rust-lang/crates.io-index" 2333 | checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" 2334 | dependencies = [ 2335 | "cfg-if", 2336 | "fastrand 2.0.1", 2337 | "redox_syscall 0.4.1", 2338 | "rustix 0.38.28", 2339 | "windows-sys 0.52.0", 2340 | ] 2341 | 2342 | [[package]] 2343 | name = "termcolor" 2344 | version = "1.4.0" 2345 | source = "registry+https://github.com/rust-lang/crates.io-index" 2346 | checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" 2347 | dependencies = [ 2348 | "winapi-util", 2349 | ] 2350 | 2351 | [[package]] 2352 | name = "thiserror" 2353 | version = "1.0.53" 2354 | source = "registry+https://github.com/rust-lang/crates.io-index" 2355 | checksum = "b2cd5904763bad08ad5513ddbb12cf2ae273ca53fa9f68e843e236ec6dfccc09" 2356 | dependencies = [ 2357 | "thiserror-impl", 2358 | ] 2359 | 2360 | [[package]] 2361 | name = "thiserror-impl" 2362 | version = "1.0.53" 2363 | source = "registry+https://github.com/rust-lang/crates.io-index" 2364 | checksum = "3dcf4a824cce0aeacd6f38ae6f24234c8e80d68632338ebaa1443b5df9e29e19" 2365 | dependencies = [ 2366 | "proc-macro2", 2367 | "quote", 2368 | "syn 2.0.43", 2369 | ] 2370 | 2371 | [[package]] 2372 | name = "tiny-skia" 2373 | version = "0.8.4" 2374 | source = "registry+https://github.com/rust-lang/crates.io-index" 2375 | checksum = "df8493a203431061e901613751931f047d1971337153f96d0e5e363d6dbf6a67" 2376 | dependencies = [ 2377 | "arrayref", 2378 | "arrayvec", 2379 | "bytemuck", 2380 | "cfg-if", 2381 | "png", 2382 | "tiny-skia-path", 2383 | ] 2384 | 2385 | [[package]] 2386 | name = "tiny-skia-path" 2387 | version = "0.8.4" 2388 | source = "registry+https://github.com/rust-lang/crates.io-index" 2389 | checksum = "adbfb5d3f3dd57a0e11d12f4f13d4ebbbc1b5c15b7ab0a156d030b21da5f677c" 2390 | dependencies = [ 2391 | "arrayref", 2392 | "bytemuck", 2393 | "strict-num", 2394 | ] 2395 | 2396 | [[package]] 2397 | name = "tinyvec" 2398 | version = "1.6.0" 2399 | source = "registry+https://github.com/rust-lang/crates.io-index" 2400 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 2401 | dependencies = [ 2402 | "tinyvec_macros", 2403 | ] 2404 | 2405 | [[package]] 2406 | name = "tinyvec_macros" 2407 | version = "0.1.1" 2408 | source = "registry+https://github.com/rust-lang/crates.io-index" 2409 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 2410 | 2411 | [[package]] 2412 | name = "toml_datetime" 2413 | version = "0.6.5" 2414 | source = "registry+https://github.com/rust-lang/crates.io-index" 2415 | checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" 2416 | 2417 | [[package]] 2418 | name = "toml_edit" 2419 | version = "0.19.15" 2420 | source = "registry+https://github.com/rust-lang/crates.io-index" 2421 | checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" 2422 | dependencies = [ 2423 | "indexmap", 2424 | "toml_datetime", 2425 | "winnow", 2426 | ] 2427 | 2428 | [[package]] 2429 | name = "tracing" 2430 | version = "0.1.40" 2431 | source = "registry+https://github.com/rust-lang/crates.io-index" 2432 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 2433 | dependencies = [ 2434 | "pin-project-lite", 2435 | "tracing-attributes", 2436 | "tracing-core", 2437 | ] 2438 | 2439 | [[package]] 2440 | name = "tracing-attributes" 2441 | version = "0.1.27" 2442 | source = "registry+https://github.com/rust-lang/crates.io-index" 2443 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 2444 | dependencies = [ 2445 | "proc-macro2", 2446 | "quote", 2447 | "syn 2.0.43", 2448 | ] 2449 | 2450 | [[package]] 2451 | name = "tracing-core" 2452 | version = "0.1.32" 2453 | source = "registry+https://github.com/rust-lang/crates.io-index" 2454 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 2455 | dependencies = [ 2456 | "once_cell", 2457 | ] 2458 | 2459 | [[package]] 2460 | name = "ttf-parser" 2461 | version = "0.20.0" 2462 | source = "registry+https://github.com/rust-lang/crates.io-index" 2463 | checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4" 2464 | 2465 | [[package]] 2466 | name = "typenum" 2467 | version = "1.17.0" 2468 | source = "registry+https://github.com/rust-lang/crates.io-index" 2469 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 2470 | 2471 | [[package]] 2472 | name = "uds_windows" 2473 | version = "1.1.0" 2474 | source = "registry+https://github.com/rust-lang/crates.io-index" 2475 | checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" 2476 | dependencies = [ 2477 | "memoffset 0.9.0", 2478 | "tempfile", 2479 | "winapi", 2480 | ] 2481 | 2482 | [[package]] 2483 | name = "unicase" 2484 | version = "2.7.0" 2485 | source = "registry+https://github.com/rust-lang/crates.io-index" 2486 | checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" 2487 | dependencies = [ 2488 | "version_check", 2489 | ] 2490 | 2491 | [[package]] 2492 | name = "unicode-bidi" 2493 | version = "0.3.14" 2494 | source = "registry+https://github.com/rust-lang/crates.io-index" 2495 | checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" 2496 | 2497 | [[package]] 2498 | name = "unicode-ident" 2499 | version = "1.0.12" 2500 | source = "registry+https://github.com/rust-lang/crates.io-index" 2501 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 2502 | 2503 | [[package]] 2504 | name = "unicode-normalization" 2505 | version = "0.1.22" 2506 | source = "registry+https://github.com/rust-lang/crates.io-index" 2507 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 2508 | dependencies = [ 2509 | "tinyvec", 2510 | ] 2511 | 2512 | [[package]] 2513 | name = "untrusted" 2514 | version = "0.9.0" 2515 | source = "registry+https://github.com/rust-lang/crates.io-index" 2516 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 2517 | 2518 | [[package]] 2519 | name = "ureq" 2520 | version = "2.9.1" 2521 | source = "registry+https://github.com/rust-lang/crates.io-index" 2522 | checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" 2523 | dependencies = [ 2524 | "base64", 2525 | "flate2", 2526 | "log", 2527 | "once_cell", 2528 | "rustls", 2529 | "rustls-webpki", 2530 | "url", 2531 | "webpki-roots", 2532 | ] 2533 | 2534 | [[package]] 2535 | name = "url" 2536 | version = "2.5.0" 2537 | source = "registry+https://github.com/rust-lang/crates.io-index" 2538 | checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" 2539 | dependencies = [ 2540 | "form_urlencoded", 2541 | "idna", 2542 | "percent-encoding", 2543 | ] 2544 | 2545 | [[package]] 2546 | name = "vec_map" 2547 | version = "0.8.2" 2548 | source = "registry+https://github.com/rust-lang/crates.io-index" 2549 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" 2550 | 2551 | [[package]] 2552 | name = "version_check" 2553 | version = "0.9.4" 2554 | source = "registry+https://github.com/rust-lang/crates.io-index" 2555 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 2556 | 2557 | [[package]] 2558 | name = "waker-fn" 2559 | version = "1.1.1" 2560 | source = "registry+https://github.com/rust-lang/crates.io-index" 2561 | checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" 2562 | 2563 | [[package]] 2564 | name = "walkdir" 2565 | version = "2.4.0" 2566 | source = "registry+https://github.com/rust-lang/crates.io-index" 2567 | checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" 2568 | dependencies = [ 2569 | "same-file", 2570 | "winapi-util", 2571 | ] 2572 | 2573 | [[package]] 2574 | name = "wasi" 2575 | version = "0.11.0+wasi-snapshot-preview1" 2576 | source = "registry+https://github.com/rust-lang/crates.io-index" 2577 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2578 | 2579 | [[package]] 2580 | name = "wasm-bindgen" 2581 | version = "0.2.89" 2582 | source = "registry+https://github.com/rust-lang/crates.io-index" 2583 | checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" 2584 | dependencies = [ 2585 | "cfg-if", 2586 | "wasm-bindgen-macro", 2587 | ] 2588 | 2589 | [[package]] 2590 | name = "wasm-bindgen-backend" 2591 | version = "0.2.89" 2592 | source = "registry+https://github.com/rust-lang/crates.io-index" 2593 | checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" 2594 | dependencies = [ 2595 | "bumpalo", 2596 | "log", 2597 | "once_cell", 2598 | "proc-macro2", 2599 | "quote", 2600 | "syn 2.0.43", 2601 | "wasm-bindgen-shared", 2602 | ] 2603 | 2604 | [[package]] 2605 | name = "wasm-bindgen-futures" 2606 | version = "0.4.39" 2607 | source = "registry+https://github.com/rust-lang/crates.io-index" 2608 | checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" 2609 | dependencies = [ 2610 | "cfg-if", 2611 | "js-sys", 2612 | "wasm-bindgen", 2613 | "web-sys", 2614 | ] 2615 | 2616 | [[package]] 2617 | name = "wasm-bindgen-macro" 2618 | version = "0.2.89" 2619 | source = "registry+https://github.com/rust-lang/crates.io-index" 2620 | checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" 2621 | dependencies = [ 2622 | "quote", 2623 | "wasm-bindgen-macro-support", 2624 | ] 2625 | 2626 | [[package]] 2627 | name = "wasm-bindgen-macro-support" 2628 | version = "0.2.89" 2629 | source = "registry+https://github.com/rust-lang/crates.io-index" 2630 | checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" 2631 | dependencies = [ 2632 | "proc-macro2", 2633 | "quote", 2634 | "syn 2.0.43", 2635 | "wasm-bindgen-backend", 2636 | "wasm-bindgen-shared", 2637 | ] 2638 | 2639 | [[package]] 2640 | name = "wasm-bindgen-shared" 2641 | version = "0.2.89" 2642 | source = "registry+https://github.com/rust-lang/crates.io-index" 2643 | checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" 2644 | 2645 | [[package]] 2646 | name = "wasm-streams" 2647 | version = "0.4.0" 2648 | source = "registry+https://github.com/rust-lang/crates.io-index" 2649 | checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" 2650 | dependencies = [ 2651 | "futures-util", 2652 | "js-sys", 2653 | "wasm-bindgen", 2654 | "wasm-bindgen-futures", 2655 | "web-sys", 2656 | ] 2657 | 2658 | [[package]] 2659 | name = "wayland-client" 2660 | version = "0.29.5" 2661 | source = "registry+https://github.com/rust-lang/crates.io-index" 2662 | checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" 2663 | dependencies = [ 2664 | "bitflags 1.3.2", 2665 | "downcast-rs", 2666 | "libc", 2667 | "nix 0.24.3", 2668 | "scoped-tls", 2669 | "wayland-commons", 2670 | "wayland-scanner", 2671 | "wayland-sys 0.29.5", 2672 | ] 2673 | 2674 | [[package]] 2675 | name = "wayland-commons" 2676 | version = "0.29.5" 2677 | source = "registry+https://github.com/rust-lang/crates.io-index" 2678 | checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" 2679 | dependencies = [ 2680 | "nix 0.24.3", 2681 | "once_cell", 2682 | "smallvec", 2683 | "wayland-sys 0.29.5", 2684 | ] 2685 | 2686 | [[package]] 2687 | name = "wayland-cursor" 2688 | version = "0.29.5" 2689 | source = "registry+https://github.com/rust-lang/crates.io-index" 2690 | checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661" 2691 | dependencies = [ 2692 | "nix 0.24.3", 2693 | "wayland-client", 2694 | "xcursor", 2695 | ] 2696 | 2697 | [[package]] 2698 | name = "wayland-protocols" 2699 | version = "0.29.5" 2700 | source = "registry+https://github.com/rust-lang/crates.io-index" 2701 | checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" 2702 | dependencies = [ 2703 | "bitflags 1.3.2", 2704 | "wayland-client", 2705 | "wayland-commons", 2706 | "wayland-scanner", 2707 | ] 2708 | 2709 | [[package]] 2710 | name = "wayland-scanner" 2711 | version = "0.29.5" 2712 | source = "registry+https://github.com/rust-lang/crates.io-index" 2713 | checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" 2714 | dependencies = [ 2715 | "proc-macro2", 2716 | "quote", 2717 | "xml-rs", 2718 | ] 2719 | 2720 | [[package]] 2721 | name = "wayland-sys" 2722 | version = "0.29.5" 2723 | source = "registry+https://github.com/rust-lang/crates.io-index" 2724 | checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" 2725 | dependencies = [ 2726 | "dlib", 2727 | "lazy_static", 2728 | "pkg-config", 2729 | ] 2730 | 2731 | [[package]] 2732 | name = "wayland-sys" 2733 | version = "0.30.1" 2734 | source = "registry+https://github.com/rust-lang/crates.io-index" 2735 | checksum = "96b2a02ac608e07132978689a6f9bf4214949c85998c247abadd4f4129b1aa06" 2736 | dependencies = [ 2737 | "dlib", 2738 | "lazy_static", 2739 | "log", 2740 | "pkg-config", 2741 | ] 2742 | 2743 | [[package]] 2744 | name = "web-sys" 2745 | version = "0.3.66" 2746 | source = "registry+https://github.com/rust-lang/crates.io-index" 2747 | checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" 2748 | dependencies = [ 2749 | "js-sys", 2750 | "wasm-bindgen", 2751 | ] 2752 | 2753 | [[package]] 2754 | name = "web-time" 2755 | version = "0.2.4" 2756 | source = "registry+https://github.com/rust-lang/crates.io-index" 2757 | checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" 2758 | dependencies = [ 2759 | "js-sys", 2760 | "wasm-bindgen", 2761 | ] 2762 | 2763 | [[package]] 2764 | name = "webbrowser" 2765 | version = "0.8.12" 2766 | source = "registry+https://github.com/rust-lang/crates.io-index" 2767 | checksum = "82b2391658b02c27719fc5a0a73d6e696285138e8b12fba9d4baa70451023c71" 2768 | dependencies = [ 2769 | "core-foundation", 2770 | "home", 2771 | "jni", 2772 | "log", 2773 | "ndk-context", 2774 | "objc", 2775 | "raw-window-handle", 2776 | "url", 2777 | "web-sys", 2778 | ] 2779 | 2780 | [[package]] 2781 | name = "webpki-roots" 2782 | version = "0.25.3" 2783 | source = "registry+https://github.com/rust-lang/crates.io-index" 2784 | checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" 2785 | 2786 | [[package]] 2787 | name = "winapi" 2788 | version = "0.3.9" 2789 | source = "registry+https://github.com/rust-lang/crates.io-index" 2790 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2791 | dependencies = [ 2792 | "winapi-i686-pc-windows-gnu", 2793 | "winapi-x86_64-pc-windows-gnu", 2794 | ] 2795 | 2796 | [[package]] 2797 | name = "winapi-i686-pc-windows-gnu" 2798 | version = "0.4.0" 2799 | source = "registry+https://github.com/rust-lang/crates.io-index" 2800 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2801 | 2802 | [[package]] 2803 | name = "winapi-util" 2804 | version = "0.1.6" 2805 | source = "registry+https://github.com/rust-lang/crates.io-index" 2806 | checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" 2807 | dependencies = [ 2808 | "winapi", 2809 | ] 2810 | 2811 | [[package]] 2812 | name = "winapi-wsapoll" 2813 | version = "0.1.1" 2814 | source = "registry+https://github.com/rust-lang/crates.io-index" 2815 | checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" 2816 | dependencies = [ 2817 | "winapi", 2818 | ] 2819 | 2820 | [[package]] 2821 | name = "winapi-x86_64-pc-windows-gnu" 2822 | version = "0.4.0" 2823 | source = "registry+https://github.com/rust-lang/crates.io-index" 2824 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2825 | 2826 | [[package]] 2827 | name = "windows" 2828 | version = "0.48.0" 2829 | source = "registry+https://github.com/rust-lang/crates.io-index" 2830 | checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" 2831 | dependencies = [ 2832 | "windows-implement", 2833 | "windows-interface", 2834 | "windows-targets 0.48.5", 2835 | ] 2836 | 2837 | [[package]] 2838 | name = "windows-implement" 2839 | version = "0.48.0" 2840 | source = "registry+https://github.com/rust-lang/crates.io-index" 2841 | checksum = "5e2ee588991b9e7e6c8338edf3333fbe4da35dc72092643958ebb43f0ab2c49c" 2842 | dependencies = [ 2843 | "proc-macro2", 2844 | "quote", 2845 | "syn 1.0.109", 2846 | ] 2847 | 2848 | [[package]] 2849 | name = "windows-interface" 2850 | version = "0.48.0" 2851 | source = "registry+https://github.com/rust-lang/crates.io-index" 2852 | checksum = "e6fb8df20c9bcaa8ad6ab513f7b40104840c8867d5751126e4df3b08388d0cc7" 2853 | dependencies = [ 2854 | "proc-macro2", 2855 | "quote", 2856 | "syn 1.0.109", 2857 | ] 2858 | 2859 | [[package]] 2860 | name = "windows-sys" 2861 | version = "0.45.0" 2862 | source = "registry+https://github.com/rust-lang/crates.io-index" 2863 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 2864 | dependencies = [ 2865 | "windows-targets 0.42.2", 2866 | ] 2867 | 2868 | [[package]] 2869 | name = "windows-sys" 2870 | version = "0.48.0" 2871 | source = "registry+https://github.com/rust-lang/crates.io-index" 2872 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2873 | dependencies = [ 2874 | "windows-targets 0.48.5", 2875 | ] 2876 | 2877 | [[package]] 2878 | name = "windows-sys" 2879 | version = "0.52.0" 2880 | source = "registry+https://github.com/rust-lang/crates.io-index" 2881 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2882 | dependencies = [ 2883 | "windows-targets 0.52.0", 2884 | ] 2885 | 2886 | [[package]] 2887 | name = "windows-targets" 2888 | version = "0.42.2" 2889 | source = "registry+https://github.com/rust-lang/crates.io-index" 2890 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 2891 | dependencies = [ 2892 | "windows_aarch64_gnullvm 0.42.2", 2893 | "windows_aarch64_msvc 0.42.2", 2894 | "windows_i686_gnu 0.42.2", 2895 | "windows_i686_msvc 0.42.2", 2896 | "windows_x86_64_gnu 0.42.2", 2897 | "windows_x86_64_gnullvm 0.42.2", 2898 | "windows_x86_64_msvc 0.42.2", 2899 | ] 2900 | 2901 | [[package]] 2902 | name = "windows-targets" 2903 | version = "0.48.5" 2904 | source = "registry+https://github.com/rust-lang/crates.io-index" 2905 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2906 | dependencies = [ 2907 | "windows_aarch64_gnullvm 0.48.5", 2908 | "windows_aarch64_msvc 0.48.5", 2909 | "windows_i686_gnu 0.48.5", 2910 | "windows_i686_msvc 0.48.5", 2911 | "windows_x86_64_gnu 0.48.5", 2912 | "windows_x86_64_gnullvm 0.48.5", 2913 | "windows_x86_64_msvc 0.48.5", 2914 | ] 2915 | 2916 | [[package]] 2917 | name = "windows-targets" 2918 | version = "0.52.0" 2919 | source = "registry+https://github.com/rust-lang/crates.io-index" 2920 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 2921 | dependencies = [ 2922 | "windows_aarch64_gnullvm 0.52.0", 2923 | "windows_aarch64_msvc 0.52.0", 2924 | "windows_i686_gnu 0.52.0", 2925 | "windows_i686_msvc 0.52.0", 2926 | "windows_x86_64_gnu 0.52.0", 2927 | "windows_x86_64_gnullvm 0.52.0", 2928 | "windows_x86_64_msvc 0.52.0", 2929 | ] 2930 | 2931 | [[package]] 2932 | name = "windows_aarch64_gnullvm" 2933 | version = "0.42.2" 2934 | source = "registry+https://github.com/rust-lang/crates.io-index" 2935 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 2936 | 2937 | [[package]] 2938 | name = "windows_aarch64_gnullvm" 2939 | version = "0.48.5" 2940 | source = "registry+https://github.com/rust-lang/crates.io-index" 2941 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2942 | 2943 | [[package]] 2944 | name = "windows_aarch64_gnullvm" 2945 | version = "0.52.0" 2946 | source = "registry+https://github.com/rust-lang/crates.io-index" 2947 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 2948 | 2949 | [[package]] 2950 | name = "windows_aarch64_msvc" 2951 | version = "0.42.2" 2952 | source = "registry+https://github.com/rust-lang/crates.io-index" 2953 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 2954 | 2955 | [[package]] 2956 | name = "windows_aarch64_msvc" 2957 | version = "0.48.5" 2958 | source = "registry+https://github.com/rust-lang/crates.io-index" 2959 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2960 | 2961 | [[package]] 2962 | name = "windows_aarch64_msvc" 2963 | version = "0.52.0" 2964 | source = "registry+https://github.com/rust-lang/crates.io-index" 2965 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 2966 | 2967 | [[package]] 2968 | name = "windows_i686_gnu" 2969 | version = "0.42.2" 2970 | source = "registry+https://github.com/rust-lang/crates.io-index" 2971 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 2972 | 2973 | [[package]] 2974 | name = "windows_i686_gnu" 2975 | version = "0.48.5" 2976 | source = "registry+https://github.com/rust-lang/crates.io-index" 2977 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2978 | 2979 | [[package]] 2980 | name = "windows_i686_gnu" 2981 | version = "0.52.0" 2982 | source = "registry+https://github.com/rust-lang/crates.io-index" 2983 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 2984 | 2985 | [[package]] 2986 | name = "windows_i686_msvc" 2987 | version = "0.42.2" 2988 | source = "registry+https://github.com/rust-lang/crates.io-index" 2989 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 2990 | 2991 | [[package]] 2992 | name = "windows_i686_msvc" 2993 | version = "0.48.5" 2994 | source = "registry+https://github.com/rust-lang/crates.io-index" 2995 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2996 | 2997 | [[package]] 2998 | name = "windows_i686_msvc" 2999 | version = "0.52.0" 3000 | source = "registry+https://github.com/rust-lang/crates.io-index" 3001 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 3002 | 3003 | [[package]] 3004 | name = "windows_x86_64_gnu" 3005 | version = "0.42.2" 3006 | source = "registry+https://github.com/rust-lang/crates.io-index" 3007 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 3008 | 3009 | [[package]] 3010 | name = "windows_x86_64_gnu" 3011 | version = "0.48.5" 3012 | source = "registry+https://github.com/rust-lang/crates.io-index" 3013 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 3014 | 3015 | [[package]] 3016 | name = "windows_x86_64_gnu" 3017 | version = "0.52.0" 3018 | source = "registry+https://github.com/rust-lang/crates.io-index" 3019 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 3020 | 3021 | [[package]] 3022 | name = "windows_x86_64_gnullvm" 3023 | version = "0.42.2" 3024 | source = "registry+https://github.com/rust-lang/crates.io-index" 3025 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 3026 | 3027 | [[package]] 3028 | name = "windows_x86_64_gnullvm" 3029 | version = "0.48.5" 3030 | source = "registry+https://github.com/rust-lang/crates.io-index" 3031 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 3032 | 3033 | [[package]] 3034 | name = "windows_x86_64_gnullvm" 3035 | version = "0.52.0" 3036 | source = "registry+https://github.com/rust-lang/crates.io-index" 3037 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 3038 | 3039 | [[package]] 3040 | name = "windows_x86_64_msvc" 3041 | version = "0.42.2" 3042 | source = "registry+https://github.com/rust-lang/crates.io-index" 3043 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 3044 | 3045 | [[package]] 3046 | name = "windows_x86_64_msvc" 3047 | version = "0.48.5" 3048 | source = "registry+https://github.com/rust-lang/crates.io-index" 3049 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 3050 | 3051 | [[package]] 3052 | name = "windows_x86_64_msvc" 3053 | version = "0.52.0" 3054 | source = "registry+https://github.com/rust-lang/crates.io-index" 3055 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 3056 | 3057 | [[package]] 3058 | name = "winit" 3059 | version = "0.28.7" 3060 | source = "registry+https://github.com/rust-lang/crates.io-index" 3061 | checksum = "9596d90b45384f5281384ab204224876e8e8bf7d58366d9b795ad99aa9894b94" 3062 | dependencies = [ 3063 | "android-activity", 3064 | "bitflags 1.3.2", 3065 | "cfg_aliases", 3066 | "core-foundation", 3067 | "core-graphics", 3068 | "dispatch", 3069 | "instant", 3070 | "libc", 3071 | "log", 3072 | "mio", 3073 | "ndk", 3074 | "objc2", 3075 | "once_cell", 3076 | "orbclient", 3077 | "percent-encoding", 3078 | "raw-window-handle", 3079 | "redox_syscall 0.3.5", 3080 | "sctk-adwaita", 3081 | "smithay-client-toolkit", 3082 | "wasm-bindgen", 3083 | "wayland-client", 3084 | "wayland-commons", 3085 | "wayland-protocols", 3086 | "wayland-scanner", 3087 | "web-sys", 3088 | "windows-sys 0.45.0", 3089 | "x11-dl", 3090 | ] 3091 | 3092 | [[package]] 3093 | name = "winnow" 3094 | version = "0.5.31" 3095 | source = "registry+https://github.com/rust-lang/crates.io-index" 3096 | checksum = "97a4882e6b134d6c28953a387571f1acdd3496830d5e36c5e3a1075580ea641c" 3097 | dependencies = [ 3098 | "memchr", 3099 | ] 3100 | 3101 | [[package]] 3102 | name = "x11-dl" 3103 | version = "2.21.0" 3104 | source = "registry+https://github.com/rust-lang/crates.io-index" 3105 | checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" 3106 | dependencies = [ 3107 | "libc", 3108 | "once_cell", 3109 | "pkg-config", 3110 | ] 3111 | 3112 | [[package]] 3113 | name = "x11rb" 3114 | version = "0.12.0" 3115 | source = "registry+https://github.com/rust-lang/crates.io-index" 3116 | checksum = "b1641b26d4dec61337c35a1b1aaf9e3cba8f46f0b43636c609ab0291a648040a" 3117 | dependencies = [ 3118 | "gethostname", 3119 | "nix 0.26.4", 3120 | "winapi", 3121 | "winapi-wsapoll", 3122 | "x11rb-protocol", 3123 | ] 3124 | 3125 | [[package]] 3126 | name = "x11rb-protocol" 3127 | version = "0.12.0" 3128 | source = "registry+https://github.com/rust-lang/crates.io-index" 3129 | checksum = "82d6c3f9a0fb6701fab8f6cea9b0c0bd5d6876f1f89f7fada07e558077c344bc" 3130 | dependencies = [ 3131 | "nix 0.26.4", 3132 | ] 3133 | 3134 | [[package]] 3135 | name = "xcursor" 3136 | version = "0.3.5" 3137 | source = "registry+https://github.com/rust-lang/crates.io-index" 3138 | checksum = "6a0ccd7b4a5345edfcd0c3535718a4e9ff7798ffc536bb5b5a0e26ff84732911" 3139 | 3140 | [[package]] 3141 | name = "xdg-home" 3142 | version = "1.0.0" 3143 | source = "registry+https://github.com/rust-lang/crates.io-index" 3144 | checksum = "2769203cd13a0c6015d515be729c526d041e9cf2c0cc478d57faee85f40c6dcd" 3145 | dependencies = [ 3146 | "nix 0.26.4", 3147 | "winapi", 3148 | ] 3149 | 3150 | [[package]] 3151 | name = "xml-rs" 3152 | version = "0.8.19" 3153 | source = "registry+https://github.com/rust-lang/crates.io-index" 3154 | checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" 3155 | 3156 | [[package]] 3157 | name = "zbus" 3158 | version = "3.14.1" 3159 | source = "registry+https://github.com/rust-lang/crates.io-index" 3160 | checksum = "31de390a2d872e4cd04edd71b425e29853f786dc99317ed72d73d6fcf5ebb948" 3161 | dependencies = [ 3162 | "async-broadcast", 3163 | "async-executor", 3164 | "async-fs", 3165 | "async-io 1.13.0", 3166 | "async-lock 2.8.0", 3167 | "async-process", 3168 | "async-recursion", 3169 | "async-task", 3170 | "async-trait", 3171 | "blocking", 3172 | "byteorder", 3173 | "derivative", 3174 | "enumflags2", 3175 | "event-listener 2.5.3", 3176 | "futures-core", 3177 | "futures-sink", 3178 | "futures-util", 3179 | "hex", 3180 | "nix 0.26.4", 3181 | "once_cell", 3182 | "ordered-stream", 3183 | "rand", 3184 | "serde", 3185 | "serde_repr", 3186 | "sha1", 3187 | "static_assertions", 3188 | "tracing", 3189 | "uds_windows", 3190 | "winapi", 3191 | "xdg-home", 3192 | "zbus_macros", 3193 | "zbus_names", 3194 | "zvariant", 3195 | ] 3196 | 3197 | [[package]] 3198 | name = "zbus_macros" 3199 | version = "3.14.1" 3200 | source = "registry+https://github.com/rust-lang/crates.io-index" 3201 | checksum = "41d1794a946878c0e807f55a397187c11fc7a038ba5d868e7db4f3bd7760bc9d" 3202 | dependencies = [ 3203 | "proc-macro-crate", 3204 | "proc-macro2", 3205 | "quote", 3206 | "regex", 3207 | "syn 1.0.109", 3208 | "zvariant_utils", 3209 | ] 3210 | 3211 | [[package]] 3212 | name = "zbus_names" 3213 | version = "2.6.0" 3214 | source = "registry+https://github.com/rust-lang/crates.io-index" 3215 | checksum = "fb80bb776dbda6e23d705cf0123c3b95df99c4ebeaec6c2599d4a5419902b4a9" 3216 | dependencies = [ 3217 | "serde", 3218 | "static_assertions", 3219 | "zvariant", 3220 | ] 3221 | 3222 | [[package]] 3223 | name = "zerocopy" 3224 | version = "0.7.32" 3225 | source = "registry+https://github.com/rust-lang/crates.io-index" 3226 | checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" 3227 | dependencies = [ 3228 | "zerocopy-derive", 3229 | ] 3230 | 3231 | [[package]] 3232 | name = "zerocopy-derive" 3233 | version = "0.7.32" 3234 | source = "registry+https://github.com/rust-lang/crates.io-index" 3235 | checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" 3236 | dependencies = [ 3237 | "proc-macro2", 3238 | "quote", 3239 | "syn 2.0.43", 3240 | ] 3241 | 3242 | [[package]] 3243 | name = "zvariant" 3244 | version = "3.15.0" 3245 | source = "registry+https://github.com/rust-lang/crates.io-index" 3246 | checksum = "44b291bee0d960c53170780af148dca5fa260a63cdd24f1962fa82e03e53338c" 3247 | dependencies = [ 3248 | "byteorder", 3249 | "enumflags2", 3250 | "libc", 3251 | "serde", 3252 | "static_assertions", 3253 | "zvariant_derive", 3254 | ] 3255 | 3256 | [[package]] 3257 | name = "zvariant_derive" 3258 | version = "3.15.0" 3259 | source = "registry+https://github.com/rust-lang/crates.io-index" 3260 | checksum = "934d7a7dfc310d6ee06c87ffe88ef4eca7d3e37bb251dece2ef93da8f17d8ecd" 3261 | dependencies = [ 3262 | "proc-macro-crate", 3263 | "proc-macro2", 3264 | "quote", 3265 | "syn 1.0.109", 3266 | "zvariant_utils", 3267 | ] 3268 | 3269 | [[package]] 3270 | name = "zvariant_utils" 3271 | version = "1.0.1" 3272 | source = "registry+https://github.com/rust-lang/crates.io-index" 3273 | checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" 3274 | dependencies = [ 3275 | "proc-macro2", 3276 | "quote", 3277 | "syn 1.0.109", 3278 | ] 3279 | --------------------------------------------------------------------------------