diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 8001af650..7e5cfe5fa 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -27,22 +27,30 @@ on: - lib.rs - Cargo.toml +# workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true +env: + CARGO_TERM_COLOR: always + CARGO_INCREMENTAL: "0" + jobs: check: if: github.event.pull_request.draft == false name: Check runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 + - run: sudo apt-get update + - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + save-if: ${{ github.ref == 'refs/heads/master' }} - uses: ilammy/setup-nasm@v1 - - run: sudo apt-get update - - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev - - uses: actions/checkout@v4 - run: cargo check --all --examples --tests test: @@ -50,15 +58,24 @@ jobs: name: Test Suite runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 + - run: sudo apt-get update + - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + save-if: ${{ github.ref == 'refs/heads/master' }} - uses: ilammy/setup-nasm@v1 - - run: sudo apt-get update - - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev - uses: davidB/rust-cargo-make@v1 - uses: browser-actions/setup-firefox@latest - uses: jetli/wasm-pack-action@v0.4.0 - - uses: actions/checkout@v4 + - run: sudo rm -rf /usr/share/dotnet + - run: sudo rm -rf "$AGENT_TOOLSDIRECTORY" + - run: | + df -h + sudo rm -rf ${GITHUB_WORKSPACE}/.git + df -h - run: cargo make tests fmt: @@ -66,11 +83,15 @@ jobs: name: Rustfmt runs-on: ubuntu-latest steps: - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - - uses: ilammy/setup-nasm@v1 - - run: rustup component add rustfmt - uses: actions/checkout@v4 + - uses: ilammy/setup-nasm@v1 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt + - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + save-if: ${{ github.ref == 'refs/heads/master' }} - run: cargo fmt --all -- --check clippy: @@ -78,17 +99,104 @@ jobs: name: Clippy runs-on: ubuntu-latest steps: - - uses: dtolnay/rust-toolchain@stable - - uses: Swatinem/rust-cache@v2 - - uses: ilammy/setup-nasm@v1 + - uses: actions/checkout@v4 - run: sudo apt-get update - run: sudo apt install libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev - - run: rustup component add clippy - - uses: actions/checkout@v4 + - uses: ilammy/setup-nasm@v1 + - uses: dtolnay/rust-toolchain@stable + with: + components: rustfmt, clippy + - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + save-if: ${{ github.ref == 'refs/heads/master' }} - run: cargo clippy --workspace --examples --tests -- -D warnings + miri: + if: github.event.pull_request.draft == false + name: Miri + runs-on: ubuntu-latest + env: + CARGO_UNSTABLE_SPARSE_REGISTRY: 'true' + RUSTFLAGS: -Dwarnings + RUST_BACKTRACE: 1 + MIRIFLAGS: -Zmiri-tag-gc=1 + # Change to specific Rust release to pin + rust_stable: stable + rust_nightly: nightly-2023-11-16 + rust_clippy: 1.70.0 + + steps: + - uses: actions/checkout@v4 + - uses: ilammy/setup-nasm@v1 + - name: Install Rust ${{ env.rust_nightly }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.rust_nightly }} + components: miri + - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + save-if: ${{ github.ref == 'refs/heads/master' }} + - name: miri + # Many of tests in tokio/tests and doctests use #[tokio::test] or + # #[tokio::main] that calls epoll_create1 that Miri does not support. + # run: cargo miri test --features full --lib --no-fail-fast + run: | + cargo miri test --package dioxus-core -- --exact --nocapture + cargo miri test --package dioxus-native-core --test miri_native -- --exact --nocapture + env: + MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-retag-fields + PROPTEST_CASES: 10 + + playwright: + if: github.event.pull_request.draft == false + name: Playwright Tests + runs-on: ubuntu-latest + steps: + # Do our best to cache the toolchain and node install steps + - uses: actions/checkout@v4 + - uses: ilammy/setup-nasm@v1 + - uses: actions/setup-node@v4 + with: + node-version: 16 + - name: Install Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + targets: x86_64-unknown-linux-gnu,wasm32-unknown-unknown + - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + save-if: ${{ github.ref == 'refs/heads/master' }} + + - name: Install dependencies + run: npm ci + working-directory: ./playwright-tests + + - name: Install Playwright + run: npm install -D @playwright/test + working-directory: ./playwright-tests + + - name: Install Playwright Browsers + run: npx playwright install --with-deps + working-directory: ./playwright-tests + + - name: Run Playwright tests + run: npx playwright test + working-directory: ./playwright-tests + + - uses: actions/upload-artifact@v4 + if: always() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 + + matrix_test: runs-on: ${{ matrix.platform.os }} + if: github.event.pull_request.draft == false env: RUST_CARGO_COMMAND: ${{ matrix.platform.cross == true && 'cross' || 'cargo' }} strategy: @@ -135,20 +243,18 @@ jobs: with: toolchain: ${{ matrix.platform.toolchain }} targets: ${{ matrix.platform.target }} + components: rustfmt - name: Install cross if: ${{ matrix.platform.cross == true }} + uses: taiki-e/install-action@cross - uses: Swatinem/rust-cache@v2 with: - workspaces: core -> ../target - save-if: ${{ matrix.features.key == 'all' }} - - - name: Install rustfmt - run: rustup component add rustfmt - - - uses: actions/checkout@v4 + key: "${{ matrix.platform.target }}" + cache-all-crates: "true" + save-if: ${{ github.ref == 'refs/heads/master' }} - name: test run: | diff --git a/.github/workflows/miri.yml b/.github/workflows/miri.yml deleted file mode 100644 index 6c8a260b3..000000000 --- a/.github/workflows/miri.yml +++ /dev/null @@ -1,133 +0,0 @@ -name: Miri Tests - -on: - push: - # Run in PRs and for bors, but not on master. - branches: - - 'auto' - - 'try' - paths: - - packages/** - - examples/** - - src/** - - .github/** - - lib.rs - - Cargo.toml - pull_request: - types: [opened, synchronize, reopened, ready_for_review] - branches: - - 'master' - schedule: - - cron: '6 6 * * *' # At 6:06 UTC every day. - -env: - CARGO_UNSTABLE_SPARSE_REGISTRY: 'true' - RUSTFLAGS: -Dwarnings - RUST_BACKTRACE: 1 - # Change to specific Rust release to pin - rust_stable: stable - rust_nightly: nightly-2023-11-16 - rust_clippy: 1.70.0 - # When updating this, also update: - # - README.md - # - tokio/README.md - # - CONTRIBUTING.md - # - tokio/Cargo.toml - # - tokio-util/Cargo.toml - # - tokio-test/Cargo.toml - # - tokio-stream/Cargo.toml - # rust_min: 1.49.0 - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -jobs: - test: - runs-on: ${{ matrix.os }} - env: - RUST_BACKTRACE: 1 - HOST_TARGET: ${{ matrix.host_target }} - strategy: - fail-fast: false - matrix: - include: - - os: ubuntu-latest - host_target: x86_64-unknown-linux-gnu - # - os: macos-latest - # host_target: x86_64-apple-darwin - # - os: windows-latest - # host_target: i686-pc-windows-msvc - # - os: windows-latest - # host_target: i686-pc-windows-msvc - # - os: windows-latest - # host_target: i686-pc-windows-msvc - # - os: windows-latest - # host_target: i686-pc-windows-msvc - steps: - - name: Set the tag GC interval to 1 on linux - if: runner.os == 'Linux' - run: echo "MIRIFLAGS=-Zmiri-tag-gc=1" >> $GITHUB_ENV - - - uses: actions/checkout@v4 - - uses: ilammy/setup-nasm@v1 - - name: Install Rust ${{ env.rust_nightly }} - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.rust_nightly }} - components: miri - - uses: Swatinem/rust-cache@v2 - - name: miri - # Many of tests in tokio/tests and doctests use #[tokio::test] or - # #[tokio::main] that calls epoll_create1 that Miri does not support. - # run: cargo miri test --features full --lib --no-fail-fast - run: | - cargo miri test --package dioxus-core -- --exact --nocapture - cargo miri test --package dioxus-native-core --test miri_native -- --exact --nocapture - - # working-directory: tokio - env: - MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-retag-fields - PROPTEST_CASES: 10 - - # Cache the global cargo directory, but NOT the local `target` directory which - # we cannot reuse anyway when the nightly changes (and it grows quite large - # over time). - # - name: Add cache for cargo - # id: cache - # uses: actions/cache@v3 - # with: - # path: | - # # Taken from . - # ~/.cargo/bin - # ~/.cargo/registry/index - # ~/.cargo/registry/cache - # ~/.cargo/git/db - # # contains package information of crates installed via `cargo install`. - # ~/.cargo/.crates.toml - # ~/.cargo/.crates2.json - # key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - # restore-keys: ${{ runner.os }}-cargo - - # - name: Install rustup-toolchain-install-master - # if: ${{ steps.cache.outputs.cache-hit != 'true' }} - # shell: bash - # run: | - # cargo install -f rustup-toolchain-install-master - # - name: Install "master" toolchain - # shell: bash - # run: | - # if [[ ${{ github.event_name }} == 'schedule' ]]; then - # echo "Building against latest rustc git version" - # git ls-remote https://github.com/rust-lang/rust/ HEAD | cut -f 1 > rust-version - # fi - # toolchain --host ${{ matrix.host_target }} - # - name: Show Rust version - # run: | - # rustup show - # rustc -Vv - # cargo -V - # - name: Test - # run: | - # MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-ignore-leaks" cargo +nightly miri test --package dioxus-core --test miri_stress -- --exact --nocapture - # MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-ignore-leaks" cargo +nightly miri test --package dioxus-native-core --test miri_native -- --exact --nocapture diff --git a/.github/workflows/playwright.yml b/.github/workflows/playwright.yml deleted file mode 100644 index 6b1b5acf0..000000000 --- a/.github/workflows/playwright.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Playwright Tests -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] -defaults: - run: - working-directory: ./playwright-tests - -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} - cancel-in-progress: true - -jobs: - test: - if: github.event.pull_request.draft == false - timeout-minutes: 60 - runs-on: ubuntu-latest - steps: - # Do our best to cache the toolchain and node install steps - - uses: actions/checkout@v4 - - uses: ilammy/setup-nasm@v1 - - uses: actions/setup-node@v4 - with: - node-version: 16 - - name: Install Rust - uses: dtolnay/rust-toolchain@master - with: - toolchain: stable - targets: x86_64-unknown-linux-gnu,wasm32-unknown-unknown - - uses: Swatinem/rust-cache@v2 - - name: Install dependencies - run: npm ci - - name: Install Playwright - run: npm install -D @playwright/test - - name: Install Playwright Browsers - run: npx playwright install --with-deps - # Cache the CLI by using cargo run internally - # - name: Install Dioxus CLI - # uses: actions-rs/cargo@v1 - # with: - # command: install - # args: --path packages/cli - - name: Run Playwright tests - run: npx playwright test - - uses: actions/upload-artifact@v4 - if: always() - with: - name: playwright-report - path: playwright-report/ - retention-days: 30 diff --git a/.github/workflows/wipe_cache.yml b/.github/workflows/wipe_cache.yml new file mode 100644 index 000000000..2ecced4af --- /dev/null +++ b/.github/workflows/wipe_cache.yml @@ -0,0 +1,37 @@ +name: Clear cache + +on: + workflow_dispatch: + +permissions: + actions: write + +jobs: + clear-cache: + runs-on: ubuntu-latest + steps: + - name: Clear cache + uses: actions/github-script@v6 + with: + github-token: ${{ secrets.cache_controller }} + script: | + console.log("About to clear") + + while (true) { + const caches = await github.rest.actions.getActionsCacheList({ + owner: context.repo.owner, + repo: context.repo.repo + }) + if (caches.data.actions_caches.length === 0) { + break + } + for (const cache of caches.data.actions_caches) { + console.log(cache) + github.rest.actions.deleteActionsCacheById({ + owner: context.repo.owner, + repo: context.repo.repo, + cache_id: cache.id, + }) + } + } + console.log("Clear completed") diff --git a/.gitignore b/.gitignore index 364e8d0fb..da3dfceb6 100644 --- a/.gitignore +++ b/.gitignore @@ -2,10 +2,12 @@ /playwright-tests/web/dist /playwright-tests/fullstack/dist /dist -Cargo.lock .DS_Store /examples/assets/test_video.mp4 +# new recommendation to keep the lockfile in for CI and reproducible builds +# Cargo.lock + .vscode/* !.vscode/settings.json !.vscode/tasks.json diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 000000000..e26164bba --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,12337 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli 0.28.1", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array 0.14.7", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom 0.2.12", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "const-random", + "getrandom 0.2.12", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +dependencies = [ + "memchr", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "aligned" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80a21b9440a626c7fc8573a9e3d3a06b75c7c97754c2949bc7857b90353ca655" +dependencies = [ + "as-slice", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstream" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" + +[[package]] +name = "anymap" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344" + +[[package]] +name = "anymap" +version = "1.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1f8f5a6f3d50d89e3797d7593a50f96bb2aaa20ca0cc7be1fb673232c91d72" + +[[package]] +name = "anymap2" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" + +[[package]] +name = "ar" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d67af77d68a931ecd5cbd8a3b5987d63a1d1d1278f7f6a60ae33db485cdebb69" + +[[package]] +name = "arbitrary" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db55d72333851e17d572bec876e390cd3b11eb1ef53ae821dd9f3b653d2b4569" + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" + +[[package]] +name = "arc-swap" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" + +[[package]] +name = "arg_enum_proc_macro" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "argh" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7af5ba06967ff7214ce4c7419c7d185be7ecd6cc4965a8f6e1d8ce0398aad219" +dependencies = [ + "argh_derive", + "argh_shared", +] + +[[package]] +name = "argh_derive" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56df0aeedf6b7a2fc67d06db35b09684c3e8da0c95f8f27685cb17e08413d87a" +dependencies = [ + "argh_shared", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "argh_shared" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5693f39141bda5760ecc4111ab08da40565d1771038c4a0250f03457ec707531" +dependencies = [ + "serde", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +dependencies = [ + "serde", +] + +[[package]] +name = "as-slice" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516b6b4f0e40d50dcda9365d53964ec74560ad4284da2e7fc97122cd83174516" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "askama_escape" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" + +[[package]] +name = "async-broadcast" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" +dependencies = [ + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +dependencies = [ + "concurrent-queue", + "event-listener 4.0.3", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-compression" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a" +dependencies = [ + "brotli", + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-compression" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc2d0cfb2a7388d34f590e76686704c494ed7aaceed62ee1ba35cbf363abc2a5" +dependencies = [ + "flate2", + "futures-core", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-executor" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +dependencies = [ + "async-lock 3.3.0", + "async-task", + "concurrent-queue", + "fastrand 2.0.1", + "futures-lite 2.2.0", + "slab", +] + +[[package]] +name = "async-fs" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "blocking", + "futures-lite 1.13.0", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite 1.13.0", + "log", + "parking", + "polling 2.8.0", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-io" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +dependencies = [ + "async-lock 3.3.0", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite 2.2.0", + "parking", + "polling 3.3.1", + "rustix 0.38.28", + "slab", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-process" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +dependencies = [ + "async-io 1.13.0", + "async-lock 2.8.0", + "async-signal", + "blocking", + "cfg-if", + "event-listener 3.1.0", + "futures-lite 1.13.0", + "rustix 0.38.28", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-recursion" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "async-signal" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +dependencies = [ + "async-io 2.2.2", + "async-lock 2.8.0", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 0.38.28", + "signal-hook-registry", + "slab", + "windows-sys 0.48.0", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "async-task" +version = "4.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbb36e985947064623dbd357f727af08ffd077f93d696782f3c56365fa2e2799" + +[[package]] +name = "async-trait" +version = "0.1.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "atk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4af014b17dd80e8af9fa689b2d4a211ddba6eb583c1622f35d0cb543f6b17e4" +dependencies = [ + "atk-sys", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "251e0b7d90e33e0ba930891a505a9a35ece37b2dd37a14f3ffc306c13b980009" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atomic" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" + +[[package]] +name = "atomic" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atomic-write-file" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" +dependencies = [ + "nix 0.27.1", + "rand 0.8.5", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "auth-git2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41e7771d4ab6635cbd685ce8db215b29c78a468098126de77c57f3b2e6eb3757" +dependencies = [ + "dirs 5.0.1", + "git2", + "terminal-prompt", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "av1-grain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6678909d8c5d46a42abcf571271e15fdbc0a225e3646cf23762cd415046c78bf" +dependencies = [ + "anyhow", + "arrayvec", + "log", + "nom", + "num-rational", + "serde", + "v_frame", +] + +[[package]] +name = "avif-serialize" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876c75a42f6364451a033496a14c44bffe41f5f4a8236f697391f11024e596d2" +dependencies = [ + "arrayvec", +] + +[[package]] +name = "axum" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acee9fd5073ab6b045a275b3e709c163dd36c90685219cb21804a147b58dba43" +dependencies = [ + "async-trait", + "axum-core 0.2.9", + "base64 0.13.1", + "bitflags 1.3.2", + "bytes", + "futures-util", + "headers 0.3.9", + "http 0.2.11", + "http-body 0.4.6", + "hyper 0.14.28", + "itoa 1.0.10", + "matchit 0.5.0", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sha-1", + "sync_wrapper", + "tokio", + "tokio-tungstenite 0.17.2", + "tower", + "tower-http 0.3.5", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core 0.3.4", + "axum-macros", + "base64 0.21.6", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http 0.2.11", + "http-body 0.4.6", + "hyper 0.14.28", + "itoa 1.0.10", + "matchit 0.7.3", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sha1", + "sync_wrapper", + "tokio", + "tokio-tungstenite 0.20.1", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-auth" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "axum 0.6.20", + "axum_session", + "axum_session_auth", + "dioxus", + "dioxus-fullstack", + "dioxus-web", + "execute", + "http 0.2.11", + "serde", + "simple_logger", + "sqlx", + "tokio", + "tower", + "tower-http 0.4.4", +] + +[[package]] +name = "axum-core" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37e5939e02c56fecd5c017c37df4238c0a839fa76b7f97acdd7efb804fd181cc" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 0.2.11", + "http-body 0.4.6", + "mime", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http 0.2.11", + "http-body 0.4.6", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-desktop" +version = "0.1.0" +dependencies = [ + "axum 0.6.20", + "dioxus", + "dioxus-desktop", + "dioxus-fullstack", + "dioxus-router", + "serde", + "tokio", +] + +[[package]] +name = "axum-hello-world" +version = "0.1.0" +dependencies = [ + "dioxus", + "dioxus-fullstack", + "reqwest", + "serde", + "simple_logger", + "tracing", + "tracing-subscriber", + "tracing-wasm", +] + +[[package]] +name = "axum-macros" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdca6a10ecad987bda04e95606ef85a5417dcaac1a78455242d72e031e2b6b62" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "axum-router" +version = "0.1.0" +dependencies = [ + "axum 0.6.20", + "dioxus", + "dioxus-fullstack", + "dioxus-router", + "dioxus-web", + "serde", + "tokio", +] + +[[package]] +name = "axum-server" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447f28c85900215cc1bea282f32d4a2f22d55c5a300afdfbc661c8d6a632e063" +dependencies = [ + "arc-swap", + "bytes", + "futures-util", + "http 0.2.11", + "http-body 0.4.6", + "hyper 0.14.28", + "pin-project-lite", + "rustls 0.21.10", + "rustls-pemfile", + "tokio", + "tokio-rustls 0.24.1", + "tower-service", +] + +[[package]] +name = "axum_session" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b9a35d2907b706dcd52f875c4f9fe55293ebc03fc5b3c2d8883104c821452b8" +dependencies = [ + "aes-gcm", + "async-trait", + "axum-core 0.3.4", + "base64 0.21.6", + "bytes", + "chrono", + "cookie 0.17.0", + "dashmap", + "futures", + "http 0.2.11", + "http-body 0.4.6", + "rand 0.8.5", + "serde", + "serde_json", + "sqlx", + "thiserror", + "tokio", + "tower-layer", + "tower-service", + "tracing", + "uuid", +] + +[[package]] +name = "axum_session_auth" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d26b395b86d34230970c09fee81cad335704d5b6b797714a9ebb8a51cc4fa6" +dependencies = [ + "anyhow", + "async-recursion", + "async-trait", + "axum-core 0.3.4", + "axum_session", + "bytes", + "chrono", + "dashmap", + "futures", + "http 0.2.11", + "http-body 0.4.6", + "serde", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" +dependencies = [ + "byteorder", + "safemem", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c79fed4cdb43e993fcdadc7e58a09fd0e3e649c4436fa11da71c9f1f3ee7feb9" + +[[package]] +name = "base64-simd" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "781dd20c3aff0bd194fe7d2a977dd92f21c173891f3a03b677359e5fa457e5d5" +dependencies = [ + "simd-abstraction", +] + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "basic-toml" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" +dependencies = [ + "serde", +] + +[[package]] +name = "bigdecimal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "binascii" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bit_field" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +dependencies = [ + "serde", +] + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "bitstream-io" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e445576659fd04a57b44cbd00aa37aaa815ebefa0aa3cb677a6b5e63d883074f" + +[[package]] +name = "bitstream-io" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06c9989a51171e2e81038ab168b6ae22886fe9ded214430dbb4f41c28cf176da" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "blocking" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +dependencies = [ + "async-channel 2.1.1", + "async-lock 3.3.0", + "async-task", + "fastrand 2.0.1", + "futures-io", + "futures-lite 2.2.0", + "piper", + "tracing", +] + +[[package]] +name = "borsh" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d4d6dafc1a3bb54687538972158f07b2c948bc57d5890df22c0739098b3028" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4918709cc4dd777ad2b6303ed03cb37f3ca0ccede8c1b0d28ac6db8f4710e0" +dependencies = [ + "once_cell", + "proc-macro-crate 2.0.1", + "proc-macro2", + "quote", + "syn 2.0.48", + "syn_derive", +] + +[[package]] +name = "brotli" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bstr" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223" +dependencies = [ + "memchr", +] + +[[package]] +name = "bstr" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" +dependencies = [ + "memchr", + "regex-automata 0.4.3", + "serde", +] + +[[package]] +name = "btoi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd6407f73a9b8b6162d8a2ef999fe6afd7cc15902ebf42c5cd296addf17e0ad" +dependencies = [ + "num-traits", +] + +[[package]] +name = "built" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9c056b9ed43aee5e064b683aa1ec783e19c6acec7559e3ae931b7490472fbe" +dependencies = [ + "cargo-lock 8.0.3", +] + +[[package]] +name = "built" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d17f4d6e4dc36d1a02fbedc2753a096848e7c1b0772f7654eab8e2c927dd53" + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytecheck" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytemuck" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "cairo-rs" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +dependencies = [ + "bitflags 2.4.1", + "cairo-sys-rs", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-generate" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a2885ae054e000b117515ab33e91c10eca90c2788a7baec1b97ada1f1f51e57" +dependencies = [ + "anyhow", + "auth-git2", + "clap 4.4.14", + "console", + "dialoguer", + "env_logger", + "fs-err", + "git2", + "gix-config", + "heck 0.4.1", + "home", + "ignore", + "indexmap 2.1.0", + "indicatif", + "liquid", + "liquid-core", + "liquid-derive", + "liquid-lib", + "log", + "names", + "paste", + "path-absolutize", + "regex", + "remove_dir_all", + "rhai", + "sanitize-filename", + "semver", + "serde", + "tempfile", + "thiserror", + "toml 0.8.2", + "walkdir", +] + +[[package]] +name = "cargo-lock" +version = "8.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031718ddb8f78aa5def78a09e90defe30151d1f6c672f937af4dd916429ed996" +dependencies = [ + "semver", + "serde", + "toml 0.5.11", + "url", +] + +[[package]] +name = "cargo-lock" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e11c675378efb449ed3ce8de78d75d0d80542fc98487c26aba28eb3b82feac72" +dependencies = [ + "petgraph", + "semver", + "serde", + "toml 0.7.8", + "url", +] + +[[package]] +name = "cargo-platform" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cargo_metadata" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7daec1a2a2129eeba1644b220b4647ec537b0b5d4bfd6876fcc5a540056b592" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cargo_toml" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3f9629bc6c4388ea699781dc988c2b99766d7679b151c81990b4fa1208fafd3" +dependencies = [ + "serde", + "toml 0.8.2", +] + +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bbc13bf6290a6b202cc3efb36f7ec2b739a80634215630c8053a313edf6abef" +dependencies = [ + "smallvec", +] + +[[package]] +name = "cfg-expr" +version = "0.15.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6100bc57b6209840798d95cb2775684849d332f7bd788db2a8c8caf7ef82a41a" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "chrono" +version = "0.4.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.48.5", +] + +[[package]] +name = "ciborium" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" + +[[package]] +name = "ciborium-ll" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +dependencies = [ + "ciborium-io", + "half 1.8.2", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "bitflags 1.3.2", + "textwrap", + "unicode-width", +] + +[[package]] +name = "clap" +version = "4.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e92c5c1a78c62968ec57dbc2440366a2d6e5a23faf829970ff1585dc6b18e2" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4323769dc8a61e2c39ad7dc26f6f2800524691a44d74fe3d1071a5c24db6370" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "closure" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6173fd61b610d15a7566dd7b7620775627441c4ab9dac8906e17cb93a24b782" + +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types 0.5.0", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation", + "core-graphics-types", + "libc", + "objc", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "colored" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f741c91823341bebf717d4c71bda820630ce065443b58bd1b7451af008355" +dependencies = [ + "is-terminal", + "lazy_static", + "winapi", +] + +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const-random" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aaf16c9c2c612020bcfd042e170f6e32de9b9d75adb5277cdbbd2e2c8c8299a" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom 0.2.12", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "const-str" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21077772762a1002bb421c3af42ac1725fa56066bfc53d9a55bb79905df2aaf3" +dependencies = [ + "const-str-proc-macro", +] + +[[package]] +name = "const-str-proc-macro" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1e0fdd2e5d3041e530e1b21158aeeef8b5d0e306bc5c1e3d6cf0930d10e25a" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "constcat" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd7e35aee659887cbfb97aaf227ac12cad1a9d7c71e55ff3376839ed4e282d08" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "cookie" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" +dependencies = [ + "aes-gcm", + "base64 0.21.6", + "percent-encoding", + "rand 0.8.5", + "subtle", + "time", + "version_check", +] + +[[package]] +name = "cookie" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8" +dependencies = [ + "aes-gcm", + "base64 0.21.6", + "hmac", + "percent-encoding", + "rand 0.8.5", + "sha2", + "subtle", + "time", + "version_check", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "core-graphics" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "criterion" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f" +dependencies = [ + "atty", + "cast", + "clap 2.34.0", + "criterion-plot 0.4.5", + "csv", + "itertools 0.10.5", + "lazy_static", + "num-traits", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_cbor", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", +] + +[[package]] +name = "criterion" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" +dependencies = [ + "anes", + "cast", + "ciborium", + "clap 4.4.14", + "criterion-plot 0.5.0", + "futures", + "is-terminal", + "itertools 0.10.5", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "tokio", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" +dependencies = [ + "cast", + "itertools 0.10.5", +] + +[[package]] +name = "criterion-plot" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" +dependencies = [ + "cast", + "itertools 0.10.5", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crossterm" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" +dependencies = [ + "bitflags 1.3.2", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.4.1", + "crossterm_winapi", + "libc", + "mio", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "cruet" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6132609543972496bc97b1e01f1ce6586768870aeb4cabeb3385f4e05b5caead" +dependencies = [ + "once_cell", + "regex", +] + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf 0.8.0", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser" +version = "0.29.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 1.0.10", + "matches", + "phf 0.10.1", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be934d936a0fbed5bcdc01042b770de1398bf79d0e192f49fa7faea0e99281e" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 1.0.10", + "phf 0.11.2", + "smallvec", +] + +[[package]] +name = "cssparser-color" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556c099a61d85989d7af52b692e35a8d68a57e7df8c6d07563dc0778b3960c9f" +dependencies = [ + "cssparser 0.33.0", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.48", +] + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa 1.0.10", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "ctor" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e" +dependencies = [ + "quote", + "syn 2.0.48", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "ctrlc" +version = "3.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b" +dependencies = [ + "nix 0.27.1", + "windows-sys 0.52.0", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "cvt" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ae9bf77fbf2d39ef573205d554d87e86c12f1994e9ea335b0651b9b278bcf1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.48", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + +[[package]] +name = "data-url" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a30bfce702bcfa94e906ef82421f2c0e61c076ad76030c16ee5d2e9a32fe193" +dependencies = [ + "matches", +] + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "devise" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6eacefd3f541c66fc61433d65e54e0e46e0a029a819a7dbbc7a7b489e8a85f8" +dependencies = [ + "devise_codegen", + "devise_core", +] + +[[package]] +name = "devise_codegen" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8cf4b8dd484ede80fd5c547592c46c3745a617c8af278e2b72bea86b2dfed6" +dependencies = [ + "devise_core", + "quote", +] + +[[package]] +name = "devise_core" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a" +dependencies = [ + "bitflags 2.4.1", + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "dialoguer" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de" +dependencies = [ + "console", + "shell-words", + "tempfile", + "thiserror", + "zeroize", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dioxus" +version = "0.4.3" +dependencies = [ + "criterion 0.3.6", + "dioxus-core", + "dioxus-core-macro", + "dioxus-hooks", + "dioxus-hot-reload", + "dioxus-html", + "dioxus-rsx", + "dioxus-signals", + "env_logger", + "futures-util", + "rand 0.8.5", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "dioxus-autofmt" +version = "0.4.3" +dependencies = [ + "dioxus-rsx", + "prettier-please", + "pretty_assertions", + "proc-macro2", + "quote", + "serde", + "syn 2.0.48", +] + +[[package]] +name = "dioxus-check" +version = "0.4.3" +dependencies = [ + "indoc", + "owo-colors", + "pretty_assertions", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "dioxus-cli" +version = "0.4.3" +dependencies = [ + "anyhow", + "atty", + "axum 0.5.17", + "axum-server", + "cargo-generate", + "cargo_metadata 0.15.4", + "cargo_toml", + "chrono", + "clap 4.4.14", + "colored 2.1.0", + "ctrlc", + "dioxus-autofmt", + "dioxus-check", + "dioxus-cli-config", + "dioxus-core", + "dioxus-hot-reload", + "dioxus-html", + "dioxus-rsx", + "dirs 4.0.0", + "fern", + "flate2", + "fs_extra", + "futures", + "gitignore", + "headers 0.3.9", + "html_parser", + "hyper 0.14.28", + "hyper-rustls 0.23.2", + "indicatif", + "interprocess-docfix", + "lazy_static", + "log", + "manganis-cli-support", + "mlua", + "notify", + "open", + "reqwest", + "rsx-rosetta", + "serde", + "serde_json", + "subprocess", + "syn 2.0.48", + "tar", + "tauri-bundler", + "tauri-utils", + "tempfile", + "thiserror", + "tokio", + "toml 0.5.11", + "toml_edit 0.19.15", + "tower", + "tower-http 0.2.5", + "walkdir", + "wasm-bindgen-cli-support", + "zip", +] + +[[package]] +name = "dioxus-cli-config" +version = "0.4.1" +dependencies = [ + "cargo_toml", + "clap 4.4.14", + "once_cell", + "serde", + "serde_json", + "tauri-bundler", + "tauri-utils", + "toml 0.5.11", + "tracing", +] + +[[package]] +name = "dioxus-core" +version = "0.4.3" +dependencies = [ + "dioxus", + "dioxus-core", + "dioxus-html", + "dioxus-ssr", + "futures-channel", + "futures-util", + "longest-increasing-subsequence", + "pretty_assertions", + "rand 0.8.5", + "rustc-hash", + "serde", + "slab", + "smallbox", + "tokio", + "tracing", +] + +[[package]] +name = "dioxus-core-macro" +version = "0.4.3" +dependencies = [ + "constcat", + "convert_case 0.6.0", + "dioxus", + "dioxus-rsx", + "prettyplease", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.48", + "trybuild", +] + +[[package]] +name = "dioxus-debug-cell" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ea539174bb236e0e7dc9c12b19b88eae3cb574dedbd0252a2d43ea7e6de13e2" + +[[package]] +name = "dioxus-desktop" +version = "0.4.3" +dependencies = [ + "async-trait", + "core-foundation", + "crossbeam-channel", + "dioxus", + "dioxus-cli-config", + "dioxus-core", + "dioxus-core-macro", + "dioxus-hooks", + "dioxus-hot-reload", + "dioxus-html", + "dioxus-interpreter-js", + "dunce", + "exitcode", + "futures-channel", + "futures-util", + "global-hotkey", + "infer 0.11.0", + "minify-js", + "muda", + "objc", + "objc_id", + "rfd", + "rustc-hash", + "scraper", + "serde", + "serde_json", + "slab", + "tao", + "thiserror", + "tokio", + "tracing", + "urlencoding", + "webbrowser", + "wry", +] + +[[package]] +name = "dioxus-examples" +version = "0.4.3" +dependencies = [ + "anyhow", + "dioxus", + "dioxus-desktop", + "dioxus-router", + "dioxus-signals", + "dioxus-ssr", + "env_logger", + "fermi", + "futures-util", + "http-range", + "im-rc", + "log", + "manganis", + "num-format", + "rand 0.8.5", + "reqwest", + "separator", + "serde", + "serde_json", + "simple_logger", + "thiserror", + "tokio", + "tracing-subscriber", +] + +[[package]] +name = "dioxus-ext" +version = "0.1.0" +dependencies = [ + "dioxus-autofmt", + "html_parser", + "rsx-rosetta", + "wasm-bindgen", +] + +[[package]] +name = "dioxus-fullstack" +version = "0.4.3" +dependencies = [ + "anymap 0.12.1", + "async-trait", + "axum 0.6.20", + "base64 0.21.6", + "bytes", + "ciborium", + "dioxus", + "dioxus-desktop", + "dioxus-hot-reload", + "dioxus-router", + "dioxus-ssr", + "dioxus-web", + "dioxus_server_macro", + "futures-util", + "http 0.2.11", + "http-body-util", + "hyper 0.14.28", + "once_cell", + "pin-project", + "salvo", + "serde", + "serde_json", + "server_fn", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-http 0.4.4", + "tower-layer", + "tracing", + "tracing-futures", + "warp", + "web-sys", +] + +[[package]] +name = "dioxus-hooks" +version = "0.4.3" +dependencies = [ + "dioxus", + "dioxus-core", + "dioxus-debug-cell", + "futures-channel", + "futures-util", + "slab", + "thiserror", + "tracing", + "web-sys", +] + +[[package]] +name = "dioxus-hot-reload" +version = "0.4.3" +dependencies = [ + "chrono", + "dioxus-core", + "dioxus-html", + "dioxus-rsx", + "execute", + "ignore", + "interprocess-docfix", + "notify", + "once_cell", + "serde", + "serde_json", +] + +[[package]] +name = "dioxus-html" +version = "0.4.3" +dependencies = [ + "async-channel 1.9.0", + "async-trait", + "dioxus-core", + "dioxus-html-internal-macro", + "dioxus-rsx", + "enumset", + "euclid", + "keyboard-types", + "rfd", + "serde", + "serde-value", + "serde_json", + "serde_repr", + "tokio", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "dioxus-html-internal-macro" +version = "0.4.3" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2", + "quote", + "syn 2.0.48", + "trybuild", +] + +[[package]] +name = "dioxus-interpreter-js" +version = "0.4.3" +dependencies = [ + "dioxus-core", + "dioxus-html", + "js-sys", + "serde", + "sledgehammer_bindgen", + "sledgehammer_utils", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "dioxus-liveview" +version = "0.4.3" +dependencies = [ + "async-trait", + "axum 0.6.20", + "dioxus", + "dioxus-core", + "dioxus-hot-reload", + "dioxus-html", + "dioxus-interpreter-js", + "futures-channel", + "futures-util", + "minify-js", + "once_cell", + "pretty_env_logger", + "rocket", + "rocket_ws", + "rustc-hash", + "salvo", + "serde", + "serde_json", + "slab", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tracing", + "warp", +] + +[[package]] +name = "dioxus-logger" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7cbab0b5519060fe9e14b3c21e3f2329b8386cd905618f78c7b929cd00cf54" +dependencies = [ + "log", + "web-sys", +] + +[[package]] +name = "dioxus-mobile" +version = "0.4.3" +dependencies = [ + "dioxus-desktop", +] + +[[package]] +name = "dioxus-native-core" +version = "0.4.3" +dependencies = [ + "anymap 1.0.0-beta.2", + "dashmap", + "dioxus", + "dioxus-core", + "dioxus-native-core", + "dioxus-native-core-macro", + "keyboard-types", + "lightningcss", + "parking_lot", + "rand 0.8.5", + "rustc-hash", + "shipyard", + "smallvec", + "taffy", + "tokio", +] + +[[package]] +name = "dioxus-native-core-macro" +version = "0.4.3" +dependencies = [ + "anymap 0.12.1", + "dioxus", + "dioxus-native-core", + "quote", + "rustc-hash", + "smallvec", + "syn 2.0.48", +] + +[[package]] +name = "dioxus-playwright-fullstack-test" +version = "0.1.0" +dependencies = [ + "axum 0.6.20", + "dioxus", + "dioxus-fullstack", + "dioxus-web", + "execute", + "serde", + "tokio", +] + +[[package]] +name = "dioxus-playwright-liveview-test" +version = "0.0.1" +dependencies = [ + "axum 0.6.20", + "dioxus", + "dioxus-liveview", + "tokio", +] + +[[package]] +name = "dioxus-playwright-web-test" +version = "0.0.1" +dependencies = [ + "dioxus", + "dioxus-html", + "dioxus-web", + "serde_json", +] + +[[package]] +name = "dioxus-pwa-example" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "dioxus", + "dioxus-web", + "log", + "wasm-logger", +] + +[[package]] +name = "dioxus-router" +version = "0.4.3" +dependencies = [ + "axum 0.6.20", + "console_error_panic_hook", + "criterion 0.5.1", + "dioxus", + "dioxus-cli-config", + "dioxus-desktop", + "dioxus-liveview", + "dioxus-router", + "dioxus-router-macro", + "dioxus-ssr", + "dioxus-web", + "gloo", + "gloo-utils 0.1.7", + "js-sys", + "serde", + "serde_json", + "tokio", + "tracing", + "url", + "urlencoding", + "wasm-bindgen", + "wasm-bindgen-test", + "wasm-logger", + "web-sys", +] + +[[package]] +name = "dioxus-router-macro" +version = "0.4.3" +dependencies = [ + "proc-macro2", + "quote", + "slab", + "syn 2.0.48", +] + +[[package]] +name = "dioxus-rsx" +version = "0.4.3" +dependencies = [ + "dioxus-core", + "internment", + "krates", + "proc-macro2", + "quote", + "serde", + "syn 2.0.48", + "tracing", +] + +[[package]] +name = "dioxus-signals" +version = "0.4.3" +dependencies = [ + "dioxus", + "dioxus-core", + "dioxus-desktop", + "generational-box", + "serde", + "simple_logger", + "tokio", + "tracing", +] + +[[package]] +name = "dioxus-ssr" +version = "0.4.3" +dependencies = [ + "anyhow", + "argh", + "askama_escape", + "async-trait", + "dioxus", + "dioxus-core", + "dioxus-html", + "dioxus-signals", + "fern", + "fs_extra", + "http 0.2.11", + "lru 0.10.1", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "dioxus-tailwind" +version = "0.0.0" +dependencies = [ + "dioxus", + "dioxus-desktop", + "dioxus-web", + "manganis", +] + +[[package]] +name = "dioxus-tui" +version = "0.4.3" +dependencies = [ + "criterion 0.3.6", + "crossterm 0.26.1", + "dioxus", + "dioxus-core", + "dioxus-hot-reload", + "dioxus-html", + "dioxus-native-core", + "dioxus-native-core-macro", + "futures", + "plasmo", + "taffy", + "tokio", +] + +[[package]] +name = "dioxus-web" +version = "0.4.3" +dependencies = [ + "async-channel 1.9.0", + "async-trait", + "console_error_panic_hook", + "dioxus", + "dioxus-core", + "dioxus-html", + "dioxus-interpreter-js", + "dioxus-ssr", + "dioxus-web", + "futures-channel", + "futures-util", + "gloo-dialogs", + "gloo-timers", + "js-sys", + "rustc-hash", + "serde", + "serde-wasm-bindgen", + "serde_json", + "tracing", + "tracing-wasm", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "wasm-logger", + "web-sys", +] + +[[package]] +name = "dioxus_server_macro" +version = "0.4.3" +dependencies = [ + "convert_case 0.6.0", + "proc-macro2", + "quote", + "server_fn_macro", + "syn 2.0.48", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys 0.3.7", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dissimilar" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86e3bdc80eee6e16b2b6b0f87fbc98c04bee3455e35174c0de1a125d0688c632" + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dtoa-short" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "dyn-clone" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "ego-tree" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +dependencies = [ + "serde", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array 0.14.7", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-as-inner" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "enumflags2" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5998b4f30320c9d93aed72f63af821bfdac50465b75428fce77b48ec482c3939" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "enumset" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226c0da7462c13fb57e5cc9e0dc8f0635e7d27f276a3a7fd30054647f669007d" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "env_logger" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +dependencies = [ + "humantime", + "is-terminal", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "etag" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b3d0661a2ccddc26cba0b834e9b717959ed6fdd76c7129ee159c170a875bf44" +dependencies = [ + "str-buf", + "xxhash-rust", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "euclid" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f253bc5c813ca05792837a0ff4b3a580336b224512d48f7eda1d7dd9210787" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite", +] + +[[package]] +name = "execute" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a82608ee96ce76aeab659e9b8d3c2b787bffd223199af88c674923d861ada10" +dependencies = [ + "execute-command-macro", + "execute-command-tokens", + "generic-array 1.0.0", +] + +[[package]] +name = "execute-command-macro" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90dec53d547564e911dc4ff3ecb726a64cf41a6fa01a2370ebc0d95175dd08bd" +dependencies = [ + "execute-command-macro-impl", +] + +[[package]] +name = "execute-command-macro-impl" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8cd46a041ad005ab9c71263f9a0ff5b529eac0fe4cc9b4a20f4f0765d8cf4b" +dependencies = [ + "execute-command-tokens", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "execute-command-tokens" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69dc321eb6be977f44674620ca3aa21703cb20ffbe560e1ae97da08401ffbcad" + +[[package]] +name = "exitcode" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193" + +[[package]] +name = "exr" +version = "1.71.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8" +dependencies = [ + "bit_field", + "flume", + "half 2.2.1", + "lebe", + "miniz_oxide", + "rayon-core", + "smallvec", + "zune-inflate", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "faster-hex" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2a2b11eda1d40935b26cf18f6833c526845ae8c41e58d09af6adeb6f0269183" +dependencies = [ + "serde", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fdeflate" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "209098dd6dfc4445aa6111f0e98653ac323eaa4dfd212c9ca3931bf9955c31bd" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "fermi" +version = "0.4.3" +dependencies = [ + "closure", + "dioxus-core", + "im-rc", + "tracing", +] + +[[package]] +name = "fern" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f0c14694cbd524c8720dd69b0e3179344f04ebb5f90f2e4a440c6ea3b2f1ee" +dependencies = [ + "colored 1.9.4", + "log", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset 0.9.0", + "rustc_version", +] + +[[package]] +name = "figment" +version = "0.10.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7629b8c7bcd214a072c2c88b263b5bb3ceb54c34365d8c41c1665461aeae0993" +dependencies = [ + "atomic 0.6.0", + "pear", + "serde", + "toml 0.8.2", + "uncased", + "version_check", +] + +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys 0.52.0", +] + +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared 0.3.1", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fs-err" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] + +[[package]] +name = "fs_at" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "982f82cc75107eef84f417ad6c53ae89bf65b561937ca4a3b3b0fd04d0aa2425" +dependencies = [ + "aligned", + "cfg-if", + "cvt", + "libc", + "nix 0.26.4", + "windows-sys 0.48.0", +] + +[[package]] +name = "fs_extra" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" + +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-lite" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445ba825b27408685aaecefd65178908c36c6e96aaf6d8599419d46e624192ba" +dependencies = [ + "fastrand 2.0.1", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5ba081bdef3b75ebcdbfc953699ed2d7417d6bd853347a42a37d76406a33646" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", + "once_cell", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31ff856cb3386dae1703a920f803abafcc580e9b5f711ca62ed1620c25b51ff2" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a90fbf5c033c65d93792192a49a8efb5bb1e640c419682a58bb96f5ae77f3d4a" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkx11" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2ea8a4909d530f79921290389cbd7c34cb9d623bfe970eaae65ca5f9cd9cce" +dependencies = [ + "gdk", + "gdkx11-sys", + "gio", + "glib", + "libc", + "x11", +] + +[[package]] +name = "gdkx11-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee8f00f4ee46cad2939b8990f5c70c94ff882c3028f3cc5abf950fa4ab53043" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] + +[[package]] +name = "generational-box" +version = "0.4.3" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "generator" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" +dependencies = [ + "cc", + "libc", + "log", + "rustversion", + "windows 0.48.0", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "generic-array" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe739944a5406424e080edccb6add95685130b9f160d5407c639c7df0c5836b0" +dependencies = [ + "typenum", +] + +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "ghash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d930750de5717d2dd0b8c0d42c076c0e884c81a73e6cab859bbd2339c71e3e40" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gif" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80792593675e051cf94a4b111980da2ba60d4a83e43e0048c5693baab3977045" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gimli" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d" +dependencies = [ + "fallible-iterator", + "indexmap 1.9.3", + "stable_deref_trait", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "gio" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "git2" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf97ba92db08df386e10c8ede66a2a0369bd277090afd8710e19e38de9ec0cd" +dependencies = [ + "bitflags 2.4.1", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url", +] + +[[package]] +name = "gitignore" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d051488d9a601181a9b90c9ad8ae7e8251d642ddd2463008f2f5019d255bd89" +dependencies = [ + "glob", +] + +[[package]] +name = "gix-actor" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eadca029ef716b4378f7afb19f7ee101fde9e58ba1f1445971315ac866db417" +dependencies = [ + "bstr 1.9.0", + "btoi", + "gix-date", + "itoa 1.0.10", + "thiserror", + "winnow", +] + +[[package]] +name = "gix-config" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cae98c6b4c66c09379bc35274b172587d6b0ac369a416c39128ad8c6454f9bb" +dependencies = [ + "bstr 1.9.0", + "gix-config-value", + "gix-features", + "gix-glob", + "gix-path", + "gix-ref", + "gix-sec", + "memchr", + "once_cell", + "smallvec", + "thiserror", + "unicode-bom", + "winnow", +] + +[[package]] +name = "gix-config-value" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e0be46f4cf1f8f9e88d0e3eb7b29718aff23889563249f379119bd1ab6910e" +dependencies = [ + "bitflags 2.4.1", + "bstr 1.9.0", + "gix-path", + "libc", + "thiserror", +] + +[[package]] +name = "gix-date" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb7f3dfb72bebe3449b5e642be64e3c6ccbe9821c8b8f19f487cf5bfbbf4067e" +dependencies = [ + "bstr 1.9.0", + "itoa 1.0.10", + "thiserror", + "time", +] + +[[package]] +name = "gix-features" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d46a4a5c6bb5bebec9c0d18b65ada20e6517dbd7cf855b87dd4bbdce3a771b2" +dependencies = [ + "gix-hash", + "gix-trace", + "libc", + "prodash", + "sha1_smol", + "walkdir", +] + +[[package]] +name = "gix-fs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20e86eb040f5776a5ade092282e51cdcad398adb77d948b88d17583c2ae4e107" +dependencies = [ + "gix-features", +] + +[[package]] +name = "gix-glob" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db19298c5eeea2961e5b3bf190767a2d1f09b8802aeb5f258e42276350aff19" +dependencies = [ + "bitflags 2.4.1", + "bstr 1.9.0", + "gix-features", + "gix-path", +] + +[[package]] +name = "gix-hash" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f8cf8c2266f63e582b7eb206799b63aa5fa68ee510ad349f637dfe2d0653de0" +dependencies = [ + "faster-hex", + "thiserror", +] + +[[package]] +name = "gix-lock" +version = "11.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e5c65e6a29830a435664891ced3f3c1af010f14900226019590ee0971a22f37" +dependencies = [ + "gix-tempfile", + "gix-utils", + "thiserror", +] + +[[package]] +name = "gix-object" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740f2a44267f58770a1cb3a3d01d14e67b089c7136c48d4bddbb3cfd2bf86a51" +dependencies = [ + "bstr 1.9.0", + "btoi", + "gix-actor", + "gix-date", + "gix-features", + "gix-hash", + "gix-validate", + "itoa 1.0.10", + "smallvec", + "thiserror", + "winnow", +] + +[[package]] +name = "gix-path" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dd0998ab245f33d40ca2267e58d542fe54185ebd1dc41923346cf28d179fb6" +dependencies = [ + "bstr 1.9.0", + "gix-trace", + "home", + "once_cell", + "thiserror", +] + +[[package]] +name = "gix-ref" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec2f6d07ac88d2fb8007ee3fa3e801856fb9d82e7366ec0ca332eb2c9d74a52" +dependencies = [ + "gix-actor", + "gix-date", + "gix-features", + "gix-fs", + "gix-hash", + "gix-lock", + "gix-object", + "gix-path", + "gix-tempfile", + "gix-validate", + "memmap2", + "thiserror", + "winnow", +] + +[[package]] +name = "gix-sec" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78f6dce0c6683e2219e8169aac4b1c29e89540a8262fef7056b31d80d969408c" +dependencies = [ + "bitflags 2.4.1", + "gix-path", + "libc", + "windows 0.52.0", +] + +[[package]] +name = "gix-tempfile" +version = "11.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388dd29114a86ec69b28d1e26d6d63a662300ecf61ab3f4cc578f7d7dc9e7e23" +dependencies = [ + "gix-fs", + "libc", + "once_cell", + "parking_lot", + "tempfile", +] + +[[package]] +name = "gix-trace" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8e1127ede0475b58f4fe9c0aaa0d9bb0bad2af90bbd93ccd307c8632b863d89" + +[[package]] +name = "gix-utils" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de6225e2de30b6e9bca2d9f1cc4731640fcef0fb3cabddceee366e7e85d3e94f" +dependencies = [ + "fastrand 2.0.1", +] + +[[package]] +name = "gix-validate" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac7cc36f496bd5d96cdca0f9289bb684480725d40db60f48194aa7723b883854" +dependencies = [ + "bstr 1.9.0", + "thiserror", +] + +[[package]] +name = "glib" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +dependencies = [ + "bitflags 2.4.1", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 2.0.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "glib-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "global-hotkey" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d505f007b733fc3b3261ca0710e7e689411422ace5f5b2a63a14d8596159db23" +dependencies = [ + "crossbeam-channel", + "keyboard-types", + "once_cell", + "thiserror", + "windows-sys 0.52.0", + "x11-dl", +] + +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick 1.1.2", + "bstr 1.9.0", + "log", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", +] + +[[package]] +name = "gloo" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28999cda5ef6916ffd33fb4a7b87e1de633c47c0dc6d97905fee1cdaa142b94d" +dependencies = [ + "gloo-console", + "gloo-dialogs", + "gloo-events", + "gloo-file", + "gloo-history", + "gloo-net 0.3.1", + "gloo-render", + "gloo-storage 0.2.2", + "gloo-timers", + "gloo-utils 0.1.7", + "gloo-worker", +] + +[[package]] +name = "gloo-console" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b7ce3c05debe147233596904981848862b068862e9ec3e34be446077190d3f" +dependencies = [ + "gloo-utils 0.1.7", + "js-sys", + "serde", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-dialogs" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67062364ac72d27f08445a46cab428188e2e224ec9e37efdba48ae8c289002e6" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-events" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b107f8abed8105e4182de63845afcc7b69c098b7852a813ea7462a320992fc" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-file" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d5564e570a38b43d78bdc063374a0c3098c4f0d64005b12f9bbe87e869b6d7" +dependencies = [ + "gloo-events", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-history" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85725d90bf0ed47063b3930ef28e863658a7905989e9929a8708aab74a1d5e7f" +dependencies = [ + "gloo-events", + "gloo-utils 0.1.7", + "serde", + "serde-wasm-bindgen", + "serde_urlencoded", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-net" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9902a044653b26b99f7e3693a42f171312d9be8b26b5697bd1e43ad1f8a35e10" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils 0.1.7", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-net" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66b4e3c7d9ed8d315fd6b97c8b1f74a7c6ecbbc2320e65ae7ed38b7068cc620" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils 0.1.7", + "http 0.2.11", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-render" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd9306aef67cfd4449823aadcd14e3958e0800aa2183955a309112a84ec7764" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-storage" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6ab60bf5dbfd6f0ed1f7843da31b41010515c745735c970e821945ca91e480" +dependencies = [ + "gloo-utils 0.1.7", + "js-sys", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-storage" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc8031e8c92758af912f9bc08fbbadd3c6f3cfcbf6b64cdf3d6a81f0139277a" +dependencies = [ + "gloo-utils 0.2.0", + "js-sys", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-utils" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-worker" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13471584da78061a28306d1359dd0178d8d6fc1c7c80e5e35d27260346e0516a" +dependencies = [ + "anymap2", + "bincode", + "gloo-console", + "gloo-utils 0.1.7", + "js-sys", + "serde", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gobject-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "grid" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eec1c01eb1de97451ee0d60de7d81cf1e72aabefb021616027f3d1c3ec1c723c" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "gtk" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93c4f5e0e20b60e10631a5f06da7fe3dda744b05ad0ea71fee2f47adf865890c" +dependencies = [ + "atk", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771437bf1de2c1c0b496c11505bdf748e26066bbe942dfc8f614c9460f6d7722" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6063efb63db582968fb7df72e1ae68aa6360dcfb0a75143f34fc7d616bad75e" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "h2" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b553656127a00601c8ae5590fcfdc118e4083a7924b6cf4ffc1ea4b99dc429d7" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.11", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "991910e35c615d8cab86b5ab04be67e6ad24d2bf5f4f11fdbbed26da999bbeab" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 1.0.0", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + +[[package]] +name = "half" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" +dependencies = [ + "crunchy", +] + +[[package]] +name = "handlebars" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225" +dependencies = [ + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.7", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.7", + "bumpalo", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash 0.8.7", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.3", +] + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64 0.21.6", + "bytes", + "headers-core 0.2.0", + "http 0.2.11", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9" +dependencies = [ + "base64 0.21.6", + "bytes", + "headers-core 0.3.0", + "http 1.0.0", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http 0.2.11", +] + +[[package]] +name = "headers-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" +dependencies = [ + "http 1.0.0", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "html5ever" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bea68cab48b8459f17cf1c944c67ddc572d272d9f2b274140f223ecb1da4a3b7" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "html_parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f56db07b6612644f6f7719f8ef944f75fff9d6378fdf3d316fd32194184abd" +dependencies = [ + "doc-comment", + "pest", + "pest_derive", + "serde", + "serde_derive", + "serde_json", + "thiserror", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.10", +] + +[[package]] +name = "http" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.10", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.11", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.0.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cb79eb393015dadd30fc252023adb0b2400a0caee0fa2a077e6e21a551e840" +dependencies = [ + "bytes", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "pin-project-lite", +] + +[[package]] +name = "http-range" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.23", + "http 0.2.11", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa 1.0.10", + "pin-project-lite", + "socket2 0.5.5", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5aa53871fc917b1a9ed87b683a5d86db645e23acb32c2e0785a353e522fb75" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.1", + "http 1.0.0", + "http-body 1.0.0", + "httparse", + "httpdate", + "itoa 1.0.10", + "pin-project-lite", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1788965e61b367cd03a62950836d5cd41560c3577d90e40e0819373194d1661c" +dependencies = [ + "http 0.2.11", + "hyper 0.14.28", + "log", + "rustls 0.20.9", + "rustls-native-certs", + "tokio", + "tokio-rustls 0.23.4", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.11", + "hyper 0.14.28", + "rustls 0.21.10", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper 0.14.28", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "hyper-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdea9aac0dbe5a9240d68cfd9501e2db94222c6dc06843e06640b9e07f0fdc67" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.0.0", + "http-body 1.0.0", + "hyper 1.1.0", + "pin-project-lite", + "socket2 0.5.5", + "tokio", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "ignore" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata 0.4.3", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] +name = "im-rc" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe" +dependencies = [ + "bitmaps", + "rand_core 0.6.4", + "rand_xoshiro", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "image" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-rational", + "num-traits", + "png", + "qoi", + "ravif", + "rgb", + "tiff", + "webp", +] + +[[package]] +name = "imagequant" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84d51957ac48371e8e2eaaeb4eba56150ff2109c1c8c200002afb7dd6e2d260f" +dependencies = [ + "arrayvec", + "once_cell", + "rayon", + "rgb", + "thread_local", +] + +[[package]] +name = "imgref" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90d944e334f00f4449c9640b440a171f816be0152305c12ef90424fc35fd035c" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", + "serde", +] + +[[package]] +name = "indicatif" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25" +dependencies = [ + "console", + "instant", + "number_prefix", + "portable-atomic", + "unicode-width", +] + +[[package]] +name = "indoc" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" + +[[package]] +name = "infer" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6c16b11a665b26aeeb9b1d7f954cdeb034be38dd00adab4f2ae921a8fee804" +dependencies = [ + "cfb", +] + +[[package]] +name = "infer" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f551f8c3a39f68f986517db0d1759de85881894fdc7db798bd2a9df9cb04b7fc" +dependencies = [ + "cfb", +] + +[[package]] +name = "inlinable_string" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" + +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "internment" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e976188335292f66a1533fd41d5c2ce24b32dc2c000569b8dccf4e57f489806" +dependencies = [ + "hashbrown 0.12.3", + "parking_lot", +] + +[[package]] +name = "interpolate_name" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "interprocess-docfix" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b84ee245c606aeb0841649a9288e3eae8c61b853a8cd5c0e14450e96d53d28f" +dependencies = [ + "blocking", + "cfg-if", + "futures-core", + "futures-io", + "intmap", + "libc", + "once_cell", + "rustc_version", + "spinning", + "thiserror", + "to_method", + "winapi", +] + +[[package]] +name = "intmap" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae52f28f45ac2bc96edb7714de995cffc174a395fb0abf5bff453587c980d7b9" + +[[package]] +name = "inventory" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8573b2b1fb643a372c73b23f4da5f888677feef3305146d68a539250a9bccc7" + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.3", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2 0.5.5", + "widestring", + "windows-sys 0.48.0", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "ipnetwork" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e" +dependencies = [ + "serde", +] + +[[package]] +name = "iri-string" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f0f7638c1e223529f1bfdc48c8b133b9e0b434094d1d28473161ee48b235f78" +dependencies = [ + "nom", +] + +[[package]] +name = "is-docker" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +dependencies = [ + "once_cell", +] + +[[package]] +name = "is-terminal" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" +dependencies = [ + "hermit-abi 0.3.3", + "rustix 0.38.28", + "windows-sys 0.52.0", +] + +[[package]] +name = "is-wsl" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +dependencies = [ + "is-docker", + "once_cell", +] + +[[package]] +name = "is_ci" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "javascriptcore-rs" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" +dependencies = [ + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json-patch" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ff1e1486799e3f64129f8ccad108b38290df9cd7015cd31bed17239f0789d6" +dependencies = [ + "serde", + "serde_json", + "thiserror", + "treediff", +] + +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags 2.4.1", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "kqueue" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "krates" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "942c43a6cba1c201dfe81a943c89fa5c9140b34993e0c027f542c80b92e319a7" +dependencies = [ + "cargo_metadata 0.15.4", + "cfg-expr 0.12.0", + "petgraph", + "semver", +] + +[[package]] +name = "kstring" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" +dependencies = [ + "serde", + "static_assertions", +] + +[[package]] +name = "kuchikiki" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e4755b7b995046f510a7520c42b2fed58b77bd94d5a87a8eb43d2fd126da8" +dependencies = [ + "cssparser 0.27.2", + "html5ever", + "indexmap 1.9.3", + "matches", + "selectors 0.22.0", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "lebe" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "libflate" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ff4ae71b685bbad2f2f391fe74f6b7659a34871c08b210fdc039e43bee07d18" +dependencies = [ + "adler32", + "crc32fast", + "libflate_lz77", +] + +[[package]] +name = "libflate_lz77" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a52d3a8bfc85f250440e4424db7d857e241a3aebbbe301f3eb606ab15c39acbf" +dependencies = [ + "rle-decode-fast", +] + +[[package]] +name = "libfuzzer-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcf184a4b6b274f82a5df6b357da6055d3e82272327bba281c28bbba6f1664ef" +dependencies = [ + "arbitrary 0.4.7", + "cc", +] + +[[package]] +name = "libfuzzer-sys" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96cfd5557eb82f2b83fed4955246c988d331975a002961b07c81584d107e7f7" +dependencies = [ + "arbitrary 1.3.2", + "cc", + "once_cell", +] + +[[package]] +name = "libgit2-sys" +version = "0.16.1+1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2a2bb3680b094add03bb3732ec520ece34da31a8cd2d633d1389d0f0fb60d0c" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.1", + "libc", + "redox_syscall", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libssh2-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dc8a030b787e2119a731f1951d6a773e2280c660f8ec4b0f5e1505a386e71ee" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libwebp-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e0df0a0f9444d52aee6335cd724d21a2ee3285f646291799a72be518ec8ee3c" +dependencies = [ + "cc", + "glob", +] + +[[package]] +name = "libxdo" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00333b8756a3d28e78def82067a377de7fa61b24909000aeaa2b446a948d14db" +dependencies = [ + "libxdo-sys", +] + +[[package]] +name = "libxdo-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db23b9e7e2b7831bbd8aac0bbeeeb7b68cbebc162b227e7052e8e55829a09212" +dependencies = [ + "libc", + "x11", +] + +[[package]] +name = "libz-sys" +version = "1.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "295c17e837573c8c821dbaeb3cceb3d745ad082f7572191409e69cbc1b3fd050" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "lightningcss" +version = "1.0.0-alpha.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d6ad516c08b24c246b339159dc2ee2144c012e8ebdf4db4bddefb8734b2b69" +dependencies = [ + "ahash 0.7.7", + "bitflags 2.4.1", + "const-str", + "cssparser 0.33.0", + "cssparser-color", + "dashmap", + "data-encoding", + "itertools 0.10.5", + "lazy_static", + "parcel_selectors", + "parcel_sourcemap", + "paste", + "pathdiff", + "rayon", + "serde", + "smallvec", +] + +[[package]] +name = "line-col" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e69cdf6b85b5c8dce514f694089a2cf8b1a702f6cd28607bcb3cf296c9778db" + +[[package]] +name = "line-wrap" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9" +dependencies = [ + "safemem", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" + +[[package]] +name = "liquid" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f68ae1011499ae2ef879f631891f21c78e309755f4a5e483c4a8f12e10b609" +dependencies = [ + "doc-comment", + "liquid-core", + "liquid-derive", + "liquid-lib", + "serde", +] + +[[package]] +name = "liquid-core" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79e0724dfcaad5cfb7965ea0f178ca0870b8d7315178f4a7179f5696f7f04d5f" +dependencies = [ + "anymap2", + "itertools 0.10.5", + "kstring", + "liquid-derive", + "num-traits", + "pest", + "pest_derive", + "regex", + "serde", + "time", +] + +[[package]] +name = "liquid-derive" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc2fb41a9bb4257a3803154bdf7e2df7d45197d1941c9b1a90ad815231630721" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "liquid-lib" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2a17e273a6fb1fb6268f7a5867ddfd0bd4683c7e19b51084f3d567fad4348c0" +dependencies = [ + "itertools 0.10.5", + "liquid-core", + "once_cell", + "percent-encoding", + "regex", + "time", + "unicode-segmentation", +] + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +dependencies = [ + "value-bag", +] + +[[package]] +name = "longest-increasing-subsequence" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" + +[[package]] +name = "loom" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "serde", + "serde_json", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "loop9" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81a837f917de41d61ab531ba255d1913208d02325cab0d6a66a706e0dbaa699d" +dependencies = [ + "imgref", +] + +[[package]] +name = "lru" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6e8aaa3f231bb4bd57b84b2d5dc3ae7f350265df8aa96492e0bc394a1571909" +dependencies = [ + "hashbrown 0.12.3", +] + +[[package]] +name = "lru" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +dependencies = [ + "hashbrown 0.13.2", +] + +[[package]] +name = "lru" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7" +dependencies = [ + "hashbrown 0.14.3", +] + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "lua-src" +version = "546.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2da0daa7eee611a4c30c8f5ee31af55266e26e573971ba9336d2993e2da129b2" +dependencies = [ + "cc", +] + +[[package]] +name = "luajit-src" +version = "210.4.8+resty107baaf" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05167e8b2a2185758d83ed23541e5bd8bce37072e4204e0ef2c9b322bc87c4e" +dependencies = [ + "cc", + "which", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "mac_address" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4863ee94f19ed315bf3bc00299338d857d4b5bc856af375cc97d237382ad3856" +dependencies = [ + "nix 0.23.2", + "winapi", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "manganis" +version = "0.1.0" +source = "git+https://github.com/DioxusLabs/collect-assets?rev=e0093a4#e0093a47f0fa3bb50c49cd21aee5aa674faa24ad" +dependencies = [ + "manganis-macro", +] + +[[package]] +name = "manganis-cli-support" +version = "0.1.0" +source = "git+https://github.com/DioxusLabs/collect-assets?rev=e0093a4#e0093a47f0fa3bb50c49cd21aee5aa674faa24ad" +dependencies = [ + "anyhow", + "cargo-lock 9.0.0", + "cargo_metadata 0.17.0", + "cargo_toml", + "image", + "imagequant", + "lightningcss", + "manganis-common", + "mozjpeg", + "petgraph", + "png", + "railwind", + "rayon", + "reqwest", + "rustc-hash", + "serde", + "toml 0.7.8", + "tracing", + "url", +] + +[[package]] +name = "manganis-common" +version = "0.1.0" +source = "git+https://github.com/DioxusLabs/collect-assets?rev=e0093a4#e0093a47f0fa3bb50c49cd21aee5aa674faa24ad" +dependencies = [ + "anyhow", + "base64 0.21.6", + "home", + "infer 0.11.0", + "reqwest", + "serde", + "toml 0.7.8", + "url", +] + +[[package]] +name = "manganis-macro" +version = "0.0.1" +source = "git+https://github.com/DioxusLabs/collect-assets?rev=e0093a4#e0093a47f0fa3bb50c49cd21aee5aa674faa24ad" +dependencies = [ + "base64 0.21.6", + "manganis-cli-support", + "manganis-common", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "markup5ever" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2629bb1404f3d34c2e921f21fd34ba00b206124c81f65c50b43b6aaefeb016" +dependencies = [ + "log", + "phf 0.10.1", + "phf_codegen 0.10.0", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "matchit" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "maybe-rayon" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea1f30cedd69f0a2954655f7188c6a834246d2bcf1e315e2ac40c4b24dc9519" +dependencies = [ + "cfg-if", + "rayon", +] + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "memmap2" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49388d20533534cd19360ad3d6a7dadc885944aa802ba3995040c5ec11288c6" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" +dependencies = [ + "autocfg", +] + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime-infer" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91caed19dd472bc88bcd063571df18153529d49301a1918f4cf37f42332bee2e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minify-js" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22d6c512a82abddbbc13b70609cb2beff01be2c7afff534d6e5e1c85e438fc8b" +dependencies = [ + "lazy_static", + "parse-js", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "mlua" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb37b0ba91f017aa7ca2b98ef99496827770cd635b4a932a6047c5b4bbe678e" +dependencies = [ + "bstr 0.2.17", + "cc", + "futures-core", + "futures-task", + "futures-util", + "lua-src", + "luajit-src", + "mlua_derive", + "num-traits", + "once_cell", + "pkg-config", + "rustc-hash", +] + +[[package]] +name = "mlua_derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9214e60d3cf1643013b107330fcd374ccec1e4ba1eef76e7e5da5e8202e71c0" +dependencies = [ + "itertools 0.10.5", + "once_cell", + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", +] + +[[package]] +name = "mozjpeg" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a807fbca64e7df4847726d172f459fb13e65cbf5e23b01f27408581d58258f" +dependencies = [ + "arrayvec", + "libc", + "mozjpeg-sys", + "rgb", +] + +[[package]] +name = "mozjpeg-sys" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74c4fe4006093b2948ccb37bb413b6b9da2d654a9a50419b5861b0f4e8ad4da9" +dependencies = [ + "cc", + "dunce", + "libc", + "nasm-rs", +] + +[[package]] +name = "muda" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884427679a3ef726cd4a0ad6eec2ca618737ba11ebe8c9320dc305c09c78c8fc" +dependencies = [ + "cocoa", + "crossbeam-channel", + "gtk", + "keyboard-types", + "libxdo", + "objc", + "once_cell", + "png", + "thiserror", + "windows-sys 0.52.0", +] + +[[package]] +name = "multer" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http 0.2.11", + "httparse", + "log", + "memchr", + "mime", + "spin 0.9.8", + "tokio", + "tokio-util", + "version_check", +] + +[[package]] +name = "multer" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15d522be0a9c3e46fd2632e272d178f56387bdb5c9fbb3a36c649062e9b5219" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http 1.0.0", + "httparse", + "log", + "memchr", + "mime", + "spin 0.9.8", + "version_check", +] + +[[package]] +name = "multimap" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1a5d38b9b352dbd913288736af36af41c48d61b1a8cd34bcecd727561b7d511" +dependencies = [ + "serde", +] + +[[package]] +name = "names" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bddcd3bf5144b6392de80e04c347cd7fab2508f6df16a85fc496ecd5cec39bc" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "nasm-rs" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4d98d0065f4b1daf164b3eafb11974c94662e5e2396cf03f32d0bb5c17da51" +dependencies = [ + "rayon", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "ndk" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0" +dependencies = [ + "bitflags 1.3.2", + "jni-sys", + "ndk-sys", + "num_enum", + "raw-window-handle 0.5.2", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.4.1+23.1.7779620" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nix" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3790c00a0150112de0f4cd161e3d7fc4b2d8a5542ffc35f099a2562aecb35c" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", + "memoffset 0.6.5", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", + "memoffset 0.7.1", +] + +[[package]] +name = "nix" +version = "0.27.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "libc", +] + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "noop_proc_macro" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" + +[[package]] +name = "normpath" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "notify" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729f63e1ca555a43fe3efa4f3efdf4801c479da85b432242a7b726f353c88486" +dependencies = [ + "bitflags 1.3.2", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "mio", + "serde", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-derive" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "num-format" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" +dependencies = [ + "arrayvec", + "itoa 1.0.10", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.3", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "number_prefix" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" + +[[package]] +name = "oauth2" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f" +dependencies = [ + "base64 0.13.1", + "chrono", + "getrandom 0.2.12", + "http 0.2.11", + "rand 0.8.5", + "reqwest", + "serde", + "serde_json", + "serde_path_to_error", + "sha2", + "thiserror", + "url", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "oorandom" +version = "11.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "open" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a083c0c7e5e4a8ec4176346cf61f67ac674e8bfb059d9226e1c54a96b377c12" +dependencies = [ + "is-wsl", + "libc", + "pathdiff", +] + +[[package]] +name = "openid_auth_demo" +version = "0.1.0" +dependencies = [ + "console_error_panic_hook", + "dioxus", + "dioxus-logger", + "dioxus-router", + "dioxus-web", + "fermi", + "form_urlencoded", + "gloo-storage 0.3.0", + "log", + "openidconnect", + "reqwest", + "serde", + "serde_json", + "thiserror", + "uuid", + "web-sys", +] + +[[package]] +name = "openidconnect" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62d6050f6a84b81f23c569f5607ad883293e57491036e318fafe6fc4895fadb1" +dependencies = [ + "base64 0.13.1", + "chrono", + "dyn-clone", + "ed25519-dalek", + "hmac", + "http 0.2.11", + "itertools 0.10.5", + "log", + "oauth2", + "p256", + "p384", + "rand 0.8.5", + "rsa", + "serde", + "serde-value", + "serde_derive", + "serde_json", + "serde_path_to_error", + "serde_plain", + "serde_with", + "sha2", + "subtle", + "thiserror", + "url", +] + +[[package]] +name = "openssl" +version = "0.10.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +dependencies = [ + "bitflags 2.4.1", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "300.2.1+3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fe476c29791a5ca0d1273c697e96085bbabbbea2ef7afd5617e78a4b40332d3" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ordered-stream" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" +dependencies = [ + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "os_pipe" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57119c3b893986491ec9aa85056780d3a0f3cf4da7cc09dd3650dbd6c6738fb9" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "outref" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f222829ae9293e33a9f5e9f440c6760a3d450a64affe1846486b140db81c1f4" + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +dependencies = [ + "supports-color", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p384" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "pango" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +dependencies = [ + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parcel_selectors" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d74befe2d076330d9a58bf9ca2da424568724ab278adf15fb5718253133887" +dependencies = [ + "bitflags 2.4.1", + "cssparser 0.33.0", + "fxhash", + "log", + "phf 0.10.1", + "phf_codegen 0.10.0", + "precomputed-hash", + "smallvec", +] + +[[package]] +name = "parcel_sourcemap" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "485b74d7218068b2b7c0e3ff12fbc61ae11d57cb5d8224f525bd304c6be05bbb" +dependencies = [ + "base64-simd", + "data-url", + "rkyv", + "serde", + "serde_json", + "vlq", +] + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "parse-js" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ec3b11d443640ec35165ee8f6f0559f1c6f41878d70330fe9187012b5935f02" +dependencies = [ + "aho-corasick 0.7.20", + "bumpalo", + "hashbrown 0.13.2", + "lazy_static", + "memchr", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "path-absolutize" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4af381fe79fa195b4909485d99f73a80792331df0625188e707854f0b3383f5" +dependencies = [ + "path-dedot", +] + +[[package]] +name = "path-dedot" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07ba0ad7e047712414213ff67533e6dd477af0a4e1d14fb52343e53d30ea9397" +dependencies = [ + "once_cell", +] + +[[package]] +name = "path-slash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" + +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest", + "hmac", + "password-hash", + "sha2", +] + +[[package]] +name = "pear" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ccca0f6c17acc81df8e242ed473ec144cbf5c98037e69aa6d144780aad103c8" +dependencies = [ + "inlinable_string", + "pear_codegen", + "yansi 1.0.0-rc.1", +] + +[[package]] +name = "pear_codegen" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e22670e8eb757cff11d6c199ca7b987f352f0346e0be4dd23869ec72cb53c77" +dependencies = [ + "proc-macro2", + "proc-macro2-diagnostics", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pest_meta" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.1.0", +] + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_macros 0.11.2", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_macros" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3444646e286606587e49f3bcf1679b8cef1dc2c5ecc29ddacaffc305180d464b" +dependencies = [ + "phf_generator 0.11.2", + "phf_shared 0.11.2", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +dependencies = [ + "atomic-waker", + "fastrand 2.0.1", + "futures-io", +] + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" + +[[package]] +name = "plasmo" +version = "0.4.3" +dependencies = [ + "anyhow", + "anymap 1.0.0-beta.2", + "criterion 0.3.6", + "crossterm 0.26.1", + "dioxus-html", + "dioxus-native-core", + "dioxus-native-core-macro", + "futures", + "futures-channel", + "once_cell", + "ratatui", + "rustc-hash", + "shipyard", + "smallvec", + "taffy", + "tokio", +] + +[[package]] +name = "platforms" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" + +[[package]] +name = "plist" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5699cc8a63d1aa2b1ee8e12b9ad70ac790d65788cd36101fa37f87ea46c4cef" +dependencies = [ + "base64 0.21.6", + "indexmap 2.1.0", + "line-wrap", + "quick-xml", + "serde", + "time", +] + +[[package]] +name = "plotters" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2c224ba00d7cadd4d5c660deaf2098e5e80e07846537c51f9cfa4be50c1fd45" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e76628b4d3a7581389a35d5b6e2139607ad7c75b17aed325f210aa91f4a9609" + +[[package]] +name = "plotters-svg" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38f6d39893cca0701371e3c27294f09797214b86f1fb951b89ade8ec04e2abab" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "png" +version = "0.17.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polling" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +dependencies = [ + "cfg-if", + "concurrent-queue", + "pin-project-lite", + "rustix 0.38.28", + "tracing", + "windows-sys 0.52.0", +] + +[[package]] +name = "polyval" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52cff9d1d4dee5fe6d03729099f4a310a41179e0a10dbf542039873f2e826fb" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettier-please" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22020dfcf177fcc7bf5deaf7440af371400c67c0de14c399938d8ed4fb4645d3" +dependencies = [ + "proc-macro2", + "syn 2.0.48", +] + +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi 0.5.1", +] + +[[package]] +name = "pretty_env_logger" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "865724d4dbe39d9f3dd3b52b88d859d66bcb2d6a0acfd5ea68a65fb66d4bdc1c" +dependencies = [ + "env_logger", + "log", +] + +[[package]] +name = "prettyplease" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a41cf62165e97c7f814d2221421dbb9afcbcdb0a88068e5ea206e19951c2cbb5" +dependencies = [ + "proc-macro2", + "syn 2.0.48", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +dependencies = [ + "toml_datetime", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", + "version_check", + "yansi 1.0.0-rc.1", +] + +[[package]] +name = "prodash" +version = "26.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794b5bf8e2d19b53dcdcec3e4bba628e20f5b6062503ba89281fa7037dd7bbcf" + +[[package]] +name = "profiling" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d135ede8821cf6376eb7a64148901e1690b788c11ae94dc297ae917dbc91dc0e" +dependencies = [ + "profiling-procmacros", +] + +[[package]] +name = "profiling-procmacros" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b322d7d65c1ab449be3c890fcbd0db6e1092d0dd05d79dba2dd28032cebeb05" +dependencies = [ + "quote", + "syn 2.0.48", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "qoi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6d64c71eb498fe9eae14ce4ec935c555749aef511cca85b5568910d6e48001" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "query_segments_demo" +version = "0.1.0" +dependencies = [ + "dioxus", + "dioxus-router", + "dioxus-web", + "form_urlencoded", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "railwind" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc2b6ca634162c78a6e8d399e12e22b42bcbf2eb60f2b7a2f99aa2379d41800" +dependencies = [ + "hex", + "indexmap 1.9.3", + "lazy_static", + "line-col", + "regex", + "ron", + "serde", + "serde_regex", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.12", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "ratatui" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ebc917cfb527a566c37ecb94c7e3fd098353516fb4eb6bea17015ade0182425" +dependencies = [ + "bitflags 2.4.1", + "cassowary", + "crossterm 0.27.0", + "indoc", + "itertools 0.11.0", + "lru 0.12.1", + "paste", + "strum", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "rav1e" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16c383692a5e7abd9f6d1eddb1a5e0269f859392387883361bb09e5555852ec1" +dependencies = [ + "arbitrary 0.4.7", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io 1.10.0", + "built 0.5.2", + "cc", + "cfg-if", + "interpolate_name", + "itertools 0.10.5", + "libc", + "libfuzzer-sys 0.3.5", + "log", + "maybe-rayon", + "nasm-rs", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive 0.3.3", + "num-traits", + "once_cell", + "paste", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rust_hawktracer", + "rustc_version", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", + "wasm-bindgen", +] + +[[package]] +name = "rav1e" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9" +dependencies = [ + "arbitrary 1.3.2", + "arg_enum_proc_macro", + "arrayvec", + "av1-grain", + "bitstream-io 2.2.0", + "built 0.7.1", + "cc", + "cfg-if", + "interpolate_name", + "itertools 0.12.0", + "libc", + "libfuzzer-sys 0.4.7", + "log", + "maybe-rayon", + "nasm-rs", + "new_debug_unreachable", + "noop_proc_macro", + "num-derive 0.4.1", + "num-traits", + "once_cell", + "paste", + "profiling", + "rand 0.8.5", + "rand_chacha 0.3.1", + "simd_helpers", + "system-deps", + "thiserror", + "v_frame", +] + +[[package]] +name = "ravif" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d44feba0b8a381a5efa2c0baf8dace8418904403260233f4a614503b018fc288" +dependencies = [ + "avif-serialize", + "imgref", + "loop9", + "quick-error 2.0.1", + "rav1e 0.6.6", + "rav1e 0.7.1", + "rayon", + "rgb", +] + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "raw-window-handle" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom 0.2.12", + "libredox", + "thiserror", +] + +[[package]] +name = "ref-cast" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4846d4c50d1721b1a3bef8af76924eef20d5e723647333798c1b519b3a9473f" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick 1.1.2", + "memchr", + "regex-automata 0.4.3", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick 1.1.2", + "memchr", + "regex-syntax 0.8.2", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "remove_dir_all" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23895cfadc1917fed9c6ed76a8c2903615fa3704f7493ff82b364c6540acc02b" +dependencies = [ + "aligned", + "cfg-if", + "cvt", + "fs_at", + "lazy_static", + "libc", + "normpath", + "windows-sys 0.45.0", +] + +[[package]] +name = "rend" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.11.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +dependencies = [ + "base64 0.21.6", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.23", + "http 0.2.11", + "http-body 0.4.6", + "hyper 0.14.28", + "hyper-rustls 0.24.2", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.10", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls 0.24.1", + "tokio-util", + "tower-service", + "trust-dns-resolver", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error 1.2.3", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rfd" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9e7b57df6e8472152674607f6cc68aa14a748a3157a857a94f516e11aeacc2" +dependencies = [ + "block", + "dispatch", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc", + "objc-foundation", + "objc_id", + "raw-window-handle 0.5.2", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "rgb" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "rhai" +version = "1.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3625f343d89990133d013e39c46e350915178cf94f1bec9f49b0cbef98a3e3c" +dependencies = [ + "ahash 0.8.7", + "bitflags 2.4.1", + "instant", + "num-traits", + "once_cell", + "rhai_codegen", + "smallvec", + "smartstring", +] + +[[package]] +name = "rhai_codegen" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "853977598f084a492323fe2f7896b4100a86284ee8473612de60021ea341310f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom 0.2.12", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "rkyv" +version = "0.7.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527a97cdfef66f65998b5f3b637c26f5a5ec09cc52a3f9932313ac645f4190f5" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5c462a1328c8e67e4d6dbad1eb0355dd43e8ab432c6e227a43657f16ade5033" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rle-decode-fast" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3582f63211428f83597b51b2ddb88e2a91a9d52d12831f9d08f5e624e8977422" + +[[package]] +name = "rocket" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e7bb57ccb26670d73b6a47396c83139447b9e7878cab627fdfe9ea8da489150" +dependencies = [ + "async-stream", + "async-trait", + "atomic 0.5.3", + "binascii", + "bytes", + "either", + "figment", + "futures", + "indexmap 2.1.0", + "log", + "memchr", + "multer 2.1.0", + "num_cpus", + "parking_lot", + "pin-project-lite", + "rand 0.8.5", + "ref-cast", + "rocket_codegen", + "rocket_http", + "serde", + "state", + "tempfile", + "time", + "tokio", + "tokio-stream", + "tokio-util", + "ubyte", + "version_check", + "yansi 1.0.0-rc.1", +] + +[[package]] +name = "rocket_codegen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2238066abf75f21be6cd7dc1a09d5414a671f4246e384e49fe3f8a4936bd04c" +dependencies = [ + "devise", + "glob", + "indexmap 2.1.0", + "proc-macro2", + "quote", + "rocket_http", + "syn 2.0.48", + "unicode-xid", + "version_check", +] + +[[package]] +name = "rocket_http" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a1663694d059fe5f943ea5481363e48050acedd241d46deb2e27f71110389e" +dependencies = [ + "cookie 0.18.0", + "either", + "futures", + "http 0.2.11", + "hyper 0.14.28", + "indexmap 2.1.0", + "log", + "memchr", + "pear", + "percent-encoding", + "pin-project-lite", + "ref-cast", + "serde", + "smallvec", + "stable-pattern", + "state", + "time", + "tokio", + "uncased", +] + +[[package]] +name = "rocket_ws" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6677b3fe72e2d73dd632c412546ed8153e8685c830ee8d20e4488575cb905d9" +dependencies = [ + "rocket", + "tokio-tungstenite 0.20.1", +] + +[[package]] +name = "ron" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" +dependencies = [ + "base64 0.21.6", + "bitflags 2.4.1", + "indexmap 2.1.0", + "serde", + "serde_derive", +] + +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rsx-rosetta" +version = "0.4.3" +dependencies = [ + "convert_case 0.5.0", + "dioxus-autofmt", + "dioxus-html", + "dioxus-rsx", + "html_parser", + "pretty_assertions", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "rust-embed" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82c0bbc10308ed323529fd3c1dce8badda635aa319a5ff0e6466f33b8101e3f" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6227c01b1783cdfee1bcf844eb44594cd16ec71c35305bf1c9fb5aade2735e16" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn 2.0.48", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cb0a25bfbb2d4b4402179c2cf030387d9990857ce08a32592c6238db9fa8665" +dependencies = [ + "sha2", + "walkdir", +] + +[[package]] +name = "rust_decimal" +version = "1.33.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "rust_hawktracer" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3480a29b927f66c6e06527be7f49ef4d291a01d694ec1fe85b0de71d6b02ac1" +dependencies = [ + "rust_hawktracer_normal_macro", + "rust_hawktracer_proc_macro", +] + +[[package]] +name = "rust_hawktracer_normal_macro" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a570059949e1dcdc6f35228fa389f54c2c84dfe0c94c05022baacd56eacd2e9" + +[[package]] +name = "rust_hawktracer_proc_macro" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb626abdbed5e93f031baae60d72032f56bc964e11ac2ff65f2ba3ed98d6d3e1" + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +dependencies = [ + "bitflags 2.4.1", + "errno", + "libc", + "linux-raw-sys 0.4.12", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct", + "webpki", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring 0.17.7", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.6", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "safemem" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072" + +[[package]] +name = "salvo" +version = "0.63.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc1aaf77a4c306270cb7b1a6e08a5b12ee14935ac5a5c6b0ce1958d66a72ad9" +dependencies = [ + "salvo-compression", + "salvo-serve-static", + "salvo_core", + "salvo_extra", +] + +[[package]] +name = "salvo-compression" +version = "0.63.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c487a736613df6e2ae455bdd3775d86ad9a2a2dcf0cd4067adc9ce08dc9f0d97" +dependencies = [ + "brotli", + "bytes", + "flate2", + "futures-util", + "indexmap 2.1.0", + "salvo_core", + "tokio", + "tokio-util", + "tracing", + "zstd 0.13.0", +] + +[[package]] +name = "salvo-hello-world" +version = "0.1.0" +dependencies = [ + "dioxus", + "dioxus-fullstack", + "dioxus-web", + "execute", + "reqwest", + "salvo", + "serde", + "simple_logger", + "tracing", + "tracing-subscriber", + "tracing-wasm", +] + +[[package]] +name = "salvo-serve-static" +version = "0.63.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef927fe76c5444b3ef6386180ec0f39998e26414dee66e6ce48b91da6f2ef8e" +dependencies = [ + "hex", + "mime", + "mime-infer", + "path-slash", + "percent-encoding", + "rust-embed", + "salvo_core", + "serde", + "serde_json", + "time", + "tokio", + "tracing", +] + +[[package]] +name = "salvo_core" +version = "0.63.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c36a49a4227992bb0e27f3c9589e24b2bd8c68a29e2ed42e03f6de6da39faa0f" +dependencies = [ + "async-trait", + "base64 0.21.6", + "bytes", + "cookie 0.18.0", + "cruet", + "enumflags2", + "form_urlencoded", + "futures-channel", + "futures-util", + "headers 0.4.0", + "http 1.0.0", + "http-body-util", + "hyper 1.1.0", + "hyper-util", + "indexmap 2.1.0", + "mime", + "mime-infer", + "multer 3.0.0", + "multimap", + "nix 0.27.1", + "once_cell", + "parking_lot", + "percent-encoding", + "pin-project", + "rand 0.8.5", + "regex", + "salvo_macros", + "serde", + "serde-xml-rs", + "serde_json", + "sync_wrapper", + "tempfile", + "thiserror", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "salvo_extra" +version = "0.63.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcfdffe788f7ae4c79bdeea16db85cd27e473a8d4bef44ba10b9323461f78087" +dependencies = [ + "base64 0.21.6", + "etag", + "futures-util", + "hyper 1.1.0", + "pin-project", + "salvo_core", + "serde", + "serde_json", + "tokio", + "tokio-tungstenite 0.21.0", + "tracing", + "ulid", +] + +[[package]] +name = "salvo_macros" +version = "0.63.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fa50756ef995d410bb1968b403a1eca169b54c3c0eb4be4bcb1da8c7591cb7d" +dependencies = [ + "cruet", + "proc-macro-crate 2.0.1", + "proc-macro2", + "quote", + "regex", + "syn 2.0.48", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sanitize-filename" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ed72fbaf78e6f2d41744923916966c4fbe3d7c74e3037a8ee482f1115572603" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scraper" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59e25654b5e9fd557a67dbaab5a5d36b8c448d0561beb4c041b6dbb902eddfa6" +dependencies = [ + "ahash 0.8.7", + "cssparser 0.29.6", + "ego-tree", + "getopts", + "html5ever", + "once_cell", + "selectors 0.24.0", + "smallvec", + "tendril", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array 0.14.7", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags 1.3.2", + "cssparser 0.27.2", + "derive_more", + "fxhash", + "log", + "matches", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc 0.1.1", + "smallvec", + "thin-slice", +] + +[[package]] +name = "selectors" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" +dependencies = [ + "bitflags 1.3.2", + "cssparser 0.29.6", + "derive_more", + "fxhash", + "log", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc 0.2.0", + "smallvec", +] + +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +dependencies = [ + "serde", +] + +[[package]] +name = "separator" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5" + +[[package]] +name = "serde" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde-xml-rs" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782" +dependencies = [ + "log", + "serde", + "thiserror", + "xml-rs", +] + +[[package]] +name = "serde_cbor" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" +dependencies = [ + "half 1.8.2", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_json" +version = "1.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +dependencies = [ + "itoa 1.0.10", + "ryu", + "serde", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebd154a240de39fdebcf5775d2675c204d7c13cf39a4c697be6493c8e734337c" +dependencies = [ + "itoa 1.0.10", + "serde", +] + +[[package]] +name = "serde_plain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_qs" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c" +dependencies = [ + "percent-encoding", + "serde", + "thiserror", +] + +[[package]] +name = "serde_regex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8136f1a4ea815d7eac4101cfd0b16dc0cb5e1fe1b8609dfd728058656b7badf" +dependencies = [ + "regex", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa 1.0.10", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +dependencies = [ + "base64 0.21.6", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.1.0", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "server_fn" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfed18dfcc8d9004579c40482c3419c07f60ffb9c5b250542edca99f508b0ce9" +dependencies = [ + "ciborium", + "const_format", + "gloo-net 0.2.6", + "inventory", + "js-sys", + "lazy_static", + "once_cell", + "proc-macro2", + "quote", + "reqwest", + "serde", + "serde_json", + "serde_qs", + "server_fn_macro_default", + "syn 2.0.48", + "thiserror", + "xxhash-rust", +] + +[[package]] +name = "server_fn_macro" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b70ae8e22546ba85500391b36c08e3fba64871be8a26557a3663a8e08acb56f" +dependencies = [ + "const_format", + "proc-macro-error", + "proc-macro2", + "quote", + "serde", + "syn 2.0.48", + "xxhash-rust", +] + +[[package]] +name = "server_fn_macro_default" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7256ba61dfadb220598db418376e7bc2a34b96df36c4dc48f24ffe161810fc0b" +dependencies = [ + "server_fn_macro", + "syn 2.0.48", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "servo_arc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha1_smol" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae1a47186c03a32177042e55dbc5fd5aee900b8e0069a8d70fba96a9375cd012" + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + +[[package]] +name = "shipyard" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3511ae730f2e1c3d62a9025e2f9b2acbf130968057f1b3caab6d74a54a5e0e56" +dependencies = [ + "hashbrown 0.12.3", + "lock_api", + "rayon", + "shipyard_proc", +] + +[[package]] +name = "shipyard_proc" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb847f4b9582e468198b5cfb5731b65cc67fe5e535acc9cbf3c11703d15f08c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "signal-hook" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "simd-abstraction" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cadb29c57caadc51ff8346233b5cec1d240b68ce55cf1afc764818791876987" +dependencies = [ + "outref", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simd_helpers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95890f873bec569a0362c235787f3aca6e1e887302ba4840839bcc6459c42da6" +dependencies = [ + "quote", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "simple_logger" +version = "4.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e7e46c8c90251d47d08b28b8a419ffb4aede0f87c2eea95e17d1d5bacbf3ef1" +dependencies = [ + "colored 2.1.0", + "log", + "time", + "windows-sys 0.48.0", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "sledgehammer_bindgen" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9298e863f0143b89972299110a7fa3e2fc08c412341d588c497bae38409f9e68" +dependencies = [ + "quote", + "syn 2.0.48", +] + +[[package]] +name = "sledgehammer_utils" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd16550f1dd7866c7580dbf80c892dc1bef106737eeb850d42c62ec61896059" +dependencies = [ + "lru 0.8.1", + "once_cell", + "rustc-hash", +] + +[[package]] +name = "slotmap" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallbox" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d92359f97e6b417da4328a970cf04a044db104fbd57f7d72cb7ff665bb8806af" + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "smartstring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" +dependencies = [ + "autocfg", + "static_assertions", + "version_check", +] + +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "soup3" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" +dependencies = [ + "futures-channel", + "gio", + "glib", + "libc", + "soup3-sys", +] + +[[package]] +name = "soup3-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spinning" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d4f0e86297cad2658d92a707320d87bf4e6ae1050287f51d19b67ef3f153a7b" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +dependencies = [ + "itertools 0.12.0", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +dependencies = [ + "ahash 0.8.7", + "atoi", + "bigdecimal", + "bit-vec", + "byteorder", + "bytes", + "chrono", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener 2.5.3", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap 2.1.0", + "ipnetwork", + "log", + "mac_address", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rust_decimal", + "rustls 0.21.10", + "rustls-pemfile", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "time", + "tokio", + "tokio-stream", + "tracing", + "url", + "uuid", + "webpki-roots", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +dependencies = [ + "atomic-write-file", + "dotenvy", + "either", + "heck 0.4.1", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +dependencies = [ + "atoi", + "base64 0.21.6", + "bigdecimal", + "bitflags 2.4.1", + "byteorder", + "bytes", + "chrono", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array 0.14.7", + "hex", + "hkdf", + "hmac", + "itoa 1.0.10", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand 0.8.5", + "rsa", + "rust_decimal", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +dependencies = [ + "atoi", + "base64 0.21.6", + "bigdecimal", + "bit-vec", + "bitflags 2.4.1", + "byteorder", + "chrono", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "ipnetwork", + "itoa 1.0.10", + "log", + "mac_address", + "md-5", + "memchr", + "num-bigint", + "once_cell", + "rand 0.8.5", + "rust_decimal", + "serde", + "serde_json", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "time", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +dependencies = [ + "atoi", + "chrono", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "time", + "tracing", + "url", + "urlencoding", + "uuid", +] + +[[package]] +name = "stable-pattern" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" +dependencies = [ + "memchr", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "state" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" +dependencies = [ + "loom", +] + +[[package]] +name = "static-hydrated" +version = "0.1.0" +dependencies = [ + "dioxus", + "dioxus-fullstack", + "dioxus-router", + "dioxus-web", + "serde", + "tokio", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "str-buf" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e75b72ee54e2f93c3ea1354066162be893ee5e25773ab743de3e088cecbb4f31" + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strum" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.48", +] + +[[package]] +name = "subprocess" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2e86926081dda636c546d8c5e641661049d7562a68f5488be4a1f7f66f6086" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "supports-color" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ba6faf2ca7ee42fdd458f4347ae0a9bd6bcc445ad7cb57ad82b383f18870d6f" +dependencies = [ + "atty", + "is_ci", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "system-deps" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2d580ff6a20c55dfb86be5f9c238f67835d0e81cbdea8bf5680e0897320331" +dependencies = [ + "cfg-expr 0.15.6", + "heck 0.4.1", + "pkg-config", + "toml 0.8.2", + "version-compare", +] + +[[package]] +name = "taffy" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c2287b6d7f721ada4cddf61ade5e760b2c6207df041cac9bfaa192897362fd3" +dependencies = [ + "arrayvec", + "grid", + "num-traits", + "slotmap", +] + +[[package]] +name = "tao" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0dff18fed076d29cb5779e918ef4b8a5dbb756204e4a027794f0bce233d949" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cocoa", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dispatch", + "gdkwayland-sys", + "gdkx11-sys", + "gtk", + "image", + "instant", + "jni", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "once_cell", + "parking_lot", + "png", + "raw-window-handle 0.5.2", + "raw-window-handle 0.6.0", + "scopeguard", + "tao-macros", + "unicode-segmentation", + "url", + "windows 0.52.0", + "windows-implement", + "windows-version", + "x11-dl", + "zbus", +] + +[[package]] +name = "tao-macros" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec114582505d158b669b136e6851f85840c109819d77c42bb7c0709f727d18c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tar" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b16afcea1f22891c49a00c751c7b63b2233284064f11a200fc624137c51e2ddb" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "target-lexicon" +version = "0.12.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69758bda2e78f098e4ccb393021a0963bb3442eac05f135c30f61b7370bbafae" + +[[package]] +name = "tauri-bundler" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c08935ca08f698ea9fc1038322b95f0a2834a7864d7e6ef62ba619ae5b51876" +dependencies = [ + "anyhow", + "ar", + "dirs-next", + "dunce", + "glob", + "handlebars", + "heck 0.4.1", + "hex", + "image", + "libflate", + "log", + "md5", + "native-tls", + "os_pipe", + "plist", + "regex", + "semver", + "serde", + "serde_json", + "sha1", + "sha2", + "strsim", + "tar", + "tauri-icns", + "tauri-utils", + "tempfile", + "thiserror", + "time", + "ureq", + "uuid", + "walkdir", + "windows-sys 0.48.0", + "winreg", + "zip", +] + +[[package]] +name = "tauri-icns" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b7eb4d0d43724ba9ba6a6717420ee68aee377816a3edbb45db8c18862b1431" +dependencies = [ + "byteorder", + "png", +] + +[[package]] +name = "tauri-utils" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ece74810b1d3d44f29f732a7ae09a63183d63949bbdd59c61f8ed2a1b70150db" +dependencies = [ + "ctor", + "dunce", + "glob", + "heck 0.4.1", + "html5ever", + "infer 0.13.0", + "json-patch", + "kuchikiki", + "log", + "memchr", + "phf 0.11.2", + "semver", + "serde", + "serde_json", + "serde_with", + "thiserror", + "url", + "walkdir", + "windows-version", +] + +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand 2.0.1", + "redox_syscall", + "rustix 0.38.28", + "windows-sys 0.48.0", +] + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "terminal-prompt" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "572818b3472910acbd5dff46a3413715c18e934b071ab2ba464a7b2c2af16376" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tiff" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "time" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +dependencies = [ + "deranged", + "itoa 1.0.10", + "libc", + "num_threads", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +dependencies = [ + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "to_method" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8" + +[[package]] +name = "tokio" +version = "1.35.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.5.5", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.9", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.10", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.17.3", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.20.1", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c83b561d025642014097b66e6c1bb422783339e0909e4429cde4749d1990bc38" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.21.0", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "futures-util", + "hashbrown 0.14.3", + "pin-project-lite", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.19.15", +] + +[[package]] +name = "toml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +dependencies = [ + "indexmap 2.1.0", + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit 0.20.2", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.1.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.1.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aba3f3efabf7fb41fae8534fc20a817013dd1c12cb45441efb6c82e6556b4cd8" +dependencies = [ + "async-compression 0.3.15", + "base64 0.13.1", + "bitflags 1.3.2", + "bytes", + "futures-core", + "futures-util", + "http 0.2.11", + "http-body 0.4.6", + "http-range-header", + "httpdate", + "iri-string", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f873044bf02dd1e8239e9c1293ea39dad76dc594ec16185d0a1bf31d8dc8d858" +dependencies = [ + "bitflags 1.3.2", + "bytes", + "futures-core", + "futures-util", + "http 0.2.11", + "http-body 0.4.6", + "http-range-header", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +dependencies = [ + "async-compression 0.4.5", + "base64 0.21.6", + "bitflags 2.4.1", + "bytes", + "futures-core", + "futures-util", + "http 0.2.11", + "http-body 0.4.6", + "http-range-header", + "httpdate", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "tracing-wasm" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07" +dependencies = [ + "tracing", + "tracing-subscriber", + "wasm-bindgen", +] + +[[package]] +name = "treediff" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52984d277bdf2a751072b5df30ec0377febdb02f7696d64c2d7d54630bac4303" +dependencies = [ + "serde_json", +] + +[[package]] +name = "trust-dns-proto" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.4.0", + "ipnet", + "once_cell", + "rand 0.8.5", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand 0.8.5", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", + "trust-dns-proto", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "trybuild" +version = "1.0.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76de4f783e610194f6c98bfd53f9fc52bb2e0d02c947621e8a0f4ecc799b2880" +dependencies = [ + "basic-toml", + "dissimilar", + "glob", + "once_cell", + "serde", + "serde_derive", + "serde_json", + "termcolor", +] + +[[package]] +name = "tungstenite" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes", + "http 0.2.11", + "httparse", + "log", + "rand 0.8.5", + "sha-1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 0.2.11", + "httparse", + "log", + "rand 0.8.5", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ef1a641ea34f399a848dea702823bbecfb4c486f911735368f1f137cb8257e1" +dependencies = [ + "byteorder", + "bytes", + "log", + "rand 0.8.5", + "thiserror", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ubyte" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f720def6ce1ee2fc44d40ac9ed6d3a59c361c80a75a7aa8e75bb9baed31cf2ea" +dependencies = [ + "serde", +] + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset 0.9.0", + "tempfile", + "winapi", +] + +[[package]] +name = "ulid" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e37c4b6cbcc59a8dcd09a6429fbc7890286bcbb79215cea7b38a3c4c0921d93" +dependencies = [ + "rand 0.8.5", +] + +[[package]] +name = "uncased" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68" +dependencies = [ + "serde", + "version_check", +] + +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" + +[[package]] +name = "unicode-bom" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7eec5d1121208364f6793f7d2e222bf75a915c19557537745b195b253dd64217" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" +dependencies = [ + "base64 0.21.6", + "log", + "native-tls", + "once_cell", + "rustls 0.21.10", + "rustls-webpki", + "url", + "webpki-roots", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +dependencies = [ + "getrandom 0.2.12", + "serde", + "sha1_smol", +] + +[[package]] +name = "v_frame" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c372e4e6fad129795fb86fda6021b258948560b39883b80ed00510a7d19846b0" +dependencies = [ + "cfg-if", + "noop_proc_macro", + "num-derive 0.4.1", + "num-traits", + "profiling", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "value-bag" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cdbaf5e132e593e9fc1de6a15bbec912395b11fb9719e061cf64f804524c503" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version-compare" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vlq" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65dd7eed29412da847b0f78bcec0ac98588165988a8cfe41d4ea1d429f8ccfff" + +[[package]] +name = "waker-fn" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "walrus" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c03529cd0c4400a2449f640d2f27cd1b48c3065226d15e26d98e4429ab0adb7" +dependencies = [ + "anyhow", + "gimli 0.26.2", + "id-arena", + "leb128", + "log", + "walrus-macro", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "walrus-macro" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e5bd22c71e77d60140b0bd5be56155a37e5bd14e24f5f87298040d0cc40d7" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "warp" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1e92e22e03ff1230c03a1a8ee37d2f89cd489e2e541b7550d6afad96faed169" +dependencies = [ + "async-compression 0.3.15", + "bytes", + "futures-channel", + "futures-util", + "headers 0.3.9", + "http 0.2.11", + "hyper 0.14.28", + "log", + "mime", + "mime_guess", + "multer 2.1.0", + "percent-encoding", + "pin-project", + "rustls-pemfile", + "scoped-tls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-stream", + "tokio-tungstenite 0.20.1", + "tokio-util", + "tower-service", + "tracing", +] + +[[package]] +name = "warp-hello-world" +version = "0.1.0" +dependencies = [ + "dioxus", + "dioxus-fullstack", + "dioxus-web", + "execute", + "reqwest", + "serde", + "simple_logger", + "tracing", + "tracing-subscriber", + "tracing-wasm", + "warp", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-cli-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8226e223e2dfbe8f921b7f20b82d1b5d86a6b143e9d6286cca8edd16695583" +dependencies = [ + "anyhow", + "base64 0.9.3", + "log", + "rustc-demangle", + "serde_json", + "tempfile", + "unicode-ident", + "walrus", + "wasm-bindgen-externref-xform", + "wasm-bindgen-multi-value-xform", + "wasm-bindgen-shared", + "wasm-bindgen-threads-xform", + "wasm-bindgen-wasm-conventions", + "wasm-bindgen-wasm-interpreter", +] + +[[package]] +name = "wasm-bindgen-externref-xform" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a719be856d8b0802c7195ca26ee6eb02cb9639a12b80be32db960ce9640cb8" +dependencies = [ + "anyhow", + "walrus", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-multi-value-xform" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12766255d4b9026700376cc81894eeb62903e4414cbc94675f6f9babd9cfb76" +dependencies = [ + "anyhow", + "walrus", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cf9242c0d27999b831eae4767b2a146feb0b27d332d553e605864acd2afd403" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "794645f5408c9a039fd09f4d113cdfb2e7eba5ff1956b07bcf701cf4b394fe89" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "wasm-bindgen-threads-xform" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2b14c5b9c2c7aa9dd1eb7161857de9783f40e98582e7f41f2d7c04ffdc155" +dependencies = [ + "anyhow", + "walrus", + "wasm-bindgen-wasm-conventions", +] + +[[package]] +name = "wasm-bindgen-wasm-conventions" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaedf88769cb23c6fd2e3bfed65bcbff6c5d92c8336afbd80d2dfcc8eb5cf047" +dependencies = [ + "anyhow", + "walrus", +] + +[[package]] +name = "wasm-bindgen-wasm-interpreter" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8a79039df1e0822e6d66508ec86052993deac201e26060f62abcd85e1daf951" +dependencies = [ + "anyhow", + "log", + "walrus", + "wasm-bindgen-wasm-conventions", +] + +[[package]] +name = "wasm-encoder" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18c41dbd92eaebf3612a39be316540b8377c871cb9bde6b064af962984912881" +dependencies = [ + "leb128", +] + +[[package]] +name = "wasm-logger" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "074649a66bb306c8f2068c9016395fa65d8e08d2affcbf95acf3c24c3ab19718" +dependencies = [ + "log", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-streams" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasmparser" +version = "0.80.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "449167e2832691a1bff24cde28d2804e90e09586a448c8e76984792c44334a6b" + +[[package]] +name = "web-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webbrowser" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b2391658b02c27719fc5a0a73d6e696285138e8b12fba9d4baa70451023c71" +dependencies = [ + "core-foundation", + "home", + "jni", + "log", + "ndk-context", + "objc", + "raw-window-handle 0.5.2", + "url", + "web-sys", +] + +[[package]] +name = "webkit2gtk" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", +] + +[[package]] +name = "webp" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb5d8e7814e92297b0e1c773ce43d290bef6c17452dafd9fc49e5edb5beba71" +dependencies = [ + "libwebp-sys", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "webpki-roots" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" + +[[package]] +name = "webview2-com" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0ae9c7e420783826cf769d2c06ac9ba462f450eca5893bb8c6c6529a4e5dd33" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows 0.52.0", + "windows-core", + "windows-implement", + "windows-interface", +] + +[[package]] +name = "webview2-com-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1345798ecd8122468840bcdf1b95e5dc6d2206c5e4b0eafa078d061f59c9bc" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "webview2-com-sys" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ad85fceee6c42fa3d61239eba5a11401bf38407a849ed5ea1b407df08cca72" +dependencies = [ + "thiserror", + "windows 0.52.0", + "windows-core", +] + +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.28", +] + +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" + +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-implement", + "windows-interface", + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-implement" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12168c33176773b86799be25e2a2ba07c7aab9968b37541f1094dbd7a60c8946" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "windows-interface" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d8dc32e0095a7eeccebd0e3f09e9509365ecb3fc6ac4d6f5f14a3f6392942d1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows-version" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75aa004c988e080ad34aff5739c39d0312f4684699d6d71fc8a198d057b8b9b4" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winnow" +version = "0.5.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wry" +version = "0.35.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3016c47c9b6f7029a9da7cd48af8352327226bba0e955f3c92e2966651365a9" +dependencies = [ + "base64 0.21.6", + "block", + "cfg_aliases", + "cocoa", + "core-graphics", + "crossbeam-channel", + "dunce", + "gdkx11", + "gtk", + "html5ever", + "http 0.2.11", + "javascriptcore-rs", + "jni", + "kuchikiki", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "objc_id", + "once_cell", + "raw-window-handle 0.5.2", + "serde", + "serde_json", + "sha2", + "soup3", + "tao-macros", + "thiserror", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows 0.52.0", + "windows-implement", + "windows-version", + "x11-dl", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "xattr" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "914566e6413e7fa959cc394fb30e563ba80f3541fbd40816d4c05a0fc3f2a0f1" +dependencies = [ + "libc", + "linux-raw-sys 0.4.12", + "rustix 0.38.28", +] + +[[package]] +name = "xdg-home" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2769203cd13a0c6015d515be729c526d041e9cf2c0cc478d57faee85f40c6dcd" +dependencies = [ + "nix 0.26.4", + "winapi", +] + +[[package]] +name = "xml-rs" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcb9cbac069e033553e8bb871be2fbdffcab578eb25bd0f7c508cedc6dcd75a" + +[[package]] +name = "xxhash-rust" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53be06678ed9e83edb1745eb72efc0bbcd7b5c3c35711a860906aed827a13d61" + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "yansi" +version = "1.0.0-rc.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1367295b8f788d371ce2dbc842c7b709c73ee1364d30351dd300ec2203b12377" +dependencies = [ + "is-terminal", +] + +[[package]] +name = "zbus" +version = "3.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31de390a2d872e4cd04edd71b425e29853f786dc99317ed72d73d6fcf5ebb948" +dependencies = [ + "async-broadcast", + "async-executor", + "async-fs", + "async-io 1.13.0", + "async-lock 2.8.0", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "byteorder", + "derivative", + "enumflags2", + "event-listener 2.5.3", + "futures-core", + "futures-sink", + "futures-util", + "hex", + "nix 0.26.4", + "once_cell", + "ordered-stream", + "rand 0.8.5", + "serde", + "serde_repr", + "sha1", + "static_assertions", + "tracing", + "uds_windows", + "winapi", + "xdg-home", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "3.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1794a946878c0e807f55a397187c11fc7a038ba5d868e7db4f3bd7760bc9d" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "regex", + "syn 1.0.109", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb80bb776dbda6e23d705cf0123c3b95df99c4ebeaec6c2599d4a5419902b4a9" +dependencies = [ + "serde", + "static_assertions", + "zvariant", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils", + "flate2", + "hmac", + "pbkdf2", + "sha1", + "time", + "zstd 0.11.2+zstd.1.5.2", +] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe 5.0.2+zstd.1.5.2", +] + +[[package]] +name = "zstd" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" +dependencies = [ + "zstd-safe 7.0.0", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-safe" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", +] + +[[package]] +name = "zune-inflate" +version = "0.2.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ab332fe2f6680068f3582b16a24f90ad7096d5d39b974d1c0aff0125116f02" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "zvariant" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44b291bee0d960c53170780af148dca5fa260a63cdd24f1962fa82e03e53338c" +dependencies = [ + "byteorder", + "enumflags2", + "libc", + "serde", + "static_assertions", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "934d7a7dfc310d6ee06c87ffe88ef4eca7d3e37bb251dece2ef93da8f17d8ecd" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] diff --git a/Cargo.toml b/Cargo.toml index 9fc38df5f..a3de51715 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,11 +4,13 @@ members = [ "packages/dioxus", "packages/core", "packages/cli", + "packages/cli-config", "packages/core-macro", "packages/router-macro", "packages/extension", "packages/router", "packages/html", + "packages/html-internal-macro", "packages/hooks", "packages/web", "packages/ssr", @@ -60,6 +62,7 @@ dioxus-core-macro = { path = "packages/core-macro", version = "0.4.0" } dioxus-router = { path = "packages/router", version = "0.4.1" } dioxus-router-macro = { path = "packages/router-macro", version = "0.4.1" } dioxus-html = { path = "packages/html", default-features = false, version = "0.4.0" } +dioxus-html-internal-macro = { path = "packages/html-internal-macro", version = "0.4.0" } dioxus-hooks = { path = "packages/hooks", version = "0.4.0" } dioxus-web = { path = "packages/web", version = "0.4.0" } dioxus-ssr = { path = "packages/ssr", version = "0.4.0" } @@ -77,6 +80,7 @@ dioxus-native-core = { path = "packages/native-core", version = "0.4.0" } dioxus-native-core-macro = { path = "packages/native-core-macro", version = "0.4.0" } rsx-rosetta = { path = "packages/rsx-rosetta", version = "0.4.0" } dioxus-signals = { path = "packages/signals" } +dioxus-cli-config = { path = "packages/cli-config", version = "0.4.1" } generational-box = { path = "packages/generational-box", version = "0.4.3" } dioxus-hot-reload = { path = "packages/hot-reload", version = "0.4.0" } dioxus-fullstack = { path = "packages/fullstack", version = "0.4.1" } @@ -94,6 +98,11 @@ thiserror = "1.0.40" prettyplease = { package = "prettier-please", version = "0.2", features = [ "verbatim", ] } +manganis-cli-support = { git = "https://github.com/DioxusLabs/collect-assets", rev = "e0093a4", features = [ + "webp", + "html", +] } +manganis = { git = "https://github.com/DioxusLabs/collect-assets", rev = "e0093a4" } # This is a "virtual package" # It is not meant to be published, but is used so "cargo run --example XYZ" works properly @@ -129,12 +138,10 @@ serde_json = "1.0.79" rand = { version = "0.8.4", features = ["small_rng"] } tokio = { version = "1.16.1", features = ["full"] } reqwest = { version = "0.11.9", features = ["json"] } -fern = { version = "0.6.0", features = ["colored"] } env_logger = "0.10.0" simple_logger = "4.0.0" thiserror = { workspace = true } - - -[dependencies] +manganis = { workspace = true } tracing-subscriber = "0.3.17" http-range = "0.1.5" + diff --git a/Makefile.toml b/Makefile.toml index 1bfb02217..98af226aa 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -105,6 +105,8 @@ args = [ "dioxus-router", "--exclude", "dioxus-desktop", + "--exclude", + "dioxus-mobile", ] private = true diff --git a/examples/README.md b/examples/README.md index 93530ba30..a20ffe60e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -139,7 +139,6 @@ Missing Features Missing examples - Shared state - Root-less element groups -- Spread props - Custom elements - Component Children: Pass children into child components - Render To string: Render a mounted virtualdom to a string diff --git a/examples/all_events.rs b/examples/all_events.rs index 3f57ec747..14fd1282e 100644 --- a/examples/all_events.rs +++ b/examples/all_events.rs @@ -76,7 +76,11 @@ fn app(cx: Scope) -> Element { "Hover, click, type or scroll to see the info down below" } - div { events.read().iter().map(|event| rsx!( div { "{event:?}" } )) } + div { + for event in events.read().iter() { + div { "{event:?}" } + } + } } )) } diff --git a/examples/calculator.rs b/examples/calculator.rs index 648ccfbc3..11151dcbf 100644 --- a/examples/calculator.rs +++ b/examples/calculator.rs @@ -6,13 +6,13 @@ This calculator version uses React-style state management. All state is held as use dioxus::events::*; use dioxus::html::input_data::keyboard_types::Key; use dioxus::prelude::*; -use dioxus_desktop::{Config, WindowBuilder}; +use dioxus_desktop::{Config, LogicalSize, WindowBuilder}; fn main() { let config = Config::new().with_window( WindowBuilder::default() .with_title("Calculator") - .with_inner_size(dioxus_desktop::LogicalSize::new(300.0, 500.0)), + .with_inner_size(LogicalSize::new(300.0, 500.0)), ); dioxus_desktop::launch_cfg(app, config); @@ -58,13 +58,13 @@ fn app(cx: Scope) -> Element { }; cx.render(rsx!( - style { include_str!("./assets/calculator.css") } + style { {include_str!("./assets/calculator.css")} } div { id: "wrapper", div { class: "app", div { class: "calculator", tabindex: "0", onkeydown: handle_key_down_event, - div { class: "calculator-display", val.to_string() } + div { class: "calculator-display", "{val}" } div { class: "calculator-keypad", div { class: "input-keys", div { class: "function-keys", @@ -103,14 +103,14 @@ fn app(cx: Scope) -> Element { div { class: "digit-keys", button { class: "calculator-key key-0", onclick: move |_| input_digit(0), "0" } button { class: "calculator-key key-dot", onclick: move |_| val.make_mut().push('.'), "●" } - (1..10).map(|k| rsx!{ + for k in 1..10 { button { class: "calculator-key {k}", name: "key-{k}", onclick: move |_| input_digit(k), "{k}" } - }), + } } } div { class: "operator-keys", diff --git a/examples/clock.rs b/examples/clock.rs index f9c1892d9..ba47d994a 100644 --- a/examples/clock.rs +++ b/examples/clock.rs @@ -10,7 +10,7 @@ fn app(cx: Scope) -> Element { use_future!(cx, || async move { loop { - tokio::time::sleep(std::time::Duration::from_millis(100)).await; + tokio::time::sleep(std::time::Duration::from_millis(10)).await; count += 1; println!("current: {count}"); } diff --git a/examples/compose.rs b/examples/compose.rs index 133192281..180cd6983 100644 --- a/examples/compose.rs +++ b/examples/compose.rs @@ -32,12 +32,12 @@ fn app(cx: Scope) -> Element { } ul { - emails_sent.read().iter().map(|message| cx.render(rsx! { + for message in emails_sent.read().iter() { li { h3 { "email" } span {"{message}"} } - })) + } } } }) diff --git a/examples/control_focus.rs b/examples/control_focus.rs index 4f4c2ddcb..f161652f0 100644 --- a/examples/control_focus.rs +++ b/examples/control_focus.rs @@ -15,8 +15,8 @@ fn app(cx: Scope) -> Element { if *running.current() { loop { tokio::time::sleep(std::time::Duration::from_millis(10)).await; - if let Some(element) = elements.read().get(focused) { - element.set_focus(true); + if let Some(element) = elements.with(|f| f.get(focused).cloned()) { + _ = element.set_focus(true).await; } else { focused = 0; } diff --git a/examples/crm.rs b/examples/crm.rs index 8af49b401..cd9ea330d 100644 --- a/examples/crm.rs +++ b/examples/crm.rs @@ -62,7 +62,7 @@ fn ClientList(cx: Scope) -> Element { Link { to: Route::ClientAdd {}, class: "pure-button pure-button-primary", "Add Client" } Link { to: Route::Settings {}, class: "pure-button", "Settings" } - clients.read().iter().map(|client| rsx! { + for client in clients.read().iter() { div { class: "client", style: "margin-bottom: 50px", @@ -70,7 +70,7 @@ fn ClientList(cx: Scope) -> Element { p { "Name: {client.first_name} {client.last_name}" } p { "Description: {client.description}" } } - }) + } }) } diff --git a/examples/custom_assets.rs b/examples/custom_assets.rs index 7eb9db375..9f46df924 100644 --- a/examples/custom_assets.rs +++ b/examples/custom_assets.rs @@ -10,7 +10,7 @@ fn app(cx: Scope) -> Element { p { "This should show an image:" } - img { src: mg!(image("examples/assets/logo.png").format(ImageType::Avif)).to_string() } + img { src: manganis::mg!(image("examples/assets/logo.png").format(ImageType::Avif)).to_string() } } }) } diff --git a/examples/drops.rs b/examples/drops.rs index 71a791990..6328a3f64 100644 --- a/examples/drops.rs +++ b/examples/drops.rs @@ -14,9 +14,9 @@ fn app(cx: Scope) -> Element { } render! { - (0..count).map(|_| rsx!{ + for _ in 0..count { drop_child {} - }) + } } } diff --git a/examples/dynamic_asset.rs b/examples/dynamic_asset.rs index 1c004e015..ac2ad82c1 100644 --- a/examples/dynamic_asset.rs +++ b/examples/dynamic_asset.rs @@ -1,29 +1,25 @@ use dioxus::prelude::*; -use dioxus_desktop::wry::http::Response; -use dioxus_desktop::{use_asset_handler, AssetRequest}; -use std::path::Path; +use dioxus_desktop::{use_asset_handler, wry::http::Response}; fn main() { dioxus_desktop::launch(app); } fn app(cx: Scope) -> Element { - use_asset_handler(cx, |request: &AssetRequest| { - let path = request.path().to_path_buf(); - async move { - if path != Path::new("logo.png") { - return None; - } - let image_data: &[u8] = include_bytes!("./assets/logo.png"); - Some(Response::new(image_data.into())) + use_asset_handler(cx, "logos", |request, response| { + // Note that the "logos" prefix is stripped from the URI + // + // However, the asset is absolute to its "virtual folder" - meaning it starts with a leading slash + if request.uri().path() != "/logo.png" { + return; } + + response.respond(Response::new(include_bytes!("./assets/logo.png").to_vec())); }); - cx.render(rsx! { + render! { div { - img { - src: "logo.png" - } + img { src: "/logos/logo.png" } } - }) + } } diff --git a/examples/error_handle.rs b/examples/error_handle.rs index 21b16ec45..5461032fd 100644 --- a/examples/error_handle.rs +++ b/examples/error_handle.rs @@ -22,9 +22,7 @@ fn DemoC(cx: Scope, x: i32) -> Element { result.throw()?; - cx.render(rsx! { - h1 { - "{x}" - } - }) + render! { + h1 { "{x}" } + } } diff --git a/examples/fermi.rs b/examples/fermi.rs index a15fc807f..3250471a4 100644 --- a/examples/fermi.rs +++ b/examples/fermi.rs @@ -39,9 +39,9 @@ fn ChildWithRef(cx: Scope) -> Element { cx.render(rsx! { div { ul { - names.read().iter().map(|f| rsx!{ - li { "hello: {f}" } - }) + for name in names.read().iter() { + li { "hello: {name}" } + } } button { onclick: move |_| { diff --git a/examples/file_explorer.rs b/examples/file_explorer.rs index f0534cbf8..ea89fab77 100644 --- a/examples/file_explorer.rs +++ b/examples/file_explorer.rs @@ -18,7 +18,7 @@ fn main() { ); } -const _STYLE: &str = mg!(file("./examples/assets/fileexplorer.css")); +const _STYLE: &str = manganis::mg!(file("./examples/assets/fileexplorer.css")); fn app(cx: Scope) -> Element { let files = use_ref(cx, Files::new); @@ -28,39 +28,36 @@ fn app(cx: Scope) -> Element { link { href:"https://fonts.googleapis.com/icon?family=Material+Icons", rel:"stylesheet", } header { i { class: "material-icons icon-menu", "menu" } - h1 { "Files: ", files.read().current() } + h1 { "Files: ", {files.read().current()} } span { } i { class: "material-icons", onclick: move |_| files.write().go_up(), "logout" } } main { - files.read().path_names.iter().enumerate().map(|(dir_id, path)| { + {files.read().path_names.iter().enumerate().map(|(dir_id, path)| { let path_end = path.split('/').last().unwrap_or(path.as_str()); - let icon_type = if path_end.contains('.') { - "description" - } else { - "folder" - }; rsx! ( div { class: "folder", key: "{path}", i { class: "material-icons", onclick: move |_| files.write().enter_dir(dir_id), - "{icon_type}" + if path_end.contains('.') { + "description" + } else { + "folder" + } p { class: "cooltip", "0 folders / 0 files" } } h1 { "{path_end}" } } ) - }), - files.read().err.as_ref().map(|err| { - rsx! ( - div { - code { "{err}" } - button { onclick: move |_| files.write().clear_err(), "x" } - } - ) - }) + })}, + if let Some(err) = files.read().err.as_ref() { + div { + code { "{err}" } + button { onclick: move |_| files.write().clear_err(), "x" } + } + } } } }) diff --git a/examples/file_upload.rs b/examples/file_upload.rs index 882285ddf..b78a5b343 100644 --- a/examples/file_upload.rs +++ b/examples/file_upload.rs @@ -1,4 +1,5 @@ #![allow(non_snake_case)] +use dioxus::html::HasFileData; use dioxus::prelude::*; use tokio::time::sleep; @@ -39,9 +40,30 @@ fn App(cx: Scope) -> Element { } } }, - }, - - div { "progress: {files_uploaded.read().len()}" }, + } + div { + width: "100px", + height: "100px", + border: "1px solid black", + prevent_default: "ondrop dragover dragenter", + ondrop: move |evt| { + to_owned![files_uploaded]; + async move { + if let Some(file_engine) = &evt.files() { + let files = file_engine.files(); + for file_name in &files { + if let Some(file) = file_engine.read_file_to_string(file_name).await{ + files_uploaded.write().push(file); + } + } + } + } + }, + ondragover: move |event: DragEvent| { + event.stop_propagation(); + }, + "Drop files here" + } ul { for file in files_uploaded.read().iter() { diff --git a/examples/framework_benchmark.rs b/examples/framework_benchmark.rs index 7e7a320a9..3e286332b 100644 --- a/examples/framework_benchmark.rs +++ b/examples/framework_benchmark.rs @@ -66,9 +66,9 @@ fn app(cx: Scope) -> Element { } table { tbody { - items.read().iter().enumerate().map(|(id, item)| { - let is_in_danger = if (*selected).map(|s| s == id).unwrap_or(false) {"danger"} else {""}; - rsx!(tr { class: "{is_in_danger}", + for (id, item) in items.read().iter().enumerate() { + tr { + class: if (*selected).map(|s| s == id).unwrap_or(false) { "danger" }, td { class:"col-md-1" } td { class:"col-md-1", "{item.key}" } td { class:"col-md-1", onclick: move |_| selected.set(Some(id)), @@ -80,8 +80,9 @@ fn app(cx: Scope) -> Element { } } td { class: "col-md-6" } - }) - }) + } + } + } } span { class: "preloadicon glyphicon glyphicon-remove", aria_hidden: "true" } diff --git a/examples/generic_component.rs b/examples/generic_component.rs index 3d6171a9b..ec8eeb660 100644 --- a/examples/generic_component.rs +++ b/examples/generic_component.rs @@ -7,9 +7,9 @@ fn main() { } fn app(cx: Scope) -> Element { - cx.render(rsx! { generic_child { - data: 0i32 - } }) + render! { + generic_child { data: 0 } + } } #[derive(PartialEq, Props)] @@ -18,9 +18,7 @@ struct GenericChildProps { } fn generic_child(cx: Scope>) -> Element { - let data = &cx.props.data; - - cx.render(rsx! { div { - "{data}" - } }) + render! { + div { "{&cx.props.data}" } + } } diff --git a/examples/hello_world.rs b/examples/hello_world.rs index 9553f5c7e..52d9e9886 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -5,7 +5,7 @@ fn main() { } fn app(cx: Scope) -> Element { - cx.render(rsx! ( + render! { div { "Hello, world!" } - )) + } } diff --git a/examples/inputs.rs b/examples/inputs.rs index 311afc1f0..00fc279ed 100644 --- a/examples/inputs.rs +++ b/examples/inputs.rs @@ -37,7 +37,7 @@ const FIELDS: &[(&str, &str)] = &[ fn app(cx: Scope) -> Element { cx.render(rsx! { div { margin_left: "30px", - select_example(cx), + {select_example(cx)}, div { // handling inputs on divs will catch all input events below // so the value of our input event will be either huey, dewey, louie, or true/false (because of the checkboxe) @@ -114,7 +114,7 @@ fn app(cx: Scope) -> Element { } } - FIELDS.iter().map(|(field, value)| rsx! { + for (field, value) in FIELDS.iter() { div { input { id: "{field}", @@ -131,7 +131,7 @@ fn app(cx: Scope) -> Element { } br {} } - }) + } } }) } diff --git a/examples/mobile_demo/Cargo.lock b/examples/mobile_demo/Cargo.lock new file mode 100644 index 000000000..e9f9225fb --- /dev/null +++ b/examples/mobile_demo/Cargo.lock @@ -0,0 +1,3240 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fa78e18c64fce05e902adecd7a5eed15a5e0a3439f7b0e169f0252214865e3" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aho-corasick" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" +dependencies = [ + "memchr", +] + +[[package]] +name = "android_log-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85965b6739a430150bdd138e2374a98af0c3ee0d030b3bb7fc3bddff58d0102e" + +[[package]] +name = "android_logger" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ec2333c185d826313162cee39d3fcc6a84ba08114a839bebf53b961e7e75773" +dependencies = [ + "android_log-sys", + "env_logger 0.7.1", + "lazy_static", + "log", +] + +[[package]] +name = "anyhow" +version = "1.0.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener", + "futures-core", +] + +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite", + "log", + "parking", + "polling", + "rustix", + "slab", + "socket2", + "waker-fn", +] + +[[package]] +name = "async-lock" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa24f727524730b077666307f2734b4a1a1c57acb79193127dcc8914d5242dd7" +dependencies = [ + "event-listener", +] + +[[package]] +name = "async-task" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" + +[[package]] +name = "async-trait" +version = "0.1.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "atk" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39991bc421ddf72f70159011b323ff49b0f783cc676a7287c59453da2e2531cf" +dependencies = [ + "atk-sys", + "bitflags", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ad703eb64dc058024f0e57ccfa069e15a413b98dbd50a1a950e743b7f11148" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "atomic-waker" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4319208da049c43661739c5fade2ba182f09d1dc2299b32298d3a31692b17e12" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" +dependencies = [ + "async-channel", + "async-lock", + "async-task", + "atomic-waker", + "fastrand", + "futures-lite", + "log", +] + +[[package]] +name = "bumpalo" +version = "3.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" + +[[package]] +name = "bytemuck" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + +[[package]] +name = "cairo-rs" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3125b15ec28b84c238f6f476c6034016a5f6cc0221cb514ca46c532139fc97d" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "glib", + "libc", + "once_cell", + "thiserror", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c48f4af05fabdcfa9658178e1326efa061853f040ce7d72e33af6885196f421" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b40ccee03b5175c18cde8f37e7d2a33bcef6f8ec8f7cc0d81090d1bb380949c9" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cocoa" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "931d3837c286f56e3c58423ce4eba12d08db2374461a785c86f672b08b5650d6" +dependencies = [ + "bitflags", + "block", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "combine" +version = "4.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "concurrent-queue" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" + +[[package]] +name = "core-graphics" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb" +dependencies = [ + "bitflags", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" +dependencies = [ + "bitflags", + "core-foundation", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "754b69d351cdc2d8ee09ae203db831e005560fc6030da058f86ad60c92a9cb0a" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa 0.4.8", + "matches", + "phf", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.28", +] + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "debug-cell" +version = "0.1.1" +source = "git+https://github.com/Niedzwiedzw/debug-cell?rev=3352a1f8aff19f56f5e3b2018200a3338fd43d2e#3352a1f8aff19f56f5e3b2018200a3338fd43d2e" + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dioxus" +version = "0.3.2" +dependencies = [ + "dioxus-core", + "dioxus-core-macro", + "dioxus-hooks", + "dioxus-hot-reload", + "dioxus-html", + "dioxus-rsx", +] + +[[package]] +name = "dioxus-core" +version = "0.3.3" +dependencies = [ + "bumpalo", + "futures-channel", + "futures-util", + "log", + "longest-increasing-subsequence", + "rustc-hash", + "serde", + "slab", + "smallbox", +] + +[[package]] +name = "dioxus-core-macro" +version = "0.3.0" +dependencies = [ + "dioxus-rsx", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "dioxus-desktop" +version = "0.3.0" +dependencies = [ + "async-trait", + "core-foundation", + "dioxus-core", + "dioxus-html", + "dioxus-interpreter-js", + "dunce", + "futures-channel", + "futures-util", + "infer", + "log", + "objc", + "objc_id", + "rfd", + "serde", + "serde_json", + "slab", + "thiserror", + "tokio", + "urlencoding", + "webbrowser", + "wry", +] + +[[package]] +name = "dioxus-hooks" +version = "0.3.1" +dependencies = [ + "debug-cell", + "dioxus-core", + "futures-channel", + "log", + "thiserror", +] + +[[package]] +name = "dioxus-hot-reload" +version = "0.1.1" +dependencies = [ + "dioxus-core", + "dioxus-html", + "dioxus-rsx", + "interprocess-docfix", + "serde", + "serde_json", +] + +[[package]] +name = "dioxus-html" +version = "0.3.1" +dependencies = [ + "async-channel", + "async-trait", + "dioxus-core", + "enumset", + "euclid", + "keyboard-types", + "serde", + "serde-value", + "serde_json", + "serde_repr", + "tokio", +] + +[[package]] +name = "dioxus-interpreter-js" +version = "0.3.3" + +[[package]] +name = "dioxus-rsx" +version = "0.0.3" +dependencies = [ + "dioxus-core", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dtoa-short" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbaceec3c6e4211c79e7b1800fb9680527106beb2f9c51904a3210c03a448c74" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "enumset" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e875f1719c16de097dee81ed675e2d9bb63096823ed3f0ca827b7dea3028bbbb" +dependencies = [ + "enumset_derive", +] + +[[package]] +name = "enumset_derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08b6c6ab82d70f08844964ba10c7babb716de2ecaeab9be5717918a5177d3af" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "euclid" +version = "0.22.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f253bc5c813ca05792837a0ff4b3a580336b224512d48f7eda1d7dd9210787" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fdeflate" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "flate2" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a62bc1cf6f830c2ec14a513a9fb124d0a213a629668a4186f329db21fe045652" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures-channel" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" + +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" + +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "futures-task" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" + +[[package]] +name = "futures-util" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9cb33da481c6c040404a11f8212d193889e9b435db2c14fd86987f630d3ce1" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3578c60dee9d029ad86593ed88cb40f35c1b83360e12498d055022385dd9a05" +dependencies = [ + "bitflags", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3092cf797a5f1210479ea38070d9ae8a5b8e9f8f1be9f32f4643c529c7d70016" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76354f97a913e55b984759a997b693aa7dc71068c9e98bcce51aa167a0a5c5a" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4511710212ed3020b61a8622a37aa6f0dd2a84516575da92e9b96928dcbe83ba" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkx11-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa2bf8b5b8c414bc5d05e48b271896d0fd3ddb57464a3108438082da61de6af" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + +[[package]] +name = "gimli" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" + +[[package]] +name = "gio" +version = "0.16.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a1c84b4534a290a29160ef5c6eff2a9c95833111472e824fc5cb78b513dd092" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror", +] + +[[package]] +name = "gio-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9b693b8e39d042a95547fc258a7b07349b1f0b48f4b2fa3108ba3c51c0b5229" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16aa2475c9debed5a32832cb5ff2af5a3f9e1ab9e69df58eaadc1ab2004d6eba" +dependencies = [ + "bitflags", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "once_cell", + "smallvec", + "thiserror", +] + +[[package]] +name = "glib-macros" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb1a9325847aa46f1e96ffea37611b9d51fc4827e67f79e7de502a297560a67b" +dependencies = [ + "anyhow", + "heck", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "glib-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61a4f46316d06bfa33a7ac22df6f0524c8be58e3db2d9ca99ccb1f357b62a65" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gobject-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3520bb9c07ae2a12c7f2fbb24d4efc11231c8146a86956413fb1a79bb760a0f1" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gtk" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4d3507d43908c866c805f74c9dd593c0ce7ba5c38e576e41846639cdcd4bee6" +dependencies = [ + "atk", + "bitflags", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "once_cell", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b5f8946685d5fe44497007786600c2f368ff6b1e61a16251c89f72a97520a3" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "096eb63c6fedf03bafe65e5924595785eaf1bcb7200dac0f2cbe9c9738f05ad8" +dependencies = [ + "anyhow", + "proc-macro-crate", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys 0.48.0", +] + +[[package]] +name = "html5ever" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5c13fb08e5d4dfc151ee5e88bae63f7773d61852f3bdc73c9f4b9e1bde03148" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "http" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.9", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "image" +version = "0.24.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "527909aa81e20ac3a44803521443a765550f09b5130c2c2fa1ea59c2f8f50a3a" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "num-rational", + "num-traits", +] + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "infer" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6c16b11a665b26aeeb9b1d7f954cdeb034be38dd00adab4f2ae921a8fee804" +dependencies = [ + "cfb", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "interprocess-docfix" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b84ee245c606aeb0841649a9288e3eae8c61b853a8cd5c0e14450e96d53d28f" +dependencies = [ + "blocking", + "cfg-if", + "futures-core", + "futures-io", + "intmap", + "libc", + "once_cell", + "rustc_version", + "spinning", + "thiserror", + "to_method", + "winapi", +] + +[[package]] +name = "intmap" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae52f28f45ac2bc96edb7714de995cffc174a395fb0abf5bff453587c980d7b9" + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi 0.3.2", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "javascriptcore-rs" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "110b9902c80c12bf113c432d0b71c7a94490b294a8234f326fd0abca2fac0b00" +dependencies = [ + "bitflags", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98a216519a52cd941a733a0ad3f1023cfdb1cd47f3955e8e863ed56f558f916c" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "jni" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "js-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "keyboard-types" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7668b7cff6a51fe61cdde64cd27c8a220786f399501b57ebe36f7d8112fd68" +dependencies = [ + "bitflags", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "kuchiki" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ea8e9c6e031377cff82ee3001dc8026cdf431ed4e2e6b51f98ab8c73484a358" +dependencies = [ + "cssparser", + "html5ever", + "matches", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "lock_api" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" + +[[package]] +name = "longest-increasing-subsequence" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "markup5ever" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a24f40fb03852d1cdd84330cddcaf98e9ec08a7b7768e952fad3b4cf048ec8fd" +dependencies = [ + "log", + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + +[[package]] +name = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", + "simd-adler32", +] + +[[package]] +name = "mobile-demo" +version = "0.1.0" +dependencies = [ + "android_logger", + "anyhow", + "core-foundation", + "dioxus", + "dioxus-desktop", + "env_logger 0.9.3", + "jni 0.19.0", + "log", + "paste", + "wry", +] + +[[package]] +name = "ndk" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2032c77e030ddee34a6787a64166008da93f6a352b629261d0fee232b8742dd4" +dependencies = [ + "bitflags", + "jni-sys", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e5a6ae77c8ee183dcbbba6150e2e6b9f3f4196a7666c02a715a95692ec1fa97" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.2", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f646caf906c20226733ed5b1374287eb97e3c2a5c227ce668c1f2ce20ae57c9" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "object" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bda667d9f2b5051b8833f59f3bf748b28ef54f850f4fcb389a252aa383866d1" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "ordered-float" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" +dependencies = [ + "num-traits", +] + +[[package]] +name = "pango" +version = "0.16.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdff66b271861037b89d028656184059e03b0b6ccb36003820be19f7200b1e94" +dependencies = [ + "bitflags", + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e134909a9a293e04d2cc31928aa95679c5e4df954d0b85483159bd20d8f047f" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parking" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.1", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "percent-encoding" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_macros", + "phf_shared 0.8.0", + "proc-macro-hack", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c40d25201921e5ff0c862a505c6557ea88568a4e3ace775ab55e93f2f4f9d57" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" + +[[package]] +name = "png" +version = "0.17.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59871cc5b6cce7eaccca5a802b4173377a1c2ba90654246789a8fa2334426d11" +dependencies = [ + "bitflags", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" + +[[package]] +name = "rfd" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fe664af397d2b6a13a8ba1d172a2b5c87c6c5149039edbf8fa122b98c9ed96f" +dependencies = [ + "async-io", + "block", + "dispatch", + "futures-util", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc", + "objc-foundation", + "objc_id", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.37.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" +dependencies = [ + "bitflags", + "errno", + "io-lifetimes", + "libc", + "linux-raw-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "selectors" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df320f1889ac4ba6bc0cdc9c9af7af4bd64bb927bccdf32d81140dc1f9be12fe" +dependencies = [ + "bitflags", + "cssparser", + "derive_more", + "fxhash", + "log", + "matches", + "phf", + "phf_codegen", + "precomputed-hash", + "servo_arc", + "smallvec", + "thin-slice", +] + +[[package]] +name = "semver" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" + +[[package]] +name = "serde" +version = "1.0.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ea67f183f058fe88a4e3ec6e2788e003840893b91bac4559cabedd00863b3ed" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e744d7782b686ab3b73267ef05697159cc0e5abbed3f47f9933165e5219036" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "serde_json" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +dependencies = [ + "itoa 1.0.9", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "serde_spanned" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +dependencies = [ + "serde", +] + +[[package]] +name = "servo_arc" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98238b800e0d1576d8b6e3de32827c2d74bee68bb97748dcf5071fb53965432" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha2" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "siphasher" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "slab" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallbox" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4679d6eef28b85020158619fc09769de89e90886c5de7157587d87cb72648faa" + +[[package]] +name = "smallvec" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" + +[[package]] +name = "socket2" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "soup3" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82bc46048125fefd69d30b32b9d263d6556c9ffe82a7a7df181a86d912da5616" +dependencies = [ + "bitflags", + "futures-channel", + "gio", + "glib", + "libc", + "once_cell", + "soup3-sys", +] + +[[package]] +name = "soup3-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "014bbeb1c4cdb30739dc181e8d98b7908f124d9555843afa89b5570aaf4ec62b" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "spinning" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d4f0e86297cad2658d92a707320d87bf4e6ae1050287f51d19b67ef3f153a7b" +dependencies = [ + "lock_api", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot", + "phf_shared 0.10.0", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bb30289b722be4ff74a408c3cc27edeaad656e06cb1fe8fa9231fa59c728988" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro2", + "quote", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-deps" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30c2de8a4d8f4b823d634affc9cd2a74ec98c53a756f317e529a48046cbf71f3" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "tao" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "746ae5d0ca57ae275a792f109f6e992e0b41a443abdf3f5c6eff179ef5b3443a" +dependencies = [ + "bitflags", + "cairo-rs", + "cc", + "cocoa", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dispatch", + "gdk", + "gdk-pixbuf", + "gdk-sys", + "gdkwayland-sys", + "gdkx11-sys", + "gio", + "glib", + "glib-sys", + "gtk", + "image", + "instant", + "jni 0.20.0", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc", + "once_cell", + "parking_lot", + "png", + "raw-window-handle", + "scopeguard", + "serde", + "tao-macros", + "unicode-segmentation", + "uuid", + "windows", + "windows-implement", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b27a4bcc5eb524658234589bdffc7e7bfb996dbae6ce9393bfd39cb4159b445" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "target-lexicon" +version = "0.12.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thin-slice" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" + +[[package]] +name = "thiserror" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "to_method" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8" + +[[package]] +name = "tokio" +version = "1.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "532826ff75199d5833b9d2c5fe410f29235e25704ee5f0ef599fb51c21f4a4da" +dependencies = [ + "autocfg", + "backtrace", + "bytes", + "num_cpus", + "pin-project-lite", + "tokio-macros", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", +] + +[[package]] +name = "toml" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17e963a819c331dcacd7ab957d80bc2b9a9c1e71c804826d2f283dd65306542" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "unicode-bidi" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92888ba5573ff080736b3648696b70cafad7d250551175acbaa4e0385b3e1460" + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "url" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d" +dependencies = [ + "getrandom 0.2.10", +] + +[[package]] +name = "version-compare" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "waker-fn" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" + +[[package]] +name = "walkdir" +version = "2.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36df944cda56c7d8d8b7496af378e6b16de9284591917d307c9b4d313c44e698" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.28", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c02dbc21516f9f1f04f187958890d7e6026df8d16540b7ad9492bc34a67cea03" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.28", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" + +[[package]] +name = "web-sys" +version = "0.3.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webbrowser" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd222aa310eb7532e3fd427a5d7db7e44bc0b0cf1c1e21139c345325511a85b6" +dependencies = [ + "core-foundation", + "home", + "jni 0.21.1", + "log", + "ndk-context", + "objc", + "raw-window-handle", + "url", + "web-sys", +] + +[[package]] +name = "webkit2gtk" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8eea819afe15eb8dcdff4f19d8bfda540bae84d874c10e6f4b8faf2d6704bd1" +dependencies = [ + "bitflags", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0ac7a95ddd3fdfcaf83d8e513b4b1ad101b95b413b6aa6662ed95f284fc3d5b" +dependencies = [ + "bitflags", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", +] + +[[package]] +name = "webview2-com" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11296e5daf3a653b79bf47d66c380e4143d5b9c975818871179a3bda79499562" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows-implement", +] + +[[package]] +name = "webview2-com-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaebe196c01691db62e9e4ca52c5ef1e4fd837dcae27dae3ada599b5a8fd05ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "webview2-com-sys" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde542bed28058a5b028d459689ee57f1d06685bb6c266da3b91b1be6703952f" +dependencies = [ + "regex", + "serde", + "serde_json", + "thiserror", + "windows", + "windows-bindgen", + "windows-metadata", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e745dab35a0c4c77aa3ce42d595e13d2003d6902d6b08c9ef5fc326d08da12b" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-bindgen" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "222204ecf46521382a4d88b4a1bbefca9f8855697b4ab7d20803901425e061a3" +dependencies = [ + "windows-metadata", + "windows-tokens", +] + +[[package]] +name = "windows-implement" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce87ca8e3417b02dc2a8a22769306658670ec92d78f1bd420d6310a67c245c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "windows-interface" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "853f69a591ecd4f810d29f17e902d40e349fb05b0b11fff63b08b826bfe39c7f" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "windows-metadata" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee78911e3f4ce32c1ad9d3c7b0bd95389662ad8d8f1a3155688fed70bd96e2b6" + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.48.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +dependencies = [ + "windows_aarch64_gnullvm 0.48.0", + "windows_aarch64_msvc 0.48.0", + "windows_i686_gnu 0.48.0", + "windows_i686_msvc 0.48.0", + "windows_x86_64_gnu 0.48.0", + "windows_x86_64_gnullvm 0.48.0", + "windows_x86_64_msvc 0.48.0", +] + +[[package]] +name = "windows-tokens" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4251900975a0d10841c5d4bde79c56681543367ef811f3fabb8d1803b0959b" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" + +[[package]] +name = "winnow" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bd122eb777186e60c3fdf765a58ac76e41c582f1f535fbf3314434c6b58f3f7" +dependencies = [ + "memchr", +] + +[[package]] +name = "wry" +version = "0.28.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d15f9f827d537cefe6d047be3930f5d89b238dfb85e08ba6a319153217635aa" +dependencies = [ + "base64", + "block", + "cocoa", + "core-graphics", + "crossbeam-channel", + "dunce", + "gdk", + "gio", + "glib", + "gtk", + "html5ever", + "http", + "javascriptcore-rs", + "kuchiki", + "libc", + "log", + "objc", + "objc_id", + "once_cell", + "serde", + "serde_json", + "sha2", + "soup3", + "tao", + "thiserror", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", + "windows-implement", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] diff --git a/examples/mobile_demo/Cargo.toml b/examples/mobile_demo/Cargo.toml index a90ff4f36..e980774e7 100644 --- a/examples/mobile_demo/Cargo.toml +++ b/examples/mobile_demo/Cargo.toml @@ -35,7 +35,7 @@ frameworks = ["WebKit"] [dependencies] anyhow = "1.0.56" log = "0.4.11" -wry = "0.34.0" +wry = "0.35.0" dioxus = { path = "../../packages/dioxus" } dioxus-desktop = { path = "../../packages/desktop", features = [ "tokio_runtime", diff --git a/examples/openid_connect_demo/src/views/header.rs b/examples/openid_connect_demo/src/views/header.rs index 1f2c6e057..b9b99e584 100644 --- a/examples/openid_connect_demo/src/views/header.rs +++ b/examples/openid_connect_demo/src/views/header.rs @@ -41,7 +41,7 @@ pub fn LogOut(cx: Scope) -> Element { } Err(error) => { rsx! { - div { format!{"Failed to load disconnection url: {:?}", error} } + div { "Failed to load disconnection url: {error:?}" } } } }, @@ -143,9 +143,9 @@ pub fn LoadClient(cx: Scope) -> Element { } } Err(error) => { + log::info! {"Failed to load client: {:?}", error}; rsx! { - div { format!{"Failed to load client: {:?}", error} } - log::info!{"Failed to load client: {:?}", error}, + div { "Failed to load client: {error:?}" } Outlet:: {} } } @@ -184,7 +184,7 @@ pub fn AuthHeader(cx: Scope) -> Element { Ok(email) => { rsx! { div { - div { email } + div { {email} } LogOut { client_id: client_props.client_id, client: client_props.client } Outlet:: {} } @@ -207,7 +207,7 @@ pub fn AuthHeader(cx: Scope) -> Element { log::info!("Other issue with token"); rsx! { div { - div { error.to_string() } + div { "{error}" } Outlet:: {} } } diff --git a/examples/openid_connect_demo/src/views/not_found.rs b/examples/openid_connect_demo/src/views/not_found.rs index 6321dc9fc..b8fb1d8b8 100644 --- a/examples/openid_connect_demo/src/views/not_found.rs +++ b/examples/openid_connect_demo/src/views/not_found.rs @@ -2,6 +2,9 @@ use dioxus::prelude::*; #[component] pub fn NotFound(cx: Scope, route: Vec) -> Element { - let routes = route.join(""); - render! {rsx! {div{routes}}} + render! { + div{ + {route.join("")} + } + } } diff --git a/examples/pattern_model.rs b/examples/pattern_model.rs index a6c35d17a..6dd3e8825 100644 --- a/examples/pattern_model.rs +++ b/examples/pattern_model.rs @@ -21,7 +21,7 @@ use dioxus::events::*; use dioxus::html::input_data::keyboard_types::Key; use dioxus::html::MouseEvent; use dioxus::prelude::*; -use dioxus_desktop::wry::application::dpi::LogicalSize; +use dioxus_desktop::tao::dpi::LogicalSize; use dioxus_desktop::{Config, WindowBuilder}; fn main() { @@ -35,15 +35,17 @@ fn main() { dioxus_desktop::launch_cfg(app, cfg); } +const STYLE: &str = include_str!("./assets/calculator.css"); + fn app(cx: Scope) -> Element { let state = use_ref(cx, Calculator::new); cx.render(rsx! { - style { include_str!("./assets/calculator.css") } + style { {STYLE} } div { id: "wrapper", div { class: "app", div { class: "calculator", onkeypress: move |evt| state.write().handle_keydown(evt), - div { class: "calculator-display", state.read().formatted_display() } + div { class: "calculator-display", {state.read().formatted_display()} } div { class: "calculator-keypad", div { class: "input-keys", div { class: "function-keys", @@ -74,14 +76,14 @@ fn app(cx: Scope) -> Element { onclick: move |_| state.write().input_dot(), "●" } - (1..10).map(move |k| rsx!{ + for k in 1..10 { CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| state.write().input_digit(k), "{k}" } - }) + } } } div { class: "operator-keys", @@ -130,7 +132,7 @@ fn CalculatorKey<'a>(cx: Scope<'a, CalculatorKeyProps<'a>>) -> Element { button { class: "calculator-key {cx.props.name}", onclick: move |e| cx.props.onclick.call(e), - &cx.props.children + {&cx.props.children} } }) } diff --git a/examples/pattern_reducer.rs b/examples/pattern_reducer.rs index 6f7e16f6e..98c4fb2c6 100644 --- a/examples/pattern_reducer.rs +++ b/examples/pattern_reducer.rs @@ -20,7 +20,7 @@ fn app(cx: Scope) -> Element { cx.render(rsx!( div { h1 {"Select an option"} - h3 { "The radio is... ", state.is_playing(), "!" } + h3 { "The radio is... ", {state.is_playing()}, "!" } button { onclick: move |_| state.make_mut().reduce(PlayerAction::Pause), "Pause" } diff --git a/examples/query_segments_demo/src/main.rs b/examples/query_segments_demo/src/main.rs index 3303aeecd..24896a403 100644 --- a/examples/query_segments_demo/src/main.rs +++ b/examples/query_segments_demo/src/main.rs @@ -66,7 +66,7 @@ impl FromQuery for ManualBlogQuerySegments { fn BlogPost(cx: Scope, query_params: ManualBlogQuerySegments) -> Element { render! { div{"This is your blogpost with a query segment:"} - div{format!("{:?}", query_params)} + div{ "{query_params:?}" } } } @@ -74,7 +74,7 @@ fn BlogPost(cx: Scope, query_params: ManualBlogQuerySegments) -> Element { fn AutomaticBlogPost(cx: Scope, name: String, surname: String) -> Element { render! { div{"This is your blogpost with a query segment:"} - div{format!("name={}&surname={}", name, surname)} + div{ "name={name}&surname={surname}" } } } diff --git a/examples/rsx_compile_fail.rs b/examples/rsx_compile_fail.rs index 40bad709b..ad2577b08 100644 --- a/examples/rsx_compile_fail.rs +++ b/examples/rsx_compile_fail.rs @@ -36,17 +36,17 @@ fn example(cx: Scope) -> Element { div { id: "asd", "your neighborhood spiderman" - items.iter().cycle().take(5).map(|f| rsx!{ - div { "{f.a}" } - }) + for item in items.iter().cycle().take(5) { + div { "{item.a}" } + } - things_list.iter().map(|f| rsx!{ - div { "{f.a}" "{f.b}" } - }) + for thing in things_list.iter() { + div { "{thing.a}" "{thing.b}" } + } - mything_read.as_ref().map(|f| rsx! { + if let Some(f) = mything_read.as_ref() { div { "{f}" } - }) + } } } )) diff --git a/examples/rsx_usage.rs b/examples/rsx_usage.rs index 317288d55..dc452af48 100644 --- a/examples/rsx_usage.rs +++ b/examples/rsx_usage.rs @@ -61,7 +61,7 @@ fn App(cx: Scope) -> Element { h1 {"Some text"} h1 {"Some text with {formatting}"} h1 {"Formatting basic expressions {formatting_tuple.0} and {formatting_tuple.1}"} - h1 {"Formatting without interpolation " formatting_tuple.0 "and" formatting_tuple.1 } + h1 {"Formatting without interpolation " {formatting_tuple.0} "and" {formatting_tuple.1} } h2 { "Multiple" "Text" @@ -94,10 +94,10 @@ fn App(cx: Scope) -> Element { } // Expressions can be used in element position too: - rsx!(p { "More templating!" }), + {rsx!(p { "More templating!" })}, // Iterators - (0..10).map(|i| rsx!(li { "{i}" })), + {(0..10).map(|i| rsx!(li { "{i}" }))}, // Iterators within expressions { @@ -117,24 +117,25 @@ fn App(cx: Scope) -> Element { // Conditional rendering // Dioxus conditional rendering is based around None/Some. We have no special syntax for conditionals. // You can convert a bool condition to rsx! with .then and .or - true.then(|| rsx!(div {})), + {true.then(|| rsx!(div {}))}, // Alternatively, you can use the "if" syntax - but both branches must be resolve to Element if false { - rsx!(h1 {"Top text"}) + h1 {"Top text"} } else { - rsx!(h1 {"Bottom text"}) + h1 {"Bottom text"} } // Using optionals for diverging branches - if true { + // Note that since this is wrapped in curlies, it's interpreted as an expression + {if true { Some(rsx!(h1 {"Top text"})) } else { None - } + }} // returning "None" without a diverging branch is a bit noisy... but rare in practice - None as Option<()>, + {None as Option<()>}, // can also just use empty fragments Fragment {} @@ -169,13 +170,13 @@ fn App(cx: Scope) -> Element { // Can pass in props directly as an expression { - let props = TallerProps {a: "hello", children: cx.render(rsx!(()))}; + let props = TallerProps {a: "hello", children: None }; rsx!(Taller { ..props }) } // Spreading can also be overridden manually Taller { - ..TallerProps { a: "ballin!", children: cx.render(rsx!(()) )}, + ..TallerProps { a: "ballin!", children: None }, a: "not ballin!" } @@ -204,16 +205,16 @@ fn App(cx: Scope) -> Element { // helper functions // Anything that implements IntoVnode can be dropped directly into Rsx - helper(cx, "hello world!") + {helper(cx, "hello world!")} // Strings can be supplied directly - String::from("Hello world!") + {String::from("Hello world!")} // So can format_args - format_args!("Hello {}!", "world") + {format_args!("Hello {}!", "world")} // Or we can shell out to a helper function - format_dollars(10, 50) + {format_dollars(10, 50)} } }) } @@ -269,7 +270,7 @@ pub struct TallerProps<'a> { #[component] pub fn Taller<'a>(cx: Scope<'a, TallerProps<'a>>) -> Element { cx.render(rsx! { - &cx.props.children + {&cx.props.children} }) } diff --git a/examples/scroll_to_top.rs b/examples/scroll_to_top.rs index 4eb38a451..eed0a00b5 100644 --- a/examples/scroll_to_top.rs +++ b/examples/scroll_to_top.rs @@ -22,8 +22,10 @@ fn app(cx: Scope) -> Element { button { onclick: move |_| { - if let Some(header) = header_element.read().as_ref() { - header.scroll_to(ScrollBehavior::Smooth); + if let Some(header) = header_element.read().as_ref().cloned() { + cx.spawn(async move { + let _ = header.scroll_to(ScrollBehavior::Smooth).await; + }); } }, "Scroll to top" diff --git a/examples/shared_state.rs b/examples/shared_state.rs index 487aa3fe3..65ec76a71 100644 --- a/examples/shared_state.rs +++ b/examples/shared_state.rs @@ -51,26 +51,23 @@ pub fn App(cx: Scope) -> Element { #[component] fn DataEditor(cx: Scope, id: usize) -> Element { - let cool_data = use_shared_state::(cx).unwrap().read(); + let data = use_shared_state::(cx)?; - let my_data = &cool_data.view(id).unwrap(); - - render!(p { - "{my_data}" - }) + render! { + p { + {data.read().view(id)?} + } + } } #[component] fn DataView(cx: Scope, id: usize) -> Element { - let cool_data = use_shared_state::(cx).unwrap(); + let data = use_shared_state::(cx)?; - let oninput = |e: FormEvent| cool_data.write().set(*id, e.value()); - - let cool_data = cool_data.read(); - let my_data = &cool_data.view(id).unwrap(); - - render!(input { - oninput: oninput, - value: "{my_data}" - }) + render! { + input { + oninput: move |e: FormEvent| data.write().set(*id, e.value()), + value: data.read().view(id)? + } + } } diff --git a/examples/shorthand.rs b/examples/shorthand.rs new file mode 100644 index 000000000..2d71b046b --- /dev/null +++ b/examples/shorthand.rs @@ -0,0 +1,45 @@ +use dioxus::prelude::*; + +fn main() { + dioxus_desktop::launch(app); +} + +fn app(cx: Scope) -> Element { + let a = 123; + let b = 456; + let c = 789; + let class = "class"; + let id = "id"; + + // todo: i'd like it for children on elements to be inferred as the children of the element + // also should shorthands understand references/dereferences? + // ie **a, *a, &a, &mut a, etc + let children = render! { "Child" }; + let onclick = move |_| println!("Clicked!"); + + render! { + div { class, id, {&children} } + Component { a, b, c, children, onclick } + Component { a, ..ComponentProps { a: 1, b: 2, c: 3, children: None, onclick: Default::default() } } + } +} + +#[component] +fn Component<'a>( + cx: Scope<'a>, + a: i32, + b: i32, + c: i32, + children: Element<'a>, + onclick: EventHandler<'a, ()>, +) -> Element { + render! { + div { "{a}" } + div { "{b}" } + div { "{c}" } + div { {children} } + div { + onclick: move |_| onclick.call(()), + } + } +} diff --git a/examples/signals.rs b/examples/signals.rs index 0faac0af4..e72488443 100644 --- a/examples/signals.rs +++ b/examples/signals.rs @@ -31,7 +31,7 @@ fn app(cx: Scope) -> Element { // We can do boolean operations on the current signal value if count.value() > 5 { - rsx!{ h2 { "High five!" } } + h2 { "High five!" } } // We can cleanly map signals with iterators @@ -41,9 +41,9 @@ fn app(cx: Scope) -> Element { // We can also use the signal value as a slice if let [ref first, .., ref last] = saved_values.read().as_slice() { - rsx! { li { "First and last: {first}, {last}" } } + li { "First and last: {first}, {last}" } } else { - rsx! { "No saved values" } + "No saved values" } }) } diff --git a/examples/simple_list.rs b/examples/simple_list.rs index 84cd9db71..feb5aa3b4 100644 --- a/examples/simple_list.rs +++ b/examples/simple_list.rs @@ -8,17 +8,17 @@ fn app(cx: Scope) -> Element { cx.render(rsx!( div { // Use Map directly to lazily pull elements - (0..10).map(|f| rsx! { "{f}" }), + {(0..10).map(|f| rsx! { "{f}" })}, // Collect into an intermediate collection if necessary, and call into_iter - ["a", "b", "c", "d", "e", "f"] + {["a", "b", "c", "d", "e", "f"] .into_iter() .map(|f| rsx! { "{f}" }) .collect::>() - .into_iter(), + .into_iter()}, // Use optionals - Some(rsx! { "Some" }), + {Some(rsx! { "Some" })}, // use a for loop where the body itself is RSX for name in 0..10 { @@ -27,7 +27,7 @@ fn app(cx: Scope) -> Element { // Or even use an unterminated conditional if true { - rsx!{ "hello world!" } + "hello world!" } } )) diff --git a/examples/spread.rs b/examples/spread.rs new file mode 100644 index 000000000..45bdc90af --- /dev/null +++ b/examples/spread.rs @@ -0,0 +1,36 @@ +use dioxus::prelude::*; + +fn main() { + let mut dom = VirtualDom::new(app); + let _ = dom.rebuild(); + let html = dioxus_ssr::render(&dom); + + println!("{}", html); +} + +fn app(cx: Scope) -> Element { + render! { + Component { + width: "10px", + extra_data: "hello{1}", + extra_data2: "hello{2}", + height: "10px", + left: 1 + } + } +} + +#[component] +fn Component<'a>(cx: Scope<'a, Props<'a>>) -> Element<'a> { + render! { + audio { ..cx.props.attributes, "1: {cx.props.extra_data}\n2: {cx.props.extra_data2}" } + } +} + +#[derive(Props)] +struct Props<'a> { + #[props(extends = GlobalAttributes)] + attributes: Vec>, + extra_data: &'a str, + extra_data2: &'a str, +} diff --git a/examples/streams.rs b/examples/streams.rs new file mode 100644 index 000000000..005f73f53 --- /dev/null +++ b/examples/streams.rs @@ -0,0 +1,33 @@ +use dioxus::prelude::*; +use dioxus_signals::use_signal; +use futures_util::{future, stream, Stream, StreamExt}; +use std::time::Duration; + +fn main() { + dioxus_desktop::launch(app); +} + +fn app(cx: Scope) -> Element { + let count = use_signal(cx, || 10); + + use_future(cx, (), |_| async move { + let mut stream = some_stream(); + + while let Some(second) = stream.next().await { + count.set(second); + } + }); + + cx.render(rsx! { + h1 { "High-Five counter: {count}" } + }) +} + +fn some_stream() -> std::pin::Pin>> { + Box::pin( + stream::once(future::ready(0)).chain(stream::iter(1..).then(|second| async move { + tokio::time::sleep(Duration::from_secs(1)).await; + second + })), + ) +} diff --git a/examples/svg.rs b/examples/svg.rs index 329cbe6ae..f7a28d0cb 100644 --- a/examples/svg.rs +++ b/examples/svg.rs @@ -97,7 +97,7 @@ pub fn Die<'a>(cx: Scope<'a, DieProps<'a>>) -> Element { fill: "{fill}", } - dots + {dots} } }) } diff --git a/examples/tailwind/Cargo.toml b/examples/tailwind/Cargo.toml index 26ac202f1..f61f1def8 100644 --- a/examples/tailwind/Cargo.toml +++ b/examples/tailwind/Cargo.toml @@ -13,6 +13,7 @@ publish = false [dependencies] dioxus = { path = "../../packages/dioxus" } +manganis = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] dioxus-desktop = { path = "../../packages/desktop" } diff --git a/examples/tailwind/src/main.rs b/examples/tailwind/src/main.rs index 10124e47c..fe0016651 100644 --- a/examples/tailwind/src/main.rs +++ b/examples/tailwind/src/main.rs @@ -2,7 +2,7 @@ use dioxus::prelude::*; -const _STYLE: &str = mg!(file("./public/tailwind.css")); +const _STYLE: &str = manganis::mg!(file("./public/tailwind.css")); fn main() { #[cfg(not(target_arch = "wasm32"))] diff --git a/examples/todomvc.rs b/examples/todomvc.rs index cdf41aaa0..d5e56dd1a 100644 --- a/examples/todomvc.rs +++ b/examples/todomvc.rs @@ -7,8 +7,6 @@ fn main() { dioxus_desktop::launch(app); } -const _STYLE: &str = mg!(file("./examples/assets/todomvc.css")); - #[derive(PartialEq, Eq, Clone, Copy)] pub enum FilterState { All, @@ -49,33 +47,34 @@ pub fn app(cx: Scope<()>) -> Element { cx.render(rsx! { section { class: "todoapp", + style { {include_str!("./assets/todomvc.css")} } TodoHeader { todos: todos } section { class: "main", if !todos.is_empty() { - rsx! { - input { - id: "toggle-all", - class: "toggle-all", - r#type: "checkbox", - onchange: move |_| { - let check = active_todo_count != 0; - for (_, item) in todos.make_mut().iter_mut() { - item.checked = check; - } - }, - checked: if active_todo_count == 0 { "true" } else { "false" }, - } - label { r#for: "toggle-all" } + input { + id: "toggle-all", + class: "toggle-all", + r#type: "checkbox", + onchange: move |_| { + let check = active_todo_count != 0; + for (_, item) in todos.make_mut().iter_mut() { + item.checked = check; + } + }, + checked: if active_todo_count == 0 { "true" } else { "false" }, } + label { r#for: "toggle-all" } } ul { class: "todo-list", - filtered_todos.iter().map(|id| rsx!(TodoEntry { - key: "{id}", - id: *id, - todos: todos, - })) + for id in filtered_todos.iter() { + TodoEntry { + key: "{id}", + id: *id, + todos: todos, + } + } } - (!todos.is_empty()).then(|| rsx!( + if !todos.is_empty() { ListFooter { active_todo_count: active_todo_count, active_todo_text: active_todo_text, @@ -83,7 +82,7 @@ pub fn app(cx: Scope<()>) -> Element { todos: todos, filter: filter, } - )) + } } } PageFooter {} @@ -172,7 +171,7 @@ pub fn TodoEntry<'a>(cx: Scope<'a, TodoEntryProps<'a>>) -> Element { prevent_default: "onclick" } } - is_editing.then(|| rsx!{ + if **is_editing { input { class: "edit", value: "{todo.contents}", @@ -186,7 +185,7 @@ pub fn TodoEntry<'a>(cx: Scope<'a, TodoEntryProps<'a>>) -> Element { } }, } - }) + } } }) } @@ -220,29 +219,27 @@ pub fn ListFooter<'a>(cx: Scope<'a, ListFooterProps<'a>>) -> Element { } ul { class: "filters", for (state , state_text , url) in [ - (FilterState::All, "All", "#/"), - (FilterState::Active, "Active", "#/active"), - (FilterState::Completed, "Completed", "#/completed"), -] { + (FilterState::All, "All", "#/"), + (FilterState::Active, "Active", "#/active"), + (FilterState::Completed, "Completed", "#/completed"), + ] { li { a { href: url, class: selected(state), onclick: move |_| cx.props.filter.set(state), prevent_default: "onclick", - state_text + {state_text} } } } } if cx.props.show_clear_completed { - cx.render(rsx! { - button { - class: "clear-completed", - onclick: move |_| cx.props.todos.make_mut().retain(|_, todo| !todo.checked), - "Clear completed" - } - }) + button { + class: "clear-completed", + onclick: move |_| cx.props.todos.make_mut().retain(|_, todo| !todo.checked), + "Clear completed" + } } } }) diff --git a/examples/video_stream.rs b/examples/video_stream.rs index f495299f4..c1e0c3c49 100644 --- a/examples/video_stream.rs +++ b/examples/video_stream.rs @@ -3,7 +3,6 @@ use dioxus_desktop::wry::http; use dioxus_desktop::wry::http::Response; use dioxus_desktop::{use_asset_handler, AssetRequest}; use http::{header::*, response::Builder as ResponseBuilder, status::StatusCode}; -use std::borrow::Cow; use std::{io::SeekFrom, path::PathBuf}; use tokio::io::AsyncReadExt; use tokio::io::AsyncSeekExt; @@ -31,28 +30,33 @@ fn main() { } fn app(cx: Scope) -> Element { - use_asset_handler(cx, move |request: &AssetRequest| { - let request = request.clone(); - async move { + use_asset_handler(cx, "videos", move |request, responder| { + // Using dioxus::spawn works, but is slower than a dedicated thread + tokio::task::spawn(async move { let video_file = PathBuf::from(VIDEO_PATH); let mut file = tokio::fs::File::open(&video_file).await.unwrap(); - let response: Option>> = - match get_stream_response(&mut file, &request).await { - Ok(response) => Some(response.map(Cow::Owned)), - Err(err) => { - eprintln!("Error: {}", err); - None - } - }; - response - } + + match get_stream_response(&mut file, &request).await { + Ok(response) => responder.respond(response), + Err(err) => eprintln!("Error: {}", err), + } + }); }); render! { - div { video { src: "test_video.mp4", autoplay: true, controls: true, width: 640, height: 480 } } + div { + video { + src: "/videos/test_video.mp4", + autoplay: true, + controls: true, + width: 640, + height: 480 + } + } } } +/// This was taken from wry's example async fn get_stream_response( asset: &mut (impl tokio::io::AsyncSeek + tokio::io::AsyncRead + Unpin + Send + Sync), request: &AssetRequest, diff --git a/examples/window_focus.rs b/examples/window_focus.rs index 79a5e5044..612e38d6d 100644 --- a/examples/window_focus.rs +++ b/examples/window_focus.rs @@ -1,7 +1,7 @@ use dioxus::prelude::*; +use dioxus_desktop::tao::event::Event as WryEvent; use dioxus_desktop::tao::event::WindowEvent; use dioxus_desktop::use_wry_event_handler; -use dioxus_desktop::wry::application::event::Event as WryEvent; use dioxus_desktop::{Config, WindowCloseBehaviour}; fn main() { diff --git a/flake.lock b/flake.lock new file mode 100644 index 000000000..e5c50616d --- /dev/null +++ b/flake.lock @@ -0,0 +1,247 @@ +{ + "nodes": { + "crane": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils", + "nixpkgs": [ + "nixpkgs" + ], + "rust-overlay": "rust-overlay" + }, + "locked": { + "lastModified": 1696384830, + "narHash": "sha256-j8ZsVqzmj5sOm5MW9cqwQJUZELFFwOislDmqDDEMl6k=", + "owner": "ipetkov", + "repo": "crane", + "rev": "f2143cd27f8bd09ee4f0121336c65015a2a0a19c", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1696267196, + "narHash": "sha256-AAQ/2sD+0D18bb8hKuEEVpHUYD1GmO2Uh/taFamn6XQ=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "4f910c9827911b1ec2bf26b5a062cd09f8d89f85", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1696343447, + "narHash": "sha256-B2xAZKLkkeRFG5XcHHSXXcP7To9Xzr59KXeZiRf4vdQ=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "c9afaba3dfa4085dbd2ccb38dfade5141e33d9d4", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { + "inputs": { + "systems": "systems_2" + }, + "locked": { + "lastModified": 1681202837, + "narHash": "sha256-H+Rh19JDwRtpVPAWp64F+rlEtxUWBAQW28eAi3SRSzg=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "cfacdce06f30d2b68473a46042957675eebb3401", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1697009197, + "narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "dir": "lib", + "lastModified": 1696019113, + "narHash": "sha256-X3+DKYWJm93DRSdC5M6K5hLqzSya9BjibtBsuARoPco=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "f5892ddac112a1e9b3612c39af1b72987ee5783a", + "type": "github" + }, + "original": { + "dir": "lib", + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { + "locked": { + "lastModified": 1681358109, + "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "96ba1c52e54e74c3197f4d43026b3f3d92e83ff9", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "crane": "crane", + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay_2", + "systems": "systems_3" + } + }, + "rust-overlay": { + "inputs": { + "flake-utils": [ + "crane", + "flake-utils" + ], + "nixpkgs": [ + "crane", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1696299134, + "narHash": "sha256-RS77cAa0N+Sfj5EmKbm5IdncNXaBCE1BSSQvUE8exvo=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "611ccdceed92b4d94ae75328148d84ee4a5b462d", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "rust-overlay_2": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": "nixpkgs_2" + }, + "locked": { + "lastModified": 1697076655, + "narHash": "sha256-NcCtVUOd0X81srZkrdP8qoA1BMsPdO2tGtlZpsGijeU=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "aa7584f5bbf5947716ad8ec14eccc0334f0d28f0", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_2": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 000000000..7f151a660 --- /dev/null +++ b/flake.nix @@ -0,0 +1,63 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + flake-parts.url = "github:hercules-ci/flake-parts"; + systems.url = "github:nix-systems/default"; + + rust-overlay.url = "github:oxalica/rust-overlay"; + crane.url = "github:ipetkov/crane"; + crane.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = inputs: + inputs.flake-parts.lib.mkFlake { inherit inputs; } { + systems = import inputs.systems; + + perSystem = { config, self', pkgs, lib, system, ... }: + let + rustToolchain = pkgs.rust-bin.stable.latest.default.override { + extensions = [ + "rust-src" + "rust-analyzer" + "clippy" + ]; + }; + rustBuildInputs = [ + pkgs.openssl + pkgs.libiconv + pkgs.pkg-config + ] ++ lib.optionals pkgs.stdenv.isDarwin (with pkgs.darwin.apple_sdk.frameworks; [ + IOKit + Carbon + WebKit + Security + Cocoa + ]); + + # This is useful when building crates as packages + # Note that it does require a `Cargo.lock` which this repo does not have + # craneLib = (inputs.crane.mkLib pkgs).overrideToolchain rustToolchain; + in + { + _module.args.pkgs = import inputs.nixpkgs { + inherit system; + overlays = [ + inputs.rust-overlay.overlays.default + ]; + }; + + devShells.default = pkgs.mkShell { + name = "dioxus-dev"; + buildInputs = rustBuildInputs; + nativeBuildInputs = [ + # Add shell dependencies here + rustToolchain + ]; + shellHook = '' + # For rust-analyzer 'hover' tooltips to work. + export RUST_SRC_PATH="${rustToolchain}/lib/rustlib/src/rust/library"; + ''; + }; + }; + }; +} diff --git a/packages/autofmt/src/component.rs b/packages/autofmt/src/component.rs index 8cf36811d..c83f9b333 100644 --- a/packages/autofmt/src/component.rs +++ b/packages/autofmt/src/component.rs @@ -67,7 +67,7 @@ impl Writer<'_> { } // multiline handlers bump everything down - if attr_len > 1000 { + if attr_len > 1000 || self.out.indent.split_line_attributes() { opt_level = ShortOptimization::NoOpt; } @@ -158,7 +158,7 @@ impl Writer<'_> { while let Some(field) = field_iter.next() { if !sameline { - self.out.indented_tabbed_line()?; + self.out.indented_tabbed_line().unwrap(); } let name = &field.name; @@ -182,6 +182,9 @@ impl Writer<'_> { s.source.as_ref().unwrap().to_token_stream() )?; } + ContentField::Shorthand(e) => { + write!(self.out, "{}", e.to_token_stream())?; + } ContentField::OnHandlerRaw(exp) => { let out = prettyplease::unparse_expr(exp); let mut lines = out.split('\n').peekable(); @@ -206,7 +209,7 @@ impl Writer<'_> { if let Some(exp) = manual_props { if !sameline { - self.out.indented_tabbed_line()?; + self.out.indented_tabbed_line().unwrap(); } self.write_manual_props(exp)?; } @@ -223,6 +226,7 @@ impl Writer<'_> { .iter() .map(|field| match &field.content { ContentField::Formatted(s) => ifmt_to_string(s).len() , + ContentField::Shorthand(e) => e.to_token_stream().to_string().len(), ContentField::OnHandlerRaw(exp) | ContentField::ManExpr(exp) => { let formatted = prettyplease::unparse_expr(exp); let len = if formatted.contains('\n') { diff --git a/packages/autofmt/src/element.rs b/packages/autofmt/src/element.rs index ebbce7538..d386f8b72 100644 --- a/packages/autofmt/src/element.rs +++ b/packages/autofmt/src/element.rs @@ -103,7 +103,7 @@ impl Writer<'_> { } // multiline handlers bump everything down - if attr_len > 1000 { + if attr_len > 1000 || self.out.indent.split_line_attributes() { opt_level = ShortOptimization::NoOpt; } @@ -166,7 +166,7 @@ impl Writer<'_> { fn write_attributes( &mut self, - attributes: &[ElementAttrNamed], + attributes: &[AttributeType], key: &Option, sameline: bool, ) -> Result { @@ -188,7 +188,7 @@ impl Writer<'_> { while let Some(attr) = attr_iter.next() { self.out.indent_level += 1; if !sameline { - self.write_comments(attr.attr.start())?; + self.write_comments(attr.start())?; } self.out.indent_level -= 1; @@ -237,6 +237,9 @@ impl Writer<'_> { ElementAttrValue::AttrLiteral(value) => { write!(self.out, "{value}", value = ifmt_to_string(value))?; } + ElementAttrValue::Shorthand(value) => { + write!(self.out, "{value}",)?; + } ElementAttrValue::AttrExpr(value) => { let out = prettyplease::unparse_expr(value); let mut lines = out.split('\n').peekable(); @@ -262,7 +265,6 @@ impl Writer<'_> { } ElementAttrValue::EventTokens(tokens) => { let out = self.retrieve_formatted_expr(tokens).to_string(); - let mut lines = out.split('\n').peekable(); let first = lines.next().unwrap(); @@ -289,7 +291,14 @@ impl Writer<'_> { Ok(()) } - fn write_attribute(&mut self, attr: &ElementAttrNamed) -> Result { + fn write_attribute(&mut self, attr: &AttributeType) -> Result { + match attr { + AttributeType::Named(attr) => self.write_named_attribute(attr), + AttributeType::Spread(attr) => self.write_spread_attribute(attr), + } + } + + fn write_named_attribute(&mut self, attr: &ElementAttrNamed) -> Result { self.write_attribute_name(&attr.attr.name)?; write!(self.out, ": ")?; self.write_attribute_value(&attr.attr.value)?; @@ -297,6 +306,13 @@ impl Writer<'_> { Ok(()) } + fn write_spread_attribute(&mut self, attr: &Expr) -> Result { + write!(self.out, "..")?; + write!(self.out, "{}", prettyplease::unparse_expr(attr))?; + + Ok(()) + } + // make sure the comments are actually relevant to this element. // test by making sure this element is the primary element on this line pub fn current_span_is_primary(&self, location: Span) -> bool { @@ -313,6 +329,10 @@ impl Writer<'_> { beginning.is_empty() } + pub fn is_empty_children(&self, children: &[BodyNode]) -> bool { + children.is_empty() + } + // check if the children are short enough to be on the same line // We don't have the notion of current line depth - each line tries to be < 80 total // returns the total line length if it's short diff --git a/packages/autofmt/src/indent.rs b/packages/autofmt/src/indent.rs index 2cce7cf1e..f7d514865 100644 --- a/packages/autofmt/src/indent.rs +++ b/packages/autofmt/src/indent.rs @@ -8,10 +8,11 @@ pub enum IndentType { pub struct IndentOptions { width: usize, indent_string: String, + split_line_attributes: bool, } impl IndentOptions { - pub fn new(typ: IndentType, width: usize) -> Self { + pub fn new(typ: IndentType, width: usize, split_line_attributes: bool) -> Self { assert_ne!(width, 0, "Cannot have an indent width of 0"); Self { width, @@ -19,6 +20,7 @@ impl IndentOptions { IndentType::Tabs => "\t".into(), IndentType::Spaces => " ".repeat(width), }, + split_line_attributes, } } @@ -62,11 +64,15 @@ impl IndentOptions { } indent } + + pub fn split_line_attributes(&self) -> bool { + self.split_line_attributes + } } impl Default for IndentOptions { fn default() -> Self { - Self::new(IndentType::Spaces, 4) + Self::new(IndentType::Spaces, 4, false) } } @@ -77,31 +83,31 @@ mod tests { #[test] fn count_indents() { assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents("no indentation here!"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents("no indentation here!"), 0 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"), 1 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"), 2 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents(" v += 2"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents(" v += 2"), 2 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents("\t\tv += 2"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents("\t\tv += 2"), 2 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 4).count_indents("\t\t v += 2"), + IndentOptions::new(IndentType::Spaces, 4, false).count_indents("\t\t v += 2"), 2 ); assert_eq!( - IndentOptions::new(IndentType::Spaces, 2).count_indents(" v += 2"), + IndentOptions::new(IndentType::Spaces, 2, false).count_indents(" v += 2"), 2 ); } diff --git a/packages/autofmt/src/lib.rs b/packages/autofmt/src/lib.rs index 0c3fe6bb8..e40b873d6 100644 --- a/packages/autofmt/src/lib.rs +++ b/packages/autofmt/src/lib.rs @@ -140,7 +140,9 @@ pub fn write_block_out(body: CallBody) -> Option { } fn write_body(buf: &mut Writer, body: &CallBody) { - if buf.is_short_children(&body.roots).is_some() { + let is_short = buf.is_short_children(&body.roots).is_some(); + let is_empty = buf.is_empty_children(&body.roots); + if (is_short && !buf.out.indent.split_line_attributes()) || is_empty { // write all the indents with spaces and commas between for idx in 0..body.roots.len() - 1 { let ident = &body.roots[idx]; diff --git a/packages/autofmt/src/writer.rs b/packages/autofmt/src/writer.rs index ede35d768..be375aa9d 100644 --- a/packages/autofmt/src/writer.rs +++ b/packages/autofmt/src/writer.rs @@ -1,11 +1,11 @@ -use dioxus_rsx::{BodyNode, ElementAttrNamed, ElementAttrValue, ForLoop}; +use dioxus_rsx::{AttributeType, BodyNode, ElementAttrValue, ForLoop, IfChain}; use proc_macro2::{LineColumn, Span}; use quote::ToTokens; use std::{ collections::{HashMap, VecDeque}, fmt::{Result, Write}, }; -use syn::{spanned::Spanned, Expr, ExprIf}; +use syn::{spanned::Spanned, Expr}; use crate::buffer::Buffer; use crate::ifmt_to_string; @@ -142,6 +142,7 @@ impl<'a> Writer<'a> { } ElementAttrValue::AttrLiteral(lit) => ifmt_to_string(lit).len(), ElementAttrValue::AttrExpr(expr) => expr.span().line_length(), + ElementAttrValue::Shorthand(expr) => expr.span().line_length(), ElementAttrValue::EventTokens(tokens) => { let location = Location::new(tokens.span().start()); @@ -165,12 +166,12 @@ impl<'a> Writer<'a> { } } - pub(crate) fn is_short_attrs(&mut self, attributes: &[ElementAttrNamed]) -> usize { + pub(crate) fn is_short_attrs(&mut self, attributes: &[AttributeType]) -> usize { let mut total = 0; for attr in attributes { - if self.current_span_is_primary(attr.attr.start()) { - 'line: for line in self.src[..attr.attr.start().start().line - 1].iter().rev() { + if self.current_span_is_primary(attr.start()) { + 'line: for line in self.src[..attr.start().start().line - 1].iter().rev() { match (line.trim().starts_with("//"), line.is_empty()) { (true, _) => return 100000, (_, true) => continue 'line, @@ -179,16 +180,24 @@ impl<'a> Writer<'a> { } } - total += match &attr.attr.name { - dioxus_rsx::ElementAttrName::BuiltIn(name) => { - let name = name.to_string(); - name.len() + match attr { + AttributeType::Named(attr) => { + let name_len = match &attr.attr.name { + dioxus_rsx::ElementAttrName::BuiltIn(name) => { + let name = name.to_string(); + name.len() + } + dioxus_rsx::ElementAttrName::Custom(name) => name.value().len() + 2, + }; + total += name_len; + total += self.attr_value_len(&attr.attr.value); + } + AttributeType::Spread(expr) => { + let expr_len = self.retrieve_formatted_expr(expr).len(); + total += expr_len + 3; } - dioxus_rsx::ElementAttrName::Custom(name) => name.value().len() + 2, }; - total += self.attr_value_len(&attr.attr.value); - total += 6; } @@ -223,8 +232,49 @@ impl<'a> Writer<'a> { Ok(()) } - fn write_if_chain(&mut self, ifchain: &ExprIf) -> std::fmt::Result { - self.write_raw_expr(ifchain.span()) + fn write_if_chain(&mut self, ifchain: &IfChain) -> std::fmt::Result { + // Recurse in place by setting the next chain + let mut branch = Some(ifchain); + + while let Some(chain) = branch { + let IfChain { + if_token, + cond, + then_branch, + else_if_branch, + else_branch, + } = chain; + + write!( + self.out, + "{} {} {{", + if_token.to_token_stream(), + prettyplease::unparse_expr(cond) + )?; + + self.write_body_indented(then_branch)?; + + if let Some(else_if_branch) = else_if_branch { + // write the closing bracket and else + self.out.tabbed_line()?; + write!(self.out, "}} else ")?; + + branch = Some(else_if_branch); + } else if let Some(else_branch) = else_branch { + self.out.tabbed_line()?; + write!(self.out, "}} else {{")?; + + self.write_body_indented(else_branch)?; + branch = None; + } else { + branch = None; + } + } + + self.out.tabbed_line()?; + write!(self.out, "}}")?; + + Ok(()) } } diff --git a/packages/autofmt/tests/samples/attributes.rsx b/packages/autofmt/tests/samples/attributes.rsx index fa08b1cf4..4a0bdcdda 100644 --- a/packages/autofmt/tests/samples/attributes.rsx +++ b/packages/autofmt/tests/samples/attributes.rsx @@ -12,18 +12,6 @@ rsx! { let blah = 120; true }, - onclick: move |_| { - let blah = 120; - true - }, - onclick: move |_| { - let blah = 120; - true - }, - onclick: move |_| { - let blah = 120; - true - }, div { div { "hi" } h2 { class: "asd" } diff --git a/packages/autofmt/tests/samples/commentshard.rsx b/packages/autofmt/tests/samples/commentshard.rsx index f6c2fc19e..71782f39d 100644 --- a/packages/autofmt/tests/samples/commentshard.rsx +++ b/packages/autofmt/tests/samples/commentshard.rsx @@ -8,17 +8,17 @@ rsx! { "hello world" // Comments - expr1, + {expr1}, // Comments - expr2, + {expr2}, // Comments // Comments // Comments // Comments // Comments - expr3, + {expr3}, div { // todo some work in here diff --git a/packages/autofmt/tests/samples/complex.rsx b/packages/autofmt/tests/samples/complex.rsx index 1bf29a767..6ee62cfa5 100644 --- a/packages/autofmt/tests/samples/complex.rsx +++ b/packages/autofmt/tests/samples/complex.rsx @@ -6,7 +6,7 @@ rsx! { show_user_menu.set(!show_user_menu.get()); evt.cancel_bubble(); }, - onclick: move |evt| show_user_menu.set(!show_user_menu.get()), + onmousedown: move |evt| show_user_menu.set(!show_user_menu.get()), span { class: "inline-block mr-4", icons::icon_14 {} } span { "Settings" } } @@ -18,7 +18,7 @@ rsx! { to: "{to}", span { class: "inline-block mr-3", icons::icon_0 {} } span { "{name}" } - children.is_some().then(|| rsx! { + {children.is_some().then(|| rsx! { span { class: "inline-block ml-auto hover:bg-gray-500", onclick: move |evt| { @@ -27,9 +27,9 @@ rsx! { }, icons::icon_8 {} } - }) + })} } - div { class: "px-4", is_current.then(|| rsx!{ children }) } + div { class: "px-4", {is_current.then(|| rsx!{ children })} } } // No nesting @@ -48,5 +48,5 @@ rsx! { } } - div { asdbascasdbasd, asbdasbdabsd, asbdabsdbasdbas } + div { "asdbascasdbasd", "asbdasbdabsd", {asbdabsdbasdbas} } } diff --git a/packages/autofmt/tests/samples/ifchain_forloop.rsx b/packages/autofmt/tests/samples/ifchain_forloop.rsx index 9ec7326af..728b2d3d3 100644 --- a/packages/autofmt/tests/samples/ifchain_forloop.rsx +++ b/packages/autofmt/tests/samples/ifchain_forloop.rsx @@ -8,6 +8,20 @@ rsx! { // Some ifchain if a > 10 { // - rsx! { div {} } + div {} + } else if a > 20 { + h1 {} + } else if a > 20 { + h1 {} + } else if a > 20 { + h1 {} + } else if a > 20 { + h1 {} + } else if a > 20 { + h1 {} + } else if a > 20 { + h1 {} + } else { + h3 {} } } diff --git a/packages/autofmt/tests/samples/immediate_expr.rsx b/packages/autofmt/tests/samples/immediate_expr.rsx index 9e298499d..cea8dc7db 100644 --- a/packages/autofmt/tests/samples/immediate_expr.rsx +++ b/packages/autofmt/tests/samples/immediate_expr.rsx @@ -1,4 +1,4 @@ fn it_works() { - cx.render(rsx!(())) + cx.render(rsx!({()})) } diff --git a/packages/autofmt/tests/samples/long.rsx b/packages/autofmt/tests/samples/long.rsx index 1bda8a006..056e16061 100644 --- a/packages/autofmt/tests/samples/long.rsx +++ b/packages/autofmt/tests/samples/long.rsx @@ -11,7 +11,7 @@ pub fn Explainer<'a>( // pt-5 sm:pt-24 lg:pt-24 let mut right = rsx! { - div { class: "relative w-1/2", flasher } + div { class: "relative w-1/2", {flasher} } }; let align = match invert { @@ -24,7 +24,7 @@ pub fn Explainer<'a>( h2 { class: "mb-6 text-3xl leading-tight md:text-4xl md:leading-tight lg:text-3xl lg:leading-tight font-heading font-mono font-bold", "{title}" } - content + {content} } }; @@ -34,8 +34,8 @@ pub fn Explainer<'a>( cx.render(rsx! { div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", - left, - right + {left}, + {right} } }) } diff --git a/packages/autofmt/tests/samples/long_exprs.rsx b/packages/autofmt/tests/samples/long_exprs.rsx index fb4dab93f..490bc5541 100644 --- a/packages/autofmt/tests/samples/long_exprs.rsx +++ b/packages/autofmt/tests/samples/long_exprs.rsx @@ -6,7 +6,7 @@ rsx! { section { class: "body-font overflow-hidden dark:bg-ideblack", div { class: "container px-6 mx-auto", div { class: "-my-8 divide-y-2 divide-gray-100", - POSTS.iter().enumerate().map(|(id, post)| rsx! { BlogPostItem { post: post, id: id } }) + {POSTS.iter().enumerate().map(|(id, post)| rsx! { BlogPostItem { post: post, id: id } })} } } } diff --git a/packages/autofmt/tests/samples/multirsx.rsx b/packages/autofmt/tests/samples/multirsx.rsx index 380ef3487..84340f5ba 100644 --- a/packages/autofmt/tests/samples/multirsx.rsx +++ b/packages/autofmt/tests/samples/multirsx.rsx @@ -4,20 +4,20 @@ rsx! { div {} // hi - div { abcd, ball, s } + div { "abcd", "ball", "s" } // // // - div { abcd, ball, s } + div { "abcd", "ball", "s" } // // // div { - abcd, - ball, - s, + "abcd" + "ball" + "s" // "asdasd" diff --git a/packages/autofmt/tests/samples/trailing_expr.rsx b/packages/autofmt/tests/samples/trailing_expr.rsx index 667b8bb32..a57a822ab 100644 --- a/packages/autofmt/tests/samples/trailing_expr.rsx +++ b/packages/autofmt/tests/samples/trailing_expr.rsx @@ -1,7 +1,7 @@ fn it_works() { cx.render(rsx! { div { - span { "Description: ", package.description.as_deref().unwrap_or("❌❌❌❌ missing") } + span { "Description: ", {package.description.as_deref().unwrap_or("❌❌❌❌ missing")} } } }) } diff --git a/packages/autofmt/tests/wrong.rs b/packages/autofmt/tests/wrong.rs index 06a0f00d1..8f2d08452 100644 --- a/packages/autofmt/tests/wrong.rs +++ b/packages/autofmt/tests/wrong.rs @@ -18,11 +18,11 @@ macro_rules! twoway { }; } -twoway!("comments-4sp" => comments_4sp (IndentOptions::new(IndentType::Spaces, 4))); -twoway!("comments-tab" => comments_tab (IndentOptions::new(IndentType::Tabs, 4))); +twoway!("comments-4sp" => comments_4sp (IndentOptions::new(IndentType::Spaces, 4, false))); +twoway!("comments-tab" => comments_tab (IndentOptions::new(IndentType::Tabs, 4, false))); -twoway!("multi-4sp" => multi_4sp (IndentOptions::new(IndentType::Spaces, 4))); -twoway!("multi-tab" => multi_tab (IndentOptions::new(IndentType::Tabs, 4))); +twoway!("multi-4sp" => multi_4sp (IndentOptions::new(IndentType::Spaces, 4, false))); +twoway!("multi-tab" => multi_tab (IndentOptions::new(IndentType::Tabs, 4, false))); -twoway!("multiexpr-4sp" => multiexpr_4sp (IndentOptions::new(IndentType::Spaces, 4))); -twoway!("multiexpr-tab" => multiexpr_tab (IndentOptions::new(IndentType::Tabs, 4))); +twoway!("multiexpr-4sp" => multiexpr_4sp (IndentOptions::new(IndentType::Spaces, 4, false))); +twoway!("multiexpr-tab" => multiexpr_tab (IndentOptions::new(IndentType::Tabs, 4, false))); diff --git a/packages/autofmt/tests/wrong/multiexpr-4sp.rsx b/packages/autofmt/tests/wrong/multiexpr-4sp.rsx index 56c57e37e..ecb2f8bdc 100644 --- a/packages/autofmt/tests/wrong/multiexpr-4sp.rsx +++ b/packages/autofmt/tests/wrong/multiexpr-4sp.rsx @@ -1,8 +1,8 @@ fn ItWroks() { cx.render(rsx! { div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", - left, - right + {left}, + {right} } }) } diff --git a/packages/autofmt/tests/wrong/multiexpr-4sp.wrong.rsx b/packages/autofmt/tests/wrong/multiexpr-4sp.wrong.rsx index 5732f2cdd..15752f172 100644 --- a/packages/autofmt/tests/wrong/multiexpr-4sp.wrong.rsx +++ b/packages/autofmt/tests/wrong/multiexpr-4sp.wrong.rsx @@ -1,5 +1,5 @@ fn ItWroks() { cx.render(rsx! { - div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", left, right } + div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", {left}, {right} } }) } diff --git a/packages/autofmt/tests/wrong/multiexpr-tab.rsx b/packages/autofmt/tests/wrong/multiexpr-tab.rsx index 1fc3401c4..85f2216a1 100644 --- a/packages/autofmt/tests/wrong/multiexpr-tab.rsx +++ b/packages/autofmt/tests/wrong/multiexpr-tab.rsx @@ -1,8 +1,8 @@ fn ItWroks() { cx.render(rsx! { div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", - left, - right + {left}, + {right} } }) } diff --git a/packages/autofmt/tests/wrong/multiexpr-tab.wrong.rsx b/packages/autofmt/tests/wrong/multiexpr-tab.wrong.rsx index 073107541..6872d0b43 100644 --- a/packages/autofmt/tests/wrong/multiexpr-tab.wrong.rsx +++ b/packages/autofmt/tests/wrong/multiexpr-tab.wrong.rsx @@ -1,5 +1,5 @@ fn ItWroks() { cx.render(rsx! { - div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", left, right } + div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", {left}, {right} } }) } diff --git a/packages/cli-config/.gitignore b/packages/cli-config/.gitignore new file mode 100644 index 000000000..6700b1332 --- /dev/null +++ b/packages/cli-config/.gitignore @@ -0,0 +1,4 @@ +/target +Cargo.lock +.DS_Store +.idea/ diff --git a/packages/cli-config/Cargo.toml b/packages/cli-config/Cargo.toml new file mode 100644 index 000000000..d6f422b3c --- /dev/null +++ b/packages/cli-config/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "dioxus-cli-config" +version = "0.4.1" +authors = ["Jonathan Kelley"] +edition = "2021" +description = "Configuration for the Dioxus CLI" +repository = "https://github.com/DioxusLabs/dioxus/" +license = "MIT OR Apache-2.0" +keywords = ["react", "gui", "cli", "dioxus", "wasm"] + +[dependencies] +clap = { version = "4.2", features = ["derive"], optional = true } +serde = { version = "1.0.136", features = ["derive"] } +serde_json = "1.0.79" +toml = { version = "0.5.8", optional = true } +cargo_toml = { version = "0.16.0", optional = true } +once_cell = "1.18.0" +tracing.workspace = true + +# bundling +tauri-bundler = { version = "=1.4.0", features = ["native-tls-vendored"], optional = true } +tauri-utils = { version = "=1.5.*", optional = true } + +[features] +default = [] +cli = ["tauri-bundler", "tauri-utils", "clap", "toml", "cargo_toml"] diff --git a/packages/cli-config/README.md b/packages/cli-config/README.md new file mode 100644 index 000000000..ef2435713 --- /dev/null +++ b/packages/cli-config/README.md @@ -0,0 +1,5 @@ +
+

📦✨ Dioxus CLI Configuration

+
+ +The **dioxus-cli-config** contains the configuration for the **dioxus-cli**. diff --git a/packages/cli-config/src/bundle.rs b/packages/cli-config/src/bundle.rs new file mode 100644 index 000000000..07c4fec21 --- /dev/null +++ b/packages/cli-config/src/bundle.rs @@ -0,0 +1,260 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use std::path::PathBuf; + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct BundleConfig { + pub identifier: Option, + pub publisher: Option, + pub icon: Option>, + pub resources: Option>, + pub copyright: Option, + pub category: Option, + pub short_description: Option, + pub long_description: Option, + pub external_bin: Option>, + pub deb: Option, + pub macos: Option, + pub windows: Option, +} + +#[cfg(feature = "cli")] +impl From for tauri_bundler::BundleSettings { + fn from(val: BundleConfig) -> Self { + tauri_bundler::BundleSettings { + identifier: val.identifier, + publisher: val.publisher, + icon: val.icon, + resources: val.resources, + copyright: val.copyright, + category: val.category.and_then(|c| c.parse().ok()), + short_description: val.short_description, + long_description: val.long_description, + external_bin: val.external_bin, + deb: val.deb.map(Into::into).unwrap_or_default(), + macos: val.macos.map(Into::into).unwrap_or_default(), + windows: val.windows.map(Into::into).unwrap_or_default(), + ..Default::default() + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct DebianSettings { + pub depends: Option>, + pub files: HashMap, + pub nsis: Option, +} + +#[cfg(feature = "cli")] +impl From for tauri_bundler::DebianSettings { + fn from(val: DebianSettings) -> Self { + tauri_bundler::DebianSettings { + depends: val.depends, + files: val.files, + desktop_template: None, + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct WixSettings { + pub language: Vec<(String, Option)>, + pub template: Option, + pub fragment_paths: Vec, + pub component_group_refs: Vec, + pub component_refs: Vec, + pub feature_group_refs: Vec, + pub feature_refs: Vec, + pub merge_refs: Vec, + pub skip_webview_install: bool, + pub license: Option, + pub enable_elevated_update_task: bool, + pub banner_path: Option, + pub dialog_image_path: Option, + pub fips_compliant: bool, +} + +#[cfg(feature = "cli")] +impl From for tauri_bundler::WixSettings { + fn from(val: WixSettings) -> Self { + tauri_bundler::WixSettings { + language: tauri_bundler::bundle::WixLanguage({ + let mut languages: Vec<_> = val + .language + .iter() + .map(|l| { + ( + l.0.clone(), + tauri_bundler::bundle::WixLanguageConfig { + locale_path: l.1.clone(), + }, + ) + }) + .collect(); + if languages.is_empty() { + languages.push(("en-US".into(), Default::default())); + } + languages + }), + template: val.template, + fragment_paths: val.fragment_paths, + component_group_refs: val.component_group_refs, + component_refs: val.component_refs, + feature_group_refs: val.feature_group_refs, + feature_refs: val.feature_refs, + merge_refs: val.merge_refs, + skip_webview_install: val.skip_webview_install, + license: val.license, + enable_elevated_update_task: val.enable_elevated_update_task, + banner_path: val.banner_path, + dialog_image_path: val.dialog_image_path, + fips_compliant: val.fips_compliant, + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize, Default)] +pub struct MacOsSettings { + pub frameworks: Option>, + pub minimum_system_version: Option, + pub license: Option, + pub exception_domain: Option, + pub signing_identity: Option, + pub provider_short_name: Option, + pub entitlements: Option, + pub info_plist_path: Option, +} + +#[cfg(feature = "cli")] +impl From for tauri_bundler::MacOsSettings { + fn from(val: MacOsSettings) -> Self { + tauri_bundler::MacOsSettings { + frameworks: val.frameworks, + minimum_system_version: val.minimum_system_version, + license: val.license, + exception_domain: val.exception_domain, + signing_identity: val.signing_identity, + provider_short_name: val.provider_short_name, + entitlements: val.entitlements, + info_plist_path: val.info_plist_path, + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WindowsSettings { + pub digest_algorithm: Option, + pub certificate_thumbprint: Option, + pub timestamp_url: Option, + pub tsp: bool, + pub wix: Option, + pub icon_path: Option, + pub webview_install_mode: WebviewInstallMode, + pub webview_fixed_runtime_path: Option, + pub allow_downgrades: bool, + pub nsis: Option, +} + +#[cfg(feature = "cli")] +impl From for tauri_bundler::WindowsSettings { + fn from(val: WindowsSettings) -> Self { + tauri_bundler::WindowsSettings { + digest_algorithm: val.digest_algorithm, + certificate_thumbprint: val.certificate_thumbprint, + timestamp_url: val.timestamp_url, + tsp: val.tsp, + wix: val.wix.map(Into::into), + icon_path: val.icon_path.unwrap_or("icons/icon.ico".into()), + webview_install_mode: val.webview_install_mode.into(), + webview_fixed_runtime_path: val.webview_fixed_runtime_path, + allow_downgrades: val.allow_downgrades, + nsis: val.nsis.map(Into::into), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct NsisSettings { + pub template: Option, + pub license: Option, + pub header_image: Option, + pub sidebar_image: Option, + pub installer_icon: Option, + pub install_mode: NSISInstallerMode, + pub languages: Option>, + pub custom_language_files: Option>, + pub display_language_selector: bool, +} + +#[cfg(feature = "cli")] +impl From for tauri_bundler::NsisSettings { + fn from(val: NsisSettings) -> Self { + tauri_bundler::NsisSettings { + license: val.license, + header_image: val.header_image, + sidebar_image: val.sidebar_image, + installer_icon: val.installer_icon, + install_mode: val.install_mode.into(), + languages: val.languages, + display_language_selector: val.display_language_selector, + custom_language_files: None, + template: None, + compression: None, + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum NSISInstallerMode { + CurrentUser, + PerMachine, + Both, +} + +#[cfg(feature = "cli")] +impl From for tauri_utils::config::NSISInstallerMode { + fn from(val: NSISInstallerMode) -> Self { + match val { + NSISInstallerMode::CurrentUser => tauri_utils::config::NSISInstallerMode::CurrentUser, + NSISInstallerMode::PerMachine => tauri_utils::config::NSISInstallerMode::PerMachine, + NSISInstallerMode::Both => tauri_utils::config::NSISInstallerMode::Both, + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum WebviewInstallMode { + Skip, + DownloadBootstrapper { silent: bool }, + EmbedBootstrapper { silent: bool }, + OfflineInstaller { silent: bool }, + FixedRuntime { path: PathBuf }, +} + +#[cfg(feature = "cli")] +impl WebviewInstallMode { + fn into(self) -> tauri_utils::config::WebviewInstallMode { + match self { + Self::Skip => tauri_utils::config::WebviewInstallMode::Skip, + Self::DownloadBootstrapper { silent } => { + tauri_utils::config::WebviewInstallMode::DownloadBootstrapper { silent } + } + Self::EmbedBootstrapper { silent } => { + tauri_utils::config::WebviewInstallMode::EmbedBootstrapper { silent } + } + Self::OfflineInstaller { silent } => { + tauri_utils::config::WebviewInstallMode::OfflineInstaller { silent } + } + Self::FixedRuntime { path } => { + tauri_utils::config::WebviewInstallMode::FixedRuntime { path } + } + } + } +} + +impl Default for WebviewInstallMode { + fn default() -> Self { + Self::OfflineInstaller { silent: false } + } +} diff --git a/packages/cli/src/cargo.rs b/packages/cli-config/src/cargo.rs similarity index 69% rename from packages/cli/src/cargo.rs rename to packages/cli-config/src/cargo.rs index b52fa4b09..97e4040db 100644 --- a/packages/cli/src/cargo.rs +++ b/packages/cli-config/src/cargo.rs @@ -1,12 +1,33 @@ //! Utilities for working with cargo and rust files -use crate::error::{Error, Result}; +use std::error::Error; use std::{ - env, fs, + env, + fmt::{Display, Formatter}, + fs, path::{Path, PathBuf}, process::Command, str, }; +#[derive(Debug, Clone)] +pub struct CargoError { + msg: String, +} + +impl CargoError { + pub fn new(msg: String) -> Self { + Self { msg } + } +} + +impl Display for CargoError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "CargoError: {}", self.msg) + } +} + +impl Error for CargoError {} + /// How many parent folders are searched for a `Cargo.toml` const MAX_ANCESTORS: u32 = 10; @@ -19,7 +40,7 @@ pub struct Metadata { /// Returns the root of the crate that the command is run from /// /// If the command is run from the workspace root, this will return the top-level Cargo.toml -pub fn crate_root() -> Result { +pub fn crate_root() -> Result { // From the current directory we work our way up, looking for `Cargo.toml` env::current_dir() .ok() @@ -35,7 +56,7 @@ pub fn crate_root() -> Result { None }) .ok_or_else(|| { - Error::CargoError("Failed to find directory containing Cargo.toml".to_string()) + CargoError::new("Failed to find directory containing Cargo.toml".to_string()) }) } @@ -53,11 +74,11 @@ fn contains_manifest(path: &Path) -> bool { impl Metadata { /// Returns the struct filled from `cargo metadata` output /// TODO @Jon, find a different way that doesn't rely on the cargo metadata command (it's slow) - pub fn get() -> Result { + pub fn get() -> Result { let output = Command::new("cargo") .args(["metadata"]) .output() - .map_err(|_| Error::CargoError("Manifset".to_string()))?; + .map_err(|_| CargoError::new("Manifset".to_string()))?; if !output.status.success() { let mut msg = str::from_utf8(&output.stderr).unwrap().trim(); @@ -65,22 +86,22 @@ impl Metadata { msg = &msg[7..]; } - return Err(Error::CargoError(msg.to_string())); + return Err(CargoError::new(msg.to_string())); } let stdout = str::from_utf8(&output.stdout).unwrap(); if let Some(line) = stdout.lines().next() { let meta: serde_json::Value = serde_json::from_str(line) - .map_err(|_| Error::CargoError("InvalidOutput".to_string()))?; + .map_err(|_| CargoError::new("InvalidOutput".to_string()))?; let workspace_root = meta["workspace_root"] .as_str() - .ok_or_else(|| Error::CargoError("InvalidOutput".to_string()))? + .ok_or_else(|| CargoError::new("InvalidOutput".to_string()))? .into(); let target_directory = meta["target_directory"] .as_str() - .ok_or_else(|| Error::CargoError("InvalidOutput".to_string()))? + .ok_or_else(|| CargoError::new("InvalidOutput".to_string()))? .into(); return Ok(Self { @@ -89,6 +110,6 @@ impl Metadata { }); } - Err(Error::CargoError("InvalidOutput".to_string())) + Err(CargoError::new("InvalidOutput".to_string())) } } diff --git a/packages/cli-config/src/config.rs b/packages/cli-config/src/config.rs new file mode 100644 index 000000000..716b2bac4 --- /dev/null +++ b/packages/cli-config/src/config.rs @@ -0,0 +1,492 @@ +use crate::BundleConfig; +use crate::CargoError; +use core::fmt::{Display, Formatter}; +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Debug)] +#[cfg_attr(feature = "cli", derive(clap::ValueEnum))] +pub enum Platform { + #[cfg_attr(feature = "cli", clap(name = "web"))] + #[serde(rename = "web")] + Web, + #[cfg_attr(feature = "cli", clap(name = "desktop"))] + #[serde(rename = "desktop")] + Desktop, + #[cfg_attr(feature = "cli", clap(name = "fullstack"))] + #[serde(rename = "fullstack")] + Fullstack, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct DioxusConfig { + pub application: ApplicationConfig, + + pub web: WebConfig, + + #[serde(default)] + pub bundle: BundleConfig, + + #[cfg(feature = "cli")] + #[serde(default = "default_plugin")] + pub plugin: toml::Value, +} + +#[cfg(feature = "cli")] +fn default_plugin() -> toml::Value { + toml::Value::Boolean(true) +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct LoadDioxusConfigError { + location: String, + error: String, +} + +impl std::fmt::Display for LoadDioxusConfigError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{} {}", self.location, self.error) + } +} + +impl std::error::Error for LoadDioxusConfigError {} + +#[derive(Debug)] +pub enum CrateConfigError { + Cargo(CargoError), + Io(std::io::Error), + #[cfg(feature = "cli")] + Toml(toml::de::Error), + LoadDioxusConfig(LoadDioxusConfigError), +} + +impl From for CrateConfigError { + fn from(err: CargoError) -> Self { + Self::Cargo(err) + } +} + +impl From for CrateConfigError { + fn from(err: std::io::Error) -> Self { + Self::Io(err) + } +} + +#[cfg(feature = "cli")] +impl From for CrateConfigError { + fn from(err: toml::de::Error) -> Self { + Self::Toml(err) + } +} + +impl From for CrateConfigError { + fn from(err: LoadDioxusConfigError) -> Self { + Self::LoadDioxusConfig(err) + } +} + +impl Display for CrateConfigError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Self::Cargo(err) => write!(f, "{}", err), + Self::Io(err) => write!(f, "{}", err), + #[cfg(feature = "cli")] + Self::Toml(err) => write!(f, "{}", err), + Self::LoadDioxusConfig(err) => write!(f, "{}", err), + } + } +} + +impl std::error::Error for CrateConfigError {} + +impl DioxusConfig { + #[cfg(feature = "cli")] + /// Load the dioxus config from a path + pub fn load(bin: Option) -> Result, CrateConfigError> { + let crate_dir = crate::cargo::crate_root(); + + let crate_dir = match crate_dir { + Ok(dir) => { + if let Some(bin) = bin { + dir.join(bin) + } else { + dir + } + } + Err(_) => return Ok(None), + }; + let crate_dir = crate_dir.as_path(); + + let Some(dioxus_conf_file) = acquire_dioxus_toml(crate_dir) else { + return Ok(None); + }; + + let dioxus_conf_file = dioxus_conf_file.as_path(); + let cfg = toml::from_str::(&std::fs::read_to_string(dioxus_conf_file)?) + .map_err(|err| { + let error_location = dioxus_conf_file + .strip_prefix(crate_dir) + .unwrap_or(dioxus_conf_file) + .display(); + CrateConfigError::LoadDioxusConfig(LoadDioxusConfigError { + location: error_location.to_string(), + error: err.to_string(), + }) + }) + .map(Some); + match cfg { + Ok(Some(mut cfg)) => { + let name = cfg.application.name.clone(); + if cfg.bundle.identifier.is_none() { + cfg.bundle.identifier = Some(format!("io.github.{name}")); + } + if cfg.bundle.publisher.is_none() { + cfg.bundle.publisher = Some(name); + } + Ok(Some(cfg)) + } + cfg => cfg, + } + } +} + +#[cfg(feature = "cli")] +fn acquire_dioxus_toml(dir: &std::path::Path) -> Option { + // prefer uppercase + let uppercase_conf = dir.join("Dioxus.toml"); + if uppercase_conf.is_file() { + return Some(uppercase_conf); + } + + // lowercase is fine too + let lowercase_conf = dir.join("dioxus.toml"); + if lowercase_conf.is_file() { + return Some(lowercase_conf); + } + + None +} + +impl Default for DioxusConfig { + fn default() -> Self { + let name = default_name(); + Self { + application: ApplicationConfig { + name: name.clone(), + default_platform: default_platform(), + out_dir: out_dir_default(), + asset_dir: asset_dir_default(), + + #[cfg(feature = "cli")] + tools: Default::default(), + + sub_package: None, + }, + web: WebConfig { + app: WebAppConfig { + title: default_title(), + base_path: None, + }, + proxy: vec![], + watcher: Default::default(), + resource: WebResourceConfig { + dev: WebDevResourceConfig { + style: vec![], + script: vec![], + }, + style: Some(vec![]), + script: Some(vec![]), + }, + https: WebHttpsConfig { + enabled: None, + mkcert: None, + key_path: None, + cert_path: None, + }, + }, + bundle: BundleConfig { + identifier: Some(format!("io.github.{name}")), + publisher: Some(name), + ..Default::default() + }, + #[cfg(feature = "cli")] + plugin: toml::Value::Table(toml::map::Map::new()), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct ApplicationConfig { + #[serde(default = "default_name")] + pub name: String, + #[serde(default = "default_platform")] + pub default_platform: Platform, + #[serde(default = "out_dir_default")] + pub out_dir: PathBuf, + #[serde(default = "asset_dir_default")] + pub asset_dir: PathBuf, + + #[cfg(feature = "cli")] + #[serde(default)] + pub tools: std::collections::HashMap, + + #[serde(default)] + pub sub_package: Option, +} + +fn default_name() -> String { + "name".into() +} + +fn default_platform() -> Platform { + Platform::Web +} + +fn asset_dir_default() -> PathBuf { + PathBuf::from("public") +} + +fn out_dir_default() -> PathBuf { + PathBuf::from("dist") +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WebConfig { + #[serde(default)] + pub app: WebAppConfig, + #[serde(default)] + pub proxy: Vec, + #[serde(default)] + pub watcher: WebWatcherConfig, + #[serde(default)] + pub resource: WebResourceConfig, + #[serde(default)] + pub https: WebHttpsConfig, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WebAppConfig { + #[serde(default = "default_title")] + pub title: String, + pub base_path: Option, +} + +impl Default for WebAppConfig { + fn default() -> Self { + Self { + title: default_title(), + base_path: None, + } + } +} + +fn default_title() -> String { + "dioxus | ⛺".into() +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WebProxyConfig { + pub backend: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WebWatcherConfig { + #[serde(default = "watch_path_default")] + pub watch_path: Vec, + #[serde(default)] + pub reload_html: bool, + #[serde(default = "true_bool")] + pub index_on_404: bool, +} + +impl Default for WebWatcherConfig { + fn default() -> Self { + Self { + watch_path: watch_path_default(), + reload_html: false, + index_on_404: true, + } + } +} + +fn watch_path_default() -> Vec { + vec![PathBuf::from("src"), PathBuf::from("examples")] +} + +#[derive(Default, Debug, Clone, Serialize, Deserialize)] +pub struct WebResourceConfig { + pub dev: WebDevResourceConfig, + pub style: Option>, + pub script: Option>, +} + +#[derive(Default, Debug, Clone, Serialize, Deserialize)] +pub struct WebDevResourceConfig { + #[serde(default)] + pub style: Vec, + #[serde(default)] + pub script: Vec, +} + +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +pub struct WebHttpsConfig { + pub enabled: Option, + pub mkcert: Option, + pub key_path: Option, + pub cert_path: Option, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CrateConfig { + pub out_dir: PathBuf, + pub crate_dir: PathBuf, + pub workspace_dir: PathBuf, + pub target_dir: PathBuf, + pub asset_dir: PathBuf, + #[cfg(feature = "cli")] + pub manifest: cargo_toml::Manifest, + pub executable: ExecutableType, + pub dioxus_config: DioxusConfig, + pub release: bool, + pub hot_reload: bool, + pub cross_origin_policy: bool, + pub verbose: bool, + pub custom_profile: Option, + pub features: Option>, + pub target: Option, + pub cargo_args: Vec, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub enum ExecutableType { + Binary(String), + Lib(String), + Example(String), +} + +impl CrateConfig { + #[cfg(feature = "cli")] + pub fn new(bin: Option) -> Result { + let dioxus_config = DioxusConfig::load(bin.clone())?.unwrap_or_default(); + + let crate_root = crate::crate_root()?; + + let crate_dir = if let Some(package) = &dioxus_config.application.sub_package { + crate_root.join(package) + } else if let Some(bin) = bin { + crate_root.join(bin) + } else { + crate_root + }; + + let meta = crate::Metadata::get()?; + let workspace_dir = meta.workspace_root; + let target_dir = meta.target_directory; + + let out_dir = crate_dir.join(&dioxus_config.application.out_dir); + + let cargo_def = &crate_dir.join("Cargo.toml"); + + let asset_dir = crate_dir.join(&dioxus_config.application.asset_dir); + + let manifest = cargo_toml::Manifest::from_path(cargo_def).unwrap(); + + let mut output_filename = String::from("dioxus_app"); + if let Some(package) = &manifest.package.as_ref() { + output_filename = match &package.default_run { + Some(default_run_target) => default_run_target.to_owned(), + None => manifest + .bin + .iter() + .find(|b| b.name == manifest.package.as_ref().map(|pkg| pkg.name.clone())) + .or(manifest + .bin + .iter() + .find(|b| b.path == Some("src/main.rs".to_owned()))) + .or(manifest.bin.first()) + .or(manifest.lib.as_ref()) + .and_then(|prod| prod.name.clone()) + .unwrap_or(String::from("dioxus_app")), + }; + } + + let executable = ExecutableType::Binary(output_filename); + + let release = false; + let hot_reload = false; + let verbose = false; + let custom_profile = None; + let features = None; + let target = None; + let cargo_args = vec![]; + + Ok(Self { + out_dir, + crate_dir, + workspace_dir, + target_dir, + asset_dir, + #[cfg(feature = "cli")] + manifest, + executable, + release, + dioxus_config, + hot_reload, + cross_origin_policy: false, + custom_profile, + features, + verbose, + target, + cargo_args, + }) + } + + pub fn as_example(&mut self, example_name: String) -> &mut Self { + self.executable = ExecutableType::Example(example_name); + self + } + + pub fn with_release(&mut self, release: bool) -> &mut Self { + self.release = release; + self + } + + pub fn with_hot_reload(&mut self, hot_reload: bool) -> &mut Self { + self.hot_reload = hot_reload; + self + } + + pub fn with_cross_origin_policy(&mut self, cross_origin_policy: bool) -> &mut Self { + self.cross_origin_policy = cross_origin_policy; + self + } + + pub fn with_verbose(&mut self, verbose: bool) -> &mut Self { + self.verbose = verbose; + self + } + + pub fn set_profile(&mut self, profile: String) -> &mut Self { + self.custom_profile = Some(profile); + self + } + + pub fn set_features(&mut self, features: Vec) -> &mut Self { + self.features = Some(features); + self + } + + pub fn set_target(&mut self, target: String) -> &mut Self { + self.target = Some(target); + self + } + + pub fn set_cargo_args(&mut self, cargo_args: Vec) -> &mut Self { + self.cargo_args = cargo_args; + self + } +} + +fn true_bool() -> bool { + true +} diff --git a/packages/cli-config/src/lib.rs b/packages/cli-config/src/lib.rs new file mode 100644 index 000000000..da7446918 --- /dev/null +++ b/packages/cli-config/src/lib.rs @@ -0,0 +1,58 @@ +#![doc = include_str!("../README.md")] +#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/79236386")] +#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")] + +mod config; +pub use config::*; +mod bundle; +pub use bundle::*; +mod cargo; +pub use cargo::*; + +#[doc(hidden)] +pub mod __private { + use crate::CrateConfig; + + pub const CONFIG_ENV: &str = "DIOXUS_CONFIG"; + + pub fn save_config(config: &CrateConfig) -> CrateConfigDropGuard { + std::env::set_var(CONFIG_ENV, serde_json::to_string(config).unwrap()); + CrateConfigDropGuard + } + + /// A guard that removes the config from the environment when dropped. + pub struct CrateConfigDropGuard; + + impl Drop for CrateConfigDropGuard { + fn drop(&mut self) { + std::env::remove_var(CONFIG_ENV); + } + } +} + +/// An error that occurs when the dioxus CLI was not used to build the application. +#[derive(Debug)] +pub struct DioxusCLINotUsed; + +impl std::fmt::Display for DioxusCLINotUsed { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str("dioxus CLI was not used to build the application") + } +} + +impl std::error::Error for DioxusCLINotUsed {} + +/// The current crate's configuration. +pub static CURRENT_CONFIG: once_cell::sync::Lazy< + Result, +> = once_cell::sync::Lazy::new(|| { + CURRENT_CONFIG_JSON + .and_then(|config| serde_json::from_str(config).ok()) + .ok_or_else(|| { + tracing::error!("A library is trying to access the crate's configuration, but the dioxus CLI was not used to build the application."); + DioxusCLINotUsed + }) +}); + +/// The current crate's configuration. +pub const CURRENT_CONFIG_JSON: Option<&str> = std::option_env!("DIOXUS_CONFIG"); diff --git a/packages/cli/Cargo.toml b/packages/cli/Cargo.toml index 4335faa22..8f0c0dc8a 100644 --- a/packages/cli/Cargo.toml +++ b/packages/cli/Cargo.toml @@ -14,6 +14,7 @@ clap = { version = "4.2", features = ["derive"] } thiserror = { workspace = true } wasm-bindgen-cli-support = "0.2" colored = "2.0.0" +dioxus-cli-config = { workspace = true, features = ["cli"] } # features log = "0.4.14" @@ -72,10 +73,10 @@ cargo-generate = "0.18" toml_edit = "0.19.11" # bundling -tauri-bundler = { version = "=1.3.0", features = ["native-tls-vendored"] } -tauri-utils = "=1.4.*" +tauri-bundler = { version = "=1.4.*", features = ["native-tls-vendored"] } +tauri-utils = "=1.5.*" -manganis-cli-support= { git = "https://github.com/DioxusLabs/collect-assets", features = ["webp", "html"] } +manganis-cli-support = { workspace = true, features = ["webp", "html"] } dioxus-autofmt = { workspace = true } dioxus-check = { workspace = true } diff --git a/packages/cli/README.md b/packages/cli/README.md index 2325d6784..93c695e4f 100644 --- a/packages/cli/README.md +++ b/packages/cli/README.md @@ -35,13 +35,13 @@ cargo install --path . --debug ## Get started -Use `dx create project-name` to initialize a new Dioxus project. +Use `dx create` to initialize a new Dioxus project. It will be cloned from the [dioxus-template](https://github.com/DioxusLabs/dioxus-template) repository. Alternatively, you can specify the template path: ```shell -dx create hello --template gh:dioxuslabs/dioxus-template +dx create --template gh:dioxuslabs/dioxus-template ``` Run `dx --help` for a list of all the available commands. diff --git a/packages/cli/build.rs b/packages/cli/build.rs index 15935e2da..050f38761 100644 --- a/packages/cli/build.rs +++ b/packages/cli/build.rs @@ -5,14 +5,9 @@ use std::{env, path::PathBuf, process::Command}; fn main() { set_rerun(); set_commit_info(); - if option_env!("CFG_RELEASE").is_none() { - println!("cargo:rustc-env=POKE_RA_DEVS=1"); - } } fn set_rerun() { - println!("cargo:rerun-if-env-changed=CFG_RELEASE"); - let mut manifest_dir = PathBuf::from( env::var("CARGO_MANIFEST_DIR").expect("`CARGO_MANIFEST_DIR` is always set by cargo."), ); diff --git a/packages/cli/src/assets.rs b/packages/cli/src/assets.rs new file mode 100644 index 000000000..9248b47d5 --- /dev/null +++ b/packages/cli/src/assets.rs @@ -0,0 +1,57 @@ +use std::{fs::File, io::Write, path::PathBuf}; + +use crate::Result; +use dioxus_cli_config::CrateConfig; +use manganis_cli_support::{AssetManifest, AssetManifestExt}; + +pub fn asset_manifest(crate_config: &CrateConfig) -> AssetManifest { + AssetManifest::load_from_path( + crate_config.crate_dir.join("Cargo.toml"), + crate_config.workspace_dir.join("Cargo.lock"), + ) +} + +/// Create a head file that contains all of the imports for assets that the user project uses +pub fn create_assets_head(config: &CrateConfig, manifest: &AssetManifest) -> Result<()> { + let mut file = File::create(config.out_dir.join("__assets_head.html"))?; + file.write_all(manifest.head().as_bytes())?; + Ok(()) +} + +/// Process any assets collected from the binary +pub(crate) fn process_assets(config: &CrateConfig, manifest: &AssetManifest) -> anyhow::Result<()> { + let static_asset_output_dir = PathBuf::from( + config + .dioxus_config + .web + .app + .base_path + .clone() + .unwrap_or_default(), + ); + let static_asset_output_dir = config.out_dir.join(static_asset_output_dir); + + manifest.copy_static_assets_to(static_asset_output_dir)?; + + Ok(()) +} + +/// A guard that sets up the environment for the web renderer to compile in. This guard sets the location that assets will be served from +pub(crate) struct WebAssetConfigDropGuard; + +impl WebAssetConfigDropGuard { + pub fn new() -> Self { + // Set up the collect asset config + manganis_cli_support::Config::default() + .with_assets_serve_location("/") + .save(); + Self {} + } +} + +impl Drop for WebAssetConfigDropGuard { + fn drop(&mut self) { + // Reset the config + manganis_cli_support::Config::default().save(); + } +} diff --git a/packages/cli/src/builder.rs b/packages/cli/src/builder.rs index 6d1ccea05..92d9ab093 100644 --- a/packages/cli/src/builder.rs +++ b/packages/cli/src/builder.rs @@ -1,16 +1,18 @@ use crate::{ - config::{CrateConfig, ExecutableType}, + assets::{asset_manifest, create_assets_head, process_assets, WebAssetConfigDropGuard}, error::{Error, Result}, tools::Tool, }; use cargo_metadata::{diagnostic::Diagnostic, Message}; +use dioxus_cli_config::crate_root; +use dioxus_cli_config::CrateConfig; +use dioxus_cli_config::ExecutableType; use indicatif::{ProgressBar, ProgressStyle}; use lazy_static::lazy_static; -use manganis_cli_support::AssetManifestExt; -use serde::Serialize; +use manganis_cli_support::{AssetManifest, ManganisSupportGuard}; use std::{ fs::{copy, create_dir_all, File}, - io::{Read, Write}, + io::Read, panic, path::PathBuf, time::Duration, @@ -21,10 +23,11 @@ lazy_static! { static ref PROGRESS_BARS: indicatif::MultiProgress = indicatif::MultiProgress::new(); } -#[derive(Serialize, Debug, Clone)] +#[derive(Debug, Clone)] pub struct BuildResult { pub warnings: Vec, pub elapsed_time: u128, + pub assets: Option, } pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result { @@ -45,12 +48,14 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result Result Result cmd.arg("--bin").arg(name), - crate::ExecutableType::Lib(name) => cmd.arg("--lib").arg(name), - crate::ExecutableType::Example(name) => cmd.arg("--example").arg(name), + ExecutableType::Binary(name) => cmd.arg("--bin").arg(name), + ExecutableType::Lib(name) => cmd.arg("--lib").arg(name), + ExecutableType::Example(name) => cmd.arg("--example").arg(name), }; let warning_messages = prettier_build(cmd)?; @@ -326,7 +338,7 @@ pub fn build_desktop( let file_name: String; let mut res_path = match &config.executable { - crate::ExecutableType::Binary(name) | crate::ExecutableType::Lib(name) => { + ExecutableType::Binary(name) | ExecutableType::Lib(name) => { file_name = name.clone(); config .target_dir @@ -334,7 +346,7 @@ pub fn build_desktop( .join(release_type) .join(name) } - crate::ExecutableType::Example(name) => { + ExecutableType::Example(name) => { file_name = name.clone(); config .target_dir @@ -390,22 +402,20 @@ pub fn build_desktop( } } - if !skip_assets { + let assets = if !skip_assets { + let assets = asset_manifest(config); // Collect assets - process_assets(config)?; + process_assets(config, &assets)?; // Create the __assets_head.html file for bundling - create_assets_head(config)?; - } + create_assets_head(config, &assets)?; + Some(assets) + } else { + None + }; log::info!( "🚩 Build completed: [./{}]", - config - .dioxus_config - .application - .out_dir - .clone() - .unwrap_or_else(|| PathBuf::from("dist")) - .display() + config.dioxus_config.application.out_dir.clone().display() ); println!("build desktop done"); @@ -413,16 +423,10 @@ pub fn build_desktop( Ok(BuildResult { warnings: warning_messages, elapsed_time: t_start.elapsed().as_millis(), + assets, }) } -fn create_assets_head(config: &CrateConfig) -> Result<()> { - let manifest = config.asset_manifest(); - let mut file = File::create(config.out_dir.join("__assets_head.html"))?; - file.write_all(manifest.head().as_bytes())?; - Ok(()) -} - fn prettier_build(cmd: subprocess::Exec) -> anyhow::Result> { let mut warning_messages: Vec = vec![]; @@ -479,10 +483,10 @@ fn prettier_build(cmd: subprocess::Exec) -> anyhow::Result> { Ok(warning_messages) } -pub fn gen_page(config: &CrateConfig, serve: bool, skip_assets: bool) -> String { +pub fn gen_page(config: &CrateConfig, manifest: Option<&AssetManifest>, serve: bool) -> String { let _gaurd = WebAssetConfigDropGuard::new(); - let crate_root = crate::cargo::crate_root().unwrap(); + let crate_root = crate_root().unwrap(); let custom_html_file = crate_root.join("index.html"); let mut html = if custom_html_file.is_file() { let mut buf = String::new(); @@ -502,8 +506,8 @@ pub fn gen_page(config: &CrateConfig, serve: bool, skip_assets: bool) -> String let mut script_list = resources.script.unwrap_or_default(); if serve { - let mut dev_style = resources.dev.style.clone().unwrap_or_default(); - let mut dev_script = resources.dev.script.unwrap_or_default(); + let mut dev_style = resources.dev.style.clone(); + let mut dev_script = resources.dev.script.clone(); style_list.append(&mut dev_style); script_list.append(&mut dev_script); } @@ -520,13 +524,11 @@ pub fn gen_page(config: &CrateConfig, serve: bool, skip_assets: bool) -> String .application .tools .clone() - .unwrap_or_default() .contains_key("tailwindcss") { style_str.push_str("\n"); } - if !skip_assets { - let manifest = config.asset_manifest(); + if let Some(manifest) = manifest { style_str.push_str(&manifest.head()); } @@ -577,13 +579,7 @@ pub fn gen_page(config: &CrateConfig, serve: bool, skip_assets: bool) -> String ); } - let title = config - .dioxus_config - .web - .app - .title - .clone() - .unwrap_or_else(|| "dioxus | ⛺".into()); + let title = config.dioxus_config.web.app.title.clone(); replace_or_insert_before("{app_title}", &title, " Result> { let mut result = vec![]; let dioxus_config = &config.dioxus_config; - let dioxus_tools = dioxus_config.application.tools.clone().unwrap_or_default(); + let dioxus_tools = dioxus_config.application.tools.clone(); // check sass tool state let sass = Tool::Sass; @@ -748,42 +744,3 @@ fn build_assets(config: &CrateConfig) -> Result> { Ok(result) } - -/// Process any assets collected from the binary -fn process_assets(config: &CrateConfig) -> anyhow::Result<()> { - let manifest = config.asset_manifest(); - - let static_asset_output_dir = PathBuf::from( - config - .dioxus_config - .web - .app - .base_path - .clone() - .unwrap_or_default(), - ); - let static_asset_output_dir = config.out_dir.join(static_asset_output_dir); - - manifest.copy_static_assets_to(static_asset_output_dir)?; - - Ok(()) -} - -pub(crate) struct WebAssetConfigDropGuard; - -impl WebAssetConfigDropGuard { - pub fn new() -> Self { - // Set up the collect asset config - manganis_cli_support::Config::default() - .with_assets_serve_location("/") - .save(); - Self {} - } -} - -impl Drop for WebAssetConfigDropGuard { - fn drop(&mut self) { - // Reset the config - manganis_cli_support::Config::default().save(); - } -} diff --git a/packages/cli/src/cli/autoformat.rs b/packages/cli/src/cli/autoformat.rs index 812a4c325..d1702ebf2 100644 --- a/packages/cli/src/cli/autoformat.rs +++ b/packages/cli/src/cli/autoformat.rs @@ -22,23 +22,33 @@ pub struct Autoformat { /// Input file #[clap(short, long)] pub file: Option, + + /// Split attributes in lines or not + #[clap(short, long, default_value = "false")] + pub split_line_attributes: bool, } impl Autoformat { // Todo: autoformat the entire crate pub async fn autoformat(self) -> Result<()> { - let Autoformat { check, raw, file } = self; + let Autoformat { + check, + raw, + file, + split_line_attributes, + .. + } = self; // Default to formatting the project if raw.is_none() && file.is_none() { - if let Err(e) = autoformat_project(check).await { + if let Err(e) = autoformat_project(check, split_line_attributes).await { eprintln!("error formatting project: {}", e); exit(1); } } if let Some(raw) = raw { - let indent = indentation_for(".")?; + let indent = indentation_for(".", self.split_line_attributes)?; if let Some(inner) = dioxus_autofmt::fmt_block(&raw, 0, indent) { println!("{}", inner); } else { @@ -50,15 +60,15 @@ impl Autoformat { // Format single file if let Some(file) = file { - refactor_file(file)?; + refactor_file(file, split_line_attributes)?; } Ok(()) } } -fn refactor_file(file: String) -> Result<(), Error> { - let indent = indentation_for(".")?; +fn refactor_file(file: String, split_line_attributes: bool) -> Result<(), Error> { + let indent = indentation_for(".", split_line_attributes)?; let file_content = if file == "-" { let mut contents = String::new(); std::io::stdin().read_to_string(&mut contents)?; @@ -138,8 +148,8 @@ async fn format_file( /// Runs using Tokio for multithreading, so it should be really really fast /// /// Doesn't do mod-descending, so it will still try to format unreachable files. TODO. -async fn autoformat_project(check: bool) -> Result<()> { - let crate_config = crate::CrateConfig::new(None)?; +async fn autoformat_project(check: bool, split_line_attributes: bool) -> Result<()> { + let crate_config = dioxus_cli_config::CrateConfig::new(None)?; let files_to_format = get_project_files(&crate_config); @@ -147,7 +157,7 @@ async fn autoformat_project(check: bool) -> Result<()> { return Ok(()); } - let indent = indentation_for(&files_to_format[0])?; + let indent = indentation_for(&files_to_format[0], split_line_attributes)?; let counts = files_to_format .into_iter() @@ -181,7 +191,10 @@ async fn autoformat_project(check: bool) -> Result<()> { Ok(()) } -fn indentation_for(file_or_dir: impl AsRef) -> Result { +fn indentation_for( + file_or_dir: impl AsRef, + split_line_attributes: bool, +) -> Result { let out = std::process::Command::new("cargo") .args(["fmt", "--", "--print-config", "current"]) .arg(file_or_dir.as_ref()) @@ -221,6 +234,7 @@ fn indentation_for(file_or_dir: impl AsRef) -> Result { IndentType::Spaces }, tab_spaces, + split_line_attributes, )) } @@ -253,10 +267,10 @@ async fn test_auto_fmt() { let test_rsx = r#" // - rsx! { + div {} - } + // // @@ -269,6 +283,7 @@ async fn test_auto_fmt() { check: false, raw: Some(test_rsx), file: None, + split_line_attributes: false, }; fmt.autoformat().await.unwrap(); diff --git a/packages/cli/src/cli/build.rs b/packages/cli/src/cli/build.rs index d8032f034..ad15a8cf5 100644 --- a/packages/cli/src/cli/build.rs +++ b/packages/cli/src/cli/build.rs @@ -1,8 +1,9 @@ +use crate::assets::WebAssetConfigDropGuard; #[cfg(feature = "plugin")] use crate::plugin::PluginManager; use crate::server::fullstack::FullstackServerEnvGuard; use crate::server::fullstack::FullstackWebEnvGuard; -use crate::{cfg::Platform, WebAssetConfigDropGuard}; +use dioxus_cli_config::Platform; use super::*; @@ -16,7 +17,7 @@ pub struct Build { impl Build { pub fn build(self, bin: Option, target_dir: Option<&std::path::Path>) -> Result<()> { - let mut crate_config = crate::CrateConfig::new(bin)?; + let mut crate_config = dioxus_cli_config::CrateConfig::new(bin)?; if let Some(target_dir) = target_dir { crate_config.target_dir = target_dir.to_path_buf(); } @@ -51,12 +52,10 @@ impl Build { // #[cfg(feature = "plugin")] // let _ = PluginManager::on_build_start(&crate_config, &platform); - match platform { - Platform::Web => { - crate::builder::build(&crate_config, false, self.build.skip_assets)?; - } + let build_result = match platform { + Platform::Web => crate::builder::build(&crate_config, false, self.build.skip_assets)?, Platform::Desktop => { - crate::builder::build_desktop(&crate_config, false, self.build.skip_assets)?; + crate::builder::build_desktop(&crate_config, false, self.build.skip_assets)? } Platform::Fullstack => { // Fullstack mode must be built with web configs on the desktop (server) binary as well as the web binary @@ -86,24 +85,17 @@ impl Build { }; let _gaurd = FullstackServerEnvGuard::new(self.build.force_debug, self.build.release); - crate::builder::build_desktop(&desktop_config, false, self.build.skip_assets)?; + crate::builder::build_desktop(&desktop_config, false, self.build.skip_assets)? } } - } + }; - let temp = gen_page(&crate_config, false, self.build.skip_assets); + let temp = gen_page(&crate_config, build_result.assets.as_ref(), false); let mut file = std::fs::File::create( crate_config .crate_dir - .join( - crate_config - .dioxus_config - .application - .out_dir - .clone() - .unwrap_or_else(|| PathBuf::from("dist")), - ) + .join(crate_config.dioxus_config.application.out_dir.clone()) .join("index.html"), )?; file.write_all(temp.as_bytes())?; diff --git a/packages/cli/src/cli/bundle.rs b/packages/cli/src/cli/bundle.rs index aaa823373..a2231b31f 100644 --- a/packages/cli/src/cli/bundle.rs +++ b/packages/cli/src/cli/bundle.rs @@ -1,4 +1,5 @@ use core::panic; +use dioxus_cli_config::ExecutableType; use std::{fs::create_dir_all, str::FromStr}; use tauri_bundler::{BundleSettings, PackageSettings, SettingsBuilder}; @@ -62,7 +63,7 @@ impl From for tauri_bundler::PackageType { impl Bundle { pub fn bundle(self, bin: Option) -> Result<()> { - let mut crate_config = crate::CrateConfig::new(bin)?; + let mut crate_config = dioxus_cli_config::CrateConfig::new(bin)?; // change the release state. crate_config.with_release(self.build.release); @@ -89,9 +90,9 @@ impl Bundle { let package = crate_config.manifest.package.unwrap(); let mut name: PathBuf = match &crate_config.executable { - crate::ExecutableType::Binary(name) - | crate::ExecutableType::Lib(name) - | crate::ExecutableType::Example(name) => name, + ExecutableType::Binary(name) + | ExecutableType::Lib(name) + | ExecutableType::Example(name) => name, } .into(); if cfg!(windows) { diff --git a/packages/cli/src/cli/cfg.rs b/packages/cli/src/cli/cfg.rs index 62212e574..877fdff33 100644 --- a/packages/cli/src/cli/cfg.rs +++ b/packages/cli/src/cli/cfg.rs @@ -1,5 +1,4 @@ -use clap::ValueEnum; -use serde::Serialize; +use dioxus_cli_config::Platform; use super::*; @@ -154,19 +153,6 @@ pub struct ConfigOptsServe { pub cargo_args: Vec, } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, Serialize, Deserialize, Debug)] -pub enum Platform { - #[clap(name = "web")] - #[serde(rename = "web")] - Web, - #[clap(name = "desktop")] - #[serde(rename = "desktop")] - Desktop, - #[clap(name = "fullstack")] - #[serde(rename = "fullstack")] - Fullstack, -} - /// Config options for the bundling system. #[derive(Clone, Debug, Default, Deserialize, Parser)] pub struct ConfigOptsBundle { diff --git a/packages/cli/src/cli/check.rs b/packages/cli/src/cli/check.rs index a4d84addb..0832647f2 100644 --- a/packages/cli/src/cli/check.rs +++ b/packages/cli/src/cli/check.rs @@ -47,7 +47,7 @@ async fn check_file_and_report(path: PathBuf) -> Result<()> { /// /// Doesn't do mod-descending, so it will still try to check unreachable files. TODO. async fn check_project_and_report() -> Result<()> { - let crate_config = crate::CrateConfig::new(None)?; + let crate_config = dioxus_cli_config::CrateConfig::new(None)?; let mut files_to_check = vec![]; collect_rs_files(&crate_config.crate_dir, &mut files_to_check); diff --git a/packages/cli/src/cli/clean.rs b/packages/cli/src/cli/clean.rs index 9a0f0d4fb..04e0cb45b 100644 --- a/packages/cli/src/cli/clean.rs +++ b/packages/cli/src/cli/clean.rs @@ -7,7 +7,7 @@ pub struct Clean {} impl Clean { pub fn clean(self, bin: Option) -> Result<()> { - let crate_config = crate::CrateConfig::new(bin)?; + let crate_config = dioxus_cli_config::CrateConfig::new(bin)?; let output = Command::new("cargo") .arg("clean") @@ -19,11 +19,7 @@ impl Clean { return custom_error!("Cargo clean failed."); } - let out_dir = crate_config - .dioxus_config - .application - .out_dir - .unwrap_or_else(|| PathBuf::from("dist")); + let out_dir = crate_config.dioxus_config.application.out_dir; if crate_config.crate_dir.join(&out_dir).is_dir() { remove_dir_all(crate_config.crate_dir.join(&out_dir))?; } diff --git a/packages/cli/src/cli/config.rs b/packages/cli/src/cli/config.rs index 45fcc2f23..1a1072c2f 100644 --- a/packages/cli/src/cli/config.rs +++ b/packages/cli/src/cli/config.rs @@ -1,3 +1,5 @@ +use dioxus_cli_config::crate_root; + use super::*; /// Dioxus config file controls @@ -26,7 +28,7 @@ pub enum Config { impl Config { pub fn config(self) -> Result<()> { - let crate_root = crate::cargo::crate_root()?; + let crate_root = crate_root()?; match self { Config::Init { name, @@ -48,7 +50,10 @@ impl Config { log::info!("🚩 Init config file completed."); } Config::FormatPrint {} => { - println!("{:#?}", crate::CrateConfig::new(None)?.dioxus_config); + println!( + "{:#?}", + dioxus_cli_config::CrateConfig::new(None)?.dioxus_config + ); } Config::CustomHtml {} => { let html_path = crate_root.join("index.html"); diff --git a/packages/cli/src/cli/mod.rs b/packages/cli/src/cli/mod.rs index 9b3be33bc..4295bfa9b 100644 --- a/packages/cli/src/cli/mod.rs +++ b/packages/cli/src/cli/mod.rs @@ -15,9 +15,10 @@ use crate::{ cfg::{ConfigOptsBuild, ConfigOptsServe}, custom_error, error::Result, - gen_page, server, CrateConfig, Error, + gen_page, server, Error, }; use clap::{Parser, Subcommand}; +use dioxus_cli_config::CrateConfig; use html_parser::Dom; use serde::Deserialize; use std::{ diff --git a/packages/cli/src/cli/serve.rs b/packages/cli/src/cli/serve.rs index 1bb24ecdb..b4362729f 100644 --- a/packages/cli/src/cli/serve.rs +++ b/packages/cli/src/cli/serve.rs @@ -1,3 +1,6 @@ +use dioxus_cli_config::Platform; +use manganis_cli_support::AssetManifest; + use super::*; use std::{fs::create_dir_all, io::Write, path::PathBuf}; @@ -11,7 +14,7 @@ pub struct Serve { impl Serve { pub async fn serve(self, bin: Option) -> Result<()> { - let mut crate_config = crate::CrateConfig::new(bin)?; + let mut crate_config = dioxus_cli_config::CrateConfig::new(bin)?; let serve_cfg = self.serve.clone(); // change the relase state. @@ -32,9 +35,6 @@ impl Serve { crate_config.set_features(self.serve.features.unwrap()); } - // Subdirectories don't work with the server - crate_config.dioxus_config.web.app.base_path = None; - if let Some(target) = self.serve.target { crate_config.set_target(target); } @@ -47,10 +47,7 @@ impl Serve { .unwrap_or(crate_config.dioxus_config.application.default_platform); match platform { - cfg::Platform::Web => { - // generate dev-index page - Serve::regen_dev_page(&crate_config, self.serve.skip_assets)?; - + Platform::Web => { // start the develop server server::web::startup( self.serve.port, @@ -60,27 +57,25 @@ impl Serve { ) .await?; } - cfg::Platform::Desktop => { + Platform::Desktop => { server::desktop::startup(crate_config.clone(), &serve_cfg).await?; } - cfg::Platform::Fullstack => { + Platform::Fullstack => { server::fullstack::startup(crate_config.clone(), &serve_cfg).await?; } } Ok(()) } - pub fn regen_dev_page(crate_config: &CrateConfig, skip_assets: bool) -> Result<()> { - let serve_html = gen_page(crate_config, true, skip_assets); + pub fn regen_dev_page( + crate_config: &CrateConfig, + manifest: Option<&AssetManifest>, + ) -> anyhow::Result<()> { + let serve_html = gen_page(crate_config, manifest, true); - let dist_path = crate_config.crate_dir.join( - crate_config - .dioxus_config - .application - .out_dir - .clone() - .unwrap_or_else(|| PathBuf::from("dist")), - ); + let dist_path = crate_config + .crate_dir + .join(crate_config.dioxus_config.application.out_dir.clone()); if !dist_path.is_dir() { create_dir_all(&dist_path)?; } diff --git a/packages/cli/src/cli/version.rs b/packages/cli/src/cli/version.rs index c015a73a2..47ace1be3 100644 --- a/packages/cli/src/cli/version.rs +++ b/packages/cli/src/cli/version.rs @@ -49,7 +49,7 @@ impl fmt::Display for VersionInfo { /// Returns information about cargo's version. pub const fn version() -> VersionInfo { - let version = match option_env!("CFG_RELEASE") { + let version = match option_env!("CARGO_PKG_VERSION") { Some(x) => x, None => "0.0.0", }; diff --git a/packages/cli/src/config.rs b/packages/cli/src/config.rs deleted file mode 100644 index 5b4f23524..000000000 --- a/packages/cli/src/config.rs +++ /dev/null @@ -1,607 +0,0 @@ -use crate::{cfg::Platform, error::Result}; -use manganis_cli_support::AssetManifest; -use manganis_cli_support::AssetManifestExt; -use serde::{Deserialize, Serialize}; -use std::{ - collections::HashMap, - path::{Path, PathBuf}, -}; - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct DioxusConfig { - pub application: ApplicationConfig, - - pub web: WebConfig, - - #[serde(default)] - pub bundle: BundleConfig, - - #[serde(default = "default_plugin")] - pub plugin: toml::Value, -} - -fn default_plugin() -> toml::Value { - toml::Value::Boolean(true) -} - -impl DioxusConfig { - pub fn load(bin: Option) -> crate::error::Result> { - let crate_dir = crate::cargo::crate_root(); - - let crate_dir = match crate_dir { - Ok(dir) => { - if let Some(bin) = bin { - dir.join(bin) - } else { - dir - } - } - Err(_) => return Ok(None), - }; - let crate_dir = crate_dir.as_path(); - - let Some(dioxus_conf_file) = acquire_dioxus_toml(crate_dir) else { - return Ok(None); - }; - - let dioxus_conf_file = dioxus_conf_file.as_path(); - let cfg = toml::from_str::(&std::fs::read_to_string(dioxus_conf_file)?) - .map_err(|err| { - let error_location = dioxus_conf_file - .strip_prefix(crate_dir) - .unwrap_or(dioxus_conf_file) - .display(); - crate::Error::Unique(format!("{error_location} {err}")) - }) - .map(Some); - match cfg { - Ok(Some(mut cfg)) => { - let name = cfg.application.name.clone(); - if cfg.bundle.identifier.is_none() { - cfg.bundle.identifier = Some(format!("io.github.{name}")); - } - if cfg.bundle.publisher.is_none() { - cfg.bundle.publisher = Some(name); - } - Ok(Some(cfg)) - } - cfg => cfg, - } - } -} - -fn acquire_dioxus_toml(dir: &Path) -> Option { - // prefer uppercase - let uppercase_conf = dir.join("Dioxus.toml"); - if uppercase_conf.is_file() { - return Some(uppercase_conf); - } - - // lowercase is fine too - let lowercase_conf = dir.join("dioxus.toml"); - if lowercase_conf.is_file() { - return Some(lowercase_conf); - } - - None -} - -impl Default for DioxusConfig { - fn default() -> Self { - let name = "name"; - Self { - application: ApplicationConfig { - name: name.into(), - default_platform: Platform::Web, - out_dir: Some(PathBuf::from("dist")), - asset_dir: Some(PathBuf::from("public")), - - tools: None, - - sub_package: None, - }, - web: WebConfig { - app: WebAppConfig { - title: Some("dioxus | ⛺".into()), - base_path: None, - }, - proxy: Some(vec![]), - watcher: WebWatcherConfig { - watch_path: Some(vec![PathBuf::from("src"), PathBuf::from("examples")]), - reload_html: Some(false), - index_on_404: Some(true), - }, - resource: WebResourceConfig { - dev: WebDevResourceConfig { - style: Some(vec![]), - script: Some(vec![]), - }, - style: Some(vec![]), - script: Some(vec![]), - }, - https: WebHttpsConfig { - enabled: None, - mkcert: None, - key_path: None, - cert_path: None, - }, - }, - bundle: BundleConfig { - identifier: Some(format!("io.github.{name}")), - publisher: Some(name.into()), - ..Default::default() - }, - plugin: toml::Value::Table(toml::map::Map::new()), - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ApplicationConfig { - pub name: String, - pub default_platform: Platform, - pub out_dir: Option, - pub asset_dir: Option, - - pub tools: Option>, - - pub sub_package: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WebConfig { - pub app: WebAppConfig, - pub proxy: Option>, - pub watcher: WebWatcherConfig, - pub resource: WebResourceConfig, - #[serde(default)] - pub https: WebHttpsConfig, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WebAppConfig { - pub title: Option, - pub base_path: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WebProxyConfig { - pub backend: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WebWatcherConfig { - pub watch_path: Option>, - pub reload_html: Option, - pub index_on_404: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WebResourceConfig { - pub dev: WebDevResourceConfig, - pub style: Option>, - pub script: Option>, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WebDevResourceConfig { - pub style: Option>, - pub script: Option>, -} - -#[derive(Debug, Default, Clone, Serialize, Deserialize)] -pub struct WebHttpsConfig { - pub enabled: Option, - pub mkcert: Option, - pub key_path: Option, - pub cert_path: Option, -} - -#[derive(Debug, Clone)] -pub struct CrateConfig { - pub out_dir: PathBuf, - pub crate_dir: PathBuf, - pub workspace_dir: PathBuf, - pub target_dir: PathBuf, - pub asset_dir: PathBuf, - pub manifest: cargo_toml::Manifest, - pub executable: ExecutableType, - pub dioxus_config: DioxusConfig, - pub release: bool, - pub hot_reload: bool, - pub cross_origin_policy: bool, - pub verbose: bool, - pub custom_profile: Option, - pub features: Option>, - pub target: Option, - pub cargo_args: Vec, -} - -#[derive(Debug, Clone)] -pub enum ExecutableType { - Binary(String), - Lib(String), - Example(String), -} - -impl CrateConfig { - pub fn new(bin: Option) -> Result { - let dioxus_config = DioxusConfig::load(bin.clone())?.unwrap_or_default(); - - let crate_root = crate::cargo::crate_root()?; - - let crate_dir = if let Some(package) = &dioxus_config.application.sub_package { - crate_root.join(package) - } else if let Some(bin) = bin { - crate_root.join(bin) - } else { - crate_root - }; - - let meta = crate::cargo::Metadata::get()?; - let workspace_dir = meta.workspace_root; - let target_dir = meta.target_directory; - - let out_dir = match dioxus_config.application.out_dir { - Some(ref v) => crate_dir.join(v), - None => crate_dir.join("dist"), - }; - - let cargo_def = &crate_dir.join("Cargo.toml"); - - let asset_dir = match dioxus_config.application.asset_dir { - Some(ref v) => crate_dir.join(v), - None => crate_dir.join("public"), - }; - - let manifest = cargo_toml::Manifest::from_path(cargo_def).unwrap(); - - let mut output_filename = String::from("dioxus_app"); - if let Some(package) = &manifest.package.as_ref() { - output_filename = match &package.default_run { - Some(default_run_target) => default_run_target.to_owned(), - None => manifest - .bin - .iter() - .find(|b| b.name == manifest.package.as_ref().map(|pkg| pkg.name.clone())) - .or(manifest - .bin - .iter() - .find(|b| b.path == Some("src/main.rs".to_owned()))) - .or(manifest.bin.first()) - .or(manifest.lib.as_ref()) - .and_then(|prod| prod.name.clone()) - .unwrap_or(String::from("dioxus_app")), - }; - } - - let executable = ExecutableType::Binary(output_filename); - - let release = false; - let hot_reload = false; - let verbose = false; - let custom_profile = None; - let features = None; - let target = None; - let cargo_args = vec![]; - - Ok(Self { - out_dir, - crate_dir, - workspace_dir, - target_dir, - asset_dir, - manifest, - executable, - release, - dioxus_config, - hot_reload, - cross_origin_policy: false, - custom_profile, - features, - verbose, - target, - cargo_args, - }) - } - - pub fn asset_manifest(&self) -> AssetManifest { - AssetManifest::load_from_path( - self.crate_dir.join("Cargo.toml"), - self.workspace_dir.join("Cargo.lock"), - ) - } - - pub fn as_example(&mut self, example_name: String) -> &mut Self { - self.executable = ExecutableType::Example(example_name); - self - } - - pub fn with_release(&mut self, release: bool) -> &mut Self { - self.release = release; - self - } - - pub fn with_hot_reload(&mut self, hot_reload: bool) -> &mut Self { - self.hot_reload = hot_reload; - self - } - - pub fn with_cross_origin_policy(&mut self, cross_origin_policy: bool) -> &mut Self { - self.cross_origin_policy = cross_origin_policy; - self - } - - pub fn with_verbose(&mut self, verbose: bool) -> &mut Self { - self.verbose = verbose; - self - } - - pub fn set_profile(&mut self, profile: String) -> &mut Self { - self.custom_profile = Some(profile); - self - } - - pub fn set_features(&mut self, features: Vec) -> &mut Self { - self.features = Some(features); - self - } - - pub fn set_target(&mut self, target: String) -> &mut Self { - self.target = Some(target); - self - } - - pub fn set_cargo_args(&mut self, cargo_args: Vec) -> &mut Self { - self.cargo_args = cargo_args; - self - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -pub struct BundleConfig { - pub identifier: Option, - pub publisher: Option, - pub icon: Option>, - pub resources: Option>, - pub copyright: Option, - pub category: Option, - pub short_description: Option, - pub long_description: Option, - pub external_bin: Option>, - pub deb: Option, - pub macos: Option, - pub windows: Option, -} - -impl From for tauri_bundler::BundleSettings { - fn from(val: BundleConfig) -> Self { - tauri_bundler::BundleSettings { - identifier: val.identifier, - publisher: val.publisher, - icon: val.icon, - resources: val.resources, - copyright: val.copyright, - category: val.category.and_then(|c| c.parse().ok()), - short_description: val.short_description, - long_description: val.long_description, - external_bin: val.external_bin, - deb: val.deb.map(Into::into).unwrap_or_default(), - macos: val.macos.map(Into::into).unwrap_or_default(), - windows: val.windows.map(Into::into).unwrap_or_default(), - ..Default::default() - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -pub struct DebianSettings { - pub depends: Option>, - pub files: HashMap, - pub nsis: Option, -} - -impl From for tauri_bundler::DebianSettings { - fn from(val: DebianSettings) -> Self { - tauri_bundler::DebianSettings { - depends: val.depends, - files: val.files, - desktop_template: None, - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -pub struct WixSettings { - pub language: Vec<(String, Option)>, - pub template: Option, - pub fragment_paths: Vec, - pub component_group_refs: Vec, - pub component_refs: Vec, - pub feature_group_refs: Vec, - pub feature_refs: Vec, - pub merge_refs: Vec, - pub skip_webview_install: bool, - pub license: Option, - pub enable_elevated_update_task: bool, - pub banner_path: Option, - pub dialog_image_path: Option, - pub fips_compliant: bool, -} - -impl From for tauri_bundler::WixSettings { - fn from(val: WixSettings) -> Self { - tauri_bundler::WixSettings { - language: tauri_bundler::bundle::WixLanguage({ - let mut languages: Vec<_> = val - .language - .iter() - .map(|l| { - ( - l.0.clone(), - tauri_bundler::bundle::WixLanguageConfig { - locale_path: l.1.clone(), - }, - ) - }) - .collect(); - if languages.is_empty() { - languages.push(("en-US".into(), Default::default())); - } - languages - }), - template: val.template, - fragment_paths: val.fragment_paths, - component_group_refs: val.component_group_refs, - component_refs: val.component_refs, - feature_group_refs: val.feature_group_refs, - feature_refs: val.feature_refs, - merge_refs: val.merge_refs, - skip_webview_install: val.skip_webview_install, - license: val.license, - enable_elevated_update_task: val.enable_elevated_update_task, - banner_path: val.banner_path, - dialog_image_path: val.dialog_image_path, - fips_compliant: val.fips_compliant, - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -pub struct MacOsSettings { - pub frameworks: Option>, - pub minimum_system_version: Option, - pub license: Option, - pub exception_domain: Option, - pub signing_identity: Option, - pub provider_short_name: Option, - pub entitlements: Option, - pub info_plist_path: Option, -} - -impl From for tauri_bundler::MacOsSettings { - fn from(val: MacOsSettings) -> Self { - tauri_bundler::MacOsSettings { - frameworks: val.frameworks, - minimum_system_version: val.minimum_system_version, - license: val.license, - exception_domain: val.exception_domain, - signing_identity: val.signing_identity, - provider_short_name: val.provider_short_name, - entitlements: val.entitlements, - info_plist_path: val.info_plist_path, - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WindowsSettings { - pub digest_algorithm: Option, - pub certificate_thumbprint: Option, - pub timestamp_url: Option, - pub tsp: bool, - pub wix: Option, - pub icon_path: Option, - pub webview_install_mode: WebviewInstallMode, - pub webview_fixed_runtime_path: Option, - pub allow_downgrades: bool, - pub nsis: Option, -} - -impl From for tauri_bundler::WindowsSettings { - fn from(val: WindowsSettings) -> Self { - tauri_bundler::WindowsSettings { - digest_algorithm: val.digest_algorithm, - certificate_thumbprint: val.certificate_thumbprint, - timestamp_url: val.timestamp_url, - tsp: val.tsp, - wix: val.wix.map(Into::into), - icon_path: val.icon_path.unwrap_or("icons/icon.ico".into()), - webview_install_mode: val.webview_install_mode.into(), - webview_fixed_runtime_path: val.webview_fixed_runtime_path, - allow_downgrades: val.allow_downgrades, - nsis: val.nsis.map(Into::into), - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct NsisSettings { - pub template: Option, - pub license: Option, - pub header_image: Option, - pub sidebar_image: Option, - pub installer_icon: Option, - pub install_mode: NSISInstallerMode, - pub languages: Option>, - pub custom_language_files: Option>, - pub display_language_selector: bool, -} - -impl From for tauri_bundler::NsisSettings { - fn from(val: NsisSettings) -> Self { - tauri_bundler::NsisSettings { - license: val.license, - header_image: val.header_image, - sidebar_image: val.sidebar_image, - installer_icon: val.installer_icon, - install_mode: val.install_mode.into(), - languages: val.languages, - display_language_selector: val.display_language_selector, - custom_language_files: None, - template: None, - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum NSISInstallerMode { - CurrentUser, - PerMachine, - Both, -} - -impl From for tauri_utils::config::NSISInstallerMode { - fn from(val: NSISInstallerMode) -> Self { - match val { - NSISInstallerMode::CurrentUser => tauri_utils::config::NSISInstallerMode::CurrentUser, - NSISInstallerMode::PerMachine => tauri_utils::config::NSISInstallerMode::PerMachine, - NSISInstallerMode::Both => tauri_utils::config::NSISInstallerMode::Both, - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum WebviewInstallMode { - Skip, - DownloadBootstrapper { silent: bool }, - EmbedBootstrapper { silent: bool }, - OfflineInstaller { silent: bool }, - FixedRuntime { path: PathBuf }, -} - -impl WebviewInstallMode { - fn into(self) -> tauri_utils::config::WebviewInstallMode { - match self { - Self::Skip => tauri_utils::config::WebviewInstallMode::Skip, - Self::DownloadBootstrapper { silent } => { - tauri_utils::config::WebviewInstallMode::DownloadBootstrapper { silent } - } - Self::EmbedBootstrapper { silent } => { - tauri_utils::config::WebviewInstallMode::EmbedBootstrapper { silent } - } - Self::OfflineInstaller { silent } => { - tauri_utils::config::WebviewInstallMode::OfflineInstaller { silent } - } - Self::FixedRuntime { path } => { - tauri_utils::config::WebviewInstallMode::FixedRuntime { path } - } - } - } -} - -impl Default for WebviewInstallMode { - fn default() -> Self { - Self::OfflineInstaller { silent: false } - } -} diff --git a/packages/cli/src/error.rs b/packages/cli/src/error.rs index d577b2b40..35eea7eab 100644 --- a/packages/cli/src/error.rs +++ b/packages/cli/src/error.rs @@ -72,6 +72,24 @@ impl From for Error { } } +impl From for Error { + fn from(e: dioxus_cli_config::LoadDioxusConfigError) -> Self { + Self::RuntimeError(e.to_string()) + } +} + +impl From for Error { + fn from(e: dioxus_cli_config::CargoError) -> Self { + Self::CargoError(e.to_string()) + } +} + +impl From for Error { + fn from(e: dioxus_cli_config::CrateConfigError) -> Self { + Self::RuntimeError(e.to_string()) + } +} + #[macro_export] macro_rules! custom_error { ($msg:literal $(,)?) => { diff --git a/packages/cli/src/lib.rs b/packages/cli/src/lib.rs index b27cf55a9..191c65008 100644 --- a/packages/cli/src/lib.rs +++ b/packages/cli/src/lib.rs @@ -4,21 +4,16 @@ pub const DIOXUS_CLI_VERSION: &str = "0.4.1"; +mod assets; pub mod builder; pub mod server; pub mod tools; pub use builder::*; -pub mod cargo; -pub use cargo::*; - pub mod cli; pub use cli::*; -pub mod config; -pub use config::*; - pub mod error; pub use error::*; diff --git a/packages/cli/src/main.rs b/packages/cli/src/main.rs index 0695d7ac8..a603f7929 100644 --- a/packages/cli/src/main.rs +++ b/packages/cli/src/main.rs @@ -1,3 +1,4 @@ +use dioxus_cli_config::DioxusConfig; use std::path::PathBuf; use anyhow::anyhow; @@ -48,7 +49,7 @@ async fn main() -> anyhow::Result<()> { let _dioxus_config = DioxusConfig::load(Some(bin.clone())) .map_err(|e| anyhow!("Failed to load Dioxus config because: {e}"))? .unwrap_or_else(|| { - log::warn!("You appear to be creating a Dioxus project from scratch; we will use the default config"); + log::info!("You appear to be creating a Dioxus project from scratch; we will use the default config"); DioxusConfig::default() }); diff --git a/packages/cli/src/server/desktop/mod.rs b/packages/cli/src/server/desktop/mod.rs index 34f85a312..ad4b7bac8 100644 --- a/packages/cli/src/server/desktop/mod.rs +++ b/packages/cli/src/server/desktop/mod.rs @@ -5,8 +5,11 @@ use crate::{ output::{print_console_info, PrettierOptions}, setup_file_watcher, }, - BuildResult, CrateConfig, Result, + BuildResult, Result, }; +use dioxus_cli_config::CrateConfig; +use dioxus_cli_config::ExecutableType; + use dioxus_hot_reload::HotReloadMsg; use dioxus_html::HtmlCtx; use dioxus_rsx::hot_reload::*; @@ -215,9 +218,9 @@ fn start_desktop(config: &CrateConfig, skip_assets: bool) -> Result<(RAIIChild, let result = crate::builder::build_desktop(config, true, skip_assets)?; match &config.executable { - crate::ExecutableType::Binary(name) - | crate::ExecutableType::Lib(name) - | crate::ExecutableType::Example(name) => { + ExecutableType::Binary(name) + | ExecutableType::Lib(name) + | ExecutableType::Example(name) => { let mut file = config.out_dir.join(name); if cfg!(windows) { file.set_extension("exe"); diff --git a/packages/cli/src/server/fullstack/mod.rs b/packages/cli/src/server/fullstack/mod.rs index fa9c77459..60d685ced 100644 --- a/packages/cli/src/server/fullstack/mod.rs +++ b/packages/cli/src/server/fullstack/mod.rs @@ -1,6 +1,9 @@ +use dioxus_cli_config::CrateConfig; + use crate::{ + assets::WebAssetConfigDropGuard, cfg::{ConfigOptsBuild, ConfigOptsServe}, - CrateConfig, Result, WebAssetConfigDropGuard, + Result, }; use super::{desktop, Platform}; @@ -86,7 +89,7 @@ fn build_web(serve: ConfigOptsServe, target_directory: &std::path::Path) -> Resu } None => web_config.features = Some(vec![web_feature]), }; - web_config.platform = Some(crate::cfg::Platform::Web); + web_config.platform = Some(dioxus_cli_config::Platform::Web); let _gaurd = FullstackWebEnvGuard::new(&web_config); crate::cli::build::Build { build: web_config }.build(None, Some(target_directory)) diff --git a/packages/cli/src/server/mod.rs b/packages/cli/src/server/mod.rs index 895d9e51e..1fe5f2ea5 100644 --- a/packages/cli/src/server/mod.rs +++ b/packages/cli/src/server/mod.rs @@ -1,14 +1,12 @@ -use crate::{cfg::ConfigOptsServe, BuildResult, CrateConfig, Result}; +use crate::{cfg::ConfigOptsServe, BuildResult, Result}; +use dioxus_cli_config::CrateConfig; use cargo_metadata::diagnostic::Diagnostic; use dioxus_core::Template; use dioxus_html::HtmlCtx; use dioxus_rsx::hot_reload::*; use notify::{RecommendedWatcher, Watcher}; -use std::{ - path::PathBuf, - sync::{Arc, Mutex}, -}; +use std::sync::{Arc, Mutex}; use tokio::sync::broadcast::{self}; mod output; @@ -27,13 +25,7 @@ async fn setup_file_watcher Result + Send + 'static>( let mut last_update_time = chrono::Local::now().timestamp(); // file watcher: check file change - let allow_watch_path = config - .dioxus_config - .web - .watcher - .watch_path - .clone() - .unwrap_or_else(|| vec![PathBuf::from("src"), PathBuf::from("examples")]); + let allow_watch_path = config.dioxus_config.web.watcher.watch_path.clone(); let watcher_config = config.clone(); let mut watcher = notify::recommended_watcher(move |info: notify::Result| { diff --git a/packages/cli/src/server/output.rs b/packages/cli/src/server/output.rs index 4e148b0f1..a61dd1f59 100644 --- a/packages/cli/src/server/output.rs +++ b/packages/cli/src/server/output.rs @@ -1,6 +1,7 @@ use crate::server::Diagnostic; -use crate::CrateConfig; use colored::Colorize; +use dioxus_cli_config::crate_root; +use dioxus_cli_config::CrateConfig; use std::path::PathBuf; use std::process::Command; @@ -43,25 +44,19 @@ pub fn print_console_info( profile = config.custom_profile.as_ref().unwrap().to_string(); } let hot_reload = if config.hot_reload { "RSX" } else { "Normal" }; - let crate_root = crate::cargo::crate_root().unwrap(); + let crate_root = crate_root().unwrap(); let custom_html_file = if crate_root.join("index.html").is_file() { "Custom [index.html]" } else { "Default" }; - let url_rewrite = if config - .dioxus_config - .web - .watcher - .index_on_404 - .unwrap_or(false) - { + let url_rewrite = if config.dioxus_config.web.watcher.index_on_404 { "True" } else { "False" }; - let proxies = config.dioxus_config.web.proxy.as_ref(); + let proxies = &config.dioxus_config.web.proxy; if options.changed.is_empty() { println!( @@ -109,12 +104,10 @@ pub fn print_console_info( println!(); println!("\t> Profile : {}", profile.green()); println!("\t> Hot Reload : {}", hot_reload.cyan()); - if let Some(proxies) = proxies { - if !proxies.is_empty() { - println!("\t> Proxies :"); - for proxy in proxies { - println!("\t\t- {}", proxy.backend.blue()); - } + if !proxies.is_empty() { + println!("\t> Proxies :"); + for proxy in proxies { + println!("\t\t- {}", proxy.backend.blue()); } } println!("\t> Index Template : {}", custom_html_file.green()); diff --git a/packages/cli/src/server/web/mod.rs b/packages/cli/src/server/web/mod.rs index 896d08643..39366ee0c 100644 --- a/packages/cli/src/server/web/mod.rs +++ b/packages/cli/src/server/web/mod.rs @@ -5,7 +5,7 @@ use crate::{ output::{print_console_info, PrettierOptions, WebServerInfo}, setup_file_watcher, HotReloadState, }, - BuildResult, CrateConfig, Result, WebHttpsConfig, + BuildResult, Result, }; use axum::{ body::{Full, HttpBody}, @@ -20,6 +20,8 @@ use axum::{ Router, }; use axum_server::tls_rustls::RustlsConfig; +use dioxus_cli_config::CrateConfig; +use dioxus_cli_config::WebHttpsConfig; use dioxus_html::HtmlCtx; use dioxus_rsx::hot_reload::*; @@ -109,6 +111,9 @@ pub async fn serve( ) -> Result<()> { let first_build_result = crate::builder::build(&config, false, skip_assets)?; + // generate dev-index page + Serve::regen_dev_page(&config, first_build_result.assets.as_ref())?; + log::info!("🚀 Starting development server..."); // WS Reload Watching @@ -277,12 +282,7 @@ async fn setup_router( .override_response_header(HeaderName::from_static("cross-origin-opener-policy"), coop) .and_then( move |response: Response| async move { - let mut response = if file_service_config - .dioxus_config - .web - .watcher - .index_on_404 - .unwrap_or(false) + let mut response = if file_service_config.dioxus_config.web.watcher.index_on_404 && response.status() == StatusCode::NOT_FOUND { let body = Full::from( @@ -321,7 +321,7 @@ async fn setup_router( let mut router = Router::new().route("/_dioxus/ws", get(ws_handler)); // Setup proxy - for proxy_config in config.dioxus_config.web.proxy.unwrap_or_default() { + for proxy_config in config.dioxus_config.web.proxy { router = proxy::add_proxy(router, &proxy_config)?; } @@ -335,6 +335,18 @@ async fn setup_router( }, )); + router = if let Some(base_path) = config.dioxus_config.web.app.base_path.clone() { + let base_path = format!("/{}", base_path.trim_matches('/')); + Router::new() + .nest(&base_path, axum::routing::any_service(router)) + .fallback(get(move || { + let base_path = base_path.clone(); + async move { format!("Outside of the base path: {}", base_path) } + })) + } else { + router + }; + // Setup routes router = router .route("/_dioxus/hot_reload", get(hot_reload_handler)) @@ -438,14 +450,8 @@ fn build(config: &CrateConfig, reload_tx: &Sender<()>, skip_assets: bool) -> Res let result = builder::build(config, true, skip_assets)?; // change the websocket reload state to true; // the page will auto-reload. - if config - .dioxus_config - .web - .watcher - .reload_html - .unwrap_or(false) - { - let _ = Serve::regen_dev_page(config, skip_assets); + if config.dioxus_config.web.watcher.reload_html { + let _ = Serve::regen_dev_page(config, result.assets.as_ref()); } let _ = reload_tx.send(()); Ok(result) diff --git a/packages/cli/src/server/web/proxy.rs b/packages/cli/src/server/web/proxy.rs index e35635b6b..4242a55eb 100644 --- a/packages/cli/src/server/web/proxy.rs +++ b/packages/cli/src/server/web/proxy.rs @@ -1,4 +1,5 @@ -use crate::{Result, WebProxyConfig}; +use crate::Result; +use dioxus_cli_config::WebProxyConfig; use anyhow::Context; use axum::{http::StatusCode, routing::any, Router}; diff --git a/packages/core-macro/Cargo.toml b/packages/core-macro/Cargo.toml index 00659dcdc..1d06a7034 100644 --- a/packages/core-macro/Cargo.toml +++ b/packages/core-macro/Cargo.toml @@ -15,9 +15,10 @@ proc-macro = true [dependencies] proc-macro2 = { version = "1.0" } quote = "1.0" -syn = { version = "2.0", features = ["full", "extra-traits"] } +syn = { version = "2.0", features = ["full", "extra-traits", "visit"] } dioxus-rsx = { workspace = true } constcat = "0.3.0" +convert_case = "^0.6.0" prettyplease = "0.2.15" # testing diff --git a/packages/core-macro/src/props/mod.rs b/packages/core-macro/src/props/mod.rs index d5384d3db..bd6816070 100644 --- a/packages/core-macro/src/props/mod.rs +++ b/packages/core-macro/src/props/mod.rs @@ -24,6 +24,10 @@ pub fn impl_my_derive(ast: &syn::DeriveInput) -> Result { .included_fields() .map(|f| struct_info.field_impl(f)) .collect::, _>>()?; + let extends = struct_info + .extend_fields() + .map(|f| struct_info.extends_impl(f)) + .collect::, _>>()?; let fields = quote!(#(#fields)*).into_iter(); let required_fields = struct_info .included_fields() @@ -36,6 +40,7 @@ pub fn impl_my_derive(ast: &syn::DeriveInput) -> Result { #builder_creation #conversion_helper #( #fields )* + #( #extends )* #( #required_fields )* #build_method } @@ -167,8 +172,8 @@ mod field_info { use proc_macro2::TokenStream; use quote::quote; use syn::spanned::Spanned; - use syn::Expr; use syn::{parse::Error, punctuated::Punctuated}; + use syn::{Expr, Path}; use super::util::{ expr_to_single_string, ident_to_type, path_to_single_string, strip_raw_ident_prefix, @@ -199,6 +204,13 @@ mod field_info { ); } + // extended field is automatically empty + if !builder_attr.extends.is_empty() { + builder_attr.default = Some( + syn::parse(quote!(::core::default::Default::default()).into()).unwrap(), + ); + } + // auto detect optional let strip_option_auto = builder_attr.strip_option || !builder_attr.ignore_option @@ -253,6 +265,7 @@ mod field_info { pub auto_into: bool, pub strip_option: bool, pub ignore_option: bool, + pub extends: Vec, } impl FieldBuilderAttr { @@ -305,6 +318,17 @@ mod field_info { let name = expr_to_single_string(&assign.left) .ok_or_else(|| Error::new_spanned(&assign.left, "Expected identifier"))?; match name.as_str() { + "extends" => { + if let syn::Expr::Path(path) = *assign.right { + self.extends.push(path.path); + Ok(()) + } else { + Err(Error::new_spanned( + assign.right, + "Expected simple identifier", + )) + } + } "default" => { self.default = Some(*assign.right); Ok(()) @@ -359,6 +383,11 @@ mod field_info { Ok(()) } + "extend" => { + self.extends.push(path.path); + Ok(()) + } + _ => { macro_rules! handle_fields { ( $( $flag:expr, $field:ident, $already:expr; )* ) => { @@ -462,11 +491,14 @@ fn type_from_inside_option(ty: &syn::Type, check_option_name: bool) -> Option<&s } mod struct_info { + use convert_case::{Case, Casing}; use proc_macro2::TokenStream; use quote::quote; use syn::parse::Error; use syn::punctuated::Punctuated; - use syn::Expr; + use syn::spanned::Spanned; + use syn::visit::Visit; + use syn::{parse_quote, Expr, Ident}; use super::field_info::{FieldBuilderAttr, FieldInfo}; use super::util::{ @@ -489,7 +521,46 @@ mod struct_info { impl<'a> StructInfo<'a> { pub fn included_fields(&self) -> impl Iterator> { - self.fields.iter().filter(|f| !f.builder_attr.skip) + self.fields + .iter() + .filter(|f| !f.builder_attr.skip && f.builder_attr.extends.is_empty()) + } + + pub fn extend_fields(&self) -> impl Iterator> { + self.fields + .iter() + .filter(|f| !f.builder_attr.extends.is_empty()) + } + + fn extend_lifetime(&self) -> syn::Result> { + let first_extend = self.extend_fields().next(); + + match first_extend { + Some(f) => { + struct VisitFirstLifetime(Option); + + impl Visit<'_> for VisitFirstLifetime { + fn visit_lifetime(&mut self, lifetime: &'_ syn::Lifetime) { + if self.0.is_none() { + self.0 = Some(lifetime.clone()); + } + } + } + + let name = f.name; + let mut visitor = VisitFirstLifetime(None); + + visitor.visit_type(f.ty); + + visitor.0.ok_or_else(|| { + syn::Error::new_spanned( + name, + "Unable to find lifetime for extended field. Please specify it manually", + ) + }).map(Some) + } + None => Ok(None), + } } pub fn new( @@ -536,7 +607,17 @@ mod struct_info { // Therefore, we will generate code that shortcircuits the "comparison" in memoization let are_there_generics = !self.generics.params.is_empty(); - let (impl_generics, ty_generics, where_clause) = self.generics.split_for_impl(); + let extend_lifetime = self.extend_lifetime()?; + + let generics = self.generics.clone(); + let (_, ty_generics, where_clause) = generics.split_for_impl(); + let impl_generics = self.modify_generics(|g| { + if extend_lifetime.is_none() { + g.params.insert(0, parse_quote!('__bump)); + } + }); + let (impl_generics, _, _) = impl_generics.split_for_impl(); + let (_, b_initial_generics, _) = self.generics.split_for_impl(); let all_fields_param = syn::GenericParam::Type( syn::Ident::new("TypedBuilderFields", proc_macro2::Span::call_site()).into(), ); @@ -544,7 +625,7 @@ mod struct_info { g.params.insert(0, all_fields_param.clone()); }); let empties_tuple = type_tuple(self.included_fields().map(|_| empty_type())); - let generics_with_empty = modify_types_generics_hack(&ty_generics, |args| { + let generics_with_empty = modify_types_generics_hack(&b_initial_generics, |args| { args.insert(0, syn::GenericArgument::Type(empties_tuple.clone().into())); }); let phantom_generics = self.generics.params.iter().filter_map(|param| match param { @@ -603,8 +684,7 @@ Finally, call `.build()` to create the instance of `{name}`. quote!(#[doc(hidden)]) }; - let (b_generics_impl, b_generics_ty, b_generics_where_extras_predicates) = - b_generics.split_for_impl(); + let (_, _, b_generics_where_extras_predicates) = b_generics.split_for_impl(); let mut b_generics_where: syn::WhereClause = syn::parse2(quote! { where TypedBuilderFields: Clone })?; @@ -623,7 +703,7 @@ Finally, call `.build()` to create the instance of `{name}`. impl #impl_generics #name #ty_generics #where_clause { #[doc = #builder_method_doc] #[allow(dead_code, clippy::type_complexity)] - #vis fn builder() -> #builder_name #generics_with_empty { + #vis fn builder(_cx: & #extend_lifetime ::dioxus::prelude::ScopeState) -> #builder_name #generics_with_empty { #builder_name { fields: #empties_tuple, _phantom: ::core::default::Default::default(), @@ -639,16 +719,7 @@ Finally, call `.build()` to create the instance of `{name}`. _phantom: (#( #phantom_generics ),*), } - impl #b_generics_impl Clone for #builder_name #b_generics_ty #b_generics_where { - fn clone(&self) -> Self { - Self { - fields: self.fields.clone(), - _phantom: ::core::default::Default::default(), - } - } - } - - impl #impl_generics ::dioxus::prelude::Properties for #name #ty_generics + impl #impl_generics ::dioxus::prelude::Properties<#extend_lifetime> for #name #ty_generics #b_generics_where_extras_predicates { type Builder = #builder_name #generics_with_empty; @@ -688,11 +759,143 @@ Finally, call `.build()` to create the instance of `{name}`. }) } + pub fn extends_impl(&self, field: &FieldInfo) -> Result { + let StructInfo { + ref builder_name, .. + } = *self; + + let field_name = field.name; + + let descructuring = self.included_fields().map(|f| { + if f.ordinal == field.ordinal { + quote!(_) + } else { + let name = f.name; + quote!(#name) + } + }); + let reconstructing = self.included_fields().map(|f| f.name); + + // Add the bump lifetime to the generics + let mut ty_generics: Vec = self + .generics + .params + .iter() + .map(|generic_param| match generic_param { + syn::GenericParam::Type(type_param) => { + let ident = type_param.ident.clone(); + syn::parse(quote!(#ident).into()).unwrap() + } + syn::GenericParam::Lifetime(lifetime_def) => { + syn::GenericArgument::Lifetime(lifetime_def.lifetime.clone()) + } + syn::GenericParam::Const(const_param) => { + let ident = const_param.ident.clone(); + syn::parse(quote!(#ident).into()).unwrap() + } + }) + .collect(); + let mut target_generics_tuple = empty_type_tuple(); + let mut ty_generics_tuple = empty_type_tuple(); + let generics = self.modify_generics(|g| { + let index_after_lifetime_in_generics = g + .params + .iter() + .filter(|arg| matches!(arg, syn::GenericParam::Lifetime(_))) + .count(); + for f in self.included_fields() { + if f.ordinal == field.ordinal { + ty_generics_tuple.elems.push_value(empty_type()); + target_generics_tuple + .elems + .push_value(f.tuplized_type_ty_param()); + } else { + g.params + .insert(index_after_lifetime_in_generics, f.generic_ty_param()); + let generic_argument: syn::Type = f.type_ident(); + ty_generics_tuple.elems.push_value(generic_argument.clone()); + target_generics_tuple.elems.push_value(generic_argument); + } + ty_generics_tuple.elems.push_punct(Default::default()); + target_generics_tuple.elems.push_punct(Default::default()); + } + }); + let mut target_generics = ty_generics.clone(); + let index_after_lifetime_in_generics = target_generics + .iter() + .filter(|arg| matches!(arg, syn::GenericArgument::Lifetime(_))) + .count(); + target_generics.insert( + index_after_lifetime_in_generics, + syn::GenericArgument::Type(target_generics_tuple.into()), + ); + ty_generics.insert( + index_after_lifetime_in_generics, + syn::GenericArgument::Type(ty_generics_tuple.into()), + ); + let (impl_generics, _, where_clause) = generics.split_for_impl(); + + let forward_extended_fields = self.extend_fields().map(|f| { + let name = f.name; + quote!(#name: self.#name) + }); + + let extend_lifetime = self.extend_lifetime()?.ok_or(Error::new_spanned( + field_name, + "Unable to find lifetime for extended field. Please specify it manually", + ))?; + + let extends_impl = field.builder_attr.extends.iter().map(|path| { + let name_str = path_to_single_string(path).unwrap(); + let camel_name = name_str.to_case(Case::UpperCamel); + let marker_name = Ident::new( + format!("{}Extension", &camel_name).as_str(), + path.span(), + ); + quote! { + #[allow(dead_code, non_camel_case_types, missing_docs)] + impl #impl_generics dioxus_elements::extensions::#marker_name < #extend_lifetime > for #builder_name < #( #ty_generics ),* > #where_clause {} + } + }); + + Ok(quote! { + #[allow(dead_code, non_camel_case_types, missing_docs)] + impl #impl_generics ::dioxus::prelude::HasAttributes<#extend_lifetime> for #builder_name < #( #ty_generics ),* > #where_clause { + fn push_attribute( + mut self, + name: &#extend_lifetime str, + ns: Option<&'static str>, + attr: impl ::dioxus::prelude::IntoAttributeValue<#extend_lifetime>, + volatile: bool + ) -> Self { + let ( #(#descructuring,)* ) = self.fields; + self.#field_name.push( + ::dioxus::core::Attribute::new( + name, + { + use ::dioxus::prelude::IntoAttributeValue; + attr.into_value(self.bump) + }, + ns, + volatile, + ) + ); + #builder_name { + #(#forward_extended_fields,)* + bump: self.bump, + fields: ( #(#reconstructing,)* ), + _phantom: self._phantom, + } + } + } + + #(#extends_impl)* + }) + } + pub fn field_impl(&self, field: &FieldInfo) -> Result { let FieldInfo { - name: field_name, - ty: field_type, - .. + name: field_name, .. } = field; if *field_name == "key" { return Err(Error::new_spanned(field_name, "Naming a prop `key` is not allowed because the name can conflict with the built in key attribute. See https://dioxuslabs.com/learn/0.4/reference/dynamic_rendering#rendering-lists for more information about keys")); @@ -711,6 +914,12 @@ Finally, call `.build()` to create the instance of `{name}`. }); let reconstructing = self.included_fields().map(|f| f.name); + let FieldInfo { + name: field_name, + ty: field_type, + .. + } = field; + // Add the bump lifetime to the generics let mut ty_generics: Vec = self .generics .params @@ -794,6 +1003,16 @@ Finally, call `.build()` to create the instance of `{name}`. ); let repeated_fields_error_message = format!("Repeated field {field_name}"); + let forward_extended_fields = self.extend_fields().map(|f| { + let name = f.name; + quote!(#name: self.#name) + }); + let forward_bump = if self.extend_fields().next().is_some() { + quote!(bump: self.bump,) + } else { + quote!() + }; + Ok(quote! { #[allow(dead_code, non_camel_case_types, missing_docs)] impl #impl_generics #builder_name < #( #ty_generics ),* > #where_clause { @@ -803,6 +1022,8 @@ Finally, call `.build()` to create the instance of `{name}`. let #field_name = (#arg_expr,); let ( #(#descructuring,)* ) = self.fields; #builder_name { + #(#forward_extended_fields,)* + #forward_bump fields: ( #(#reconstructing,)* ), _phantom: self._phantom, } @@ -836,6 +1057,7 @@ Finally, call `.build()` to create the instance of `{name}`. name: ref field_name, .. } = field; + // Add a bump lifetime to the generics let mut builder_generics: Vec = self .generics .params @@ -1003,7 +1225,9 @@ Finally, call `.build()` to create the instance of `{name}`. // reordering based on that, but for now this much simpler thing is a reasonable approach. let assignments = self.fields.iter().map(|field| { let name = &field.name; - if let Some(ref default) = field.builder_attr.default { + if !field.builder_attr.extends.is_empty() { + quote!(let #name = self.#name;) + } else if let Some(ref default) = field.builder_attr.default { if field.builder_attr.skip { quote!(let #name = #default;) } else { diff --git a/packages/core/src/error_boundary.rs b/packages/core/src/error_boundary.rs index 095c91aa5..e515cbb52 100644 --- a/packages/core/src/error_boundary.rs +++ b/packages/core/src/error_boundary.rs @@ -7,7 +7,7 @@ use crate::{ use std::{ any::{Any, TypeId}, backtrace::Backtrace, - cell::RefCell, + cell::{Cell, RefCell}, error::Error, fmt::{Debug, Display}, rc::Rc, diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index 425749dbb..fede5096e 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -568,6 +568,51 @@ pub enum TemplateAttribute { }, } +/// An attribute with information about its position in the DOM and the element it was mounted to +#[derive(Debug)] +pub struct MountedAttribute<'a> { + pub(crate) ty: AttributeType<'a>, + + /// The element in the DOM that this attribute belongs to + pub(crate) mounted_element: Cell, +} + +impl<'a> From> for MountedAttribute<'a> { + fn from(attr: Attribute<'a>) -> Self { + Self { + ty: AttributeType::Single(attr), + mounted_element: Default::default(), + } + } +} + +impl<'a> From<&'a [Attribute<'a>]> for MountedAttribute<'a> { + fn from(attr: &'a [Attribute<'a>]) -> Self { + Self { + ty: AttributeType::Many(attr), + mounted_element: Default::default(), + } + } +} + +impl<'a> From<&'a Vec>> for MountedAttribute<'a> { + fn from(attr: &'a Vec>) -> Self { + attr.as_slice().into() + } +} + +impl<'a> MountedAttribute<'a> { + /// Get the type of this attribute + pub fn attribute_type(&self) -> &AttributeType<'a> { + &self.ty + } + + /// Get the element that this attribute is mounted to + pub fn mounted_element(&self) -> ElementId { + self.mounted_element.get() + } +} + /// An attribute on a DOM node, such as `id="my-thing"` or `href="https://example.com"` #[derive(Debug)] pub struct Attribute { @@ -875,3 +920,15 @@ impl IntoAttributeValue for Option { } } } + +/// A trait for anything that has a dynamic list of attributes +pub trait HasAttributes<'a> { + /// Push an attribute onto the list of attributes + fn push_attribute( + self, + name: &'a str, + ns: Option<&'static str>, + attr: impl IntoAttributeValue<'a>, + volatile: bool, + ) -> Self; +} diff --git a/packages/core/src/runtime.rs b/packages/core/src/runtime.rs index 6af1a6329..b29bc6912 100644 --- a/packages/core/src/runtime.rs +++ b/packages/core/src/runtime.rs @@ -95,6 +95,16 @@ impl Runtime { self.scope_stack.borrow().last().copied() } + /// Call this function with the current scope set to the given scope + /// + /// Useful in a limited number of scenarios, not public. + pub(crate) fn with_scope(&self, id: ScopeId, f: impl FnOnce() -> O) -> O { + self.scope_stack.borrow_mut().push(id); + let o = f(); + self.scope_stack.borrow_mut().pop(); + o + } + /// Get the context for any scope given its ID /// /// This is useful for inserting or removing contexts from a scope, or rendering out its root node @@ -145,6 +155,17 @@ impl RuntimeGuard { push_runtime(runtime.clone()); Self(runtime) } + + /// Run a function with a given runtime and scope in context + pub fn with(runtime: Rc, scope: Option, f: impl FnOnce() -> O) -> O { + let guard = Self::new(runtime.clone()); + let o = match scope { + Some(scope) => Runtime::with_scope(&runtime, scope, f), + None => f(), + }; + drop(guard); + o + } } impl Drop for RuntimeGuard { diff --git a/packages/core/src/scope_context.rs b/packages/core/src/scope_context.rs index 88421549d..47199c3dc 100644 --- a/packages/core/src/scope_context.rs +++ b/packages/core/src/scope_context.rs @@ -114,7 +114,7 @@ impl ScopeContext { } let mut search_parent = self.parent_id; - let context = with_runtime(|runtime: &crate::runtime::Runtime| { + let cur_runtime = with_runtime(|runtime: &crate::runtime::Runtime| { while let Some(parent_id) = search_parent { let parent = runtime.get_context(parent_id).unwrap(); tracing::trace!( @@ -132,9 +132,9 @@ impl ScopeContext { search_parent = parent.parent_id; } None - }) - .flatten(); - match context { + }); + + match cur_runtime.flatten() { Some(ctx) => Some(ctx), None => { tracing::trace!( @@ -389,3 +389,15 @@ impl ScopeId { with_scope(self, |cx| cx.height()).expect("to be in a dioxus runtime") } } + +/// Spawn a future on a component given its [`ScopeId`]. +pub fn spawn_at(fut: impl Future + 'static, scope_id: ScopeId) -> Option { + with_runtime(|rt| rt.get_context(scope_id).unwrap().push_future(fut)) +} + +/// Spawn a future that Dioxus won't clean up when this component is unmounted +/// +/// This is good for tasks that need to be run after the component has been dropped. +pub fn spawn_forever(fut: impl Future + 'static) -> Option { + spawn_at(fut, ScopeId(0)) +} diff --git a/packages/core/src/scopes.rs b/packages/core/src/scopes.rs index d88fe1f47..6177cd8c9 100644 --- a/packages/core/src/scopes.rs +++ b/packages/core/src/scopes.rs @@ -41,6 +41,7 @@ pub struct ScopeState { impl Drop for ScopeState { fn drop(&mut self) { + self.drop_listeners(); self.runtime.remove_context(self.context_id); } } diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index 07d81415c..89c0ab4a3 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -78,7 +78,7 @@ use std::{any::Any, cell::Cell, collections::BTreeSet, future::Future, rc::Rc}; /// #[component] /// fn Title<'a>( children: Element) -> Element { /// cx.render(rsx! { -/// div { id: "title", children } +/// div { id: "title", {children} } /// }) /// } /// ``` @@ -394,17 +394,14 @@ impl VirtualDom { let this_path = node_template.attr_paths[idx]; // Remove the "on" prefix if it exists, TODO, we should remove this and settle on one - if attr.name.trim_start_matches("on") == name - && target_path.is_decendant(&this_path) - { - listeners.push(&attr.value); - - // Break if this is the exact target element. - // This means we won't call two listeners with the same name on the same element. This should be - // documented, or be rejected from the rsx! macro outright - if target_path == this_path { - break; - } + if target_path.is_decendant(&this_path) { + attr.ty.for_each(|attribute| { + if attribute.name.trim_start_matches("on") == name { + if let AttributeValue::Listener(listener) = &attribute.value { + listeners.push(listener); + } + } + }); } } @@ -416,38 +413,67 @@ impl VirtualDom { listener.call(uievent.clone()); self.runtime.rendering.set(true); + // let origin: ScopeId = path.scope; + // self.runtime.scope_stack.borrow_mut().push(origin); + // self.runtime.rendering.set(false); + // if let Some(cb) = listener.borrow_mut().as_deref_mut() { + // cb(uievent.clone()); + // } + // self.runtime.scope_stack.borrow_mut().pop(); + // self.runtime.rendering.set(true); + if !uievent.propagates.get() { return; } } - } - let mount = el_ref.mount.get().as_usize(); - parent_node = mount.and_then(|id| self.mounts.get(id).and_then(|el| el.parent)); - } - } else { - // Otherwise, we just call the listener on the target element - if let Some(path) = parent_node { - let el_ref = &self.mounts[path.mount.0].node; - let node_template = el_ref.template.get(); - let target_path = path.path; - - for (idx, attr) in el_ref.dynamic_attrs.iter().enumerate() { - let this_path = node_template.attr_paths[idx]; - - // Remove the "on" prefix if it exists, TODO, we should remove this and settle on one - // Only call the listener if this is the exact target element. - if attr.name.trim_start_matches("on") == name && target_path == this_path { - if let AttributeValue::Listener(listener) = &attr.value { - self.runtime.rendering.set(false); - listener.call(uievent.clone()); - self.runtime.rendering.set(true); - - break; - } - } + let mount = el_ref.mount.get().as_usize(); + parent_node = mount.and_then(|id| self.mounts.get(id).and_then(|el| el.parent)); } } + + // else { + // // Otherwise, we just call the listener on the target element + // if let Some(path) = parent_node { + // let el_ref = &self.mounts[path.mount.0].node; + // let node_template = el_ref.template.get(); + // let target_path = path.path; + + // for (idx, attr) in el_ref.dynamic_attrs.iter().enumerate() { + // let this_path = node_template.attr_paths[idx]; + + // // Remove the "on" prefix if it exists, TODO, we should remove this and settle on one + // // Only call the listener if this is the exact target element. + // if attr.name.trim_start_matches("on") == name && target_path == this_path { + // if let AttributeValue::Listener(listener) = &attr.value { + // self.runtime.rendering.set(false); + // listener.call(uievent.clone()); + // self.runtime.rendering.set(true); + + // // if target_path == this_path { + // // let mut should_stop = false; + // // attr.ty.for_each(|attribute| { + // // if attribute.name.trim_start_matches("on") == name { + // // if let AttributeValue::Listener(listener) = &attribute.value { + // // let origin = path.scope; + // // self.runtime.scope_stack.borrow_mut().push(origin); + // // self.runtime.rendering.set(false); + // // if let Some(cb) = listener.borrow_mut().as_deref_mut() { + // // cb(uievent.clone()); + // // } + // // self.runtime.scope_stack.borrow_mut().pop(); + // // self.runtime.rendering.set(true); + + // should_stop = true; + // } + // } + // // }); + // if should_stop { + // return; + // } + // } + // } + // } } } diff --git a/packages/core/tests/create_fragments.rs b/packages/core/tests/create_fragments.rs index 502405b00..3da14dbef 100644 --- a/packages/core/tests/create_fragments.rs +++ b/packages/core/tests/create_fragments.rs @@ -43,19 +43,19 @@ fn fragments_nested() { render!( div { "hello" } div { "goodbye" } - render! { + {render! { div { "hello" } div { "goodbye" } - render! { + {render! { div { "hello" } div { "goodbye" } - render! { + {render! { div { "hello" } div { "goodbye" } - } - } - } - ) + }} + }} + }} + )) }); assert_eq!( @@ -77,7 +77,10 @@ fn fragments_across_components() { fn demo_child() -> Element { let world = "world"; - render! { "hellO!", world } + render! { + "hellO!" + {world} + } } assert_eq!( @@ -91,7 +94,7 @@ fn list_fragments() { fn app() -> Element { render!( h1 { "hello" } - (0..6).map(|f| render!( span { "{f}" })) + {(0..6).map(|f| render!( span { "{f}" }))} ) } assert_eq!( diff --git a/packages/core/tests/create_lists.rs b/packages/core/tests/create_lists.rs index c6be50c79..408d98f2b 100644 --- a/packages/core/tests/create_lists.rs +++ b/packages/core/tests/create_lists.rs @@ -11,12 +11,12 @@ use dioxus_core::ElementId; fn app() -> Element { render! { div { - (0..3).map(|i| render! { + for i in 0..3 { div { h1 { "hello world! "} p { "{i}" } } - }) + } } } } diff --git a/packages/core/tests/create_passthru.rs b/packages/core/tests/create_passthru.rs index ac8b16c38..4958018c7 100644 --- a/packages/core/tests/create_passthru.rs +++ b/packages/core/tests/create_passthru.rs @@ -17,7 +17,7 @@ fn nested_passthru_creates() { #[component] fn PassThru(children: Element) -> Element { - render!(children) + render!({ children }) } let mut dom = VirtualDom::new(app); @@ -54,7 +54,7 @@ fn nested_passthru_creates_add() { #[component] fn ChildComp(children: Element) -> Element { - render! {children} + render! {{children}} } let mut dom = VirtualDom::new(app); diff --git a/packages/core/tests/diff_component.rs b/packages/core/tests/diff_component.rs index d78dc4487..167db6c8e 100644 --- a/packages/core/tests/diff_component.rs +++ b/packages/core/tests/diff_component.rs @@ -39,7 +39,7 @@ fn component_swap() { fn nav_bar() -> Element { render! { - h1 { "NavBar", (0..3).map(|_| render!(nav_link {})) } + h1 { "NavBar", {(0..3).map(|_| render!(nav_link {}))} } } } diff --git a/packages/core/tests/diff_keyed_list.rs b/packages/core/tests/diff_keyed_list.rs index 6b8b87852..3ba2fb6f5 100644 --- a/packages/core/tests/diff_keyed_list.rs +++ b/packages/core/tests/diff_keyed_list.rs @@ -17,7 +17,7 @@ fn keyed_diffing_out_of_order() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); { @@ -59,7 +59,7 @@ fn keyed_diffing_out_of_order_adds() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); _ = dom.rebuild(&mut dioxus_core::NoOpMutations); @@ -85,7 +85,7 @@ fn keyed_diffing_out_of_order_adds_3() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); _ = dom.rebuild(&mut dioxus_core::NoOpMutations); @@ -111,7 +111,7 @@ fn keyed_diffing_out_of_order_adds_4() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); _ = dom.rebuild(&mut dioxus_core::NoOpMutations); @@ -137,7 +137,7 @@ fn keyed_diffing_out_of_order_adds_5() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); _ = dom.rebuild(&mut dioxus_core::NoOpMutations); @@ -162,7 +162,7 @@ fn keyed_diffing_additions() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); _ = dom.rebuild(&mut dioxus_core::NoOpMutations); @@ -187,7 +187,7 @@ fn keyed_diffing_additions_and_moves_on_ends() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); _ = dom.rebuild(&mut dioxus_core::NoOpMutations); @@ -216,7 +216,7 @@ fn keyed_diffing_additions_and_moves_in_middle() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); _ = dom.rebuild(&mut dioxus_core::NoOpMutations); @@ -250,7 +250,7 @@ fn controlled_keyed_diffing_out_of_order() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); _ = dom.rebuild(&mut dioxus_core::NoOpMutations); @@ -284,7 +284,7 @@ fn controlled_keyed_diffing_out_of_order_max_test() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); _ = dom.rebuild(&mut dioxus_core::NoOpMutations); @@ -313,7 +313,7 @@ fn remove_list() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); _ = dom.rebuild(&mut dioxus_core::NoOpMutations); @@ -338,7 +338,7 @@ fn no_common_keys() { _ => unreachable!(), }; - render!(order.iter().map(|i| render!(div { key: "{i}" }))) + render!({ order.iter().map(|i| render!(div { key: "{i}" })) }) }); _ = dom.rebuild(&mut dioxus_core::NoOpMutations); diff --git a/packages/core/tests/diff_unkeyed_list.rs b/packages/core/tests/diff_unkeyed_list.rs index 0e1b5a972..9fd666e29 100644 --- a/packages/core/tests/diff_unkeyed_list.rs +++ b/packages/core/tests/diff_unkeyed_list.rs @@ -9,9 +9,9 @@ fn list_creates_one_by_one() { render! { div { - (0..gen).map(|i| render! { + for i in 0..gen { div { "{i}" } - }) + } } } }); @@ -78,9 +78,9 @@ fn removes_one_by_one() { render! { div { - (0..gen).map(|i| render! { + for i in 0..gen { div { "{i}" } - }) + } } } }); @@ -153,10 +153,10 @@ fn list_shrink_multiroot() { let mut dom = VirtualDom::new(|| { render! { div { - (0..generation()).map(|i| render! { + for i in 0..cx.generation() { div { "{i}" } div { "{i}" } - }) + } } } }); @@ -214,10 +214,10 @@ fn removes_one_by_one_multiroot() { render! { div { - (0..gen).map(|i| render! { + {(0..gen).map(|i| rsx! { div { "{i}" } div { "{i}" } - }) + })} } } }); @@ -276,9 +276,9 @@ fn removes_one_by_one_multiroot() { fn two_equal_fragments_are_equal_static() { let mut dom = VirtualDom::new(|| { render! { - (0..5).map(|_| render! { + for _ in 0..5 { div { "hello" } - }) + } } }); @@ -290,9 +290,9 @@ fn two_equal_fragments_are_equal_static() { fn two_equal_fragments_are_equal() { let mut dom = VirtualDom::new(|| { render! { - (0..5).map(|i| render! { + for i in 0..5 { div { "hello {i}" } - }) + } } }); @@ -310,7 +310,11 @@ fn remove_many() { _ => unreachable!(), }; - render! {(0..num).map(|i| render! { div { "hello {i}" } })} + render! { + for i in 0..num { + div { "hello {i}" } + } + } }); { diff --git a/packages/core/tests/event_propagation.rs b/packages/core/tests/event_propagation.rs index 78136e8f3..3723e5cb1 100644 --- a/packages/core/tests/event_propagation.rs +++ b/packages/core/tests/event_propagation.rs @@ -58,11 +58,11 @@ fn app() -> Element { *CLICKS.lock().unwrap() += 1; }, - vec![ + {vec![ render! { problematic_child {} } - ].into_iter() + ].into_iter()} } } } diff --git a/packages/core/tests/fuzzing.rs b/packages/core/tests/fuzzing.rs index 4f39be4d6..e5e026de3 100644 --- a/packages/core/tests/fuzzing.rs +++ b/packages/core/tests/fuzzing.rs @@ -218,6 +218,7 @@ fn create_random_dynamic_attr() -> Attribute { random_ns(), rand::random(), ) + .into() } static mut TEMPLATE_COUNT: usize = 0; @@ -249,7 +250,9 @@ fn create_random_element(cx: DepthProps) -> Element { ) .into_boxed_str(), )); - let node = VNode::new( + println!("{template:#?}"); + let node = cx.vnode( + None.into(), None, template, dynamic_node_types diff --git a/packages/core/tests/lifecycle.rs b/packages/core/tests/lifecycle.rs index 9da47f1ef..8e68d899e 100644 --- a/packages/core/tests/lifecycle.rs +++ b/packages/core/tests/lifecycle.rs @@ -52,7 +52,7 @@ fn events_generate() { "Click me!" } }, - _ => render!(()), + _ => None, } }; diff --git a/packages/core/tests/miri_full_app.rs b/packages/core/tests/miri_full_app.rs index 8ccdc8f56..3688cb60b 100644 --- a/packages/core/tests/miri_full_app.rs +++ b/packages/core/tests/miri_full_app.rs @@ -38,9 +38,9 @@ fn app() -> Element { } button { onclick: move |_| idx -= 1, "-" } ul { - (0..*idx()).map(|i| render! { + {(0..**idx).map(|i| rsx! { ChildExample { i: i, onhover: onhover } - }) + })} } } } diff --git a/packages/core/tests/miri_stress.rs b/packages/core/tests/miri_stress.rs index 24d13b23f..b9b4d25f4 100644 --- a/packages/core/tests/miri_stress.rs +++ b/packages/core/tests/miri_stress.rs @@ -15,7 +15,7 @@ fn test_memory_leak() { spawn(async {}); if val == 2 || val == 4 { - return render!(()); + return render!({}); } let mut name = once(|| String::from("numbers: ")); @@ -73,7 +73,7 @@ fn memo_works_properly() { let val = generation(); if val == 2 || val == 4 { - return render!(()); + return None; } let name = once(|| String::from("asd")); diff --git a/packages/desktop/Cargo.toml b/packages/desktop/Cargo.toml index 357cf63e2..b888d0cfb 100644 --- a/packages/desktop/Cargo.toml +++ b/packages/desktop/Cargo.toml @@ -11,15 +11,25 @@ keywords = ["dom", "ui", "gui", "react"] [dependencies] dioxus-core = { workspace = true, features = ["serialize"] } -dioxus-html = { workspace = true, features = ["serialize", "native-bind", "mounted", "eval"] } +dioxus-html = { workspace = true, features = [ + "serialize", + "native-bind", + "mounted", + "eval", +] } dioxus-interpreter-js = { workspace = true, features = ["binary-protocol"] } dioxus-hot-reload = { workspace = true, optional = true } +dioxus-cli-config = { workspace = true } serde = "1.0.136" serde_json = "1.0.79" thiserror = { workspace = true } -tracing.workspace = true -wry = { version = "0.34.0", default-features = false, features = ["tao", "protocol", "file-drop"] } +tracing = { workspace = true } +wry = { version = "0.35.0", default-features = false, features = [ + "os-webview", + "protocol", + "file-drop", +] } futures-channel = { workspace = true } tokio = { workspace = true, features = [ "sync", @@ -39,12 +49,12 @@ futures-util = { workspace = true } urlencoding = "2.1.2" async-trait = "0.1.68" crossbeam-channel = "0.5.8" +tao = { version = "0.24.0", features = ["rwh_05"] } [target.'cfg(any(target_os = "windows",target_os = "macos",target_os = "linux",target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))'.dependencies] -# This is only for debug mode, and it appears mobile does not support some packages this uses -manganis-cli-support = { git = "https://github.com/DioxusLabs/collect-assets", features = ["webp", "html"] } rfd = "0.12" -global-hotkey = { git = "https://github.com/tauri-apps/global-hotkey" } +global-hotkey = "0.4.1" +muda = "0.11.3" [target.'cfg(target_os = "ios")'.dependencies] objc = "0.2.7" diff --git a/packages/desktop/headless_tests/rendering.rs b/packages/desktop/headless_tests/rendering.rs index e12d8644d..9fa080be8 100644 --- a/packages/desktop/headless_tests/rendering.rs +++ b/packages/desktop/headless_tests/rendering.rs @@ -2,8 +2,8 @@ use dioxus::prelude::*; use dioxus_desktop::DesktopContext; pub(crate) fn check_app_exits(app: Component) { - use dioxus_desktop::tao::window::WindowBuilder; use dioxus_desktop::Config; + use tao::window::WindowBuilder; // This is a deadman's switch to ensure that the app exits let should_panic = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(true)); let should_panic_clone = should_panic.clone(); @@ -89,7 +89,7 @@ fn check_html_renders(cx: Scope) -> Element { h1 { "text" } - dyn_element + {dyn_element} } } } diff --git a/packages/desktop/src/app.rs b/packages/desktop/src/app.rs new file mode 100644 index 000000000..6e1c75c24 --- /dev/null +++ b/packages/desktop/src/app.rs @@ -0,0 +1,355 @@ +use crate::{ + config::{Config, WindowCloseBehaviour}, + desktop_context::WindowEventHandlers, + element::DesktopElement, + file_upload::FileDialogRequest, + ipc::IpcMessage, + ipc::{EventData, UserWindowEvent}, + query::QueryResult, + shortcut::{GlobalHotKeyEvent, ShortcutRegistry}, + webview::WebviewInstance, +}; +use crossbeam_channel::Receiver; +use dioxus_core::{Component, ElementId, VirtualDom}; +use dioxus_html::{ + native_bind::NativeFileEngine, FileEngine, HasFileData, HasFormData, HtmlEvent, + PlatformEventData, +}; +use std::{ + cell::{Cell, RefCell}, + collections::HashMap, + rc::Rc, + sync::Arc, +}; +use tao::{ + event::Event, + event_loop::{ControlFlow, EventLoop, EventLoopBuilder, EventLoopProxy, EventLoopWindowTarget}, + window::WindowId, +}; + +/// The single top-level object that manages all the running windows, assets, shortcuts, etc +pub(crate) struct App

{ + // move the props into a cell so we can pop it out later to create the first window + // iOS panics if we create a window before the event loop is started, so we toss them into a cell + pub(crate) props: Cell>, + pub(crate) cfg: Cell>, + + // Stuff we need mutable access to + pub(crate) root: Component

, + pub(crate) control_flow: ControlFlow, + pub(crate) is_visible_before_start: bool, + pub(crate) window_behavior: WindowCloseBehaviour, + pub(crate) webviews: HashMap, + + /// This single blob of state is shared between all the windows so they have access to the runtime state + /// + /// This includes stuff like the event handlers, shortcuts, etc as well as ways to modify *other* windows + pub(crate) shared: Rc, +} + +/// A bundle of state shared between all the windows, providing a way for us to communicate with running webview. +/// +/// Todo: everything in this struct is wrapped in Rc<>, but we really only need the one top-level refcell +pub struct SharedContext { + pub(crate) event_handlers: WindowEventHandlers, + pub(crate) pending_webviews: RefCell>, + pub(crate) shortcut_manager: ShortcutRegistry, + pub(crate) global_hotkey_channel: Receiver, + pub(crate) proxy: EventLoopProxy, + pub(crate) target: EventLoopWindowTarget, +} + +impl App

{ + pub fn new(cfg: Config, props: P, root: Component

) -> (EventLoop, Self) { + let event_loop = EventLoopBuilder::::with_user_event().build(); + + let app = Self { + root, + window_behavior: cfg.last_window_close_behaviour, + is_visible_before_start: true, + webviews: HashMap::new(), + control_flow: ControlFlow::Wait, + props: Cell::new(Some(props)), + cfg: Cell::new(Some(cfg)), + shared: Rc::new(SharedContext { + event_handlers: WindowEventHandlers::default(), + pending_webviews: Default::default(), + shortcut_manager: ShortcutRegistry::new(), + global_hotkey_channel: GlobalHotKeyEvent::receiver().clone(), + proxy: event_loop.create_proxy(), + target: event_loop.clone(), + }), + }; + + // Set the event converter + dioxus_html::set_event_converter(Box::new(crate::events::SerializedHtmlEventConverter)); + + // Allow hotreloading to work - but only in debug mode + #[cfg(all(feature = "hot-reload", debug_assertions))] + app.connect_hotreload(); + + (event_loop, app) + } + + pub fn tick(&mut self, window_event: &Event<'_, UserWindowEvent>) { + self.control_flow = ControlFlow::Wait; + + self.shared + .event_handlers + .apply_event(window_event, &self.shared.target); + + if let Ok(event) = self.shared.global_hotkey_channel.try_recv() { + self.shared.shortcut_manager.call_handlers(event); + } + } + + #[cfg(all(feature = "hot-reload", debug_assertions))] + pub fn connect_hotreload(&self) { + dioxus_hot_reload::connect({ + let proxy = self.shared.proxy.clone(); + move |template| { + let _ = proxy.send_event(UserWindowEvent( + EventData::HotReloadEvent(template), + unsafe { WindowId::dummy() }, + )); + } + }); + } + + pub fn handle_new_window(&mut self) { + for handler in self.shared.pending_webviews.borrow_mut().drain(..) { + let id = handler.desktop_context.window.id(); + self.webviews.insert(id, handler); + _ = self + .shared + .proxy + .send_event(UserWindowEvent(EventData::Poll, id)); + } + } + + pub fn handle_close_requested(&mut self, id: WindowId) { + use WindowCloseBehaviour::*; + + match self.window_behavior { + LastWindowExitsApp => { + self.webviews.remove(&id); + if self.webviews.is_empty() { + self.control_flow = ControlFlow::Exit + } + } + + LastWindowHides => { + let Some(webview) = self.webviews.get(&id) else { + return; + }; + hide_app_window(&webview.desktop_context.webview); + } + + CloseWindow => { + self.webviews.remove(&id); + } + } + } + + pub fn window_destroyed(&mut self, id: WindowId) { + self.webviews.remove(&id); + + if matches!( + self.window_behavior, + WindowCloseBehaviour::LastWindowExitsApp + ) && self.webviews.is_empty() + { + self.control_flow = ControlFlow::Exit + } + } + + pub fn handle_start_cause_init(&mut self) { + let props = self.props.take().unwrap(); + let cfg = self.cfg.take().unwrap(); + + self.is_visible_before_start = cfg.window.window.visible; + + let webview = WebviewInstance::new( + cfg, + VirtualDom::new_with_props(self.root, props), + self.shared.clone(), + ); + + let id = webview.desktop_context.window.id(); + self.webviews.insert(id, webview); + + _ = self + .shared + .proxy + .send_event(UserWindowEvent(EventData::Poll, id)); + } + + pub fn handle_browser_open(&mut self, msg: IpcMessage) { + if let Some(temp) = msg.params().as_object() { + if temp.contains_key("href") { + let open = webbrowser::open(temp["href"].as_str().unwrap()); + if let Err(e) = open { + tracing::error!("Open Browser error: {:?}", e); + } + } + } + } + + pub fn handle_initialize_msg(&mut self, id: WindowId) { + let view = self.webviews.get_mut(&id).unwrap(); + view.desktop_context.send_edits(view.dom.rebuild()); + view.desktop_context + .window + .set_visible(self.is_visible_before_start); + } + + pub fn handle_close_msg(&mut self, id: WindowId) { + self.webviews.remove(&id); + + if self.webviews.is_empty() { + self.control_flow = ControlFlow::Exit + } + } + + pub fn handle_query_msg(&mut self, msg: IpcMessage, id: WindowId) { + let Ok(result) = serde_json::from_value::(msg.params()) else { + return; + }; + + let Some(view) = self.webviews.get(&id) else { + return; + }; + + view.desktop_context.query.send(result); + } + + pub fn handle_user_event_msg(&mut self, msg: IpcMessage, id: WindowId) { + let parsed_params = serde_json::from_value(msg.params()) + .map_err(|err| tracing::error!("Error parsing user_event: {:?}", err)); + + let Ok(evt) = parsed_params else { return }; + + let HtmlEvent { + element, + name, + bubbles, + data, + } = evt; + + let view = self.webviews.get_mut(&id).unwrap(); + let query = view.desktop_context.query.clone(); + + // check for a mounted event placeholder and replace it with a desktop specific element + let as_any = match data { + dioxus_html::EventData::Mounted => { + let element = DesktopElement::new(element, view.desktop_context.clone(), query); + Rc::new(PlatformEventData::new(Box::new(element))) + } + _ => data.into_any(), + }; + + view.dom.handle_event(&name, as_any, element, bubbles); + view.desktop_context.send_edits(view.dom.render_immediate()); + } + + #[cfg(all(feature = "hot-reload", debug_assertions))] + pub fn handle_hot_reload_msg(&mut self, msg: dioxus_hot_reload::HotReloadMsg) { + match msg { + dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => { + for webview in self.webviews.values_mut() { + webview.dom.replace_template(template); + webview.poll_vdom(); + } + } + dioxus_hot_reload::HotReloadMsg::Shutdown => { + self.control_flow = ControlFlow::Exit; + } + } + } + + pub fn handle_file_dialog_msg(&mut self, msg: IpcMessage, window: WindowId) { + let Ok(file_dialog) = serde_json::from_value::(msg.params()) else { + return; + }; + struct DesktopFileUploadForm { + files: Arc, + } + + impl HasFileData for DesktopFileUploadForm { + fn files(&self) -> Option> { + Some(self.files.clone()) + } + } + + impl HasFormData for DesktopFileUploadForm { + fn as_any(&self) -> &dyn std::any::Any { + self + } + } + + let id = ElementId(file_dialog.target); + let event_name = &file_dialog.event; + let event_bubbles = file_dialog.bubbles; + let files = file_dialog.get_file_event(); + + let data = Rc::new(PlatformEventData::new(Box::new(DesktopFileUploadForm { + files: Arc::new(NativeFileEngine::new(files)), + }))); + + let view = self.webviews.get_mut(&window).unwrap(); + + if event_name == "change&input" { + view.dom + .handle_event("input", data.clone(), id, event_bubbles); + view.dom.handle_event("change", data, id, event_bubbles); + } else { + view.dom.handle_event(event_name, data, id, event_bubbles); + } + + view.desktop_context.send_edits(view.dom.render_immediate()); + } + + /// Poll the virtualdom until it's pending + /// + /// The waker we give it is connected to the event loop, so it will wake up the event loop when it's ready to be polled again + /// + /// All IO is done on the tokio runtime we started earlier + pub fn poll_vdom(&mut self, id: WindowId) { + let Some(view) = self.webviews.get_mut(&id) else { + return; + }; + + view.poll_vdom(); + } +} + +/// Different hide implementations per platform +#[allow(unused)] +pub fn hide_app_window(window: &wry::WebView) { + #[cfg(target_os = "windows")] + { + use tao::platform::windows::WindowExtWindows; + window.set_visible(false); + // window.set_skip_taskbar(true); + } + + #[cfg(target_os = "linux")] + { + use tao::platform::unix::WindowExtUnix; + window.set_visible(false); + } + + #[cfg(target_os = "macos")] + { + // window.set_visible(false); has the wrong behaviour on macOS + // It will hide the window but not show it again when the user switches + // back to the app. `NSApplication::hide:` has the correct behaviour + use objc::runtime::Object; + use objc::{msg_send, sel, sel_impl}; + objc::rc::autoreleasepool(|| unsafe { + let app: *mut Object = msg_send![objc::class!(NSApplication), sharedApplication]; + let nil = std::ptr::null_mut::(); + let _: () = msg_send![app, hide: nil]; + }); + } +} diff --git a/packages/desktop/src/assets.rs b/packages/desktop/src/assets.rs new file mode 100644 index 000000000..f0f5a03fc --- /dev/null +++ b/packages/desktop/src/assets.rs @@ -0,0 +1,61 @@ +use dioxus_core::prelude::{Runtime, RuntimeGuard, ScopeId}; +use rustc_hash::FxHashMap; +use std::{cell::RefCell, rc::Rc}; +use wry::{http::Request, RequestAsyncResponder}; + +/// +pub type AssetRequest = Request>; + +pub struct AssetHandler { + f: Box, + scope: ScopeId, +} + +#[derive(Clone)] +pub struct AssetHandlerRegistry { + dom_rt: Rc, + handlers: Rc>>, +} + +impl AssetHandlerRegistry { + pub fn new(dom_rt: Rc) -> Self { + AssetHandlerRegistry { + dom_rt, + handlers: Default::default(), + } + } + + pub fn has_handler(&self, name: &str) -> bool { + self.handlers.borrow().contains_key(name) + } + + pub fn handle_request( + &self, + name: &str, + request: AssetRequest, + responder: RequestAsyncResponder, + ) { + if let Some(handler) = self.handlers.borrow().get(name) { + // make sure the runtime is alive for the duration of the handler + // We should do this for all the things - not just asset handlers + RuntimeGuard::with(self.dom_rt.clone(), Some(handler.scope), || { + (handler.f)(request, responder) + }); + } + } + + pub fn register_handler( + &self, + name: String, + f: Box, + scope: ScopeId, + ) { + self.handlers + .borrow_mut() + .insert(name, AssetHandler { f, scope }); + } + + pub fn remove_handler(&self, name: &str) -> Option { + self.handlers.borrow_mut().remove(name) + } +} diff --git a/packages/desktop/src/collect_assets.rs b/packages/desktop/src/collect_assets.rs deleted file mode 100644 index aa9050a75..000000000 --- a/packages/desktop/src/collect_assets.rs +++ /dev/null @@ -1,60 +0,0 @@ -pub fn copy_assets() { - #[cfg(all( - debug_assertions, - any( - target_os = "windows", - target_os = "macos", - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" - ) - ))] - { - // The CLI will copy assets to the current working directory - if std::env::var_os("DIOXUS_ACTIVE").is_some() { - return; - } - use manganis_cli_support::AssetManifest; - use manganis_cli_support::AssetManifestExt; - use manganis_cli_support::Config; - use std::path::PathBuf; - let config = Config::current(); - let asset_location = config.assets_serve_location(); - let asset_location = PathBuf::from(asset_location); - let _ = std::fs::remove_dir_all(&asset_location); - - println!("Finding assets... (Note: if you run a dioxus desktop application with the CLI. This process will be significantly faster.)"); - let manifest = AssetManifest::load(); - let has_assets = manifest - .packages() - .iter() - .any(|package| !package.assets().is_empty()); - - if has_assets { - println!("Copying and optimizing assets..."); - manifest.copy_static_assets_to(&asset_location).unwrap(); - println!("Copied assets to {}", asset_location.display()); - } else { - println!("No assets found"); - } - } - #[cfg(not(all( - debug_assertions, - any( - target_os = "windows", - target_os = "macos", - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" - ) - )))] - { - println!( - "Skipping assets in release mode. You compile assets with the dioxus-cli in release mode" - ); - } -} diff --git a/packages/desktop/src/cfg.rs b/packages/desktop/src/config.rs similarity index 85% rename from packages/desktop/src/cfg.rs rename to packages/desktop/src/config.rs index 596b21938..2b4f5d0d6 100644 --- a/packages/desktop/src/cfg.rs +++ b/packages/desktop/src/config.rs @@ -1,15 +1,13 @@ use std::borrow::Cow; use std::path::PathBuf; -use wry::application::window::Icon; +use dioxus_core::prelude::Component; +use tao::window::{Icon, WindowBuilder, WindowId}; use wry::{ - application::window::{Window, WindowBuilder}, http::{Request as HttpRequest, Response as HttpResponse}, - webview::FileDropEvent, + FileDropEvent, }; -// pub(crate) type DynEventHandlerFn = dyn Fn(&mut EventLoop<()>, &mut WebView); - /// The behaviour of the application when the last window is closed. #[derive(Copy, Clone, Eq, PartialEq)] pub enum WindowCloseBehaviour { @@ -38,7 +36,7 @@ pub struct Config { pub(crate) enable_default_menu_bar: bool, } -type DropHandler = Box bool>; +type DropHandler = Box bool>; pub(crate) type WryProtocol = ( String, @@ -49,7 +47,12 @@ impl Config { /// Initializes a new `WindowBuilder` with default values. #[inline] pub fn new() -> Self { - let window = WindowBuilder::new().with_title("Dioxus app"); + let window = WindowBuilder::new().with_title( + dioxus_cli_config::CURRENT_CONFIG + .as_ref() + .map(|c| c.dioxus_config.application.name.clone()) + .unwrap_or("Dioxus App".to_string()), + ); Self { // event_handler: None, @@ -69,6 +72,20 @@ impl Config { } } + /// Launch a Dioxus app using the given component and config + /// + /// See the [`crate::launch::launch`] function for more details. + pub fn launch(self, root: Component<()>) { + crate::launch::launch_cfg(root, self) + } + + /// Launch a Dioxus app using the given component, config, and props + /// + /// See the [`crate::launch::launch_with_props`] function for more details. + pub fn launch_with_props(self, root: Component

, props: P) { + crate::launch::launch_with_props(root, props, self) + } + /// Set whether the default menu bar should be enabled. /// /// > Note: `enable` is `true` by default. To disable the default menu bar pass `false`. @@ -117,10 +134,10 @@ impl Config { self } - /// Set a file drop handler + /// Set a file drop handler. If this is enabled, html drag events will be disabled. pub fn with_file_drop_handler( mut self, - handler: impl Fn(&Window, FileDropEvent) -> bool + 'static, + handler: impl Fn(WindowId, FileDropEvent) -> bool + 'static, ) -> Self { self.file_drop_handler = Some(Box::new(handler)); self diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs index 306e5fd76..5e0a7039c 100644 --- a/packages/desktop/src/desktop_context.rs +++ b/packages/desktop/src/desktop_context.rs @@ -1,40 +1,31 @@ -use crate::create_new_window; -use crate::events::IpcMessage; -use crate::protocol::AssetFuture; -use crate::protocol::AssetHandlerRegistry; -use crate::query::QueryEngine; -use crate::shortcut::{HotKey, ShortcutId, ShortcutRegistry, ShortcutRegistryError}; -use crate::AssetHandler; -use crate::Config; -use crate::WebviewHandler; -use dioxus_core::once; -use dioxus_core::ScopeId; -use dioxus_core::VirtualDom; -#[cfg(all(feature = "hot-reload", debug_assertions))] -use dioxus_hot_reload::HotReloadMsg; +use crate::{ + app::SharedContext, + assets::AssetHandlerRegistry, + edits::EditQueue, + ipc::{EventData, UserWindowEvent}, + query::QueryEngine, + shortcut::{HotKey, ShortcutId, ShortcutRegistryError}, + webview::WebviewInstance, + AssetRequest, Config, +}; +use dioxus_core::{ + prelude::{current_scope_id, ScopeId}, + Mutations, VirtualDom, +}; use dioxus_interpreter_js::binary_protocol::Channel; use dioxus_interpreter_js::MutationState; use rustc_hash::FxHashMap; use slab::Slab; -use std::cell::RefCell; -use std::fmt::Debug; -use std::fmt::Formatter; -use std::rc::Rc; -use std::rc::Weak; -use std::sync::atomic::AtomicU16; -use std::sync::Arc; -use std::sync::Mutex; -use wry::application::event::Event; -use wry::application::event_loop::EventLoopProxy; -use wry::application::event_loop::EventLoopWindowTarget; -#[cfg(target_os = "ios")] -use wry::application::platform::ios::WindowExtIOS; -use wry::application::window::Fullscreen as WryFullscreen; -use wry::application::window::Window; -use wry::application::window::WindowId; -use wry::webview::WebView; +use std::{cell::RefCell, fmt::Debug, rc::Rc, rc::Weak, sync::atomic::AtomicU16}; +use tao::{ + event::Event, + event_loop::EventLoopWindowTarget, + window::{Fullscreen as WryFullscreen, Window, WindowId}, +}; +use wry::{RequestAsyncResponder, WebView}; -pub type ProxyType = EventLoopProxy; +#[cfg(target_os = "ios")] +use tao::platform::ios::WindowExtIOS; /// Get an imperative handle to the current window without using a hook /// @@ -45,52 +36,8 @@ pub fn window() -> DesktopContext { dioxus_core::prelude::consume_context().unwrap() } -/// Get an imperative handle to the current window -#[deprecated = "Prefer the using the `window` function directly for cleaner code"] -pub fn use_window() -> DesktopContext { - once(window) -} - -/// This handles communication between the requests that the webview makes and the interpreter. The interpreter constantly makes long running requests to the webview to get any edits that should be made to the DOM almost like server side events. -/// It will hold onto the requests until the interpreter is ready to handle them and hold onto any pending edits until a new request is made. -#[derive(Default, Clone)] -pub(crate) struct EditQueue { - queue: Arc>>>, - responder: Arc>>, -} - -impl Debug for EditQueue { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("EditQueue") - .field("queue", &self.queue) - .field("responder", { - &self.responder.lock().unwrap().as_ref().map(|_| ()) - }) - .finish() - } -} - -impl EditQueue { - pub fn handle_request(&self, responder: wry::webview::RequestAsyncResponder) { - let mut queue = self.queue.lock().unwrap(); - if let Some(bytes) = queue.pop() { - responder.respond(wry::http::Response::new(bytes)); - } else { - *self.responder.lock().unwrap() = Some(responder); - } - } - - pub fn add_edits(&self, edits: Vec) { - let mut responder = self.responder.lock().unwrap(); - if let Some(responder) = responder.take() { - responder.respond(wry::http::Response::new(edits)); - } else { - self.queue.lock().unwrap().push(edits); - } - } -} - -pub(crate) type WebviewQueue = Rc>>; +/// A handle to the [`DesktopService`] that can be passed around. +pub type DesktopContext = Rc; /// An imperative interface to the current window. /// @@ -106,70 +53,72 @@ pub(crate) type WebviewQueue = Rc>>; /// ``` pub struct DesktopService { /// The wry/tao proxy to the current window - pub webview: Rc, + pub webview: WebView, - /// The proxy to the event loop - pub proxy: ProxyType, + /// The tao window itself + pub window: Window, + + pub(crate) shared: Rc, /// The receiver for queries about the current window pub(super) query: QueryEngine, - - pub(super) pending_windows: WebviewQueue, - - pub(crate) event_loop: EventLoopWindowTarget, - - pub(crate) event_handlers: WindowEventHandlers, - - pub(crate) shortcut_manager: ShortcutRegistry, - pub(crate) edit_queue: EditQueue, pub(crate) mutation_state: RefCell, + pub(crate) templates: RefCell>, + pub(crate) max_template_count: AtomicU16, + pub(crate) channel: RefCell, pub(crate) asset_handlers: AssetHandlerRegistry, #[cfg(target_os = "ios")] pub(crate) views: Rc>>, } -/// A handle to the [`DesktopService`] that can be passed around. -pub type DesktopContext = Rc; - /// A smart pointer to the current window. impl std::ops::Deref for DesktopService { type Target = Window; fn deref(&self) -> &Self::Target { - self.webview.window() + &self.window } } impl DesktopService { pub(crate) fn new( webview: WebView, - proxy: ProxyType, - event_loop: EventLoopWindowTarget, - webviews: WebviewQueue, - event_handlers: WindowEventHandlers, - shortcut_manager: ShortcutRegistry, + window: Window, + shared: Rc, edit_queue: EditQueue, asset_handlers: AssetHandlerRegistry, ) -> Self { Self { - webview: Rc::new(webview), - proxy, - event_loop, - query: Default::default(), - pending_windows: webviews, - event_handlers, - shortcut_manager, + window, + webview, + shared, edit_queue, mutation_state: Default::default(), asset_handlers, + query: Default::default(), + templates: Default::default(), + max_template_count: Default::default(), + channel: Default::default(), #[cfg(target_os = "ios")] views: Default::default(), } } + /// Send a list of mutations to the webview + pub(crate) fn send_edits(&self, edits: Mutations) { + if let Some(bytes) = crate::edits::apply_edits( + edits, + &mut self.channel.borrow_mut(), + &mut self.templates.borrow_mut(), + &self.max_template_count, + ) { + self.edit_queue.add_edits(bytes) + } + } + /// Create a new window using the props and window builder /// /// Returns the webview handle for the new window. @@ -178,35 +127,27 @@ impl DesktopService { /// /// Be careful to not create a cycle of windows, or you might leak memory. pub fn new_window(&self, dom: VirtualDom, cfg: Config) -> Weak { - let window = create_new_window( - cfg, - &self.event_loop, - &self.proxy, - dom, - &self.pending_windows, - &self.event_handlers, - self.shortcut_manager.clone(), - ); + let window = WebviewInstance::new(cfg, dom, self.shared.clone()); - let desktop_context = window.dom.in_runtime(|| { + let cx = window.dom.in_runtime(|| { ScopeId::ROOT .consume_context::>() .unwrap() }); - let id = window.desktop_context.webview.window().id(); - - self.proxy - .send_event(UserWindowEvent(EventData::NewWindow, id)) + self.shared + .proxy + .send_event(UserWindowEvent(EventData::NewWindow, cx.id())) .unwrap(); - self.proxy - .send_event(UserWindowEvent(EventData::Poll, id)) + self.shared + .proxy + .send_event(UserWindowEvent(EventData::Poll, cx.id())) .unwrap(); - self.pending_windows.borrow_mut().push(window); + self.shared.pending_webviews.borrow_mut().push(window); - Rc::downgrade(&desktop_context) + Rc::downgrade(&cx) } /// trigger the drag-window event @@ -218,41 +159,38 @@ impl DesktopService { /// onmousedown: move |_| { desktop.drag_window(); } /// ``` pub fn drag(&self) { - let window = self.webview.window(); - - // if the drag_window has any errors, we don't do anything - if window.fullscreen().is_none() { - window.drag_window().unwrap(); + if self.window.fullscreen().is_none() { + _ = self.window.drag_window(); } } /// Toggle whether the window is maximized or not pub fn toggle_maximized(&self) { - let window = self.webview.window(); - - window.set_maximized(!window.is_maximized()) + self.window.set_maximized(!self.window.is_maximized()) } - /// close window + /// Close this window pub fn close(&self) { let _ = self + .shared .proxy .send_event(UserWindowEvent(EventData::CloseWindow, self.id())); } - /// close window + /// Close a particular window, given its ID pub fn close_window(&self, id: WindowId) { let _ = self + .shared .proxy .send_event(UserWindowEvent(EventData::CloseWindow, id)); } /// change window to fullscreen pub fn set_fullscreen(&self, fullscreen: bool) { - if let Some(handle) = self.webview.window().current_monitor() { - self.webview - .window() - .set_fullscreen(fullscreen.then_some(WryFullscreen::Borderless(Some(handle)))); + if let Some(handle) = &self.window.current_monitor() { + self.window.set_fullscreen( + fullscreen.then_some(WryFullscreen::Borderless(Some(handle.clone()))), + ); } } @@ -285,12 +223,12 @@ impl DesktopService { &self, handler: impl FnMut(&Event, &EventLoopWindowTarget) + 'static, ) -> WryEventHandlerId { - self.event_handlers.add(self.id(), handler) + self.shared.event_handlers.add(self.window.id(), handler) } /// Remove a wry event handler created with [`DesktopContext::create_wry_event_handler`] pub fn remove_wry_event_handler(&self, id: WryEventHandlerId) { - self.event_handlers.remove(id) + self.shared.event_handlers.remove(id) } /// Create a global shortcut @@ -301,38 +239,52 @@ impl DesktopService { hotkey: HotKey, callback: impl FnMut() + 'static, ) -> Result { - self.shortcut_manager + self.shared + .shortcut_manager .add_shortcut(hotkey, Box::new(callback)) } /// Remove a global shortcut pub fn remove_shortcut(&self, id: ShortcutId) { - self.shortcut_manager.remove_shortcut(id) + self.shared.shortcut_manager.remove_shortcut(id) } /// Remove all global shortcuts pub fn remove_all_shortcuts(&self) { - self.shortcut_manager.remove_all() + self.shared.shortcut_manager.remove_all() } /// Provide a callback to handle asset loading yourself. + /// If the ScopeId isn't provided, defaults to a global handler. + /// Note that the handler is namespaced by name, not ScopeId. + /// + /// When the component is dropped, the handler is removed. /// /// See [`use_asset_handle`](crate::use_asset_handle) for a convenient hook. - pub async fn register_asset_handler(&self, f: impl AssetHandler) -> usize { - self.asset_handlers.register_handler(f).await + pub fn register_asset_handler( + &self, + name: String, + f: Box, + scope: Option, + ) { + self.asset_handlers.register_handler( + name, + f, + scope.unwrap_or(current_scope_id().unwrap_or(ScopeId(0))), + ) } /// Removes an asset handler by its identifier. /// /// Returns `None` if the handler did not exist. - pub async fn remove_asset_handler(&self, id: usize) -> Option<()> { - self.asset_handlers.remove_handler(id).await + pub fn remove_asset_handler(&self, name: &str) -> Option<()> { + self.asset_handlers.remove_handler(name).map(|_| ()) } /// Push an objc view to the window #[cfg(target_os = "ios")] pub fn push_view(&self, view: objc_id::ShareId) { - let window = self.webview.window(); + let window = &self.window; unsafe { use objc::runtime::Object; @@ -352,7 +304,7 @@ impl DesktopService { /// Pop an objc view from the window #[cfg(target_os = "ios")] pub fn pop_view(&self) { - let window = self.webview.window(); + let window = &self.window; unsafe { use objc::runtime::Object; @@ -366,23 +318,6 @@ impl DesktopService { } } -#[derive(Debug, Clone)] -pub struct UserWindowEvent(pub EventData, pub WindowId); - -#[derive(Debug, Clone)] -pub enum EventData { - Poll, - - Ipc(IpcMessage), - - #[cfg(all(feature = "hot-reload", debug_assertions))] - HotReloadEvent(HotReloadMsg), - - NewWindow, - - CloseWindow, -} - #[cfg(target_os = "ios")] fn is_main_thread() -> bool { use objc::runtime::{Class, BOOL, NO}; @@ -478,7 +413,7 @@ pub fn use_wry_event_handler( /// This will automatically be removed when the component is unmounted. #[derive(Clone)] pub struct WryEventHandler { - handlers: WindowEventHandlers, + pub(crate) handlers: WindowEventHandlers, /// The unique identifier of the event handler. pub id: WryEventHandlerId, } diff --git a/packages/desktop/src/edits.rs b/packages/desktop/src/edits.rs new file mode 100644 index 000000000..4562f2ebf --- /dev/null +++ b/packages/desktop/src/edits.rs @@ -0,0 +1,172 @@ +use dioxus_core::{BorrowedAttributeValue, Mutations, Template, TemplateAttribute, TemplateNode}; +use dioxus_html::event_bubbles; +use dioxus_interpreter_js::binary_protocol::Channel; +use rustc_hash::FxHashMap; +use std::{ + sync::atomic::AtomicU16, + sync::Arc, + sync::{atomic::Ordering, Mutex}, +}; + +use wry::RequestAsyncResponder; + +/// This handles communication between the requests that the webview makes and the interpreter. The interpreter +/// constantly makes long running requests to the webview to get any edits that should be made to the DOM almost like +/// server side events. +/// +/// It will hold onto the requests until the interpreter is ready to handle them and hold onto any pending edits until +/// a new request is made. +#[derive(Default, Clone)] +pub(crate) struct EditQueue { + queue: Arc>>>, + responder: Arc>>, +} + +impl EditQueue { + pub fn handle_request(&self, responder: RequestAsyncResponder) { + let mut queue = self.queue.lock().unwrap(); + if let Some(bytes) = queue.pop() { + responder.respond(wry::http::Response::new(bytes)); + } else { + *self.responder.lock().unwrap() = Some(responder); + } + } + + pub fn add_edits(&self, edits: Vec) { + let mut responder = self.responder.lock().unwrap(); + if let Some(responder) = responder.take() { + responder.respond(wry::http::Response::new(edits)); + } else { + self.queue.lock().unwrap().push(edits); + } + } +} + +pub(crate) fn apply_edits( + mutations: Mutations, + channel: &mut Channel, + templates: &mut FxHashMap, + max_template_count: &AtomicU16, +) -> Option> { + if mutations.templates.is_empty() && mutations.edits.is_empty() { + return None; + } + + for template in mutations.templates { + add_template(&template, channel, templates, max_template_count); + } + + use dioxus_core::Mutation::*; + for edit in mutations.edits { + match edit { + AppendChildren { id, m } => channel.append_children(id.0 as u32, m as u16), + AssignId { path, id } => channel.assign_id(path, id.0 as u32), + CreatePlaceholder { id } => channel.create_placeholder(id.0 as u32), + CreateTextNode { value, id } => channel.create_text_node(value, id.0 as u32), + HydrateText { path, value, id } => channel.hydrate_text(path, value, id.0 as u32), + LoadTemplate { name, index, id } => { + if let Some(tmpl_id) = templates.get(name) { + channel.load_template(*tmpl_id, index as u16, id.0 as u32) + } + } + ReplaceWith { id, m } => channel.replace_with(id.0 as u32, m as u16), + ReplacePlaceholder { path, m } => channel.replace_placeholder(path, m as u16), + InsertAfter { id, m } => channel.insert_after(id.0 as u32, m as u16), + InsertBefore { id, m } => channel.insert_before(id.0 as u32, m as u16), + SetAttribute { + name, + value, + id, + ns, + } => match value { + BorrowedAttributeValue::Text(txt) => { + channel.set_attribute(id.0 as u32, name, txt, ns.unwrap_or_default()) + } + BorrowedAttributeValue::Float(f) => { + channel.set_attribute(id.0 as u32, name, &f.to_string(), ns.unwrap_or_default()) + } + BorrowedAttributeValue::Int(n) => { + channel.set_attribute(id.0 as u32, name, &n.to_string(), ns.unwrap_or_default()) + } + BorrowedAttributeValue::Bool(b) => channel.set_attribute( + id.0 as u32, + name, + if b { "true" } else { "false" }, + ns.unwrap_or_default(), + ), + BorrowedAttributeValue::None => { + channel.remove_attribute(id.0 as u32, name, ns.unwrap_or_default()) + } + _ => unreachable!(), + }, + SetText { value, id } => channel.set_text(id.0 as u32, value), + NewEventListener { name, id, .. } => { + channel.new_event_listener(name, id.0 as u32, event_bubbles(name) as u8) + } + RemoveEventListener { name, id } => { + channel.remove_event_listener(name, id.0 as u32, event_bubbles(name) as u8) + } + Remove { id } => channel.remove(id.0 as u32), + PushRoot { id } => channel.push_root(id.0 as u32), + } + } + + let bytes: Vec<_> = channel.export_memory().collect(); + channel.reset(); + Some(bytes) +} + +pub fn add_template( + template: &Template<'static>, + channel: &mut Channel, + templates: &mut FxHashMap, + max_template_count: &AtomicU16, +) { + let current_max_template_count = max_template_count.load(Ordering::Relaxed); + for root in template.roots.iter() { + create_template_node(channel, root); + templates.insert(template.name.to_owned(), current_max_template_count); + } + channel.add_templates(current_max_template_count, template.roots.len() as u16); + + max_template_count.fetch_add(1, Ordering::Relaxed); +} + +pub fn create_template_node(channel: &mut Channel, node: &'static TemplateNode<'static>) { + use TemplateNode::*; + match node { + Element { + tag, + namespace, + attrs, + children, + .. + } => { + // Push the current node onto the stack + match namespace { + Some(ns) => channel.create_element_ns(tag, ns), + None => channel.create_element(tag), + } + // Set attributes on the current node + for attr in *attrs { + if let TemplateAttribute::Static { + name, + value, + namespace, + } = attr + { + channel.set_top_attribute(name, value, namespace.unwrap_or_default()) + } + } + // Add each child to the stack + for child in *children { + create_template_node(channel, child); + } + // Add all children to the parent + channel.append_children_to_top(children.len() as u16); + } + Text { text } => channel.create_raw_text(text), + DynamicText { .. } => channel.create_raw_text("p"), + Dynamic { .. } => channel.add_placeholder(), + } +} diff --git a/packages/desktop/src/eval.rs b/packages/desktop/src/eval.rs index e55a34836..256e3791d 100644 --- a/packages/desktop/src/eval.rs +++ b/packages/desktop/src/eval.rs @@ -1,23 +1,19 @@ #![allow(clippy::await_holding_refcell_ref)] use async_trait::async_trait; -use dioxus_core::prelude::consume_context; -use dioxus_core::prelude::provide_context; -use dioxus_core::ScopeId; use dioxus_html::prelude::{EvalError, EvalProvider, Evaluator}; use std::{cell::RefCell, rc::Rc}; use crate::{query::Query, DesktopContext}; -/// Provides the DesktopEvalProvider through [`cx.provide_context`]. -pub fn init_eval() { - let desktop_ctx = ScopeId::ROOT.consume_context::().unwrap(); - let provider: Rc = Rc::new(DesktopEvalProvider { desktop_ctx }); - ScopeId::ROOT.provide_context(provider); +/// Reprents the desktop-target's provider of evaluators. +pub struct DesktopEvalProvider { + pub(crate) desktop_ctx: DesktopContext, } -/// Represents the desktop-target's provider of evaluators. -pub(crate) struct DesktopEvalProvider { - desktop_ctx: DesktopContext, +impl DesktopEvalProvider { + pub fn new(desktop_ctx: DesktopContext) -> Self { + Self { desktop_ctx } + } } impl EvalProvider for DesktopEvalProvider { diff --git a/packages/desktop/src/events.rs b/packages/desktop/src/events.rs index a4fbb4e1e..ac5a3df0d 100644 --- a/packages/desktop/src/events.rs +++ b/packages/desktop/src/events.rs @@ -1,25 +1,7 @@ //! Convert a serialized event to an event trigger -use dioxus_html::*; -use serde::{Deserialize, Serialize}; - use crate::element::DesktopElement; - -#[derive(Deserialize, Serialize, Debug, Clone)] -pub struct IpcMessage { - method: String, - params: serde_json::Value, -} - -impl IpcMessage { - pub(crate) fn method(&self) -> &str { - self.method.as_str() - } - - pub(crate) fn params(self) -> serde_json::Value { - self.params - } -} +use dioxus_html::*; pub(crate) struct SerializedHtmlEventConverter; diff --git a/packages/desktop/src/file_upload.rs b/packages/desktop/src/file_upload.rs index 7b5f08fc3..98dbec437 100644 --- a/packages/desktop/src/file_upload.rs +++ b/packages/desktop/src/file_upload.rs @@ -14,74 +14,77 @@ pub(crate) struct FileDialogRequest { pub bubbles: bool, } -#[cfg(not(any( - target_os = "windows", - target_os = "macos", - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" -)))] -pub(crate) fn get_file_event(_request: &FileDialogRequest) -> Vec { - vec![] -} +#[allow(unused)] +impl FileDialogRequest { + #[cfg(not(any( + target_os = "windows", + target_os = "macos", + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd" + )))] + pub(crate) fn get_file_event(&self) -> Vec { + vec![] + } -#[cfg(any( - target_os = "windows", - target_os = "macos", - target_os = "linux", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "netbsd", - target_os = "openbsd" -))] -pub(crate) fn get_file_event(request: &FileDialogRequest) -> Vec { - fn get_file_event_for_folder( - request: &FileDialogRequest, - dialog: rfd::FileDialog, - ) -> Vec { - if request.multiple { - dialog.pick_folders().into_iter().flatten().collect() - } else { - dialog.pick_folder().into_iter().collect() + #[cfg(any( + target_os = "windows", + target_os = "macos", + target_os = "linux", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "netbsd", + target_os = "openbsd" + ))] + pub(crate) fn get_file_event(&self) -> Vec { + fn get_file_event_for_folder( + request: &FileDialogRequest, + dialog: rfd::FileDialog, + ) -> Vec { + if request.multiple { + dialog.pick_folders().into_iter().flatten().collect() + } else { + dialog.pick_folder().into_iter().collect() + } } - } - fn get_file_event_for_file( - request: &FileDialogRequest, - mut dialog: rfd::FileDialog, - ) -> Vec { - let filters: Vec<_> = request - .accept - .as_deref() - .unwrap_or_default() - .split(',') - .filter_map(|s| Filters::from_str(s).ok()) - .collect(); + fn get_file_event_for_file( + request: &FileDialogRequest, + mut dialog: rfd::FileDialog, + ) -> Vec { + let filters: Vec<_> = request + .accept + .as_deref() + .unwrap_or_default() + .split(',') + .filter_map(|s| Filters::from_str(s).ok()) + .collect(); - let file_extensions: Vec<_> = filters - .iter() - .flat_map(|f| f.as_extensions().into_iter()) - .collect(); + let file_extensions: Vec<_> = filters + .iter() + .flat_map(|f| f.as_extensions().into_iter()) + .collect(); - dialog = dialog.add_filter("name", file_extensions.as_slice()); + dialog = dialog.add_filter("name", file_extensions.as_slice()); - let files: Vec<_> = if request.multiple { - dialog.pick_files().into_iter().flatten().collect() + let files: Vec<_> = if request.multiple { + dialog.pick_files().into_iter().flatten().collect() + } else { + dialog.pick_file().into_iter().collect() + }; + + files + } + + let dialog = rfd::FileDialog::new(); + + if self.directory { + get_file_event_for_folder(self, dialog) } else { - dialog.pick_file().into_iter().collect() - }; - - files - } - - let dialog = rfd::FileDialog::new(); - - if request.directory { - get_file_event_for_folder(request, dialog) - } else { - get_file_event_for_file(request, dialog) + get_file_event_for_file(self, dialog) + } } } diff --git a/packages/desktop/src/hooks.rs b/packages/desktop/src/hooks.rs new file mode 100644 index 000000000..85d1a170b --- /dev/null +++ b/packages/desktop/src/hooks.rs @@ -0,0 +1,77 @@ +use crate::{ + assets::*, ipc::UserWindowEvent, shortcut::IntoAccelerator, window, DesktopContext, + ShortcutHandle, ShortcutRegistryError, WryEventHandler, +}; +use dioxus_core::ScopeState; +use tao::{event::Event, event_loop::EventLoopWindowTarget}; +use wry::RequestAsyncResponder; + +/// Get an imperative handle to the current window +pub fn use_window(cx: &ScopeState) -> &DesktopContext { + cx.use_hook(|| cx.consume_context::()) + .as_ref() + .unwrap() +} + +/// Get a closure that executes any JavaScript in the WebView context. +pub fn use_wry_event_handler( + cx: &ScopeState, + handler: impl FnMut(&Event, &EventLoopWindowTarget) + 'static, +) -> &WryEventHandler { + cx.use_hook(move || { + let desktop = window(); + + let id = desktop.create_wry_event_handler(handler); + + WryEventHandler { + handlers: desktop.shared.event_handlers.clone(), + id, + } + }) +} + +/// Provide a callback to handle asset loading yourself. +/// +/// The callback takes a path as requested by the web view, and it should return `Some(response)` +/// if you want to load the asset, and `None` if you want to fallback on the default behavior. +pub fn use_asset_handler( + cx: &ScopeState, + name: &str, + handler: impl Fn(AssetRequest, RequestAsyncResponder) + 'static, +) { + cx.use_hook(|| { + crate::window().asset_handlers.register_handler( + name.to_string(), + Box::new(handler), + cx.scope_id(), + ); + + Handler(name.to_string()) + }); + + // todo: can we just put ondrop in core? + struct Handler(String); + impl Drop for Handler { + fn drop(&mut self) { + _ = crate::window().asset_handlers.remove_handler(&self.0); + } + } +} + +/// Get a closure that executes any JavaScript in the WebView context. +pub fn use_global_shortcut( + cx: &ScopeState, + accelerator: impl IntoAccelerator, + handler: impl FnMut() + 'static, +) -> &Result { + cx.use_hook(move || { + let desktop = window(); + + let id = desktop.create_shortcut(accelerator.accelerator(), handler); + + Ok(ShortcutHandle { + desktop, + shortcut_id: id?, + }) + }) +} diff --git a/packages/desktop/src/index.html b/packages/desktop/src/index.html index 0704fd0f0..45926e3f1 100644 --- a/packages/desktop/src/index.html +++ b/packages/desktop/src/index.html @@ -1,12 +1,12 @@ - - Dioxus app - - - - -

- - + + Dioxus app + + + + +
+ + diff --git a/packages/desktop/src/ipc.rs b/packages/desktop/src/ipc.rs new file mode 100644 index 000000000..c8810c63a --- /dev/null +++ b/packages/desktop/src/ipc.rs @@ -0,0 +1,64 @@ +use serde::{Deserialize, Serialize}; +use tao::window::WindowId; + +/// A pair of data +#[derive(Debug, Clone)] +pub struct UserWindowEvent(pub EventData, pub WindowId); + +/// The data that might eminate from any window/webview +#[derive(Debug, Clone)] +pub enum EventData { + /// Poll the virtualdom + Poll, + + /// Handle an ipc message eminating from the window.postMessage of a given webview + Ipc(IpcMessage), + + /// Handle a hotreload event, basically telling us to update our templates + #[cfg(all(feature = "hot-reload", debug_assertions))] + HotReloadEvent(dioxus_hot_reload::HotReloadMsg), + + /// Create a new window + NewWindow, + + /// Close a given window (could be any window!) + CloseWindow, +} + +/// A message struct that manages the communication between the webview and the eventloop code +/// +/// This needs to be serializable across the JS boundary, so the method names and structs are sensitive. +#[derive(Deserialize, Serialize, Debug, Clone)] +pub struct IpcMessage { + method: String, + params: serde_json::Value, +} + +/// A set of known messages that we need to respond to +#[derive(Deserialize, Serialize, Debug, Clone)] +pub enum IpcMethod<'a> { + FileDialog, + UserEvent, + Query, + BrowserOpen, + Initialize, + Other(&'a str), +} + +impl IpcMessage { + pub(crate) fn method(&self) -> IpcMethod { + match self.method.as_str() { + // todo: this is a misspelling, needs to be fixed + "file_diolog" => IpcMethod::FileDialog, + "user_event" => IpcMethod::UserEvent, + "query" => IpcMethod::Query, + "browser_open" => IpcMethod::BrowserOpen, + "initialize" => IpcMethod::Initialize, + _ => IpcMethod::Other(&self.method), + } + } + + pub(crate) fn params(self) -> serde_json::Value { + self.params + } +} diff --git a/packages/desktop/src/launch.rs b/packages/desktop/src/launch.rs new file mode 100644 index 000000000..080dcd13e --- /dev/null +++ b/packages/desktop/src/launch.rs @@ -0,0 +1,132 @@ +use crate::{ + app::App, + ipc::{EventData, IpcMethod, UserWindowEvent}, + Config, +}; +use dioxus_core::*; +use tao::event::{Event, StartCause, WindowEvent}; + +/// Launch the WebView and run the event loop. +/// +/// This function will start a multithreaded Tokio runtime as well the WebView event loop. +/// +/// ```rust, no_run +/// use dioxus::prelude::*; +/// +/// fn main() { +/// dioxus_desktop::launch(app); +/// } +/// +/// fn app(cx: Scope) -> Element { +/// cx.render(rsx!{ +/// h1 {"hello world!"} +/// }) +/// } +/// ``` +pub fn launch(root: Component) { + launch_with_props(root, (), Config::default()) +} + +/// Launch the WebView and run the event loop, with configuration. +/// +/// This function will start a multithreaded Tokio runtime as well the WebView event loop. +/// +/// You can configure the WebView window with a configuration closure +/// +/// ```rust, no_run +/// use dioxus::prelude::*; +/// use dioxus_desktop::*; +/// +/// fn main() { +/// dioxus_desktop::launch_cfg(app, Config::default().with_window(WindowBuilder::new().with_title("My App"))); +/// } +/// +/// fn app(cx: Scope) -> Element { +/// cx.render(rsx!{ +/// h1 {"hello world!"} +/// }) +/// } +/// ``` +pub fn launch_cfg(root: Component, config_builder: Config) { + launch_with_props(root, (), config_builder) +} + +/// Launch the WebView and run the event loop, with configuration and root props. +/// +/// If the [`tokio`] feature is enabled, this will also startup and block a tokio runtime using the unconstrained task. +/// This function will start a multithreaded Tokio runtime as well the WebView event loop. This will block the current thread. +/// +/// You can configure the WebView window with a configuration closure +/// +/// ```rust, no_run +/// use dioxus::prelude::*; +/// use dioxus_desktop::Config; +/// +/// fn main() { +/// dioxus_desktop::launch_with_props(app, AppProps { name: "asd" }, Config::default()); +/// } +/// +/// struct AppProps { +/// name: &'static str +/// } +/// +/// fn app(cx: Scope) -> Element { +/// cx.render(rsx!{ +/// h1 {"hello {cx.props.name}!"} +/// }) +/// } +/// ``` +pub fn launch_with_props(root: Component

, props: P, cfg: Config) { + #[cfg(feature = "tokio")] + tokio::runtime::Builder::new_multi_thread() + .enable_all() + .build() + .unwrap() + .block_on(tokio::task::unconstrained(async move { + launch_with_props_blocking(root, props, cfg); + })); + + #[cfg(not(feature = "tokio"))] + launch_with_props_blocking(root, props, cfg); +} + +/// Launch the WebView and run the event loop, with configuration and root props. +/// +/// This will block the main thread, and *must* be spawned on the main thread. This function does not assume any runtime +/// and is equivalent to calling launch_with_props with the tokio feature disabled. +pub fn launch_with_props_blocking(root: Component

, props: P, cfg: Config) { + let (event_loop, mut app) = App::new(cfg, props, root); + + event_loop.run(move |window_event, _, control_flow| { + app.tick(&window_event); + + match window_event { + Event::NewEvents(StartCause::Init) => app.handle_start_cause_init(), + Event::WindowEvent { + event, window_id, .. + } => match event { + WindowEvent::CloseRequested => app.handle_close_requested(window_id), + WindowEvent::Destroyed { .. } => app.window_destroyed(window_id), + _ => {} + }, + Event::UserEvent(UserWindowEvent(event, id)) => match event { + EventData::Poll => app.poll_vdom(id), + EventData::NewWindow => app.handle_new_window(), + EventData::CloseWindow => app.handle_close_msg(id), + #[cfg(feature = "hot-reload")] + EventData::HotReloadEvent(msg) => app.handle_hot_reload_msg(msg), + EventData::Ipc(msg) => match msg.method() { + IpcMethod::FileDialog => app.handle_file_dialog_msg(msg, id), + IpcMethod::UserEvent => app.handle_user_event_msg(msg, id), + IpcMethod::Query => app.handle_query_msg(msg, id), + IpcMethod::BrowserOpen => app.handle_browser_open(msg), + IpcMethod::Initialize => app.handle_initialize_msg(id), + IpcMethod::Other(_) => {} + }, + }, + _ => {} + } + + *control_flow = app.control_flow; + }) +} diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs index 46737fd6c..2b673f729 100644 --- a/packages/desktop/src/lib.rs +++ b/packages/desktop/src/lib.rs @@ -3,533 +3,46 @@ #![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/79236386")] #![deny(missing_docs)] -mod cfg; -mod collect_assets; +mod app; +mod assets; +mod config; mod desktop_context; +mod edits; mod element; mod escape; mod eval; mod events; mod file_upload; -#[cfg(any(target_os = "ios", target_os = "android"))] -mod mobile_shortcut; +mod hooks; +mod ipc; +mod menubar; mod protocol; mod query; mod shortcut; mod waker; mod webview; -use crate::query::QueryResult; -use crate::shortcut::GlobalHotKeyEvent; -pub use cfg::{Config, WindowCloseBehaviour}; -pub use desktop_context::DesktopContext; -#[allow(deprecated)] -pub use desktop_context::{ - use_window, use_wry_event_handler, window, DesktopService, WryEventHandler, WryEventHandlerId, -}; -use desktop_context::{EventData, UserWindowEvent, WebviewQueue, WindowEventHandlers}; -use dioxus_core::*; -use dioxus_html::{event_bubbles, FileEngine, HasFormData, MountedData, PlatformEventData}; -use dioxus_html::{native_bind::NativeFileEngine, HtmlEvent}; -use dioxus_interpreter_js::binary_protocol::Channel; -use element::DesktopElement; -use eval::init_eval; -use events::SerializedHtmlEventConverter; -use futures_util::{pin_mut, FutureExt}; -pub use protocol::{use_asset_handler, AssetFuture, AssetHandler, AssetRequest, AssetResponse}; -use rustc_hash::FxHashMap; -use shortcut::ShortcutRegistry; -pub use shortcut::{use_global_shortcut, ShortcutHandle, ShortcutId, ShortcutRegistryError}; -use std::cell::Cell; -use std::rc::Rc; -use std::sync::atomic::AtomicU16; -use std::task::Waker; -use std::{collections::HashMap, sync::Arc}; -pub use tao::dpi::{LogicalSize, PhysicalSize}; -use tao::event_loop::{EventLoopProxy, EventLoopWindowTarget}; +// mobile shortcut is only supported on mobile platforms +#[cfg(any(target_os = "ios", target_os = "android"))] +mod mobile_shortcut; + +// The main entrypoint for this crate +pub use launch::*; +mod launch; + +// Reexport tao and wry, might want to re-export other important things +pub use tao; +pub use tao::dpi::{LogicalPosition, LogicalSize}; +pub use tao::event::WindowEvent; pub use tao::window::WindowBuilder; -use tao::{ - event::{Event, StartCause, WindowEvent}, - event_loop::ControlFlow, -}; -// pub use webview::build_default_menu_bar; pub use wry; -pub use wry::application as tao; -use wry::application::event_loop::EventLoopBuilder; -use wry::webview::WebView; -use wry::{application::window::WindowId, webview::WebContext}; -/// Launch the WebView and run the event loop. -/// -/// This function will start a multithreaded Tokio runtime as well the WebView event loop. -/// -/// ```rust, no_run -/// use dioxus::prelude::*; -/// -/// fn main() { -/// dioxus_desktop::launch(app); -/// } -/// -/// fn app(cx: Scope) -> Element { -/// cx.render(rsx!{ -/// h1 {"hello world!"} -/// }) -/// } -/// ``` -pub fn launch(root: fn() -> Element) { - launch_with_props(|root| root(), root, Config::default()) -} - -/// Launch the WebView and run the event loop, with configuration. -/// -/// This function will start a multithreaded Tokio runtime as well the WebView event loop. -/// -/// You can configure the WebView window with a configuration closure -/// -/// ```rust, no_run -/// use dioxus::prelude::*; -/// use dioxus_desktop::*; -/// -/// fn main() { -/// dioxus_desktop::launch_cfg(app, Config::default().with_window(WindowBuilder::new().with_title("My App"))); -/// } -/// -/// fn app(cx: Scope) -> Element { -/// cx.render(rsx!{ -/// h1 {"hello world!"} -/// }) -/// } -/// ``` -pub fn launch_cfg(root: Component, config_builder: Config) { - launch_with_props(root, (), config_builder) -} - -/// Launch the WebView and run the event loop, with configuration and root props. -/// -/// This function will start a multithreaded Tokio runtime as well the WebView event loop. This will block the current thread. -/// -/// You can configure the WebView window with a configuration closure -/// -/// ```rust, no_run -/// use dioxus::prelude::*; -/// use dioxus_desktop::Config; -/// -/// fn main() { -/// dioxus_desktop::launch_with_props(app, AppProps { name: "asd" }, Config::default()); -/// } -/// -/// struct AppProps { -/// name: &'static str -/// } -/// -/// fn app(cx: Scope) -> Element { -/// cx.render(rsx!{ -/// h1 {"hello {cx.props.name}!"} -/// }) -/// } -/// ``` -pub fn launch_with_props(root: Component

, props: P, cfg: Config) { - let event_loop = EventLoopBuilder::::with_user_event().build(); - - let proxy = event_loop.create_proxy(); - - let window_behaviour = cfg.last_window_close_behaviour; - - // Intialize hot reloading if it is enabled - #[cfg(all(feature = "hot-reload", debug_assertions))] - dioxus_hot_reload::connect({ - let proxy = proxy.clone(); - move |template| { - let _ = proxy.send_event(UserWindowEvent( - EventData::HotReloadEvent(template), - unsafe { WindowId::dummy() }, - )); - } - }); - - // Copy over any assets we find - crate::collect_assets::copy_assets(); - - // Set the event converter - dioxus_html::set_event_converter(Box::new(SerializedHtmlEventConverter)); - - // We start the tokio runtime *on this thread* - // Any future we poll later will use this runtime to spawn tasks and for IO - let rt = tokio::runtime::Builder::new_multi_thread() - .enable_all() - .build() - .unwrap(); - - // We enter the runtime but we poll futures manually, circumventing the per-task runtime budget - let _guard = rt.enter(); - - // We only have one webview right now, but we'll have more later - // Store them in a hashmap so we can remove them when they're closed - let mut webviews = HashMap::::new(); - - // We use this to allow dynamically adding and removing window event handlers - let event_handlers = WindowEventHandlers::default(); - - let queue = WebviewQueue::default(); - - let shortcut_manager = ShortcutRegistry::new(); - let global_hotkey_channel = GlobalHotKeyEvent::receiver(); - - // move the props into a cell so we can pop it out later to create the first window - // iOS panics if we create a window before the event loop is started - let props = Rc::new(Cell::new(Some(props))); - let cfg = Rc::new(Cell::new(Some(cfg))); - let mut is_visible_before_start = true; - - event_loop.run(move |window_event, event_loop, control_flow| { - *control_flow = ControlFlow::Poll; - - event_handlers.apply_event(&window_event, event_loop); - - if let Ok(event) = global_hotkey_channel.try_recv() { - shortcut_manager.call_handlers(event); - } - - match window_event { - Event::WindowEvent { - event, window_id, .. - } => match event { - WindowEvent::CloseRequested => match window_behaviour { - cfg::WindowCloseBehaviour::LastWindowExitsApp => { - webviews.remove(&window_id); - - if webviews.is_empty() { - *control_flow = ControlFlow::Exit - } - } - cfg::WindowCloseBehaviour::LastWindowHides => { - let Some(webview) = webviews.get(&window_id) else { - return; - }; - hide_app_window(&webview.desktop_context.webview); - } - cfg::WindowCloseBehaviour::CloseWindow => { - webviews.remove(&window_id); - } - }, - WindowEvent::Destroyed { .. } => { - webviews.remove(&window_id); - - if matches!( - window_behaviour, - cfg::WindowCloseBehaviour::LastWindowExitsApp - ) && webviews.is_empty() - { - *control_flow = ControlFlow::Exit - } - } - _ => {} - }, - - Event::NewEvents(StartCause::Init) => { - let props = props.take().unwrap(); - let cfg = cfg.take().unwrap(); - - // Create a dom - let dom = VirtualDom::new_with_props(root, props); - - is_visible_before_start = cfg.window.window.visible; - - let handler = create_new_window( - cfg, - event_loop, - &proxy, - dom, - &queue, - &event_handlers, - shortcut_manager.clone(), - ); - - let id = handler.desktop_context.webview.window().id(); - webviews.insert(id, handler); - _ = proxy.send_event(UserWindowEvent(EventData::Poll, id)); - } - - Event::UserEvent(UserWindowEvent(EventData::NewWindow, _)) => { - for handler in queue.borrow_mut().drain(..) { - let id = handler.desktop_context.webview.window().id(); - webviews.insert(id, handler); - _ = proxy.send_event(UserWindowEvent(EventData::Poll, id)); - } - } - - Event::UserEvent(event) => match event.0 { - #[cfg(all(feature = "hot-reload", debug_assertions))] - EventData::HotReloadEvent(msg) => match msg { - dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => { - for webview in webviews.values_mut() { - webview.dom.replace_template(template); - - poll_vdom(webview); - } - } - dioxus_hot_reload::HotReloadMsg::Shutdown => { - *control_flow = ControlFlow::Exit; - } - }, - - EventData::CloseWindow => { - webviews.remove(&event.1); - - if webviews.is_empty() { - *control_flow = ControlFlow::Exit - } - } - - EventData::Poll => { - if let Some(view) = webviews.get_mut(&event.1) { - poll_vdom(view); - } - } - - EventData::Ipc(msg) if msg.method() == "user_event" => { - let params = msg.params(); - - let evt = match serde_json::from_value::(params) { - Ok(value) => value, - Err(err) => { - tracing::error!("Error parsing user_event: {:?}", err); - return; - } - }; - - let HtmlEvent { - element, - name, - bubbles, - data, - } = evt; - - let view = webviews.get_mut(&event.1).unwrap(); - - // check for a mounted event placeholder and replace it with a desktop specific element - let as_any = if let dioxus_html::EventData::Mounted = &data { - let query = view.dom.in_runtime(|| { - ScopeId::ROOT - .consume_context::() - .unwrap() - .query - .clone() - }); - - let element = - DesktopElement::new(element, view.desktop_context.clone(), query); - - Rc::new(PlatformEventData::new(Box::new(MountedData::new(element)))) - } else { - data.into_any() - }; - - view.dom.handle_event(&name, as_any, element, bubbles); - - view.dom - .render_immediate(&mut *view.desktop_context.mutation_state.borrow_mut()); - send_edits(&view.desktop_context); - } - - // When the webview sends a query, we need to send it to the query manager which handles dispatching the data to the correct pending query - EventData::Ipc(msg) if msg.method() == "query" => { - let params = msg.params(); - - if let Ok(result) = serde_json::from_value::(params) { - let view = webviews.get(&event.1).unwrap(); - let query = view.dom.in_runtime(|| { - ScopeId::ROOT - .consume_context::() - .unwrap() - .query - .clone() - }); - - query.send(result); - } - } - - EventData::Ipc(msg) if msg.method() == "initialize" => { - let view = webviews.get_mut(&event.1).unwrap(); - view.dom - .rebuild(&mut *view.desktop_context.mutation_state.borrow_mut()); - send_edits(&view.desktop_context); - view.desktop_context - .webview - .window() - .set_visible(is_visible_before_start); - } - - EventData::Ipc(msg) if msg.method() == "browser_open" => { - if let Some(temp) = msg.params().as_object() { - if temp.contains_key("href") { - let open = webbrowser::open(temp["href"].as_str().unwrap()); - if let Err(e) = open { - tracing::error!("Open Browser error: {:?}", e); - } - } - } - } - - EventData::Ipc(msg) if msg.method() == "file_diolog" => { - if let Ok(file_diolog) = - serde_json::from_value::(msg.params()) - { - struct DesktopFileUploadForm { - files: Arc, - } - - impl HasFormData for DesktopFileUploadForm { - fn files(&self) -> Option> { - Some(self.files.clone()) - } - - fn as_any(&self) -> &dyn std::any::Any { - self - } - } - - let id = ElementId(file_diolog.target); - let event_name = &file_diolog.event; - let event_bubbles = file_diolog.bubbles; - let files = file_upload::get_file_event(&file_diolog); - let data = - Rc::new(PlatformEventData::new(Box::new(DesktopFileUploadForm { - files: Arc::new(NativeFileEngine::new(files)), - }))); - - let view = webviews.get_mut(&event.1).unwrap(); - - if event_name == "change&input" { - view.dom - .handle_event("input", data.clone(), id, event_bubbles); - view.dom.handle_event("change", data, id, event_bubbles); - } else { - view.dom.handle_event(event_name, data, id, event_bubbles); - } - - view.dom.render_immediate( - &mut *view.desktop_context.mutation_state.borrow_mut(), - ); - send_edits(&view.desktop_context); - } - } - - _ => {} - }, - _ => {} - } - }) -} - -fn create_new_window( - mut cfg: Config, - event_loop: &EventLoopWindowTarget, - proxy: &EventLoopProxy, - dom: VirtualDom, - queue: &WebviewQueue, - event_handlers: &WindowEventHandlers, - shortcut_manager: ShortcutRegistry, -) -> WebviewHandler { - let (webview, web_context, asset_handlers, edit_queue) = - webview::build(&mut cfg, event_loop, proxy.clone()); - let desktop_context = Rc::from(DesktopService::new( - webview, - proxy.clone(), - event_loop.clone(), - queue.clone(), - event_handlers.clone(), - shortcut_manager, - edit_queue, - asset_handlers, - )); - - let query = dom.in_runtime(|| { - let query = ScopeId::ROOT.provide_context(desktop_context.clone()); - // Init eval - init_eval(); - query - }); - - WebviewHandler { - // We want to poll the virtualdom and the event loop at the same time, so the waker will be connected to both - waker: waker::tao_waker(proxy, desktop_context.webview.window().id()), - desktop_context, - dom, - _web_context: web_context, - } -} - -struct WebviewHandler { - dom: VirtualDom, - desktop_context: DesktopContext, - waker: Waker, - - // Wry assumes the webcontext is alive for the lifetime of the webview. - // We need to keep the webcontext alive, otherwise the webview will crash - _web_context: WebContext, -} - -/// Poll the virtualdom until it's pending -/// -/// The waker we give it is connected to the event loop, so it will wake up the event loop when it's ready to be polled again -/// -/// All IO is done on the tokio runtime we started earlier -fn poll_vdom(view: &mut WebviewHandler) { - let mut cx = std::task::Context::from_waker(&view.waker); - - loop { - { - let fut = view.dom.wait_for_work(); - pin_mut!(fut); - - match fut.poll_unpin(&mut cx) { - std::task::Poll::Ready(_) => {} - std::task::Poll::Pending => break, - } - } - - view.dom - .render_immediate(&mut *view.desktop_context.mutation_state.borrow_mut()); - send_edits(&view.desktop_context); - } -} - -/// Send a list of mutations to the webview -fn send_edits(desktop_context: &DesktopContext) { - let mut mutations = desktop_context.mutation_state.borrow_mut(); - let serialized_edits = mutations.export_memory(); - desktop_context.edit_queue.add_edits(serialized_edits); -} - -/// Different hide implementations per platform -#[allow(unused)] -fn hide_app_window(webview: &WebView) { - #[cfg(target_os = "windows")] - { - use wry::application::platform::windows::WindowExtWindows; - webview.window().set_visible(false); - webview.window().set_skip_taskbar(true); - } - - #[cfg(target_os = "linux")] - { - use wry::application::platform::unix::WindowExtUnix; - webview.window().set_visible(false); - } - - #[cfg(target_os = "macos")] - { - // webview.window().set_visible(false); has the wrong behaviour on macOS - // It will hide the window but not show it again when the user switches - // back to the app. `NSApplication::hide:` has the correct behaviour - use objc::runtime::Object; - use objc::{msg_send, sel, sel_impl}; - objc::rc::autoreleasepool(|| unsafe { - let app: *mut Object = msg_send![objc::class!(NSApplication), sharedApplication]; - let nil = std::ptr::null_mut::(); - let _: () = msg_send![app, hide: nil]; - }); - } -} +// Public exports +pub use assets::AssetRequest; +pub use config::{Config, WindowCloseBehaviour}; +pub use desktop_context::{ + window, DesktopContext, DesktopService, WryEventHandler, WryEventHandlerId, +}; +pub use hooks::{use_asset_handler, use_global_shortcut, use_window, use_wry_event_handler}; +pub use shortcut::{ShortcutHandle, ShortcutId, ShortcutRegistryError}; +pub use wry::RequestAsyncResponder; diff --git a/packages/desktop/src/menubar.rs b/packages/desktop/src/menubar.rs new file mode 100644 index 000000000..71e424240 --- /dev/null +++ b/packages/desktop/src/menubar.rs @@ -0,0 +1,79 @@ +use tao::window::Window; + +#[allow(unused)] +pub fn build_menu(window: &Window, default_menu_bar: bool) { + if default_menu_bar { + #[cfg(not(any(target_os = "ios", target_os = "android")))] + impl_::build_menu_bar(impl_::build_default_menu_bar(), window) + } +} + +#[cfg(not(any(target_os = "ios", target_os = "android")))] +mod impl_ { + use super::*; + use muda::{Menu, PredefinedMenuItem, Submenu}; + + #[allow(unused)] + pub fn build_menu_bar(menu: Menu, window: &Window) { + #[cfg(target_os = "windows")] + use tao::platform::windows::WindowExtWindows; + + #[cfg(target_os = "windows")] + menu.init_for_hwnd(window.hwnd()); + + // #[cfg(target_os = "linux")] + // { + // use tao::platform::unix::WindowExtUnix; + // menu.init_for_gtk_window(window, None); + // menu.init_for_gtk_window(window, Some(&ertical_gtk_box)); + // } + + #[cfg(target_os = "macos")] + menu.init_for_nsapp(); + } + + /// Builds a standard menu bar depending on the users platform. It may be used as a starting point + /// to further customize the menu bar and pass it to a [`WindowBuilder`](tao::window::WindowBuilder). + /// > Note: The default menu bar enables macOS shortcuts like cut/copy/paste. + /// > The menu bar differs per platform because of constraints introduced + /// > by [`MenuItem`](tao::menu::MenuItem). + pub fn build_default_menu_bar() -> Menu { + let menu = Menu::new(); + + // since it is uncommon on windows to have an "application menu" + // we add a "window" menu to be more consistent across platforms with the standard menu + let window_menu = Submenu::new("Window", true); + window_menu + .append_items(&[ + &PredefinedMenuItem::fullscreen(None), + &PredefinedMenuItem::separator(), + &PredefinedMenuItem::hide(None), + &PredefinedMenuItem::hide_others(None), + &PredefinedMenuItem::show_all(None), + &PredefinedMenuItem::maximize(None), + &PredefinedMenuItem::minimize(None), + &PredefinedMenuItem::close_window(None), + &PredefinedMenuItem::separator(), + &PredefinedMenuItem::quit(None), + ]) + .unwrap(); + + let edit_menu = Submenu::new("Window", true); + edit_menu + .append_items(&[ + &PredefinedMenuItem::undo(None), + &PredefinedMenuItem::redo(None), + &PredefinedMenuItem::separator(), + &PredefinedMenuItem::cut(None), + &PredefinedMenuItem::copy(None), + &PredefinedMenuItem::paste(None), + &PredefinedMenuItem::separator(), + &PredefinedMenuItem::select_all(None), + ]) + .unwrap(); + + menu.append_items(&[&window_menu, &edit_menu]).unwrap(); + + menu + } +} diff --git a/packages/desktop/src/mobile_shortcut.rs b/packages/desktop/src/mobile_shortcut.rs index c6144344b..03566bf36 100644 --- a/packages/desktop/src/mobile_shortcut.rs +++ b/packages/desktop/src/mobile_shortcut.rs @@ -2,7 +2,7 @@ use super::*; use std::str::FromStr; -use wry::application::event_loop::EventLoopWindowTarget; +use tao::event_loop::EventLoopWindowTarget; use dioxus_html::input_data::keyboard_types::Modifiers; @@ -37,15 +37,15 @@ impl GlobalHotKeyManager { Ok(Self()) } - pub fn register(&mut self, accelerator: HotKey) -> Result { + pub fn register(&self, accelerator: HotKey) -> Result { Ok(HotKey) } - pub fn unregister(&mut self, id: HotKey) -> Result<(), HotkeyError> { + pub fn unregister(&self, id: HotKey) -> Result<(), HotkeyError> { Ok(()) } - pub fn unregister_all(&mut self, _: &[HotKey]) -> Result<(), HotkeyError> { + pub fn unregister_all(&self, _: &[HotKey]) -> Result<(), HotkeyError> { Ok(()) } } diff --git a/packages/desktop/src/protocol.rs b/packages/desktop/src/protocol.rs index 01816b1fc..82570b1bc 100644 --- a/packages/desktop/src/protocol.rs +++ b/packages/desktop/src/protocol.rs @@ -1,64 +1,160 @@ -use crate::{window, DesktopContext}; -use dioxus_core::prelude::{once, spawn}; -use dioxus_interpreter_js::INTERPRETER_JS; -use slab::Slab; -use std::{ - borrow::Cow, - future::Future, - ops::Deref, - path::{Path, PathBuf}, - pin::Pin, - rc::Rc, - sync::Arc, -}; -use tokio::{ - runtime::Handle, - sync::{OnceCell, RwLock}, -}; +use crate::{assets::*, edits::EditQueue}; +use std::path::{Path, PathBuf}; use wry::{ - http::{status::StatusCode, Request, Response}, - Result, + http::{status::StatusCode, Request, Response, Uri}, + RequestAsyncResponder, Result, }; -use crate::desktop_context::EditQueue; - static MINIFIED: &str = include_str!("./minified.js"); +static DEFAULT_INDEX: &str = include_str!("./index.html"); -fn module_loader(root_name: &str, headless: bool) -> String { - let js = INTERPRETER_JS.replace( - "/*POST_HANDLE_EDITS*/", - r#"// Prevent file inputs from opening the file dialog on click - let inputs = document.querySelectorAll("input"); - for (let input of inputs) { - if (!input.getAttribute("data-dioxus-file-listener")) { - // prevent file inputs from opening the file dialog on click - const type = input.getAttribute("type"); - if (type === "file") { - input.setAttribute("data-dioxus-file-listener", true); - input.addEventListener("click", (event) => { - let target = event.target; - let target_id = find_real_id(target); - if (target_id !== null) { - const send = (event_name) => { - const message = serializeIpcMessage("file_diolog", { accept: target.getAttribute("accept"), directory: target.getAttribute("webkitdirectory") === "true", multiple: target.hasAttribute("multiple"), target: parseInt(target_id), bubbles: event_bubbles(event_name), event: event_name }); - window.ipc.postMessage(message); - }; - send("change&input"); - } - event.preventDefault(); - }); - } - } - }"#, +/// Build the index.html file we use for bootstrapping a new app +/// +/// We use wry/webview by building a special index.html that forms a bridge between the webview and your rust code +/// +/// This is similar to tauri, except we give more power to your rust code and less power to your frontend code. +/// This lets us skip a build/bundle step - your code just works - but limits how your Rust code can actually +/// mess with UI elements. We make this decision since other renderers like LiveView are very separate and can +/// never properly bridge the gap. Eventually of course, the idea is to build a custom CSS/HTML renderer where you +/// *do* have native control over elements, but that still won't work with liveview. +pub(super) fn index_request( + request: &Request>, + custom_head: Option, + custom_index: Option, + root_name: &str, + headless: bool, +) -> Option>> { + // If the request is for the root, we'll serve the index.html file. + if request.uri().path() != "/" { + return None; + } + + // Load a custom index file if provided + let mut index = custom_index.unwrap_or_else(|| DEFAULT_INDEX.to_string()); + + // Insert a custom head if provided + // We look just for the closing head tag. If a user provided a custom index with weird syntax, this might fail + if let Some(head) = custom_head { + index.insert_str(index.find("").expect("Head element to exist"), &head); + } + + // Inject our module loader by looking for a body tag + // A failure mode here, obviously, is if the user provided a custom index without a body tag + // Might want to document this + index.insert_str( + index.find("").expect("Body element to exist"), + &module_loader(root_name, headless), ); + Response::builder() + .header("Content-Type", "text/html") + .header("Access-Control-Allow-Origin", "*") + .body(index.into()) + .ok() +} + +/// Handle a request from the webview +/// +/// - Tries to stream edits if they're requested. +/// - If that doesn't match, tries a user provided asset handler +/// - If that doesn't match, tries to serve a file from the filesystem +pub(super) fn desktop_handler( + mut request: Request>, + asset_handlers: AssetHandlerRegistry, + edit_queue: &EditQueue, + responder: RequestAsyncResponder, +) { + // If the request is asking for edits (ie binary protocol streaming, do that) + if request.uri().path().trim_matches('/') == "edits" { + return edit_queue.handle_request(responder); + } + + // If the user provided a custom asset handler, then call it and return the response if the request was handled. + // The path is the first part of the URI, so we need to trim the leading slash. + let path = PathBuf::from( + urlencoding::decode(request.uri().path().trim_start_matches('/')) + .expect("expected URL to be UTF-8 encoded") + .as_ref(), + ); + + let Some(name) = path.parent() else { + return tracing::error!("Asset request has no root {path:?}"); + }; + + if let Some(name) = name.to_str() { + if asset_handlers.has_handler(name) { + // Trim the leading path from the URI + // + // I hope this is reliable! + // + // so a request for /assets/logos/logo.png?query=123 will become /logos/logo.png?query=123 + strip_uri_prefix(&mut request, name); + + return asset_handlers.handle_request(name, request, responder); + } + } + + // Else, try to serve a file from the filesystem. + match serve_from_fs(path) { + Ok(res) => responder.respond(res), + Err(e) => tracing::error!("Error serving request from filesystem {}", e), + } +} + +fn serve_from_fs(path: PathBuf) -> Result>> { + // If the path is relative, we'll try to serve it from the assets directory. + let mut asset = get_asset_root_or_default().join(&path); + + // If we can't find it, make it absolute and try again + if !asset.exists() { + asset = PathBuf::from("/").join(path); + } + + if !asset.exists() { + return Ok(Response::builder() + .status(StatusCode::NOT_FOUND) + .body(String::from("Not Found").into_bytes())?); + } + + Ok(Response::builder() + .header("Content-Type", get_mime_from_path(&asset)?) + .body(std::fs::read(asset)?)?) +} + +fn strip_uri_prefix(request: &mut Request>, name: &str) { + // trim the leading path + if let Some(path) = request.uri().path_and_query() { + let new_path = path + .path() + .trim_start_matches('/') + .strip_prefix(name) + .expect("expected path to have prefix"); + + let new_uri = Uri::builder() + .scheme(request.uri().scheme_str().unwrap_or("http")) + .path_and_query(format!("{}{}", new_path, path.query().unwrap_or(""))) + .authority("index.html") + .build() + .expect("failed to build new URI"); + + *request.uri_mut() = new_uri; + } +} + +/// Construct the inline script that boots up the page and bridges the webview with rust code. +/// +/// The arguments here: +/// - root_name: the root element (by Id) that we stream edits into +/// - headless: is this page being loaded but invisible? Important because not all windows are visible and the +/// interpreter can't connect until the window is ready. +fn module_loader(root_id: &str, headless: bool) -> String { format!( r#" + + + \ No newline at end of file diff --git a/packages/fullstack/examples/axum-hello-world/Cargo.toml b/packages/fullstack/examples/axum-hello-world/Cargo.toml index a3b68b05a..4dda8df5b 100644 --- a/packages/fullstack/examples/axum-hello-world/Cargo.toml +++ b/packages/fullstack/examples/axum-hello-world/Cargo.toml @@ -9,7 +9,6 @@ publish = false [dependencies] dioxus = { workspace = true } dioxus-fullstack = { workspace = true } -axum = { version = "0.6.12", optional = true } serde = "1.0.159" simple_logger = "4.2.0" tracing-wasm = "0.2.1" @@ -19,5 +18,5 @@ reqwest = "0.11.18" [features] default = [] -ssr = ["axum", "dioxus-fullstack/axum"] +ssr = ["dioxus-fullstack/axum"] web = ["dioxus-fullstack/web"] diff --git a/packages/fullstack/examples/salvo-hello-world/Cargo.toml b/packages/fullstack/examples/salvo-hello-world/Cargo.toml index 3d4e74c5b..23956cefa 100644 --- a/packages/fullstack/examples/salvo-hello-world/Cargo.toml +++ b/packages/fullstack/examples/salvo-hello-world/Cargo.toml @@ -10,7 +10,6 @@ publish = false dioxus-web = { workspace = true, features=["hydrate"], optional = true } dioxus = { workspace = true } dioxus-fullstack = { workspace = true } -tokio = { workspace = true, features = ["full"], optional = true } serde = "1.0.159" salvo = { version = "0.63.0", optional = true } execute = "0.2.12" @@ -22,5 +21,5 @@ tracing-subscriber = "0.3.17" [features] default = [] -ssr = ["salvo", "tokio", "dioxus-fullstack/salvo"] +ssr = ["salvo", "dioxus-fullstack/salvo"] web = ["dioxus-web"] diff --git a/packages/fullstack/examples/warp-hello-world/Cargo.toml b/packages/fullstack/examples/warp-hello-world/Cargo.toml index 1474facf3..c2246a58d 100644 --- a/packages/fullstack/examples/warp-hello-world/Cargo.toml +++ b/packages/fullstack/examples/warp-hello-world/Cargo.toml @@ -10,7 +10,6 @@ publish = false dioxus-web = { workspace = true, features=["hydrate"], optional = true } dioxus = { workspace = true } dioxus-fullstack = { workspace = true } -tokio = { workspace = true, features = ["full"], optional = true } serde = "1.0.159" warp = { version = "0.3.3", optional = true } execute = "0.2.12" @@ -22,5 +21,5 @@ tracing-subscriber = "0.3.17" [features] default = [] -ssr = ["warp", "tokio", "dioxus-fullstack/warp"] +ssr = ["warp", "dioxus-fullstack/warp"] web = ["dioxus-web"] diff --git a/packages/fullstack/src/adapters/axum_adapter.rs b/packages/fullstack/src/adapters/axum_adapter.rs index a14c51c0a..09e6e1aa1 100644 --- a/packages/fullstack/src/adapters/axum_adapter.rs +++ b/packages/fullstack/src/adapters/axum_adapter.rs @@ -276,9 +276,6 @@ where fn serve_static_assets(mut self, assets_path: impl Into) -> Self { use tower_http::services::{ServeDir, ServeFile}; - // Copy over any assets we find - crate::collect_assets::copy_assets(); - let assets_path = assets_path.into(); // Serve all files in dist folder except index.html diff --git a/packages/fullstack/src/adapters/salvo_adapter.rs b/packages/fullstack/src/adapters/salvo_adapter.rs index 84894bbda..674722665 100644 --- a/packages/fullstack/src/adapters/salvo_adapter.rs +++ b/packages/fullstack/src/adapters/salvo_adapter.rs @@ -241,9 +241,6 @@ impl DioxusRouterExt for Router { } fn serve_static_assets(mut self, assets_path: impl Into) -> Self { - // Copy over any assets we find - crate::collect_assets::copy_assets(); - let assets_path = assets_path.into(); // Serve all files in dist folder except index.html diff --git a/packages/fullstack/src/adapters/warp_adapter.rs b/packages/fullstack/src/adapters/warp_adapter.rs index 682063084..316d70e56 100644 --- a/packages/fullstack/src/adapters/warp_adapter.rs +++ b/packages/fullstack/src/adapters/warp_adapter.rs @@ -187,9 +187,6 @@ pub fn serve_dioxus_application(string: &[u8]) -> Option } }; - match postcard::from_bytes(&decompressed) { + match ciborium::from_reader(std::io::Cursor::new(decompressed)) { Ok(data) => Some(data), Err(err) => { tracing::error!("Failed to deserialize: {}", err); diff --git a/packages/fullstack/src/html_storage/mod.rs b/packages/fullstack/src/html_storage/mod.rs index 5b4d2804f..a6ae2ebe1 100644 --- a/packages/fullstack/src/html_storage/mod.rs +++ b/packages/fullstack/src/html_storage/mod.rs @@ -1,6 +1,6 @@ #![allow(unused)] -use std::sync::atomic::AtomicUsize; +use std::{io::Cursor, sync::atomic::AtomicUsize}; use serde::{de::DeserializeOwned, Serialize}; @@ -15,7 +15,8 @@ pub(crate) struct HTMLData { impl HTMLData { pub(crate) fn push(&mut self, value: &T) { - let serialized = postcard::to_allocvec(value).unwrap(); + let mut serialized = Vec::new(); + serialize::serde_to_writable(value, &mut serialized).unwrap(); self.data.push(serialized); } @@ -45,7 +46,7 @@ impl HTMLDataCursor { } let mut cursor = &self.data[current]; self.index.fetch_add(1, std::sync::atomic::Ordering::SeqCst); - match postcard::from_bytes(cursor) { + match ciborium::from_reader(Cursor::new(cursor)) { Ok(x) => Some(x), Err(e) => { tracing::error!("Error deserializing data: {:?}", e); @@ -57,7 +58,7 @@ impl HTMLDataCursor { #[test] fn serialized_and_deserializes() { - use postcard::to_allocvec; + use ciborium::{from_reader, into_writer}; #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)] struct Data { @@ -97,7 +98,9 @@ fn serialized_and_deserializes() { "original size: {}", std::mem::size_of::() * data.len() ); - println!("serialized size: {}", to_allocvec(&data).unwrap().len()); + let mut bytes = Vec::new(); + into_writer(&data, &mut bytes).unwrap(); + println!("serialized size: {}", bytes.len()); println!("compressed size: {}", as_string.len()); let decoded: Vec = deserialize::serde_from_bytes(&as_string).unwrap(); diff --git a/packages/fullstack/src/html_storage/serialize.rs b/packages/fullstack/src/html_storage/serialize.rs index 7f0a7efc7..482864eb3 100644 --- a/packages/fullstack/src/html_storage/serialize.rs +++ b/packages/fullstack/src/html_storage/serialize.rs @@ -7,8 +7,9 @@ use base64::Engine; pub(crate) fn serde_to_writable( value: &T, write_to: &mut impl std::io::Write, -) -> std::io::Result<()> { - let serialized = postcard::to_allocvec(value).unwrap(); +) -> Result<(), ciborium::ser::Error> { + let mut serialized = Vec::new(); + ciborium::into_writer(value, &mut serialized)?; write_to.write_all(STANDARD.encode(serialized).as_bytes())?; Ok(()) } @@ -18,12 +19,12 @@ pub(crate) fn serde_to_writable( pub(crate) fn encode_props_in_element( data: &T, write_to: &mut impl std::io::Write, -) -> std::io::Result<()> { +) -> Result<(), ciborium::ser::Error> { write_to.write_all( r#""#.as_bytes()) + Ok(write_to.write_all(r#"" />"#.as_bytes())?) } #[cfg(feature = "ssr")] @@ -31,10 +32,10 @@ pub(crate) fn encode_props_in_element( pub(crate) fn encode_in_element( data: &super::HTMLData, write_to: &mut impl std::io::Write, -) -> std::io::Result<()> { +) -> Result<(), ciborium::ser::Error> { write_to.write_all( r#""#.as_bytes()) + Ok(write_to.write_all(r#"" />"#.as_bytes())?) } diff --git a/packages/fullstack/src/lib.rs b/packages/fullstack/src/lib.rs index 8b166757f..7ef582da1 100644 --- a/packages/fullstack/src/lib.rs +++ b/packages/fullstack/src/lib.rs @@ -14,7 +14,6 @@ pub mod router; mod adapters; #[cfg(feature = "ssr")] pub use adapters::*; -mod collect_assets; mod hooks; #[cfg(all(debug_assertions, feature = "hot-reload", feature = "ssr"))] mod hot_reload; diff --git a/packages/fullstack/src/render.rs b/packages/fullstack/src/render.rs index 886a5bd99..c3aefd605 100644 --- a/packages/fullstack/src/render.rs +++ b/packages/fullstack/src/render.rs @@ -65,7 +65,7 @@ impl SsrRendererPool { } if let Err(err) = renderer.render_to(&mut to, &vdom) { let _ = tx.send(Err( - dioxus_router::prelude::IncrementalRendererError::RenderError( + dioxus_ssr::incremental::IncrementalRendererError::RenderError( err, ), )); @@ -236,7 +236,9 @@ impl dioxus_ssr::incremental::Wrap to: &mut R, ) -> Result<(), dioxus_ssr::incremental::IncrementalRendererError> { // serialize the props - crate::html_storage::serialize::encode_props_in_element(&self.cfg.props, to)?; + crate::html_storage::serialize::encode_props_in_element(&self.cfg.props, to).map_err( + |err| dioxus_ssr::incremental::IncrementalRendererError::Other(Box::new(err)), + )?; // serialize the server state crate::html_storage::serialize::encode_in_element( &*self.server_context.html_data().map_err(|_| { @@ -258,7 +260,8 @@ impl dioxus_ssr::incremental::Wrap })) })?, to, - )?; + ) + .map_err(|err| dioxus_ssr::incremental::IncrementalRendererError::Other(Box::new(err)))?; #[cfg(all(debug_assertions, feature = "hot-reload"))] { diff --git a/packages/html-internal-macro/Cargo.toml b/packages/html-internal-macro/Cargo.toml new file mode 100644 index 000000000..ce8ad54b1 --- /dev/null +++ b/packages/html-internal-macro/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "dioxus-html-internal-macro" +version = { workspace = true } +edition = "2021" +repository = "https://github.com/DioxusLabs/dioxus/" +homepage = "https://dioxuslabs.com" +keywords = ["dom", "ui", "gui", "react", "liveview"] +license = "MIT OR Apache-2.0" +description = "HTML function macros for Dioxus" + + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +proc-macro2 = "1.0.66" +syn = { version = "2", features = ["full"] } +quote = "^1.0.26" +convert_case = "^0.6.0" + +[lib] +proc-macro = true + +[[test]] +name = "tests" +path = "tests/progress.rs" + +[dev-dependencies] +trybuild = { version = "1.0.82", features = ["diff"] } \ No newline at end of file diff --git a/packages/html-internal-macro/src/lib.rs b/packages/html-internal-macro/src/lib.rs new file mode 100644 index 000000000..a404a9b16 --- /dev/null +++ b/packages/html-internal-macro/src/lib.rs @@ -0,0 +1,76 @@ +use proc_macro::TokenStream; + +use convert_case::{Case, Casing}; +use quote::{quote, ToTokens, TokenStreamExt}; +use syn::__private::TokenStream2; +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::{braced, parse_macro_input, Ident, Token}; + +#[proc_macro] +pub fn impl_extension_attributes(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as ImplExtensionAttributes); + input.to_token_stream().into() +} + +struct ImplExtensionAttributes { + is_element: bool, + name: Ident, + attrs: Punctuated, +} + +impl Parse for ImplExtensionAttributes { + fn parse(input: ParseStream) -> syn::Result { + let content; + + let element: Ident = input.parse()?; + let name = input.parse()?; + braced!(content in input); + let attrs = content.parse_terminated(Ident::parse, Token![,])?; + + Ok(ImplExtensionAttributes { + is_element: element == "ELEMENT", + name, + attrs, + }) + } +} + +impl ToTokens for ImplExtensionAttributes { + fn to_tokens(&self, tokens: &mut TokenStream2) { + let name = &self.name; + let name_string = name.to_string(); + let camel_name = name_string + .strip_prefix("r#") + .unwrap_or(&name_string) + .to_case(Case::UpperCamel); + let impl_name = Ident::new(format!("{}Impl", &camel_name).as_str(), name.span()); + let extension_name = Ident::new(format!("{}Extension", &camel_name).as_str(), name.span()); + + if !self.is_element { + tokens.append_all(quote! { + struct #impl_name; + impl #name for #impl_name {} + }); + } + + let impls = self.attrs.iter().map(|ident| { + let d = if self.is_element { + quote! { #name::#ident } + } else { + quote! { <#impl_name as #name>::#ident } + }; + quote! { + fn #ident(self, value: impl IntoAttributeValue<'a>) -> Self { + let d = #d; + self.push_attribute(d.0, d.1, value, d.2) + } + } + }); + tokens.append_all(quote! { + pub trait #extension_name<'a>: HasAttributes<'a> + Sized { + #(#impls)* + } + }); + } +} diff --git a/packages/html-internal-macro/tests/01-simple.rs b/packages/html-internal-macro/tests/01-simple.rs new file mode 100644 index 000000000..f328e4d9d --- /dev/null +++ b/packages/html-internal-macro/tests/01-simple.rs @@ -0,0 +1 @@ +fn main() {} diff --git a/packages/html-internal-macro/tests/progress.rs b/packages/html-internal-macro/tests/progress.rs new file mode 100644 index 000000000..563805397 --- /dev/null +++ b/packages/html-internal-macro/tests/progress.rs @@ -0,0 +1,5 @@ +#[test] +fn tests() { + let t = trybuild::TestCases::new(); + t.pass("tests/01-simple.rs"); +} diff --git a/packages/html/Cargo.toml b/packages/html/Cargo.toml index 68c365579..78d0a3caa 100644 --- a/packages/html/Cargo.toml +++ b/packages/html/Cargo.toml @@ -12,6 +12,7 @@ keywords = ["dom", "ui", "gui", "react"] [dependencies] dioxus-core = { workspace = true } dioxus-rsx = { workspace = true, features = ["hot_reload"], optional = true } +dioxus-html-internal-macro = { workspace = true } serde = { version = "1", features = ["derive"], optional = true } serde_repr = { version = "0.1", optional = true } wasm-bindgen = { workspace = true, optional = true } @@ -19,7 +20,7 @@ euclid = "0.22.7" enumset = "1.1.2" keyboard-types = "0.7" async-trait = "0.1.58" -serde-value = "0.7.0" +serde-value = { version = "0.7.0", optional = true } tokio = { workspace = true, features = ["fs", "io-util"], optional = true } rfd = { version = "0.12", optional = true } async-channel = "1.8.0" @@ -33,6 +34,7 @@ features = [ "TouchList", "TouchEvent", "MouseEvent", + "DragEvent", "InputEvent", "ClipboardEvent", "KeyboardEvent", @@ -51,20 +53,20 @@ serde_json = "1" default = ["serialize", "mounted", "eval"] serialize = [ "serde", - "serde/rc", - "serde_repr", "serde_json", + "serde_repr", "euclid/serde", "keyboard-types/serde", "dioxus-core/serialize", + "serde-value", ] mounted = [ - "web-sys/Element", - "web-sys/DomRect", - "web-sys/ScrollIntoViewOptions", - "web-sys/ScrollLogicalPosition", - "web-sys/ScrollBehavior", - "web-sys/HtmlElement", + "web-sys?/Element", + "web-sys?/DomRect", + "web-sys?/ScrollIntoViewOptions", + "web-sys?/ScrollLogicalPosition", + "web-sys?/ScrollBehavior", + "web-sys?/HtmlElement", ] eval = [ "serde", diff --git a/packages/html/src/elements.rs b/packages/html/src/elements.rs index ca3f4aee7..37e6bb682 100644 --- a/packages/html/src/elements.rs +++ b/packages/html/src/elements.rs @@ -1,9 +1,14 @@ #![allow(non_upper_case_globals)] + +use dioxus_core::prelude::IntoAttributeValue; +use dioxus_core::HasAttributes; +use dioxus_html_internal_macro::impl_extension_attributes; +#[cfg(feature = "hot-reload-context")] +use dioxus_rsx::HotReloadingContext; + #[cfg(feature = "hot-reload-context")] use crate::{map_global_attributes, map_svg_attributes}; use crate::{GlobalAttributes, SvgAttributes}; -#[cfg(feature = "hot-reload-context")] -use dioxus_rsx::HotReloadingContext; pub type AttributeDiscription = (&'static str, Option<&'static str>, bool); @@ -378,6 +383,13 @@ macro_rules! builder_constructors { } ); )* + + pub(crate) mod extensions { + use super::*; + $( + impl_extension_attributes![ELEMENT $name { $($fil,)* }]; + )* + } }; } diff --git a/packages/html/src/events.rs b/packages/html/src/events.rs index a282d6483..897598ad5 100644 --- a/packages/html/src/events.rs +++ b/packages/html/src/events.rs @@ -6,7 +6,7 @@ macro_rules! impl_event { $data:ty; $( $( #[$attr:meta] )* - $name:ident + $name:ident $(: $js_name:literal)? )* ) => { $( @@ -20,10 +20,17 @@ macro_rules! impl_event { }), None, false, - ) + ).into() } )* }; + + (@name $name:ident $js_name:literal) => { + $js_name + }; + (@name $name:ident) => { + stringify!($name) + }; } static EVENT_CONVERTER: RwLock>> = RwLock::new(None); diff --git a/packages/html/src/events/drag.rs b/packages/html/src/events/drag.rs index e58c20e22..bbedf9a2b 100644 --- a/packages/html/src/events/drag.rs +++ b/packages/html/src/events/drag.rs @@ -1,3 +1,4 @@ +use crate::file_data::{FileEngine, HasFileData}; use crate::geometry::{ClientPoint, Coordinates, ElementPoint, PagePoint, ScreenPoint}; use crate::input_data::{MouseButton, MouseButtonSet}; use crate::prelude::*; @@ -53,7 +54,13 @@ impl DragData { /// Downcast this event data to a specific type pub fn downcast(&self) -> Option<&T> { - self.inner.as_any().downcast_ref::() + HasDragData::as_any(&*self.inner).downcast_ref::() + } +} + +impl HasFileData for DragData { + fn files(&self) -> Option> { + self.inner.files() } } @@ -103,19 +110,34 @@ impl PointerInteraction for DragData { #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)] pub struct SerializedDragData { mouse: crate::point_interaction::SerializedPointInteraction, + files: Option, } #[cfg(feature = "serialize")] -impl From<&DragData> for SerializedDragData { - fn from(data: &DragData) -> Self { +impl SerializedDragData { + fn new(drag: &DragData, files: Option) -> Self { Self { - mouse: crate::point_interaction::SerializedPointInteraction::from(data), + mouse: crate::point_interaction::SerializedPointInteraction::from(drag), + files, } } } #[cfg(feature = "serialize")] -impl HasDragData for SerializedDragData {} +impl HasDragData for SerializedDragData { + fn as_any(&self) -> &dyn std::any::Any { + self + } +} + +#[cfg(feature = "serialize")] +impl HasFileData for SerializedDragData { + fn files(&self) -> Option> { + self.files + .as_ref() + .map(|files| std::sync::Arc::new(files.clone()) as _) + } +} #[cfg(feature = "serialize")] impl HasMouseData for SerializedDragData { @@ -171,7 +193,7 @@ impl PointerInteraction for SerializedDragData { #[cfg(feature = "serialize")] impl serde::Serialize for DragData { fn serialize(&self, serializer: S) -> Result { - SerializedDragData::from(self).serialize(serializer) + SerializedDragData::new(self, None).serialize(serializer) } } @@ -186,7 +208,10 @@ impl<'de> serde::Deserialize<'de> for DragData { } /// A trait for any object that has the data for a drag event -pub trait HasDragData: HasMouseData {} +pub trait HasDragData: HasMouseData + HasFileData { + /// return self as Any + fn as_any(&self) -> &dyn std::any::Any; +} impl_event! { DragData; diff --git a/packages/html/src/events/form.rs b/packages/html/src/events/form.rs index de8bb0dbf..d22a5219f 100644 --- a/packages/html/src/events/form.rs +++ b/packages/html/src/events/form.rs @@ -1,9 +1,25 @@ -use std::{any::Any, collections::HashMap, fmt::Debug}; +use crate::file_data::FileEngine; +use crate::file_data::HasFileData; +use std::{collections::HashMap, fmt::Debug}; use dioxus_core::Event; pub type FormEvent = Event; +/// A form value that may either be a list of values or a single value +#[cfg_attr( + feature = "serialize", + derive(serde::Serialize, serde::Deserialize), + // this will serialize Text(String) -> String and VecText(Vec) to Vec + serde(untagged) +)] +#[derive(Debug, Clone, PartialEq)] +pub enum FormValue { + Text(String), + VecText(Vec), +} + +/* DOMEvent: Send + SyncTarget relatedTarget */ pub struct FormData { inner: Box, } @@ -43,7 +59,7 @@ impl FormData { } /// Get the values of the form event - pub fn values(&self) -> HashMap> { + pub fn values(&self) -> HashMap { self.inner.values() } @@ -59,30 +75,50 @@ impl FormData { } /// An object that has all the data for a form event -pub trait HasFormData: std::any::Any { +pub trait HasFormData: HasFileData + std::any::Any { fn value(&self) -> String { Default::default() } - fn values(&self) -> HashMap> { + fn values(&self) -> HashMap { Default::default() } - fn files(&self) -> Option> { - None - } - /// return self as Any fn as_any(&self) -> &dyn std::any::Any; } +impl FormData { + #[cfg(feature = "serialize")] + /// Parse the values into a struct with one field per value + pub fn parsed_values(&self) -> Result + where + T: serde::de::DeserializeOwned, + { + use serde::Serialize; + + fn convert_hashmap_to_json(hashmap: &HashMap) -> serde_json::Result + where + K: Serialize + std::hash::Hash + Eq, + V: Serialize, + { + serde_json::to_string(hashmap) + } + + let parsed_json = + convert_hashmap_to_json(&self.values()).expect("Failed to parse values to JSON"); + + serde_json::from_str(&parsed_json) + } +} + #[cfg(feature = "serialize")] /// A serialized form data object #[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)] pub struct SerializedFormData { value: String, - values: HashMap>, - files: Option>, + values: HashMap, + files: Option, } #[cfg(feature = "serialize")] @@ -90,8 +126,8 @@ impl SerializedFormData { /// Create a new serialized form data object pub fn new( value: String, - values: HashMap>, - files: Option>, + values: HashMap, + files: Option, ) -> Self { Self { value, @@ -114,9 +150,9 @@ impl SerializedFormData { resolved_files.insert(file, bytes.unwrap_or_default()); } - Some(std::sync::Arc::new(SerializedFileEngine { + Some(crate::file_data::SerializedFileEngine { files: resolved_files, - })) + }) } None => None, }, @@ -138,21 +174,24 @@ impl HasFormData for SerializedFormData { self.value.clone() } - fn values(&self) -> HashMap> { + fn values(&self) -> HashMap { self.values.clone() } - fn files(&self) -> Option> { - self.files - .as_ref() - .map(|files| std::sync::Arc::clone(files) as std::sync::Arc) - } - fn as_any(&self) -> &dyn std::any::Any { self } } +#[cfg(feature = "serialize")] +impl HasFileData for SerializedFormData { + fn files(&self) -> Option> { + self.files + .as_ref() + .map(|files| std::sync::Arc::new(files.clone()) as _) + } +} + #[cfg(feature = "serialize")] impl serde::Serialize for FormData { fn serialize(&self, serializer: S) -> Result { @@ -170,52 +209,6 @@ impl<'de> serde::Deserialize<'de> for FormData { } } -#[cfg(feature = "serialize")] -/// A file engine that serializes files to bytes -#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)] -pub struct SerializedFileEngine { - files: HashMap>, -} - -#[cfg(feature = "serialize")] -#[async_trait::async_trait(?Send)] -impl FileEngine for SerializedFileEngine { - fn files(&self) -> Vec { - self.files.keys().cloned().collect() - } - - async fn read_file(&self, file: &str) -> Option> { - self.files.get(file).cloned() - } - - async fn read_file_to_string(&self, file: &str) -> Option { - self.read_file(file) - .await - .map(|bytes| String::from_utf8_lossy(&bytes).to_string()) - } - - async fn get_native_file(&self, file: &str) -> Option> { - self.read_file(file) - .await - .map(|val| Box::new(val) as Box) - } -} - -#[async_trait::async_trait(?Send)] -pub trait FileEngine { - // get a list of file names - fn files(&self) -> Vec; - - // read a file to bytes - async fn read_file(&self, file: &str) -> Option>; - - // read a file to string - async fn read_file_to_string(&self, file: &str) -> Option; - - // returns a file in platform's native representation - async fn get_native_file(&self, file: &str) -> Option>; -} - impl_event! { FormData; diff --git a/packages/html/src/events/mouse.rs b/packages/html/src/events/mouse.rs index 77069ef6f..f6b3d14a9 100644 --- a/packages/html/src/events/mouse.rs +++ b/packages/html/src/events/mouse.rs @@ -78,6 +78,8 @@ impl_event! { #[deprecated(since = "0.5.0", note = "use ondoubleclick instead")] ondblclick + ondoubleclick: "ondblclick" + /// onmousedown onmousedown @@ -102,21 +104,6 @@ impl_event! { onmouseup } -/// ondoubleclick -#[inline] -pub fn ondoubleclick, T>( - mut _f: impl FnMut(::dioxus_core::Event) -> E + 'static, -) -> ::dioxus_core::Attribute { - ::dioxus_core::Attribute::new( - "ondblclick", - dioxus_core::AttributeValue::listener(move |e: ::dioxus_core::Event| { - _f(e).spawn(); - }), - None, - false, - ) -} - impl MouseData { /// Create a new instance of MouseData pub fn new(inner: impl HasMouseData + 'static) -> Self { diff --git a/packages/html/src/file_data.rs b/packages/html/src/file_data.rs new file mode 100644 index 000000000..b15eaab2b --- /dev/null +++ b/packages/html/src/file_data.rs @@ -0,0 +1,53 @@ +use std::any::Any; + +pub trait HasFileData: std::any::Any { + fn files(&self) -> Option> { + None + } +} + +#[cfg(feature = "serialize")] +/// A file engine that serializes files to bytes +#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)] +pub struct SerializedFileEngine { + pub files: std::collections::HashMap>, +} + +#[cfg(feature = "serialize")] +#[async_trait::async_trait(?Send)] +impl FileEngine for SerializedFileEngine { + fn files(&self) -> Vec { + self.files.keys().cloned().collect() + } + + async fn read_file(&self, file: &str) -> Option> { + self.files.get(file).cloned() + } + + async fn read_file_to_string(&self, file: &str) -> Option { + self.read_file(file) + .await + .map(|bytes| String::from_utf8_lossy(&bytes).to_string()) + } + + async fn get_native_file(&self, file: &str) -> Option> { + self.read_file(file) + .await + .map(|val| Box::new(val) as Box) + } +} + +#[async_trait::async_trait(?Send)] +pub trait FileEngine { + // get a list of file names + fn files(&self) -> Vec; + + // read a file to bytes + async fn read_file(&self, file: &str) -> Option>; + + // read a file to string + async fn read_file_to_string(&self, file: &str) -> Option; + + // returns a file in platform's native representation + async fn get_native_file(&self, file: &str) -> Option>; +} diff --git a/packages/html/src/global_attributes.rs b/packages/html/src/global_attributes.rs index 639026b33..b9f06a754 100644 --- a/packages/html/src/global_attributes.rs +++ b/packages/html/src/global_attributes.rs @@ -1,5 +1,9 @@ #![allow(non_upper_case_globals)] +use dioxus_core::prelude::IntoAttributeValue; +use dioxus_core::HasAttributes; +use dioxus_html_internal_macro::impl_extension_attributes; + use crate::AttributeDiscription; #[cfg(feature = "hot-reload-context")] @@ -106,6 +110,8 @@ macro_rules! trait_methods { )* None } + + impl_extension_attributes![GLOBAL $trait { $($name,)* }]; }; // Rename the incoming ident and apply a custom namespace diff --git a/packages/html/src/lib.rs b/packages/html/src/lib.rs index e7cce2657..17ca25aef 100644 --- a/packages/html/src/lib.rs +++ b/packages/html/src/lib.rs @@ -22,6 +22,8 @@ pub use elements::HtmlCtx; #[cfg(feature = "html-to-rsx")] pub use elements::{map_html_attribute_to_rsx, map_html_element_to_rsx}; pub mod events; +pub(crate) mod file_data; +pub use file_data::*; pub mod geometry; mod global_attributes; pub mod input_data; @@ -46,10 +48,17 @@ pub use render_template::*; #[cfg(feature = "eval")] pub mod eval; +pub mod extensions { + pub use crate::elements::extensions::*; + pub use crate::global_attributes::{GlobalAttributesExtension, SvgAttributesExtension}; +} + pub mod prelude { + pub use crate::elements::extensions::*; #[cfg(feature = "eval")] pub use crate::eval::*; pub use crate::events::*; + pub use crate::global_attributes::{GlobalAttributesExtension, SvgAttributesExtension}; pub use crate::point_interaction::*; pub use keyboard_types::{self, Code, Key, Location, Modifiers}; } diff --git a/packages/html/src/native_bind/native_file_engine.rs b/packages/html/src/native_bind/native_file_engine.rs index 88b996a4d..81070bf0d 100644 --- a/packages/html/src/native_bind/native_file_engine.rs +++ b/packages/html/src/native_bind/native_file_engine.rs @@ -1,10 +1,11 @@ use std::any::Any; use std::path::PathBuf; -use crate::FileEngine; use tokio::fs::File; use tokio::io::AsyncReadExt; +use crate::file_data::FileEngine; + pub struct NativeFileEngine { files: Vec, } diff --git a/packages/html/src/web_sys_bind/events.rs b/packages/html/src/web_sys_bind/events.rs index b1e6c5341..40d14f28b 100644 --- a/packages/html/src/web_sys_bind/events.rs +++ b/packages/html/src/web_sys_bind/events.rs @@ -3,6 +3,7 @@ use crate::events::{ AnimationData, CompositionData, KeyboardData, MouseData, PointerData, TouchData, TransitionData, WheelData, }; +use crate::file_data::{FileEngine, HasFileData}; use crate::geometry::{ClientPoint, ElementPoint, PagePoint, ScreenPoint}; use crate::input_data::{decode_key_location, decode_mouse_button_set, MouseButton}; use crate::prelude::*; @@ -103,8 +104,6 @@ impl ModifiersInteraction for KeyboardEvent { } } -impl HasDragData for MouseEvent {} - impl InteractionLocation for MouseEvent { fn client_coordinates(&self) -> ClientPoint { ClientPoint::new(self.client_x().into(), self.client_y().into()) @@ -162,6 +161,14 @@ impl HasMouseData for MouseEvent { } } +impl HasFileData for MouseEvent {} + +impl HasDragData for MouseEvent { + fn as_any(&self) -> &dyn std::any::Any { + self + } +} + impl ModifiersInteraction for TouchEvent { fn modifiers(&self) -> Modifiers { let mut modifiers = Modifiers::empty(); @@ -512,3 +519,23 @@ impl HasMediaData for web_sys::Event { self } } + +impl HasFileData for web_sys::Event { + fn files(&self) -> Option> { + #[cfg(not(feature = "file_engine"))] + let files = None; + #[cfg(feature = "file_engine")] + let files = element + .dyn_ref() + .and_then(|input: &web_sys::HtmlInputElement| { + input.files().and_then(|files| { + #[allow(clippy::arc_with_non_send_sync)] + crate::file_engine::WebFileEngine::new(files).map(|f| { + std::sync::Arc::new(f) as std::sync::Arc + }) + }) + }); + + files + } +} diff --git a/packages/interpreter/src/interpreter.js b/packages/interpreter/src/interpreter.js index 54f1d517c..c8384a8b7 100644 --- a/packages/interpreter/src/interpreter.js +++ b/packages/interpreter/src/interpreter.js @@ -6,7 +6,7 @@ class InterpreterConfig { // this handler is only provided on the desktop and liveview implementations since this // method is not used by the web implementation -function handler(event, name, bubbles, config) { +async function handler(event, name, bubbles, config) { let target = event.target; if (target != null) { let preventDefaultRequests = null; @@ -61,7 +61,7 @@ function handler(event, name, bubbles, config) { event.preventDefault(); } - let contents = serialize_event(event); + let contents = await serialize_event(event); // TODO: this should be liveview only if ( @@ -109,8 +109,18 @@ function handler(event, name, bubbles, config) { const formData = new FormData(target); for (let name of formData.keys()) { - let value = formData.getAll(name); - contents.values[name] = value; + const fieldType = target.elements[name].type; + + switch (fieldType) { + case "select-multiple": + contents.values[name] = formData.getAll(name); + break; + + // add cases for fieldTypes that can hold multiple values here + default: + contents.values[name] = formData.get(name); + break; + } } } @@ -321,7 +331,7 @@ function get_mouse_data(event) { }; } -function serialize_event(event) { +async function serialize_event(event) { switch (event.type) { case "copy": case "cut": @@ -407,7 +417,12 @@ function serialize_event(event) { case "dragover": case "dragstart": case "drop": { - return { mouse: get_mouse_data(event) }; + let files = null; + if (event.dataTransfer && event.dataTransfer.files) { + files = await serializeFileList(event.dataTransfer.files); + } + + return { mouse: get_mouse_data(event), files }; } case "click": case "contextmenu": diff --git a/packages/native-core/src/utils/persistant_iterator.rs b/packages/native-core/src/utils/persistant_iterator.rs index 1cbacbfd2..e40fa306b 100644 --- a/packages/native-core/src/utils/persistant_iterator.rs +++ b/packages/native-core/src/utils/persistant_iterator.rs @@ -306,15 +306,10 @@ fn persist_removes() { _ => unreachable!(), }; render!( - div{ - (0..children).map(|i|{ - rsx!{ - p{ - key: "{i}", - "{i}" - } - } - }) + div { + for i in 0..children { + p { key: "{i}", "{i}" } + } } ) } @@ -387,15 +382,10 @@ fn persist_instertions_before() { _ => unreachable!(), }; render!( - div{ - (0..children).map(|i|{ - rsx!{ - p{ - key: "{i}", - "{i}" - } - } - }) + div { + for i in 0..children { + p { key: "{i}", "{i}" } + } } ) } @@ -446,14 +436,9 @@ fn persist_instertions_after() { }; render!( div{ - (0..children).map(|i|{ - rsx!{ - p{ - key: "{i}", - "{i}" - } - } - }) + for i in 0..children { + p { key: "{i}", "{i}" } + } } ) } diff --git a/packages/native-core/tests/fuzzing.rs b/packages/native-core/tests/fuzzing.rs index 29c4fef9e..2496b1f1c 100644 --- a/packages/native-core/tests/fuzzing.rs +++ b/packages/native-core/tests/fuzzing.rs @@ -1,3 +1,5 @@ +use std::cell::Cell; + use dioxus::prelude::Props; use dioxus_core::*; use dioxus_native_core::prelude::*; @@ -178,15 +180,16 @@ fn create_random_dynamic_node(cx: &ScopeState, depth: usize) -> DynamicNode { match rand::random::() % range { 0 => DynamicNode::Placeholder(Default::default()), 1 => cx.make_node((0..(rand::random::() % 5)).map(|_| { - VNode::new( - None, - Template { + cx.vnode( + None.into(), + Default::default(), + Cell::new(Template { name: concat!(file!(), ":", line!(), ":", column!(), ":0"), roots: &[TemplateNode::Dynamic { id: 0 }], node_paths: &[&[0]], attr_paths: &[], - }, - dioxus::core::exports::bumpalo::collections::Vec::new_in(cx.bump()), + }), + dioxus::core::exports::bumpalo::collections::Vec::new_in(cx.bump()).into(), cx.bump().alloc([cx.component( create_random_element, DepthProps { depth, root: false }, @@ -214,9 +217,9 @@ fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute { 3 => AttributeValue::Bool(rand::random()), 4 => cx.any_value(rand::random::()), 5 => AttributeValue::None, - // Listener(RefCell>>), _ => unreachable!(), }; + Attribute::new( Box::leak(format!("attr{}", rand::random::()).into_boxed_str()), value, @@ -253,10 +256,11 @@ fn create_random_element(cx: Scope) -> Element { .into_boxed_str(), )); println!("{template:#?}"); - let node = VNode::new( + let node = cx.vnode( + None.into(), None, - template, - dioxus::core::exports::bumpalo::collections::Vec::new_in(cx.bump()), + Cell::new(template), + dioxus::core::exports::bumpalo::collections::Vec::new_in(cx.bump()).into(), { let dynamic_nodes: Vec<_> = dynamic_node_types .iter() @@ -271,11 +275,13 @@ fn create_random_element(cx: Scope) -> Element { .collect(); cx.bump().alloc(dynamic_nodes) }, - cx.bump().alloc( - (0..template.attr_paths.len()) - .map(|_| create_random_dynamic_attr(cx)) - .collect::>(), - ), + cx.bump() + .alloc( + (0..template.attr_paths.len()) + .map(|_| create_random_dynamic_attr(cx).into()) + .collect::>(), + ) + .as_slice(), ); Some(node) } diff --git a/packages/rink/src/hooks.rs b/packages/rink/src/hooks.rs index 1ffa361f7..d519273f0 100644 --- a/packages/rink/src/hooks.rs +++ b/packages/rink/src/hooks.rs @@ -3,8 +3,8 @@ use crossterm::event::{ MouseEventKind, }; use dioxus_html::{ - HasFormData, HasKeyboardData, HasWheelData, SerializedFocusData, SerializedKeyboardData, - SerializedMouseData, SerializedWheelData, + HasFileData, HasFormData, HasKeyboardData, HasWheelData, SerializedFocusData, + SerializedKeyboardData, SerializedMouseData, SerializedWheelData, }; use dioxus_native_core::prelude::*; use dioxus_native_core::real_dom::NodeImmutable; @@ -18,6 +18,7 @@ use dioxus_html::input_data::keyboard_types::{Code, Key, Location, Modifiers}; use dioxus_html::input_data::{ MouseButton as DioxusMouseButton, MouseButtonSet as DioxusMouseButtons, }; +use dioxus_html::FormValue; use dioxus_html::{event_bubbles, prelude::*}; use std::any::Any; use std::collections::HashMap; @@ -66,7 +67,7 @@ impl EventData { pub struct FormData { pub(crate) value: String, - pub(crate) values: HashMap>, + pub values: HashMap, pub(crate) files: Option, } @@ -76,7 +77,7 @@ impl HasFormData for FormData { self.value.clone() } - fn values(&self) -> HashMap> { + fn values(&self) -> HashMap { self.values.clone() } @@ -85,6 +86,8 @@ impl HasFormData for FormData { } } +impl HasFileData for FormData {} + #[derive(Clone, Debug, PartialEq)] pub struct Files { files: FxHashMap, diff --git a/packages/router/Cargo.toml b/packages/router/Cargo.toml index da9d3fe85..0064b5300 100644 --- a/packages/router/Cargo.toml +++ b/packages/router/Cargo.toml @@ -10,13 +10,10 @@ homepage = "https://dioxuslabs.com" keywords = ["dom", "ui", "gui", "react", "wasm"] [dependencies] -anyhow = "1.0.66" dioxus = { workspace = true } dioxus-router-macro = { workspace = true } gloo = { version = "0.8.0", optional = true } tracing = { workspace = true } -thiserror = { workspace = true } -futures-util = { workspace = true } urlencoding = "2.1.3" serde = { version = "1", features = ["derive"], optional = true } serde_json = { version = "1.0.91", optional = true } @@ -30,13 +27,14 @@ gloo-utils = { version = "0.1.6", optional = true } dioxus-liveview = { workspace = true, optional = true } dioxus-ssr = { workspace = true, optional = true } tokio = { workspace = true, features = ["full"], optional = true } +dioxus-cli-config.workspace = true [features] default = ["web"] ssr = ["dioxus-ssr", "tokio"] liveview = ["dioxus-liveview", "tokio", "dep:serde", "serde_json"] wasm_test = [] -serde = ["dep:serde", "gloo-utils/serde"] +serde = ["dep:serde", "gloo-utils?/serde"] web = ["gloo", "web-sys", "wasm-bindgen", "gloo-utils", "js-sys"] [dev-dependencies] diff --git a/packages/router/examples/simple_routes.rs b/packages/router/examples/simple_routes.rs index 6c33c275b..e7dc2289a 100644 --- a/packages/router/examples/simple_routes.rs +++ b/packages/router/examples/simple_routes.rs @@ -54,8 +54,7 @@ fn main() { #[cfg(feature = "liveview")] #[component] fn Root(cx: Scope) -> Element { - let history = LiveviewHistory::new(cx); - render! { Router:: { config: || RouterConfig::default().history(history) } } + render! { Router:: {} } } #[cfg(not(feature = "liveview"))] @@ -104,7 +103,7 @@ fn Route1(cx: Scope, user_id: usize, dynamic: usize, query: String, extra: Strin fn Route2(cx: Scope, user_id: usize) -> Element { render! { pre { "Route2{{\n\tuser_id:{user_id}\n}}" } - (0..*user_id).map(|i| rsx!{ p { "{i}" } }), + {(0..*user_id).map(|i| rsx!{ p { "{i}" } })}, p { "Footer" } Link { to: Route::Route3 { diff --git a/packages/router/src/components/history_buttons.rs b/packages/router/src/components/history_buttons.rs index ae11ad276..39c7a63a4 100644 --- a/packages/router/src/components/history_buttons.rs +++ b/packages/router/src/components/history_buttons.rs @@ -77,7 +77,7 @@ pub fn GoBackButton<'a>(cx: Scope<'a, HistoryButtonProps<'a>>) -> Element { disabled: "{disabled}", prevent_default: "onclick", onclick: move |_| router.go_back(), - children + {children} } } } @@ -149,7 +149,7 @@ pub fn GoForwardButton<'a>(cx: Scope<'a, HistoryButtonProps<'a>>) -> Element { disabled: "{disabled}", prevent_default: "onclick", onclick: move |_| router.go_forward(), - children + {children} } } } diff --git a/packages/router/src/components/link.rs b/packages/router/src/components/link.rs index 639d99ae7..b0e7a9f13 100644 --- a/packages/router/src/components/link.rs +++ b/packages/router/src/components/link.rs @@ -167,7 +167,7 @@ impl Debug for LinkProps<'_> { /// new_tab: true, /// rel: "link_rel", /// to: Route::Index {}, -/// +/// /// "A fully configured link" /// } /// } @@ -250,7 +250,7 @@ pub fn Link<'a>(cx: Scope<'a, LinkProps<'a>>) -> Element { id: "{id}", rel: "{rel}", target: "{tag_target}", - children + {children} } } } diff --git a/packages/router/src/history/liveview.rs b/packages/router/src/history/liveview.rs index 9ffb09c34..354d259b1 100644 --- a/packages/router/src/history/liveview.rs +++ b/packages/router/src/history/liveview.rs @@ -132,6 +132,15 @@ where } } +impl Default for LiveviewHistory +where + ::Err: std::fmt::Display, +{ + fn default() -> Self { + Self::new() + } +} + impl LiveviewHistory where ::Err: std::fmt::Display, @@ -141,10 +150,9 @@ where /// /// # Panics /// - /// Panics if not in a Liveview context. - pub fn new(cx: &ScopeState) -> Self { + /// Panics if the function is not called in a dioxus runtime with a Liveview context. + pub fn new() -> Self { Self::new_with_initial_path( - cx, "/".parse().unwrap_or_else(|err| { panic!("index route does not exist:\n{}\n use LiveviewHistory::new_with_initial_path to set a custom path", err) }), @@ -156,17 +164,16 @@ where /// /// # Panics /// - /// Panics if not in a Liveview context. - pub fn new_with_initial_path(cx: &ScopeState, initial_path: R) -> Self { + /// Panics if the function is not called in a dioxus runtime with a Liveview context. + pub fn new_with_initial_path(initial_path: R) -> Self { let (action_tx, action_rx) = tokio::sync::mpsc::unbounded_channel::>(); let action_rx = Arc::new(Mutex::new(action_rx)); let timeline = Arc::new(Mutex::new(Timeline::new(initial_path))); let updater_callback: Arc>> = Arc::new(RwLock::new(Arc::new(|| {}))); - let eval_provider = cx - .consume_context::>() - .expect("evaluator not provided"); + let eval_provider = + consume_context::>().expect("evaluator not provided"); let create_eval = Rc::new(move |script: &str| { eval_provider @@ -175,7 +182,7 @@ where }) as Rc Result>; // Listen to server actions - cx.push_future({ + push_future({ let timeline = timeline.clone(); let action_rx = action_rx.clone(); let create_eval = create_eval.clone(); @@ -235,7 +242,7 @@ where }); // Listen to browser actions - cx.push_future({ + push_future({ let updater = updater_callback.clone(); let timeline = timeline.clone(); let create_eval = create_eval.clone(); @@ -256,15 +263,16 @@ where Option, Option>, usize, - )>(init_eval).expect("serializable state"); + )>(init_eval) + .expect("serializable state"); let Ok(route) = R::from_str(&route.to_string()) else { return; }; let mut timeline = timeline.lock().expect("unpoisoned mutex"); let state = timeline.init(route.clone(), state, session, depth); let state = serde_json::to_string(&state).expect("serializable state"); - let session = serde_json::to_string(&timeline.session()) - .expect("serializable session"); + let session = + serde_json::to_string(&timeline.session()).expect("serializable session"); // Call the updater callback (updater.read().unwrap())(); @@ -288,22 +296,24 @@ where Ok(event) => event, Err(_) => continue, }; - let (route, state) = serde_json::from_value::<(String, Option)>(event).expect("serializable state"); + let (route, state) = serde_json::from_value::<(String, Option)>(event) + .expect("serializable state"); let Ok(route) = R::from_str(&route.to_string()) else { return; }; let mut timeline = timeline.lock().expect("unpoisoned mutex"); let state = timeline.update(route.clone(), state); let state = serde_json::to_string(&state).expect("serializable state"); - let session = serde_json::to_string(&timeline.session()) - .expect("serializable session"); + let session = + serde_json::to_string(&timeline.session()).expect("serializable session"); let _ = create_eval(&format!( r#" // this does not trigger a PopState event history.replaceState({state}, "", "{route}"); sessionStorage.setItem("liveview", '{session}'); - "#)); + "# + )); // Call the updater callback (updater.read().unwrap())(); diff --git a/packages/router/src/history/web.rs b/packages/router/src/history/web.rs index 789eed76e..a0f677e24 100644 --- a/packages/router/src/history/web.rs +++ b/packages/router/src/history/web.rs @@ -13,6 +13,16 @@ use super::{ HistoryProvider, }; +#[allow(dead_code)] +fn base_path() -> Option<&'static str> { + let base_path = dioxus_cli_config::CURRENT_CONFIG + .as_ref() + .ok() + .and_then(|c| c.dioxus_config.web.app.base_path.as_deref()); + tracing::trace!("Using base_path from Dioxus.toml: {:?}", base_path); + base_path +} + #[cfg(not(feature = "serde"))] #[allow(clippy::extra_unused_type_parameters)] fn update_scroll(window: &Window, history: &History) { @@ -160,6 +170,10 @@ impl WebHistory { .expect("`history` can set scroll restoration"); } + let prefix = prefix + .or_else(|| base_path().map(|s| s.to_string())) + .map(|prefix| format!("/{}", prefix.trim_matches('/'))); + Self { do_scroll_restoration, history, @@ -198,6 +212,16 @@ where let location = self.window.location(); let path = location.pathname().unwrap_or_else(|_| "/".into()) + &location.search().unwrap_or("".into()); + let path = match self.prefix { + None => path, + Some(ref prefix) => { + if path.starts_with(prefix) { + path[prefix.len()..].to_string() + } else { + path + } + } + }; R::from_str(&path).unwrap_or_else(|err| panic!("{}", err)) } diff --git a/packages/router/src/hooks/use_navigator.rs b/packages/router/src/hooks/use_navigator.rs index 9d367d83d..a05cd036f 100644 --- a/packages/router/src/hooks/use_navigator.rs +++ b/packages/router/src/hooks/use_navigator.rs @@ -49,7 +49,6 @@ use crate::prelude::{Navigator, RouterContext}; /// # let _ = vdom.rebuild(); /// ``` #[must_use] -#[deprecated = "Prefer acquiring the router directly with `dioxus_router::router()`"] pub fn use_navigator(cx: &ScopeState) -> &Navigator { &*cx.use_hook(|| { let router = cx diff --git a/packages/router/src/router_cfg.rs b/packages/router/src/router_cfg.rs index dd379e493..e0d2ce358 100644 --- a/packages/router/src/router_cfg.rs +++ b/packages/router/src/router_cfg.rs @@ -53,10 +53,15 @@ where { pub(crate) fn get_history(self) -> Box> { self.history.unwrap_or_else(|| { - #[cfg(all(target_arch = "wasm32", feature = "web"))] + #[cfg(all(not(feature = "liveview"), target_arch = "wasm32", feature = "web"))] let history = Box::>::default(); - #[cfg(not(all(target_arch = "wasm32", feature = "web")))] + #[cfg(all( + not(feature = "liveview"), + any(not(target_arch = "wasm32"), not(feature = "web")) + ))] let history = Box::>::default(); + #[cfg(feature = "liveview")] + let history = Box::>::default(); history }) } @@ -83,9 +88,17 @@ where { pub(crate) fn take_history(&mut self) -> Box { self.history.take().unwrap_or_else(|| { + // If we are on wasm32 and the web feature is enabled, use the web history. #[cfg(all(target_arch = "wasm32", feature = "web"))] let history = Box::>>::default(); - #[cfg(not(all(target_arch = "wasm32", feature = "web")))] + // If we are not on wasm32 and the liveview feature is enabled, use the liveview history. + #[cfg(all(feature = "liveview", not(target_arch = "wasm32")))] + let history = Box::>>::default(); + // If neither of the above are true, use the memory history. + #[cfg(all( + not(all(target_arch = "wasm32", feature = "web")), + not(all(feature = "liveview", not(target_arch = "wasm32"))), + ))] let history = Box::>>::default(); history }) diff --git a/packages/rsx-rosetta/src/lib.rs b/packages/rsx-rosetta/src/lib.rs index 882cb333e..fe68f78ad 100644 --- a/packages/rsx-rosetta/src/lib.rs +++ b/packages/rsx-rosetta/src/lib.rs @@ -5,7 +5,8 @@ use convert_case::{Case, Casing}; use dioxus_html::{map_html_attribute_to_rsx, map_html_element_to_rsx}; use dioxus_rsx::{ - BodyNode, CallBody, Component, Element, ElementAttr, ElementAttrNamed, ElementName, IfmtInput, + AttributeType, BodyNode, CallBody, Component, Element, ElementAttr, ElementAttrNamed, + ElementName, IfmtInput, }; pub use html_parser::{Dom, Node}; use proc_macro2::{Ident, Span}; @@ -63,16 +64,16 @@ pub fn rsx_node_from_html(node: &Node) -> Option { } }; - ElementAttrNamed { + AttributeType::Named(ElementAttrNamed { el_name: el_name.clone(), attr, - } + }) }) .collect(); let class = el.classes.join(" "); if !class.is_empty() { - attributes.push(ElementAttrNamed { + attributes.push(AttributeType::Named(ElementAttrNamed { el_name: el_name.clone(), attr: ElementAttr { name: dioxus_rsx::ElementAttrName::BuiltIn(Ident::new( @@ -81,11 +82,11 @@ pub fn rsx_node_from_html(node: &Node) -> Option { )), value: dioxus_rsx::ElementAttrValue::AttrLiteral(ifmt_from_text(&class)), }, - }); + })); } if let Some(id) = &el.id { - attributes.push(ElementAttrNamed { + attributes.push(AttributeType::Named(ElementAttrNamed { el_name: el_name.clone(), attr: ElementAttr { name: dioxus_rsx::ElementAttrName::BuiltIn(Ident::new( @@ -94,7 +95,7 @@ pub fn rsx_node_from_html(node: &Node) -> Option { )), value: dioxus_rsx::ElementAttrValue::AttrLiteral(ifmt_from_text(id)), }, - }); + })); } let children = el.children.iter().filter_map(rsx_node_from_html).collect(); diff --git a/packages/rsx/Cargo.toml b/packages/rsx/Cargo.toml index 20893e7f4..32da1493a 100644 --- a/packages/rsx/Cargo.toml +++ b/packages/rsx/Cargo.toml @@ -14,7 +14,7 @@ keywords = ["dom", "ui", "gui", "react"] [dependencies] proc-macro2 = { version = "1.0", features = ["span-locations"] } -dioxus-core = { workspace = true} +dioxus-core = { workspace = true, optional = true } syn = { version = "2.0", features = ["full", "extra-traits"] } quote = { version = "1.0" } serde = { version = "1.0", features = ["derive"], optional = true } @@ -24,6 +24,6 @@ tracing.workspace = true [features] default = ["html"] -hot_reload = ["krates", "internment"] +hot_reload = ["krates", "internment", "dioxus-core"] serde = ["dep:serde"] html = [] diff --git a/packages/rsx/src/attribute.rs b/packages/rsx/src/attribute.rs index b6c6f94fb..e1408e3c1 100644 --- a/packages/rsx/src/attribute.rs +++ b/packages/rsx/src/attribute.rs @@ -4,14 +4,66 @@ use super::*; use proc_macro2::{Span, TokenStream as TokenStream2}; use quote::{quote, ToTokens, TokenStreamExt}; -use syn::{parse_quote, Expr, ExprIf, Ident, LitStr}; +use syn::{parse_quote, spanned::Spanned, Expr, ExprIf, Ident, LitStr}; #[derive(PartialEq, Eq, Clone, Debug, Hash)] +pub enum AttributeType { + Named(ElementAttrNamed), + Spread(Expr), +} + +impl AttributeType { + pub fn start(&self) -> Span { + match self { + AttributeType::Named(n) => n.attr.start(), + AttributeType::Spread(e) => e.span(), + } + } + + pub fn matches_attr_name(&self, other: &Self) -> bool { + match (self, other) { + (Self::Named(a), Self::Named(b)) => a.attr.name == b.attr.name, + _ => false, + } + } + + pub(crate) fn try_combine(&self, other: &Self) -> Option { + match (self, other) { + (Self::Named(a), Self::Named(b)) => a.try_combine(b).map(Self::Named), + _ => None, + } + } +} + +impl ToTokens for AttributeType { + fn to_tokens(&self, tokens: &mut TokenStream2) { + match self { + AttributeType::Named(n) => tokens.append_all(quote! { #n }), + AttributeType::Spread(e) => tokens.append_all(quote! { (&#e).into() }), + } + } +} + +#[derive(Clone, Debug)] pub struct ElementAttrNamed { pub el_name: ElementName, pub attr: ElementAttr, } +impl Hash for ElementAttrNamed { + fn hash(&self, state: &mut H) { + self.attr.name.hash(state); + } +} + +impl PartialEq for ElementAttrNamed { + fn eq(&self, other: &Self) -> bool { + self.attr == other.attr + } +} + +impl Eq for ElementAttrNamed {} + impl ElementAttrNamed { pub(crate) fn try_combine(&self, other: &Self) -> Option { if self.el_name == other.el_name && self.attr.name == other.attr.name { @@ -57,16 +109,25 @@ impl ToTokens for ElementAttrNamed { }; let attribute = { + let value = &self.attr.value; + let is_shorthand_event = match &attr.value { + ElementAttrValue::Shorthand(s) => s.to_string().starts_with("on"), + _ => false, + }; + match &attr.value { ElementAttrValue::AttrLiteral(_) | ElementAttrValue::AttrExpr(_) - | ElementAttrValue::AttrOptionalExpr { .. } => { + | ElementAttrValue::Shorthand(_) + | ElementAttrValue::AttrOptionalExpr { .. } + if !is_shorthand_event => + { let name = &self.attr.name; let ns = ns(name); let volitile = volitile(name); let attribute = attribute(name); - let value = &self.attr.value; let value = quote! { #value }; + quote! { ::dioxus::core::Attribute::new( #attribute, @@ -84,6 +145,9 @@ impl ToTokens for ElementAttrNamed { } ElementAttrName::Custom(_) => todo!(), }, + _ => { + quote! { dioxus_elements::events::#value(__cx, #value) } + } } }; @@ -99,6 +163,8 @@ pub struct ElementAttr { #[derive(PartialEq, Eq, Clone, Debug, Hash)] pub enum ElementAttrValue { + /// attribute, + Shorthand(Ident), /// attribute: "value" AttrLiteral(IfmtInput), /// attribute: if bool { "value" } @@ -114,7 +180,7 @@ pub enum ElementAttrValue { impl Parse for ElementAttrValue { fn parse(input: ParseStream) -> syn::Result { - Ok(if input.peek(Token![if]) { + let element_attr_value = if input.peek(Token![if]) { let if_expr = input.parse::()?; if is_if_chain_terminated(&if_expr) { ElementAttrValue::AttrExpr(Expr::If(if_expr)) @@ -135,13 +201,16 @@ impl Parse for ElementAttrValue { } else { let value = input.parse::()?; ElementAttrValue::AttrExpr(value) - }) + }; + + Ok(element_attr_value) } } impl ToTokens for ElementAttrValue { fn to_tokens(&self, tokens: &mut TokenStream2) { match self { + ElementAttrValue::Shorthand(i) => tokens.append_all(quote! { #i }), ElementAttrValue::AttrLiteral(lit) => tokens.append_all(quote! { #lit }), ElementAttrValue::AttrOptionalExpr { condition, value } => { tokens.append_all(quote! { if #condition { Some(#value) } else { None } }) diff --git a/packages/rsx/src/component.rs b/packages/rsx/src/component.rs index 1865f9857..31091c113 100644 --- a/packages/rsx/src/component.rs +++ b/packages/rsx/src/component.rs @@ -19,6 +19,7 @@ use syn::{ ext::IdentExt, parse::{Parse, ParseBuffer, ParseStream}, spanned::Spanned, + token::Brace, AngleBracketedGenericArguments, Error, Expr, Ident, LitStr, PathArguments, Result, Token, }; @@ -32,8 +33,85 @@ pub struct Component { pub brace: syn::token::Brace, } +impl Parse for Component { + fn parse(stream: ParseStream) -> Result { + let mut name = stream.parse::()?; + Component::validate_component_path(&name)?; + + // extract the path arguments from the path into prop_gen_args + let prop_gen_args = normalize_path(&mut name); + + let content: ParseBuffer; + let brace = syn::braced!(content in stream); + + let mut fields = Vec::new(); + let mut children = Vec::new(); + let mut manual_props = None; + + while !content.is_empty() { + // if we splat into a component then we're merging properties + if content.peek(Token![..]) { + content.parse::()?; + manual_props = Some(content.parse()?); + } else if + // Named fields + (content.peek(Ident) && content.peek2(Token![:]) && !content.peek3(Token![:])) + // shorthand struct initialization + // Not a div {}, mod::Component {}, or web-component {} + || (content.peek(Ident) + && !content.peek2(Brace) + && !content.peek2(Token![:]) + && !content.peek2(Token![-])) + { + fields.push(content.parse()?); + } else { + children.push(content.parse()?); + } + + if content.peek(Token![,]) { + let _ = content.parse::(); + } + } + + Ok(Self { + name, + prop_gen_args, + fields, + children, + manual_props, + brace, + }) + } +} + +impl ToTokens for Component { + fn to_tokens(&self, tokens: &mut TokenStream2) { + let Self { + name, + prop_gen_args, + .. + } = self; + + let builder = self + .manual_props + .as_ref() + .map(|props| self.collect_manual_props(props)) + .unwrap_or_else(|| self.collect_props()); + + let fn_name = self.fn_name(); + + tokens.append_all(quote! { + ::dioxus::core::DynamicNode::Component(::dioxus::core::VComponent::new( + #name #prop_gen_args, + #builder, + #fn_name + )) + }) + } +} + impl Component { - pub fn validate_component_path(path: &syn::Path) -> Result<()> { + fn validate_component_path(path: &syn::Path) -> Result<()> { // ensure path segments doesn't have PathArguments, only the last // segment is allowed to have one. if path @@ -67,134 +145,53 @@ impl Component { _ => None, } } -} -impl Parse for Component { - fn parse(stream: ParseStream) -> Result { - let mut name = stream.parse::()?; - Component::validate_component_path(&name)?; - - // extract the path arguments from the path into prop_gen_args - let prop_gen_args = name.segments.last_mut().and_then(|seg| { - if let PathArguments::AngleBracketed(args) = seg.arguments.clone() { - seg.arguments = PathArguments::None; - Some(args) - } else { - None + fn collect_manual_props(&self, manual_props: &Expr) -> TokenStream2 { + let mut toks = quote! { let mut __manual_props = #manual_props; }; + for field in &self.fields { + if field.name == "key" { + continue; } - }); + let ComponentField { name, content } = field; + toks.append_all(quote! { __manual_props.#name = #content; }); + } + toks.append_all(quote! { __manual_props }); + quote! {{ #toks }} + } - let content: ParseBuffer; + fn collect_props(&self) -> TokenStream2 { + let name = &self.name; - // if we see a `{` then we have a block - // else parse as a function-like call - let brace = syn::braced!(content in stream); - - let mut fields = Vec::new(); - let mut children = Vec::new(); - let mut manual_props = None; - - while !content.is_empty() { - // if we splat into a component then we're merging properties - if content.peek(Token![..]) { - content.parse::()?; - manual_props = Some(content.parse::()?); - } else if content.peek(Ident) && content.peek2(Token![:]) && !content.peek3(Token![:]) { - fields.push(content.parse::()?); - } else { - children.push(content.parse::()?); - } - - if content.peek(Token![,]) { - let _ = content.parse::(); + let mut toks = match &self.prop_gen_args { + Some(gen_args) => quote! { fc_to_builder(__cx, #name #gen_args) }, + None => quote! { fc_to_builder(__cx, #name) }, + }; + for field in &self.fields { + match field.name.to_string().as_str() { + "key" => {} + _ => toks.append_all(quote! {#field}), } } + if !self.children.is_empty() { + let renderer: TemplateRenderer = TemplateRenderer { + roots: &self.children, + location: None, + }; - Ok(Self { - name, - prop_gen_args, - fields, - children, - manual_props, - brace, - }) + toks.append_all(quote! { + .children( + Some({ #renderer }) + ) + }); + } + toks.append_all(quote! { + .build() + }); + toks } -} -impl ToTokens for Component { - fn to_tokens(&self, tokens: &mut TokenStream2) { - let name = &self.name; - let prop_gen_args = &self.prop_gen_args; - - let builder = match &self.manual_props { - Some(manual_props) => { - let mut toks = quote! { - let mut __manual_props = #manual_props; - }; - for field in &self.fields { - if field.name == "key" { - // skip keys - } else { - let name = &field.name; - let val = &field.content; - toks.append_all(quote! { - __manual_props.#name = #val; - }); - } - } - toks.append_all(quote! { - __manual_props - }); - quote! {{ - #toks - }} - } - None => { - let mut toks = match prop_gen_args { - Some(gen_args) => quote! { fc_to_builder(#name #gen_args) }, - None => quote! { fc_to_builder(#name) }, - }; - for field in &self.fields { - match field.name.to_string().as_str() { - "key" => {} - _ => toks.append_all(quote! {#field}), - } - } - - if !self.children.is_empty() { - let renderer: TemplateRenderer = TemplateRenderer { - roots: &self.children, - location: None, - }; - - toks.append_all(quote! { - .children( - Some({ #renderer }) - ) - }); - } - - toks.append_all(quote! { - .build() - }); - toks - } - }; - - let fn_name = self.name.segments.last().unwrap().ident.to_string(); - - let gen_name = match &self.prop_gen_args { - Some(gen) => quote! { #name #gen }, - None => quote! { #name }, - }; - - tokens.append_all(quote! { - ::dioxus::core::DynamicNode::Component(::dioxus::core::VComponent::new( - #gen_name, - #builder, - #fn_name - )) - }) + fn fn_name(&self) -> String { + self.name.segments.last().unwrap().ident.to_string() } } @@ -207,14 +204,47 @@ pub struct ComponentField { #[derive(PartialEq, Eq, Clone, Debug, Hash)] pub enum ContentField { + Shorthand(Ident), ManExpr(Expr), Formatted(IfmtInput), OnHandlerRaw(Expr), } +impl ContentField { + fn new_from_name(name: &Ident, input: ParseStream) -> Result { + if name.to_string().starts_with("on") { + return Ok(ContentField::OnHandlerRaw(input.parse()?)); + } + + if *name == "key" { + return Ok(ContentField::Formatted(input.parse()?)); + } + + if input.peek(LitStr) { + let forked = input.fork(); + let t: LitStr = forked.parse()?; + + // the string literal must either be the end of the input or a followed by a comma + let res = + match (forked.is_empty() || forked.peek(Token![,])) && is_literal_foramtted(&t) { + true => ContentField::Formatted(input.parse()?), + false => ContentField::ManExpr(input.parse()?), + }; + + return Ok(res); + } + + Ok(ContentField::ManExpr(input.parse()?)) + } +} + impl ToTokens for ContentField { fn to_tokens(&self, tokens: &mut TokenStream2) { match self { + ContentField::Shorthand(i) if i.to_string().starts_with("on") => { + tokens.append_all(quote! { EventHandler::new(#i) }) + } + ContentField::Shorthand(i) => tokens.append_all(quote! { #i }), ContentField::ManExpr(e) => e.to_tokens(tokens), ContentField::Formatted(s) => tokens.append_all(quote! { #s @@ -229,30 +259,21 @@ impl ToTokens for ContentField { impl Parse for ComponentField { fn parse(input: ParseStream) -> Result { let name = Ident::parse_any(input)?; - input.parse::()?; - let content = { - if name.to_string().starts_with("on") { - ContentField::OnHandlerRaw(input.parse()?) - } else if name == "key" { - let content = ContentField::Formatted(input.parse()?); - return Ok(Self { name, content }); - } else if input.peek(LitStr) { - let forked = input.fork(); - let t: LitStr = forked.parse()?; - // the string literal must either be the end of the input or a followed by a comma - if (forked.is_empty() || forked.peek(Token![,])) && is_literal_foramtted(&t) { - ContentField::Formatted(input.parse()?) - } else { - ContentField::ManExpr(input.parse()?) - } - } else { - ContentField::ManExpr(input.parse()?) - } + // if the next token is not a colon, then it's a shorthand field + if input.parse::().is_err() { + return Ok(Self { + content: ContentField::Shorthand(name.clone()), + name, + }); }; + + let content = ContentField::new_from_name(&name, input)?; + if input.peek(LitStr) || input.peek(Ident) { missing_trailing_comma!(content.span()); } + Ok(Self { name, content }) } } @@ -260,9 +281,7 @@ impl Parse for ComponentField { impl ToTokens for ComponentField { fn to_tokens(&self, tokens: &mut TokenStream2) { let ComponentField { name, content, .. } = self; - tokens.append_all(quote! { - .#name(#content) - }) + tokens.append_all(quote! { .#name(#content) }) } } @@ -281,3 +300,14 @@ fn is_literal_foramtted(lit: &LitStr) -> bool { false } + +fn normalize_path(name: &mut syn::Path) -> Option { + let seg = name.segments.last_mut()?; + match seg.arguments.clone() { + PathArguments::AngleBracketed(args) => { + seg.arguments = PathArguments::None; + Some(args) + } + _ => None, + } +} diff --git a/packages/rsx/src/element.rs b/packages/rsx/src/element.rs index 3e14c41f8..9cd7958f5 100644 --- a/packages/rsx/src/element.rs +++ b/packages/rsx/src/element.rs @@ -8,7 +8,8 @@ use syn::{ parse::{Parse, ParseBuffer, ParseStream}, punctuated::Punctuated, spanned::Spanned, - Ident, LitStr, Result, Token, + token::Brace, + Expr, Ident, LitStr, Result, Token, }; // ======================================= @@ -18,8 +19,8 @@ use syn::{ pub struct Element { pub name: ElementName, pub key: Option, - pub attributes: Vec, - pub merged_attributes: Vec, + pub attributes: Vec, + pub merged_attributes: Vec, pub children: Vec, pub brace: syn::token::Brace, } @@ -32,7 +33,7 @@ impl Parse for Element { let content: ParseBuffer; let brace = syn::braced!(content in stream); - let mut attributes: Vec = vec![]; + let mut attributes: Vec = vec![]; let mut children: Vec = vec![]; let mut key = None; @@ -42,7 +43,24 @@ impl Parse for Element { // "def": 456, // abc: 123, loop { + if content.peek(Token![..]) { + content.parse::()?; + let expr = content.parse::()?; + let span = expr.span(); + attributes.push(attribute::AttributeType::Spread(expr)); + + if content.is_empty() { + break; + } + + if content.parse::().is_err() { + missing_trailing_comma!(span); + } + continue; + } + // Parse the raw literal fields + // "def": 456, if content.peek(LitStr) && content.peek2(Token![:]) && !content.peek3(Token![:]) { let name = content.parse::()?; let ident = name.clone(); @@ -50,13 +68,13 @@ impl Parse for Element { content.parse::()?; let value = content.parse::()?; - attributes.push(ElementAttrNamed { + attributes.push(attribute::AttributeType::Named(ElementAttrNamed { el_name: el_name.clone(), attr: ElementAttr { name: ElementAttrName::Custom(name), value, }, - }); + })); if content.is_empty() { break; @@ -68,6 +86,8 @@ impl Parse for Element { continue; } + // Parse + // abc: 123, if content.peek(Ident) && content.peek2(Token![:]) && !content.peek3(Token![:]) { let name = content.parse::()?; @@ -79,60 +99,120 @@ impl Parse for Element { let span = content.span(); if name_str.starts_with("on") { - attributes.push(ElementAttrNamed { + // check for any duplicate event listeners + if attributes.iter().any(|f| { + if let AttributeType::Named(ElementAttrNamed { + attr: + ElementAttr { + name: ElementAttrName::BuiltIn(n), + value: ElementAttrValue::EventTokens(_), + }, + .. + }) = f + { + n == &name_str + } else { + false + } + }) { + return Err(syn::Error::new( + name.span(), + format!("Duplicate event listener `{}`", name), + )); + } + attributes.push(attribute::AttributeType::Named(ElementAttrNamed { el_name: el_name.clone(), attr: ElementAttr { name: ElementAttrName::BuiltIn(name), value: ElementAttrValue::EventTokens(content.parse()?), }, - }); + })); + } else if name_str == "key" { + key = Some(content.parse()?); } else { - match name_str.as_str() { - "key" => { - key = Some(content.parse()?); - } - _ => { - let value = content.parse::()?; - attributes.push(ElementAttrNamed { - el_name: el_name.clone(), - attr: ElementAttr { - name: ElementAttrName::BuiltIn(name), - value, - }, - }); - } - } + let value = content.parse::()?; + attributes.push(attribute::AttributeType::Named(ElementAttrNamed { + el_name: el_name.clone(), + attr: ElementAttr { + name: ElementAttrName::BuiltIn(name), + value, + }, + })); } if content.is_empty() { break; } - // todo: add a message saying you need to include commas between fields if content.parse::().is_err() { missing_trailing_comma!(span); } continue; } + // Parse shorthand fields + if content.peek(Ident) + && !content.peek2(Brace) + && !content.peek2(Token![:]) + && !content.peek2(Token![-]) + { + let name = content.parse::()?; + let name_ = name.clone(); + + // If the shorthand field is children, these are actually children! + if name == "children" { + return Err(syn::Error::new( + name.span(), + r#"Shorthand element children are not supported. +To pass children into elements, wrap them in curly braces. +Like so: + div {{ {{children}} }} + +"#, + )); + }; + + let value = ElementAttrValue::Shorthand(name.clone()); + attributes.push(attribute::AttributeType::Named(ElementAttrNamed { + el_name: el_name.clone(), + attr: ElementAttr { + name: ElementAttrName::BuiltIn(name), + value, + }, + })); + + if content.is_empty() { + break; + } + + if content.parse::().is_err() { + missing_trailing_comma!(name_.span()); + } + continue; + } + break; } // Deduplicate any attributes that can be combined // For example, if there are two `class` attributes, combine them into one - let mut merged_attributes: Vec = Vec::new(); + let mut merged_attributes: Vec = Vec::new(); for attr in &attributes { - if let Some(old_attr_index) = merged_attributes + let attr_index = merged_attributes .iter() - .position(|a| a.attr.name == attr.attr.name) - { + .position(|a| a.matches_attr_name(attr)); + + if let Some(old_attr_index) = attr_index { let old_attr = &mut merged_attributes[old_attr_index]; + if let Some(combined) = old_attr.try_combine(attr) { *old_attr = combined; } - } else { - merged_attributes.push(attr.clone()); + + continue; } + + merged_attributes.push(attr.clone()); } while !content.is_empty() { @@ -173,15 +253,31 @@ impl ToTokens for Element { None => quote! { None }, }; - let listeners = self - .merged_attributes - .iter() - .filter(|f| matches!(f.attr.value, ElementAttrValue::EventTokens { .. })); + let listeners = self.merged_attributes.iter().filter(|f| { + matches!( + f, + AttributeType::Named(ElementAttrNamed { + attr: ElementAttr { + value: ElementAttrValue::EventTokens { .. }, + .. + }, + .. + }) + ) + }); - let attr = self - .merged_attributes - .iter() - .filter(|f| !matches!(f.attr.value, ElementAttrValue::EventTokens { .. })); + let attr = self.merged_attributes.iter().filter(|f| { + !matches!( + f, + AttributeType::Named(ElementAttrNamed { + attr: ElementAttr { + value: ElementAttrValue::EventTokens { .. }, + .. + }, + .. + }) + ) + }); tokens.append_all(quote! { ::dioxus::core::Element::new( diff --git a/packages/rsx/src/lib.rs b/packages/rsx/src/lib.rs index 884794937..74578b59b 100644 --- a/packages/rsx/src/lib.rs +++ b/packages/rsx/src/lib.rs @@ -252,7 +252,9 @@ impl<'a> ToTokens for TemplateRenderer<'a> { node_paths: &[ #(#node_paths),* ], attr_paths: &[ #(#attr_paths),* ], }; - ::dioxus::core::VNode::new( + + __cx.vnode( + None.into(), #key_tokens, TEMPLATE, Box::new([ #( #node_printer ),* ]), @@ -265,7 +267,7 @@ impl<'a> ToTokens for TemplateRenderer<'a> { #[cfg(feature = "hot_reload")] #[derive(Default, Debug)] struct DynamicMapping { - attribute_to_idx: std::collections::HashMap>, + attribute_to_idx: std::collections::HashMap>, last_attribute_idx: usize, node_to_idx: std::collections::HashMap>, last_element_idx: usize, @@ -281,7 +283,7 @@ impl DynamicMapping { new } - fn get_attribute_idx(&mut self, attr: &ElementAttr) -> Option { + fn get_attribute_idx(&mut self, attr: &AttributeType) -> Option { self.attribute_to_idx .get_mut(attr) .and_then(|idxs| idxs.pop()) @@ -291,7 +293,7 @@ impl DynamicMapping { self.node_to_idx.get_mut(node).and_then(|idxs| idxs.pop()) } - fn insert_attribute(&mut self, attr: ElementAttr) -> usize { + fn insert_attribute(&mut self, attr: AttributeType) -> usize { let idx = self.last_attribute_idx; self.last_attribute_idx += 1; @@ -313,10 +315,17 @@ impl DynamicMapping { match node { BodyNode::Element(el) => { for attr in el.merged_attributes { - match &attr.attr.value { - ElementAttrValue::AttrLiteral(input) if input.is_static() => {} + match &attr { + AttributeType::Named(ElementAttrNamed { + attr: + ElementAttr { + value: ElementAttrValue::AttrLiteral(input), + .. + }, + .. + }) if input.is_static() => {} _ => { - self.insert_attribute(attr.attr); + self.insert_attribute(attr); } } } @@ -344,7 +353,7 @@ impl DynamicMapping { #[derive(Default, Debug)] pub struct DynamicContext<'a> { dynamic_nodes: Vec<&'a BodyNode>, - dynamic_attributes: Vec<&'a ElementAttrNamed>, + dynamic_attributes: Vec<&'a AttributeType>, current_path: Vec, node_paths: Vec>, @@ -364,10 +373,16 @@ impl<'a> DynamicContext<'a> { let mut static_attrs = Vec::new(); for attr in &el.merged_attributes { - match &attr.attr.value { - ElementAttrValue::AttrLiteral(value) if value.is_static() => { + match &attr { + AttributeType::Named(ElementAttrNamed { + attr: + ElementAttr { + value: ElementAttrValue::AttrLiteral(value), + name, + }, + .. + }) if value.is_static() => { let value = value.source.as_ref().unwrap(); - let name = &attr.attr.name; let attribute_name_rust = name.to_string(); let (name, namespace) = Ctx::map_attribute(&element_name_rust, &attribute_name_rust) @@ -381,7 +396,7 @@ impl<'a> DynamicContext<'a> { _ => { let idx = match mapping { - Some(mapping) => mapping.get_attribute_idx(&attr.attr)?, + Some(mapping) => mapping.get_attribute_idx(attr)?, None => self.dynamic_attributes.len(), }; self.dynamic_attributes.push(attr); @@ -451,47 +466,50 @@ impl<'a> DynamicContext<'a> { ElementName::Ident(i) => quote! { dioxus_elements::#i::#name }, ElementName::Custom(_) => quote! { None }, }; - let static_attrs = el - .merged_attributes - .iter() - .map(|attr| match &attr.attr.value { - ElementAttrValue::AttrLiteral(value) if value.is_static() => { - let value = value.to_static().unwrap(); - let ns = { - match &attr.attr.name { - ElementAttrName::BuiltIn(name) => ns(quote!(#name.1)), - ElementAttrName::Custom(_) => quote!(None), - } - }; - let name = &attr.attr.name; - let name = match (el_name, name) { - (ElementName::Ident(_), ElementAttrName::BuiltIn(_)) => { - quote! { #el_name::#name.0 } - } - _ => { - let as_string = name.to_string(); - quote! { #as_string } - } - }; - quote! { - ::dioxus::core::TemplateAttribute::Static { - name: #name, - namespace: #ns, - value: #value, + let static_attrs = el.merged_attributes.iter().map(|attr| match attr { + AttributeType::Named(ElementAttrNamed { + attr: + ElementAttr { + value: ElementAttrValue::AttrLiteral(value), + name, + }, + .. + }) if value.is_static() => { + let value = value.to_static().unwrap(); + let ns = { + match name { + ElementAttrName::BuiltIn(name) => ns(quote!(#name.1)), + ElementAttrName::Custom(_) => quote!(None), + } + }; + let name = match (el_name, name) { + (ElementName::Ident(_), ElementAttrName::BuiltIn(_)) => { + quote! { #el_name::#name.0 } + } + _ => { + let as_string = name.to_string(); + quote! { #as_string } + } + }; + quote! { + ::dioxus::core::TemplateAttribute::Static { + name: #name, + namespace: #ns, + value: #value, - // todo: we don't diff these so we never apply the volatile flag - // volatile: dioxus_elements::#el_name::#name.2, - } + // todo: we don't diff these so we never apply the volatile flag + // volatile: dioxus_elements::#el_name::#name.2, } } + } - _ => { - let ct = self.dynamic_attributes.len(); - self.dynamic_attributes.push(attr); - self.attr_paths.push(self.current_path.clone()); - quote! { ::dioxus::core::TemplateAttribute::Dynamic { id: #ct } } - } - }); + _ => { + let ct = self.dynamic_attributes.len(); + self.dynamic_attributes.push(attr); + self.attr_paths.push(self.current_path.clone()); + quote! { ::dioxus::core::TemplateAttribute::Dynamic { id: #ct } } + } + }); let attrs = quote! { #(#static_attrs),*}; @@ -555,7 +573,7 @@ fn create_template() { p { "hello world" } - (0..10).map(|i| rsx!{"{i}"}) + {(0..10).map(|i| rsx!{"{i}"})} } }; @@ -647,9 +665,9 @@ fn diff_template() { p { "hello world" } - (0..10).map(|i| rsx!{"{i}"}), - (0..10).map(|i| rsx!{"{i}"}), - (0..11).map(|i| rsx!{"{i}"}), + {(0..10).map(|i| rsx!{"{i}"})}, + {(0..10).map(|i| rsx!{"{i}"})}, + {(0..11).map(|i| rsx!{"{i}"})}, Comp{} } }; @@ -693,9 +711,9 @@ fn diff_template() { "height2": "100px", width: 100, Comp{} - (0..11).map(|i| rsx!{"{i}"}), - (0..10).map(|i| rsx!{"{i}"}), - (0..10).map(|i| rsx!{"{i}"}), + {(0..11).map(|i| rsx!{"{i}"})}, + {(0..10).map(|i| rsx!{"{i}"})}, + {(0..10).map(|i| rsx!{"{i}"})}, p { "hello world" } diff --git a/packages/rsx/src/node.rs b/packages/rsx/src/node.rs index 3d98031ba..a85b727dc 100644 --- a/packages/rsx/src/node.rs +++ b/packages/rsx/src/node.rs @@ -6,7 +6,8 @@ use syn::{ braced, parse::{Parse, ParseStream}, spanned::Spanned, - token, Expr, ExprIf, LitStr, Pat, Result, + token::{self, Brace}, + Expr, ExprIf, LitStr, Pat, Result, }; /* @@ -15,14 +16,14 @@ Parse -> Component {} -> component() -> "text {with_args}" --> (0..10).map(|f| rsx!("asd")), // <--- notice the comma - must be a complete expr +-> {(0..10).map(|f| rsx!("asd"))} // <--- notice the curly braces */ #[derive(PartialEq, Eq, Clone, Debug, Hash)] pub enum BodyNode { Element(Element), Component(Component), ForLoop(ForLoop), - IfChain(ExprIf), + IfChain(IfChain), Text(IfmtInput), RawExpr(Expr), } @@ -97,7 +98,6 @@ impl Parse for BodyNode { // Input:: {} // crate::Input:: {} if body_stream.peek(token::Brace) { - Component::validate_component_path(&path)?; return Ok(BodyNode::Component(stream.parse()?)); } } @@ -112,7 +112,27 @@ impl Parse for BodyNode { return Ok(BodyNode::IfChain(stream.parse()?)); } - Ok(BodyNode::RawExpr(stream.parse::()?)) + // Match statements are special but have no special arm syntax + // we could allow arm syntax if we wanted + // + // ``` + // match { + // val => div {} + // other_val => div {} + // } + // ``` + if stream.peek(Token![match]) { + return Ok(BodyNode::RawExpr(stream.parse::()?)); + } + + if stream.peek(token::Brace) { + return Ok(BodyNode::RawExpr(stream.parse::()?)); + } + + Err(syn::Error::new( + stream.span(), + "Expected a valid body node.\nExpressions must be wrapped in curly braces.", + )) } } @@ -151,71 +171,52 @@ impl ToTokens for BodyNode { }) } BodyNode::IfChain(chain) => { - if is_if_chain_terminated(chain) { - tokens.append_all(quote! { - { - let ___nodes = (#chain).into_dyn_node(); - ___nodes - } - }); - } else { - let ExprIf { + let mut body = TokenStream2::new(); + let mut terminated = false; + + let mut elif = Some(chain); + + while let Some(chain) = elif { + let IfChain { + if_token, cond, then_branch, + else_if_branch, else_branch, - .. } = chain; - let mut body = TokenStream2::new(); + let mut renderer: TemplateRenderer = TemplateRenderer { + roots: then_branch, + location: None, + }; - body.append_all(quote! { - if #cond { - Some(#then_branch) - } - }); + body.append_all(quote! { #if_token #cond { Some({#renderer}) } }); - let mut elif = else_branch; - - while let Some((_, ref branch)) = elif { - match branch.as_ref() { - Expr::If(ref eelif) => { - let ExprIf { - cond, - then_branch, - else_branch, - .. - } = eelif; - - body.append_all(quote! { - else if #cond { - Some(#then_branch) - } - }); - - elif = else_branch; - } - _ => { - body.append_all(quote! { - else { - #branch - } - }); - break; - } - } + if let Some(next) = else_if_branch { + body.append_all(quote! { else }); + elif = Some(next); + } else if let Some(else_branch) = else_branch { + renderer.roots = else_branch; + body.append_all(quote! { else { Some({#renderer}) } }); + terminated = true; + break; + } else { + elif = None; } + } + if !terminated { body.append_all(quote! { else { None } }); - - tokens.append_all(quote! { - { - let ___nodes = (#body).into_dyn_node(); - ___nodes - } - }); } + + tokens.append_all(quote! { + { + let ___nodes = (#body).into_dyn_node(__cx); + ___nodes + } + }); } } } @@ -240,26 +241,73 @@ impl Parse for ForLoop { let in_token: Token![in] = input.parse()?; let expr: Expr = input.call(Expr::parse_without_eager_brace)?; - let content; - let brace_token = braced!(content in input); - - let mut children = vec![]; - - while !content.is_empty() { - children.push(content.parse()?); - } + let (brace_token, body) = parse_buffer_as_braced_children(input)?; Ok(Self { for_token, pat, in_token, - body: children, - expr: Box::new(expr), + body, brace_token, + expr: Box::new(expr), }) } } +#[derive(PartialEq, Eq, Clone, Debug, Hash)] +pub struct IfChain { + pub if_token: Token![if], + pub cond: Box, + pub then_branch: Vec, + pub else_if_branch: Option>, + pub else_branch: Option>, +} + +impl Parse for IfChain { + fn parse(input: ParseStream) -> Result { + let if_token: Token![if] = input.parse()?; + + // stolen from ExprIf + let cond = Box::new(input.call(Expr::parse_without_eager_brace)?); + + let (_, then_branch) = parse_buffer_as_braced_children(input)?; + + let mut else_branch = None; + let mut else_if_branch = None; + + // if the next token is `else`, set the else branch as the next if chain + if input.peek(Token![else]) { + input.parse::()?; + if input.peek(Token![if]) { + else_if_branch = Some(Box::new(input.parse::()?)); + } else { + let (_, else_branch_nodes) = parse_buffer_as_braced_children(input)?; + else_branch = Some(else_branch_nodes); + } + } + + Ok(Self { + cond, + if_token, + then_branch, + else_if_branch, + else_branch, + }) + } +} + +fn parse_buffer_as_braced_children( + input: &syn::parse::ParseBuffer<'_>, +) -> Result<(Brace, Vec)> { + let content; + let brace_token = braced!(content in input); + let mut then_branch = vec![]; + while !content.is_empty() { + then_branch.push(content.parse()?); + } + Ok((brace_token, then_branch)) +} + pub(crate) fn is_if_chain_terminated(chain: &ExprIf) -> bool { let mut current = chain; loop { diff --git a/packages/ssr/Cargo.toml b/packages/ssr/Cargo.toml index fac0907e1..b577fe4f5 100644 --- a/packages/ssr/Cargo.toml +++ b/packages/ssr/Cargo.toml @@ -17,13 +17,12 @@ rustc-hash = "1.1.0" lru = "0.10.0" tracing = { workspace = true } http = "0.2.9" -tokio = { version = "1.28", features = ["full"], optional = true } +tokio = { version = "1.28", features = ["fs", "io-util"], optional = true } async-trait = "0.1.58" serde_json = { version = "1.0" } [dev-dependencies] dioxus = { workspace = true } -thiserror = { workspace = true } tracing = { workspace = true } fern = { version = "0.6.0", features = ["colored"] } anyhow = "1.0" diff --git a/packages/ssr/src/renderer.rs b/packages/ssr/src/renderer.rs index 6b5f012c0..59ae4ed9e 100644 --- a/packages/ssr/src/renderer.rs +++ b/packages/ssr/src/renderer.rs @@ -92,27 +92,29 @@ impl Renderer { match segment { Segment::Attr(idx) => { let attr = &template.dynamic_attrs[*idx]; - if attr.name == "dangerous_inner_html" { - inner_html = Some(attr); - } else if attr.namespace == Some("style") { - accumulated_dynamic_styles.push(attr); - } else if BOOL_ATTRS.contains(&attr.name) { - if truthy(&attr.value) { - write!(buf, " {}=", attr.name)?; - write_value(buf, &attr.value)?; + attr.attribute_type().try_for_each(|attr| { + if attr.name == "dangerous_inner_html" { + inner_html = Some(attr); + } else if attr.namespace == Some("style") { + accumulated_dynamic_styles.push(attr); + } else if BOOL_ATTRS.contains(&attr.name) { + if truthy(&attr.value) { + write_attribute(buf, attr)?; + } + } else { + write_attribute(buf, attr)?; } - } else { - write_attribute(buf, attr)?; - } - if self.pre_render { - if let AttributeValue::Listener(_) = &attr.value { - // The onmounted event doesn't need a DOM listener - if attr.name != "onmounted" { - accumulated_listeners.push(attr.name); + if self.pre_render { + if let AttributeValue::Listener(_) = &attr.value { + // The onmounted event doesn't need a DOM listener + if attr.name != "onmounted" { + accumulated_listeners.push(attr.name); + } } } - } + Ok(()) + })?; } Segment::Node(idx) => match &template.dynamic_nodes[*idx] { DynamicNode::Component(node) => { @@ -240,7 +242,9 @@ fn to_string_works() { div {} div { "nest 2" } "{dyn2}" - (0..5).map(|i| render! { div { "finalize {i}" } }) + for i in (0..5) { + div { "finalize {i}" } + } } } } @@ -401,16 +405,6 @@ pub(crate) fn write_attribute(buf: &mut impl Write, attr: &Attribute) -> std::fm } } -pub(crate) fn write_value(buf: &mut impl Write, value: &AttributeValue) -> std::fmt::Result { - match value { - AttributeValue::Text(value) => write!(buf, "\"{}\"", value), - AttributeValue::Bool(value) => write!(buf, "{}", value), - AttributeValue::Int(value) => write!(buf, "{}", value), - AttributeValue::Float(value) => write!(buf, "{}", value), - _ => Ok(()), - } -} - pub(crate) fn write_value_unquoted( buf: &mut impl Write, value: &AttributeValue, diff --git a/packages/ssr/tests/hydration.rs b/packages/ssr/tests/hydration.rs index 27c3743bc..32ed071d5 100644 --- a/packages/ssr/tests/hydration.rs +++ b/packages/ssr/tests/hydration.rs @@ -70,7 +70,7 @@ fn text_nodes() { fn app(_: ()) -> Element { let dynamic_text = "hello"; render! { - div { dynamic_text } + div { {dynamic_text} } } } @@ -124,7 +124,7 @@ fn components_hydrate() { fn Child2(_: ()) -> Element { let dyn_text = "hello"; render! { - div { dyn_text } + div { {dyn_text} } } } @@ -159,11 +159,7 @@ fn components_hydrate() { fn Child4(_: ()) -> Element { render! { for _ in 0..2 { - render! { - render! { - "{1}" - } - } + {render! { "{1}" }} } } } diff --git a/packages/ssr/tests/simple.rs b/packages/ssr/tests/simple.rs index 8449e97a0..955519a2d 100644 --- a/packages/ssr/tests/simple.rs +++ b/packages/ssr/tests/simple.rs @@ -24,7 +24,7 @@ fn lists() { ul { (0..5).map(|i| render! { li { "item {i}" } - }) + } } }), "
  • item 0
  • item 1
  • item 2
  • item 3
  • item 4
" @@ -58,7 +58,7 @@ fn components() { div { (0..5).map(|name| render! { MyComponent { name: name } - }) + } } }), "
component 0
component 1
component 2
component 3
component 4
" diff --git a/packages/web/BUGS.md b/packages/web/BUGS.md deleted file mode 100644 index a865d327a..000000000 --- a/packages/web/BUGS.md +++ /dev/null @@ -1,6 +0,0 @@ -# Known quirks for browsers and their workarounds - -- text merging (solved through comment nodes) -- cursor jumping to end on inputs (not yet solved, solved in React already) -- SVG attributes cannot be set (solved using the correct method) -- volatile components diff --git a/packages/web/Cargo.toml b/packages/web/Cargo.toml index 6792d5464..4473ef1fe 100644 --- a/packages/web/Cargo.toml +++ b/packages/web/Cargo.toml @@ -42,7 +42,8 @@ features = [ "HtmlFormElement", "Text", "Window", - "console", + "DataTransfer", + "console" ] [features] @@ -50,7 +51,6 @@ default = ["panic_hook", "mounted", "file_engine", "hot_reload", "eval"] panic_hook = ["console_error_panic_hook"] hydrate = [ "web-sys/Comment", - "web-sys/console", ] mounted = [ "web-sys/Element", diff --git a/packages/web/examples/hydrate.rs b/packages/web/examples/hydrate.rs index 42b1be755..26c8bc80e 100644 --- a/packages/web/examples/hydrate.rs +++ b/packages/web/examples/hydrate.rs @@ -12,11 +12,11 @@ fn app(cx: Scope) -> Element { "asd" Bapp {} } - (0..10).map(|f| rsx!{ + {(0..10).map(|f| rsx!{ div { "thing {f}" } - }) + })} }) } diff --git a/packages/web/examples/timeout_count.rs b/packages/web/examples/timeout_count.rs index 742e6a49e..5647e92d7 100644 --- a/packages/web/examples/timeout_count.rs +++ b/packages/web/examples/timeout_count.rs @@ -24,8 +24,11 @@ fn app(cx: Scope) -> Element { start(); *count.write() += 1; }, - // format is needed as {count} does not seemed to work in `if` within content - if **started { format!("Current score: {}", count.write()) } else { "Start".to_string() } + if **started { + "Current score: {count.read()}" + } else { + "Start" + } } }) } diff --git a/packages/web/src/event.rs b/packages/web/src/event.rs index d1eed67a6..9e5ca9421 100644 --- a/packages/web/src/event.rs +++ b/packages/web/src/event.rs @@ -1,12 +1,16 @@ use std::{any::Any, collections::HashMap}; use dioxus_html::{ - FileEngine, FormData, HasFormData, HasImageData, HtmlEventConverter, ImageData, MountedData, - PlatformEventData, ScrollData, + point_interaction::{ + InteractionElementOffset, InteractionLocation, ModifiersInteraction, PointerInteraction, + }, + prelude::FormValue, + DragData, FileEngine, FormData, HasDragData, HasFileData, HasFormData, HasImageData, + HasMouseData, HtmlEventConverter, ImageData, MountedData, PlatformEventData, ScrollData, }; use js_sys::Array; -use wasm_bindgen::{prelude::wasm_bindgen, JsCast}; -use web_sys::{Document, Element, Event}; +use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue}; +use web_sys::{Document, Element, Event, MouseEvent}; pub(crate) struct WebEventConverter; @@ -44,7 +48,11 @@ impl HtmlEventConverter for WebEventConverter { #[inline(always)] fn convert_drag_data(&self, event: &dioxus_html::PlatformEventData) -> dioxus_html::DragData { - downcast_event(event).raw.clone().into() + let event = downcast_event(event); + DragData::new(WebDragData::new( + event.element.clone(), + event.raw.clone().unchecked_into(), + )) } #[inline(always)] @@ -180,8 +188,10 @@ impl WebEventExt for dioxus_html::CompositionData { impl WebEventExt for dioxus_html::DragData { fn web_event(&self) -> &web_sys::MouseEvent { - self.downcast::() + &self + .downcast::() .expect("event should be a WebMouseEvent") + .raw } } @@ -378,7 +388,7 @@ impl HasFormData for WebFormData { .expect("only an InputElement or TextAreaElement or an element with contenteditable=true can have an oninput event listener") } - fn values(&self) -> HashMap> { + fn values(&self) -> HashMap { let mut values = std::collections::HashMap::new(); // try to fill in form values @@ -388,10 +398,12 @@ impl HasFormData for WebFormData { if let Ok(array) = value.dyn_into::() { if let Some(name) = array.get(0).as_string() { if let Ok(item_values) = array.get(1).dyn_into::() { - let item_values = + let item_values: Vec = item_values.iter().filter_map(|v| v.as_string()).collect(); - values.insert(name, item_values); + values.insert(name, FormValue::VecText(item_values)); + } else if let Ok(item_value) = array.get(1).dyn_into::() { + values.insert(name, FormValue::Text(item_value.as_string().unwrap())); } } } @@ -401,6 +413,12 @@ impl HasFormData for WebFormData { values } + fn as_any(&self) -> &dyn Any { + &self.raw as &dyn Any + } +} + +impl HasFileData for WebFormData { fn files(&self) -> Option> { #[cfg(not(feature = "file_engine"))] let files = None; @@ -419,24 +437,115 @@ impl HasFormData for WebFormData { files } +} - fn as_any(&self) -> &dyn Any { - &self.raw as &dyn Any +struct WebDragData { + element: Element, + raw: MouseEvent, +} + +impl WebDragData { + fn new(element: Element, raw: MouseEvent) -> Self { + Self { element, raw } + } +} + +impl HasDragData for WebDragData { + fn as_any(&self) -> &dyn std::any::Any { + &self.raw as &dyn std::any::Any + } +} + +impl HasMouseData for WebDragData { + fn as_any(&self) -> &dyn std::any::Any { + &self.raw as &dyn std::any::Any + } +} + +impl PointerInteraction for WebDragData { + fn trigger_button(&self) -> Option { + self.raw.trigger_button() + } + + fn held_buttons(&self) -> dioxus_html::input_data::MouseButtonSet { + self.raw.held_buttons() + } +} + +impl ModifiersInteraction for WebDragData { + fn modifiers(&self) -> dioxus_html::prelude::Modifiers { + self.raw.modifiers() + } +} + +impl InteractionElementOffset for WebDragData { + fn coordinates(&self) -> dioxus_html::geometry::Coordinates { + self.raw.coordinates() + } + + fn element_coordinates(&self) -> dioxus_html::geometry::ElementPoint { + self.raw.element_coordinates() + } +} + +impl InteractionLocation for WebDragData { + fn client_coordinates(&self) -> dioxus_html::geometry::ClientPoint { + self.raw.client_coordinates() + } + + fn screen_coordinates(&self) -> dioxus_html::geometry::ScreenPoint { + self.raw.screen_coordinates() + } + + fn page_coordinates(&self) -> dioxus_html::geometry::PagePoint { + self.raw.page_coordinates() + } +} + +impl HasFileData for WebDragData { + fn files(&self) -> Option> { + #[cfg(not(feature = "file_engine"))] + let files = None; + #[cfg(feature = "file_engine")] + let files = self + .element + .dyn_ref() + .and_then(|input: &web_sys::HtmlInputElement| { + input.files().and_then(|files| { + #[allow(clippy::arc_with_non_send_sync)] + crate::file_engine::WebFileEngine::new(files).map(|f| { + std::sync::Arc::new(f) as std::sync::Arc + }) + }) + }); + + files } } // web-sys does not expose the keys api for form data, so we need to manually bind to it #[wasm_bindgen(inline_js = r#" - export function get_form_data(form) { - let values = new Map(); - const formData = new FormData(form); +export function get_form_data(form) { + let values = new Map(); + const formData = new FormData(form); - for (let name of formData.keys()) { - values.set(name, formData.getAll(name)); + for (let name of formData.keys()) { + const fieldType = target.elements[name].type; + + switch (fieldType) { + case "select-multiple": + contents.values[name] = formData.getAll(name); + break; + + // add cases for fieldTypes that can hold multiple values here + default: + contents.values[name] = formData.get(name); + break; } - - return values; } + + return values; +} "#)] extern "C" { fn get_form_data(form: &web_sys::HtmlFormElement) -> js_sys::Map; diff --git a/packages/web/src/rehydrate.rs b/packages/web/src/rehydrate.rs index 4905d1e24..e50da9e2b 100644 --- a/packages/web/src/rehydrate.rs +++ b/packages/web/src/rehydrate.rs @@ -1,4 +1,5 @@ use crate::dom::WebsysDom; +use dioxus_core::AttributeValue; use dioxus_core::{DynamicNode, ElementId, ScopeState, TemplateNode, VNode, VirtualDom}; #[derive(Debug)] @@ -81,12 +82,15 @@ impl WebsysDom { if let dioxus_core::TemplateAttribute::Dynamic { id } = attr { let attribute = &vnode.dynamic_attrs[*id]; let id = attribute.mounted_element(); - mounted_id = Some(id); - if let dioxus_core::AttributeValue::Listener(_) = attribute.value { - if attribute.name == "onmounted" { - to_mount.push(id); + attribute.attribute_type().for_each(|attribute| { + let value = &attribute.value; + mounted_id = Some(id); + if let AttributeValue::Listener(_) = value { + if attribute.name == "onmounted" { + to_mount.push(id); + } } - } + }); } } if let Some(id) = mounted_id { diff --git a/packages/web/tests/hydrate.rs b/packages/web/tests/hydrate.rs index a840722dc..982003f62 100644 --- a/packages/web/tests/hydrate.rs +++ b/packages/web/tests/hydrate.rs @@ -43,7 +43,7 @@ fn rehydrates() { }, "listener test" } - false.then(|| rsx!{ "hello" }) + {false.then(|| rsx!{ "hello" })} } }) }