diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3b2e2c7 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,20 @@ +target/ +src-tauri/target/ +node_modules/ + +dist/ + +.git/ +.github/ + +docs/ +ROADMAP.md +*.log +.DS_Store + +.idea/ +.vscode/ + +*.db +*.db-journal +proxy.db diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml new file mode 100644 index 0000000..d6c67a1 --- /dev/null +++ b/.github/workflows/docker.yml @@ -0,0 +1,72 @@ +name: Docker + +on: + push: + tags: + - "v*" + workflow_dispatch: + inputs: + tag: + description: "Image tag (e.g. v1.1.6)" + required: true + type: string + +permissions: + contents: read + packages: write + +jobs: + docker: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - name: Resolve image tag + id: meta + shell: bash + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + tag="${{ inputs.tag }}" + else + tag="${{ github.ref_name }}" + fi + case "$tag" in + v*) ;; + *) echo "Tag must start with v, got: $tag"; exit 1 ;; + esac + version="${tag#v}" + echo "tag=$tag" >> "$GITHUB_OUTPUT" + echo "version=$version" >> "$GITHUB_OUTPUT" + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to GHCR + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + file: crates/rsql-proxy/Dockerfile + platforms: linux/amd64,linux/arm64 + push: true + tags: | + ghcr.io/rust-dd/rsql:latest + ghcr.io/rust-dd/rsql:${{ steps.meta.outputs.tag }} + ghcr.io/rust-dd/rsql:${{ steps.meta.outputs.version }} + cache-from: type=gha + cache-to: type=gha,mode=max + labels: | + org.opencontainers.image.source=https://github.com/rust-dd/rust-sql + org.opencontainers.image.title=RSQL + org.opencontainers.image.description=Browser build of RSQL via WebSocket proxy + org.opencontainers.image.licenses=See LICENSE + org.opencontainers.image.version=${{ steps.meta.outputs.version }} diff --git a/BENCHMARKS.md b/BENCHMARKS.md new file mode 100644 index 0000000..c3d13ee --- /dev/null +++ b/BENCHMARKS.md @@ -0,0 +1,163 @@ +# RSQL Performance Benchmarks + +This document is the published benchmark referenced by the WASM-support design (Phase 7 exit criterion: web build perf within 10% of desktop). + +## What is measured + +Two categories: + +1. **Rust microbench** (Criterion, automated): the packed-binary encoder, the proxy's WS frame encode/decode, and the full result-set pack path. These cover the spec §10 risk register entry _"WS framing reduces packed-binary throughput"_. +2. **End-to-end scroll FPS** (manual): a 1M-row query rendered through the virtualized results panel, scrolled in both the Tauri build and the proxy build. Numbers come from Chrome DevTools' Performance panel. + +The 10% gate is interpreted as follows: +- Microbench: the proxy WS-encode overhead per frame must not exceed 10% of `pack_rows_vec` time for the same payload size. If it does, the WS framing becomes the dominant cost and we have a regression in the protocol layer. +- End-to-end: the scroll FPS in the web build must be within 10% of the Tauri build on the same machine and same dataset (`FPS_web ≥ 0.9 × FPS_desktop`). + +## How to run + +### Microbench + +```bash +cargo bench -p rsql-bench +``` + +Three bench targets run sequentially: +- `pack_rows` — 1K, 10K, 100K, 1M rows × 10 cols (sample size 20) +- `protocol_frames` — small / 1K-rows / 10K-rows JSON encode, 1K/64K/1M-byte binary encode, 1 typical request decode +- `process_simple_messages` — full pack of 1K/100K/1M synthetic result-sets (sample size 20) + +HTML reports: `target/criterion///report/index.html`. Open in a browser to see the violin plots and confidence intervals. + +To run a single target: + +```bash +cargo bench -p rsql-bench --bench pack_rows +cargo bench -p rsql-bench --bench protocol_frames +cargo bench -p rsql-bench --bench process_simple_messages +``` + +### Scroll FPS (manual) + +1. Build the proxy image: `docker build -f crates/rsql-proxy/Dockerfile -t rsql:bench .` +2. Run a Postgres with a 1M-row table: + ```bash + docker run --rm -d --name pg-bench -p 15432:5432 -e POSTGRES_PASSWORD=bench postgres:16 + psql postgresql://postgres:bench@127.0.0.1:15432/postgres <<'SQL' + CREATE TABLE bench AS + SELECT i AS id, + md5(i::text) AS name, + (random() * 1000)::numeric(10,2) AS score, + now() - (random() * interval '1000 days') AS ts + FROM generate_series(1, 1000000) g(i); + CREATE INDEX ON bench (id); + SQL + ``` +3. **Desktop:** `yarn tauri dev`, connect to the PG instance, run `SELECT * FROM bench LIMIT 1000000;`, open the Tauri devtools (debug build), Performance tab, start recording, scroll the results panel top-to-bottom over ~5 s, stop recording. Read the FPS off the "Frames" track. Record `FPS_desktop`. +4. **Web:** `docker run --rm -p 8080:8080 rsql:bench`, open `http://127.0.0.1:8080` in Chrome, connect to the same PG, same query, same scroll motion. Record `FPS_web`. +5. Compute the ratio: `FPS_web / FPS_desktop ≥ 0.9` is PASS. + +Both runs should be done on the same machine, same display, with all other apps closed. The Tauri WebView and Chrome both use the system WebKit/Blink so the rendering pipeline is comparable. + +## Reference hardware + +The numbers below were captured on: + +- **CPU:** Apple M4 Max +- **Memory:** 36 GB +- **OS:** Darwin 25.2.0 arm64 (macOS) +- **Rust:** rustc 1.97.0-nightly (e95e73209 2026-05-05) +- **Date:** 2026-05-19 + +## Microbench results + +Reported as the Criterion median time, with throughput where Criterion computed one. + +### pack_rows_vec + +| Rows × Cols | Time (median) | Throughput | +|-------------|---------------|-----------------| +| 1K × 10 | 169.39 µs | 1.1485 GiB/s | +| 10K × 10 | 1.8195 ms | 1.1204 GiB/s | +| 100K × 10 | 20.444 ms | 1.0427 GiB/s | +| 1M × 10 | 195.87 ms | 1.1359 GiB/s | + +The packer holds a steady ~1.1 GiB/s across four orders of magnitude — no per-row overhead degradation at scale. + +### protocol_encode_text + +| Payload | Time (median) | +|-------------|---------------| +| small | 220.39 ns | +| 1k_rows | 139.63 µs | +| 10k_rows | 1.4286 ms | + +10K-row JSON encode (`sonic-rs::to_string`) is **1.27× faster** than `pack_rows_vec` for the same row count (1.43 ms vs 1.82 ms), but the packer's output is the wire format consumed by the frontend directly — JSON would require a round-trip through `JSON.parse`. + +### protocol_encode_binary + +| Bytes | Time (median) | Throughput | +|-------------|---------------|-----------------| +| 1024 | 64.13 ns | 14.871 GiB/s | +| 65536 | 2.7852 µs | 21.914 GiB/s | +| 1048576 | 26.34 µs | 37.075 GiB/s | + +Binary frame envelope (16-byte UUID + `extend_from_slice` of the payload) is dominated by memcpy — it scales linearly and saturates memory bandwidth at 1 MiB. + +### protocol_decode_text + +| Payload | Time (median) | +|-------------|---------------| +| typical req | 295.61 ns | + +A typical inbound Request (cmd + 2-field payload) parses in ~300 ns. Even at 10 000 requests/sec sustained, parse cost is ~3 ms/s — negligible. + +### pack_full_resultset + +| Rows × Cols | Time (median) | Throughput | +|-------------|---------------|-----------------| +| 1K × 10 | 170.69 µs | 1.1398 GiB/s | +| 100K × 10 | 20.760 ms | 1.0268 GiB/s | +| 1M × 10 | 197.49 ms | 1.1266 GiB/s | + +Matches the `pack_rows_vec` numbers within noise — the `process_simple_messages` aggregation step (driven by `tokio_postgres` internal copy-out) is not the bottleneck for synthetic input. + +### Setup overhead control + +| Bench | Time (median) | +|---------------------|---------------| +| synth_rows_setup_1m | 426.12 ms | + +This is the cost of fabricating 10M strings in-memory — it is **larger** than the actual pack, so naïve interpretation of the `pack_full_resultset/1000000` wall clock would over-count the packer. The dedicated `pack_rows_vec` bench above reuses pre-built input and is the authoritative measurement. + +## 10% gate — microbench verification + +For a 10K-row JSON-shaped result: +- Pack: 1.82 ms (`pack_rows_vec/10000`) +- WS text encode of same payload: 1.43 ms (`protocol_encode_text/10k_rows`) + +Encode is 79% of pack time — comparable in magnitude, well within the same order. The packer dominates because it walks every cell character; the encoder writes the same bytes once. + +For a 1 MiB binary frame: +- Binary envelope: 26.34 µs (`protocol_encode_binary/1048576`) +- Pack of equivalent data (≈100K rows): 20.4 ms (`pack_rows_vec/100000`) + +Envelope is **0.13% of pack time** — the spec §10 risk ("WS framing reduces packed-binary throughput") is not realised; binary framing is essentially free compared to the pack itself. + +## Scroll FPS results + +| Build | FPS | +|---------|------| +| Desktop | TODO | +| Web | TODO | + +Ratio: TODO. Gate: PASS / FAIL. + +> **Manual measurement pending.** Run the procedure in [Scroll FPS (manual)](#scroll-fps-manual) and fill in the table. + +## Interpreting regressions + +If `pack_rows_vec` MB/s drops more than 10% between two runs on the same hardware, the rsql-core packer regressed — bisect against `crates/rsql-core/src/drivers/pgsql/query_execution/helpers.rs`. + +If `protocol_encode_text` time grows but `pack_rows_vec` stayed flat, the WS encode is the new bottleneck — inspect `crates/rsql-proxy/src/protocol.rs::Outbound::into_ws_message`. + +If the scroll FPS drops below 0.9 × desktop, the regression is in the frontend, not the bench-covered Rust path. Inspect `src/components/results-panel.tsx` virtual-scroll logic and the `WebSocketTransport.dispatch` path in `src/lib/transport/websocket-transport.ts`. diff --git a/Cargo.lock b/Cargo.lock index 91a59ed..803f98d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,54 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common 0.1.6", + "generic-array 0.14.7", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +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.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.3", + "once_cell", + "version_check", + "zerocopy 0.8.27", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -41,6 +89,12 @@ dependencies = [ "alloc-no-stdlib", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -51,2613 +105,5412 @@ dependencies = [ ] [[package]] -name = "anyhow" -version = "1.0.99" +name = "anes" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] -name = "async-trait" -version = "0.1.89" +name = "anstream" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", ] [[package]] -name = "atk" -version = "0.18.2" +name = "anstyle" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" -dependencies = [ - "atk-sys", - "glib", - "libc", -] +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] -name = "atk-sys" -version = "0.18.2" +name = "anstyle-parse" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", + "utf8parse", ] [[package]] -name = "atomic-waker" -version = "1.1.2" +name = "anstyle-query" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" +dependencies = [ + "windows-sys 0.61.0", +] [[package]] -name = "autocfg" -version = "1.5.0" +name = "anstyle-wincon" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "backend" -version = "1.0.0" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ - "bincode", - "chrono", - "common", - "serde_json", - "sled", - "tauri", - "tauri-build", - "tauri-plugin-fs", - "tauri-plugin-shell", - "tokio", - "tokio-postgres", - "tracing", - "tracing-subscriber", + "anstyle", + "once_cell_polyfill", + "windows-sys 0.61.0", ] [[package]] -name = "backtrace" -version = "0.3.75" +name = "anyhow" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] +checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" [[package]] -name = "base64" -version = "0.21.7" +name = "arbitrary" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" +dependencies = [ + "derive_arbitrary", +] [[package]] -name = "base64" -version = "0.22.1" +name = "argon2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", +] [[package]] -name = "bincode" -version = "1.3.3" +name = "async-broadcast" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" dependencies = [ - "serde", + "event-listener", + "event-listener-strategy", + "futures-core", + "pin-project-lite", ] [[package]] -name = "bitflags" -version = "1.3.2" +name = "async-channel" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] [[package]] -name = "bitflags" -version = "2.9.4" +name = "async-executor" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" dependencies = [ - "serde", + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "pin-project-lite", + "slab", ] [[package]] -name = "block-buffer" -version = "0.10.4" +name = "async-io" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "19634d6336019ef220f09fd31168ce5c184b295cbf80345437cc36094ef223ca" dependencies = [ - "generic-array", + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix 1.1.2", + "slab", + "windows-sys 0.60.2", ] [[package]] -name = "block2" -version = "0.5.1" +name = "async-lock" +version = "3.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" +checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" dependencies = [ - "objc2 0.5.2", + "event-listener", + "event-listener-strategy", + "pin-project-lite", ] [[package]] -name = "block2" -version = "0.6.1" +name = "async-process" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2" +checksum = "65daa13722ad51e6ab1a1b9c01299142bc75135b337923cfa10e79bbbd669f00" dependencies = [ - "objc2 0.6.2", + "async-channel", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if", + "event-listener", + "futures-lite", + "rustix 1.1.2", ] [[package]] -name = "brotli" -version = "8.0.2" +name = "async-recursion" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "brotli-decompressor" -version = "5.0.0" +name = "async-signal" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +checksum = "f567af260ef69e1d52c2b560ce0ea230763e6fbb9214a85d768760a920e3e3c1" dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", + "async-io", + "async-lock", + "atomic-waker", + "cfg-if", + "futures-core", + "futures-io", + "rustix 1.1.2", + "signal-hook-registry", + "slab", + "windows-sys 0.60.2", ] [[package]] -name = "bumpalo" -version = "3.19.0" +name = "async-stream" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] [[package]] -name = "bytemuck" -version = "1.23.2" +name = "async-stream-impl" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] [[package]] -name = "byteorder" -version = "1.5.0" +name = "async-task" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] -name = "bytes" -version = "1.10.1" +name = "async-trait" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ - "serde", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "cairo-rs" -version = "0.18.5" +name = "atk" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" dependencies = [ - "bitflags 2.9.4", - "cairo-sys-rs", + "atk-sys", "glib", "libc", - "once_cell", - "thiserror 1.0.69", ] [[package]] -name = "cairo-sys-rs" +name = "atk-sys" version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" dependencies = [ "glib-sys", + "gobject-sys", "libc", "system-deps", ] [[package]] -name = "camino" -version = "1.1.12" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0b03af37dad7a14518b7691d81acb0f8222604ad3d1b02f6b4bed5188c0cd5" -dependencies = [ - "serde", -] +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] -name = "cargo-platform" -version = "0.1.9" +name = "autocfg" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" -dependencies = [ - "serde", -] +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] -name = "cargo_metadata" -version = "0.19.2" +name = "aws-lc-rs" +version = "1.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" +checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror 2.0.16", + "aws-lc-sys", + "untrusted 0.7.1", + "zeroize", ] [[package]] -name = "cargo_toml" -version = "0.22.3" +name = "aws-lc-sys" +version = "0.38.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" dependencies = [ - "serde", - "toml 0.9.5", + "cc", + "cmake", + "dunce", + "fs_extra", ] [[package]] -name = "cc" -version = "1.2.36" +name = "axum" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5252b3d2648e5eedbc1a6f501e3c795e07025c1e93bbf8bbdd6eef7f447a6d54" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ - "find-msvc-tools", - "shlex", -] - -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + "async-trait", + "axum-core 0.3.4", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", + "itoa", + "matchit 0.7.3", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper 0.1.2", + "tower 0.4.13", + "tower-layer", + "tower-service", +] [[package]] -name = "cfb" -version = "0.7.3" +name = "axum" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ - "byteorder", - "fnv", - "uuid", + "axum-core 0.5.6", + "axum-macros", + "base64 0.22.1", + "bytes", + "form_urlencoded", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.7.0", + "hyper-util", + "itoa", + "matchit 0.8.4", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sha1 0.10.6", + "sync_wrapper 1.0.2", + "tokio", + "tokio-tungstenite 0.29.0", + "tower 0.5.2", + "tower-layer", + "tower-service", + "tracing", ] [[package]] -name = "cfg-expr" -version = "0.15.8" +name = "axum-core" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ - "smallvec", - "target-lexicon", + "async-trait", + "bytes", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "mime", + "rustversion", + "tower-layer", + "tower-service", ] [[package]] -name = "cfg-if" -version = "1.0.3" +name = "axum-core" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper 1.0.2", + "tower-layer", + "tower-service", + "tracing", +] [[package]] -name = "cfg_aliases" -version = "0.2.1" +name = "axum-macros" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +checksum = "7aa268c23bfbbd2c4363b9cd302a4f504fb2a9dfe7e3451d66f35dd392e20aca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] [[package]] -name = "chrono" -version = "0.4.42" +name = "backtrace" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ - "iana-time-zone", - "js-sys", - "num-traits", - "serde", - "wasm-bindgen", - "windows-link 0.2.0", + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] -name = "combine" -version = "4.6.7" +name = "base16ct" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] -name = "common" +name = "base16ct" version = "1.0.0" -dependencies = [ - "serde", -] +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" [[package]] -name = "convert_case" -version = "0.4.0" +name = "base64" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "cookie" -version = "0.18.1" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" -dependencies = [ - "time", - "version_check", -] +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "core-foundation" -version = "0.10.1" +name = "base64ct" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] -name = "core-foundation-sys" -version = "0.8.7" +name = "bcrypt-pbkdf" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +checksum = "6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2" +dependencies = [ + "blowfish", + "pbkdf2", + "sha2 0.10.9", +] [[package]] -name = "core-graphics" -version = "0.24.0" +name = "bincode" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "bitflags 2.9.4", - "core-foundation", - "core-graphics-types", - "foreign-types", - "libc", + "serde", ] [[package]] -name = "core-graphics-types" -version = "0.2.0" +name = "bindgen" +version = "0.66.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" dependencies = [ "bitflags 2.9.4", - "core-foundation", - "libc", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.106", + "which", ] [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "crc32fast" -version = "1.5.0" +name = "bitflags" +version = "2.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" dependencies = [ - "cfg-if", + "serde", ] [[package]] -name = "crossbeam-channel" -version = "0.5.15" +name = "blake2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "crossbeam-utils", + "digest 0.10.7", ] [[package]] -name = "crossbeam-epoch" -version = "0.9.18" +name = "block-buffer" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "crossbeam-utils", + "generic-array 0.14.7", ] [[package]] -name = "crossbeam-utils" -version = "0.8.21" +name = "block-buffer" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] [[package]] -name = "crypto-common" -version = "0.1.6" +name = "block-padding" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" dependencies = [ - "generic-array", - "typenum", + "generic-array 0.14.7", ] [[package]] -name = "cssparser" -version = "0.29.6" +name = "block2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa" +checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" dependencies = [ - "cssparser-macros", - "dtoa-short", - "itoa", - "matches", - "phf 0.10.1", - "proc-macro2", - "quote", - "smallvec", - "syn 1.0.109", + "objc2 0.5.2", ] [[package]] -name = "cssparser-macros" +name = "block2" version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2" dependencies = [ - "quote", - "syn 2.0.106", + "objc2 0.6.2", ] [[package]] -name = "ctor" -version = "0.2.9" +name = "blocking" +version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" dependencies = [ - "quote", - "syn 2.0.106", + "async-channel", + "async-task", + "futures-io", + "futures-lite", + "piper", ] [[package]] -name = "darling" -version = "0.20.11" +name = "blowfish" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" dependencies = [ - "darling_core", - "darling_macro", + "byteorder", + "cipher", ] [[package]] -name = "darling_core" -version = "0.20.11" +name = "brotli" +version = "8.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.106", + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", ] [[package]] -name = "darling_macro" -version = "0.20.11" +name = "brotli-decompressor" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" dependencies = [ - "darling_core", - "quote", - "syn 2.0.106", + "alloc-no-stdlib", + "alloc-stdlib", ] [[package]] -name = "deranged" -version = "0.5.3" +name = "bumpalo" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" -dependencies = [ - "powerfmt", - "serde", -] +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] -name = "derive_more" -version = "0.99.20" +name = "bytemuck" +version = "1.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.106", -] +checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" [[package]] -name = "digest" -version = "0.10.7" +name = "byteorder" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" dependencies = [ - "block-buffer", - "crypto-common", - "subtle", + "serde", ] [[package]] -name = "dirs" -version = "6.0.0" +name = "cairo-rs" +version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" dependencies = [ - "dirs-sys", + "bitflags 2.9.4", + "cairo-sys-rs", + "glib", + "libc", + "once_cell", + "thiserror 1.0.69", ] [[package]] -name = "dirs-sys" -version = "0.5.0" +name = "cairo-sys-rs" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" dependencies = [ + "glib-sys", "libc", - "option-ext", - "redox_users", - "windows-sys 0.61.0", + "system-deps", ] [[package]] -name = "dispatch" -version = "0.2.0" +name = "camino" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +checksum = "dd0b03af37dad7a14518b7691d81acb0f8222604ad3d1b02f6b4bed5188c0cd5" +dependencies = [ + "serde", +] [[package]] -name = "dispatch2" -version = "0.3.0" +name = "cargo-platform" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ - "bitflags 2.9.4", - "objc2 0.6.2", + "serde", ] [[package]] -name = "displaydoc" -version = "0.2.5" +name = "cargo_metadata" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 2.0.16", ] [[package]] -name = "dlopen2" -version = "0.8.0" +name = "cargo_toml" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b54f373ccf864bf587a89e880fb7610f8d73f3045f13580948ccbcaff26febff" +checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" dependencies = [ - "dlopen2_derive", - "libc", - "once_cell", - "winapi", + "serde", + "toml 0.9.5", ] [[package]] -name = "dlopen2_derive" -version = "0.4.1" +name = "cast" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "788160fb30de9cdd857af31c6a2675904b16ece8fc2737b2c7127ba368c9d0f4" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", + "cipher", ] [[package]] -name = "dpi" -version = "0.1.2" +name = "cc" +version = "1.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ - "serde", + "find-msvc-tools", + "jobserver", + "libc", + "shlex", ] [[package]] -name = "dtoa" -version = "1.0.10" +name = "cesu8" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" [[package]] -name = "dtoa-short" -version = "0.3.5" +name = "cexpr" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" dependencies = [ - "dtoa", + "nom", ] [[package]] -name = "dunce" -version = "1.0.5" +name = "cfb" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] [[package]] -name = "dyn-clone" -version = "1.0.20" +name = "cfg-expr" +version = "0.15.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] [[package]] -name = "embed-resource" -version = "3.0.5" +name = "cfg-if" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6d81016d6c977deefb2ef8d8290da019e27cc26167e102185da528e6c0ab38" -dependencies = [ - "cc", - "memchr", - "rustc_version", - "toml 0.9.5", - "vswhom", - "winreg", -] +checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" [[package]] -name = "embed_plist" -version = "1.2.2" +name = "cfg_aliases" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] -name = "encoding_rs" -version = "0.8.35" +name = "cfg_aliases" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", + "cipher", + "cpufeatures", ] [[package]] -name = "equivalent" -version = "1.0.2" +name = "chrono" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link 0.2.0", +] [[package]] -name = "erased-serde" -version = "0.4.6" +name = "ciborium" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ + "ciborium-io", + "ciborium-ll", "serde", - "typeid", ] [[package]] -name = "fallible-iterator" -version = "0.2.0" +name = "ciborium-io" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] -name = "fdeflate" -version = "0.3.7" +name = "ciborium-ll" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ - "simd-adler32", + "ciborium-io", + "half", ] [[package]] -name = "field-offset" -version = "0.3.6" +name = "cipher" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "memoffset", - "rustc_version", + "crypto-common 0.1.6", + "inout", ] [[package]] -name = "find-msvc-tools" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fd99930f64d146689264c637b5af2f0233a933bef0d8570e2526bf9e083192d" - -[[package]] -name = "flate2" -version = "1.1.2" +name = "clang-sys" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ - "crc32fast", - "miniz_oxide", + "glob", + "libc", + "libloading 0.8.9", ] [[package]] -name = "fnv" -version = "1.0.7" +name = "clap" +version = "4.5.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +dependencies = [ + "clap_builder", + "clap_derive", +] [[package]] -name = "foreign-types" -version = "0.5.0" +name = "clap_builder" +version = "4.5.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" dependencies = [ - "foreign-types-macros", - "foreign-types-shared", + "anstream", + "anstyle", + "clap_lex", + "strsim", ] [[package]] -name = "foreign-types-macros" -version = "0.2.3" +name = "clap_derive" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" dependencies = [ + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.106", ] [[package]] -name = "foreign-types-shared" -version = "0.3.1" +name = "clap_lex" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] -name = "form_urlencoded" -version = "1.2.2" +name = "cmake" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" dependencies = [ - "percent-encoding", + "cc", ] [[package]] -name = "fs2" -version = "0.4.3" +name = "cmov" +version = "0.5.0-pre.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" -dependencies = [ - "libc", - "winapi", -] +checksum = "5417da527aa9bf6a1e10a781231effd1edd3ee82f27d5f8529ac9b279babce96" [[package]] -name = "futf" -version = "0.1.5" +name = "colorchoice" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" -dependencies = [ - "mac", - "new_debug_unreachable", -] +checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] -name = "futures-channel" -version = "0.3.31" +name = "combine" +version = "4.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" dependencies = [ - "futures-core", - "futures-sink", + "bytes", + "memchr", ] [[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-executor" -version = "0.3.31" +name = "concurrent-queue" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ - "futures-core", - "futures-task", - "futures-util", + "crossbeam-utils", ] [[package]] -name = "futures-io" -version = "0.3.31" +name = "const-oid" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] -name = "futures-macro" -version = "0.3.31" +name = "const-oid" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] -name = "futures-sink" -version = "0.3.31" +name = "convert_case" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] -name = "futures-task" -version = "0.3.31" +name = "cookie" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "time", + "version_check", +] [[package]] -name = "futures-util" -version = "0.3.31" +name = "core-foundation" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" dependencies = [ - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", + "core-foundation-sys", + "libc", ] [[package]] -name = "fxhash" -version = "0.2.1" +name = "core-foundation" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ - "byteorder", + "core-foundation-sys", + "libc", ] [[package]] -name = "gdk" -version = "0.18.2" +name = "core-foundation-sys" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" dependencies = [ - "cairo-rs", - "gdk-pixbuf", - "gdk-sys", - "gio", - "glib", + "bitflags 2.9.4", + "core-foundation 0.10.1", + "core-graphics-types", + "foreign-types 0.5.0", "libc", - "pango", ] [[package]] -name = "gdk-pixbuf" -version = "0.18.5" +name = "core-graphics" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" dependencies = [ - "gdk-pixbuf-sys", - "gio", - "glib", + "bitflags 2.9.4", + "core-foundation 0.10.1", + "core-graphics-types", + "foreign-types 0.5.0", "libc", - "once_cell", ] [[package]] -name = "gdk-pixbuf-sys" -version = "0.18.0" +name = "core-graphics-types" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "gio-sys", - "glib-sys", - "gobject-sys", + "bitflags 2.9.4", + "core-foundation 0.10.1", "libc", - "system-deps", ] [[package]] -name = "gdk-sys" -version = "0.18.2" +name = "core-models" +version = "0.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" +checksum = "0940496e5c83c54f3b753d5317daec82e8edac71c33aaa1f666d76f518de2444" dependencies = [ - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "pkg-config", - "system-deps", + "hax-lib", + "pastey", + "rand 0.9.2", ] [[package]] -name = "gdkwayland-sys" -version = "0.18.2" +name = "cpufeatures" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" dependencies = [ - "gdk-sys", - "glib-sys", - "gobject-sys", "libc", - "pkg-config", - "system-deps", ] [[package]] -name = "gdkx11" -version = "0.18.2" +name = "crc32fast" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ - "gdk", - "gdkx11-sys", - "gio", - "glib", - "libc", - "x11", + "cfg-if", ] [[package]] -name = "gdkx11-sys" -version = "0.18.2" +name = "criterion" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" +checksum = "f2b12d017a929603d80db1831cd3a24082f8137ce19c69e6447f54f5fc8d692f" dependencies = [ - "gdk-sys", - "glib-sys", - "libc", - "system-deps", - "x11", + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "is-terminal", + "itertools 0.10.5", + "num-traits", + "once_cell", + "oorandom", + "plotters", + "rayon", + "regex", + "serde", + "serde_derive", + "serde_json", + "tinytemplate", + "walkdir", ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "criterion-plot" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1" dependencies = [ - "typenum", - "version_check", + "cast", + "itertools 0.10.5", ] [[package]] -name = "getrandom" -version = "0.1.16" +name = "crossbeam-channel" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ - "cfg-if", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", + "crossbeam-utils", ] [[package]] -name = "getrandom" -version = "0.2.16" +name = "crossbeam-deque" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ - "cfg-if", - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] -name = "getrandom" -version = "0.3.3" +name = "crossbeam-epoch" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi 0.14.5+wasi-0.2.4", + "crossbeam-utils", ] [[package]] -name = "gimli" -version = "0.31.1" +name = "crossbeam-utils" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] -name = "gio" -version = "0.18.4" +name = "crunchy" +version = "0.2.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 1.0.69", -] +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] -name = "gio-sys" -version = "0.18.1" +name = "crypto-bigint" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", - "winapi", + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", ] [[package]] -name = "glib" -version = "0.18.5" +name = "crypto-bigint" +version = "0.7.0-rc.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +checksum = "37387ceb32048ff590f2cbd24d8b05fffe63c3f69a5cfa089d4f722ca4385a19" dependencies = [ - "bitflags 2.9.4", - "futures-channel", - "futures-core", - "futures-executor", - "futures-task", - "futures-util", - "gio-sys", - "glib-macros", - "glib-sys", - "gobject-sys", - "libc", - "memchr", - "once_cell", - "smallvec", - "thiserror 1.0.69", -] - -[[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.2", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.106", + "ctutils", + "num-traits", + "rand_core 0.10.0-rc-3", + "serdect", + "zeroize", ] [[package]] -name = "glib-sys" -version = "0.18.1" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "libc", - "system-deps", + "generic-array 0.14.7", + "typenum", ] [[package]] -name = "glob" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[package]] -name = "gobject-sys" -version = "0.18.0" +name = "crypto-common" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" dependencies = [ - "glib-sys", - "libc", - "system-deps", + "hybrid-array", ] [[package]] -name = "gtk" -version = "0.18.2" +name = "crypto-primes" +version = "0.7.0-pre.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" +checksum = "e79c98a281f9441200b24e3151407a629bfbe720399186e50516da939195e482" dependencies = [ - "atk", - "cairo-rs", - "field-offset", - "futures-channel", - "gdk", - "gdk-pixbuf", - "gio", - "glib", - "gtk-sys", - "gtk3-macros", - "libc", - "pango", - "pkg-config", + "crypto-bigint 0.7.0-rc.18", + "libm", + "rand_core 0.10.0-rc-3", ] [[package]] -name = "gtk-sys" -version = "0.18.2" +name = "cssparser" +version = "0.29.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" +checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa" dependencies = [ - "atk-sys", - "cairo-sys-rs", - "gdk-pixbuf-sys", - "gdk-sys", - "gio-sys", - "glib-sys", - "gobject-sys", - "libc", - "pango-sys", - "system-deps", + "cssparser-macros", + "dtoa-short", + "itoa", + "matches", + "phf 0.10.1", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", ] [[package]] -name = "gtk3-macros" -version = "0.18.2" +name = "cssparser-macros" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro-error", - "proc-macro2", "quote", "syn 2.0.106", ] [[package]] -name = "hashbrown" -version = "0.12.3" +name = "csv" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde_core", +] [[package]] -name = "hashbrown" -version = "0.15.5" +name = "csv-core" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" +dependencies = [ + "memchr", +] [[package]] -name = "heck" -version = "0.4.1" +name = "ctor" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn 2.0.106", +] [[package]] -name = "heck" -version = "0.5.0" +name = "ctr" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] [[package]] -name = "hex" -version = "0.4.3" +name = "ctutils" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +checksum = "758e5ed90be3c8abff7f9a6f37ab7f6d8c59c2210d448b81f3f508134aec84e4" +dependencies = [ + "cmov", +] [[package]] -name = "hmac" -version = "0.12.1" +name = "curve25519-dalek" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ - "digest", + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", ] [[package]] -name = "html5ever" -version = "0.29.1" +name = "curve25519-dalek-derive" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ - "log", - "mac", - "markup5ever", - "match_token", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "http" -version = "1.3.1" +name = "darling" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ - "bytes", - "fnv", - "itoa", + "darling_core", + "darling_macro", ] [[package]] -name = "http-body" -version = "1.0.1" +name = "darling_core" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ - "bytes", - "http", + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.106", ] [[package]] -name = "http-body-util" -version = "0.1.3" +name = "darling_macro" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", + "darling_core", + "quote", + "syn 2.0.106", ] [[package]] -name = "httparse" -version = "1.10.1" +name = "data-encoding" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" [[package]] -name = "hyper" -version = "1.7.0" +name = "deadpool" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +checksum = "0be2b1d1d6ec8d846f05e137292d0b89133caf95ef33695424c09568bdd39b1b" dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", + "deadpool-runtime", + "lazy_static", + "num_cpus", "tokio", - "want", ] [[package]] -name = "hyper-util" -version = "0.1.16" +name = "deadpool-postgres" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "3d697d376cbfa018c23eb4caab1fd1883dd9c906a8c034e8d9a3cb06a7e0bef9" dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2 0.6.0", + "async-trait", + "deadpool", + "getrandom 0.2.16", "tokio", - "tower-service", + "tokio-postgres", "tracing", ] [[package]] -name = "iana-time-zone" -version = "0.1.63" +name = "deadpool-runtime" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", + "tokio", ] [[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" +name = "delegate" +version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "780eb241654bf097afb00fc5f054a09b687dad862e485fdcf8399bb056565370" dependencies = [ - "cc", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "ico" -version = "0.4.0" +name = "der" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "byteorder", - "png", + "const-oid 0.9.6", + "pem-rfc7468 0.7.0", + "zeroize", ] [[package]] -name = "icu_collections" -version = "2.0.0" +name = "der" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", + "const-oid 0.10.2", + "pem-rfc7468 1.0.0", + "zeroize", ] [[package]] -name = "icu_locale_core" -version = "2.0.0" +name = "deranged" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", + "powerfmt", + "serde", ] [[package]] -name = "icu_normalizer" -version = "2.0.0" +name = "derive_arbitrary" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "icu_normalizer_data" -version = "2.0.0" +name = "derive_more" +version = "0.99.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.106", +] [[package]] -name = "icu_properties" -version = "2.0.1" +name = "digest" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", + "block-buffer 0.10.4", + "const-oid 0.9.6", + "crypto-common 0.1.6", + "subtle", ] [[package]] -name = "icu_properties_data" -version = "2.0.1" +name = "digest" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" +checksum = "285743a676ccb6b3e116bc14cc69319b957867930ae9c4822f8e0f54509d7243" +dependencies = [ + "block-buffer 0.12.0", + "const-oid 0.10.2", + "crypto-common 0.2.1", +] [[package]] -name = "icu_provider" -version = "2.0.0" +name = "dirs" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", + "dirs-sys", ] [[package]] -name = "ident_case" -version = "1.0.1" +name = "dirs-sys" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.0", +] [[package]] -name = "idna" -version = "1.1.0" +name = "dispatch2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", + "bitflags 2.9.4", + "block2 0.6.1", + "libc", + "objc2 0.6.2", ] [[package]] -name = "idna_adapter" -version = "1.2.1" +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ - "icu_normalizer", - "icu_properties", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "indexmap" -version = "1.9.3" +name = "dlopen2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +checksum = "b54f373ccf864bf587a89e880fb7610f8d73f3045f13580948ccbcaff26febff" dependencies = [ - "autocfg", - "hashbrown 0.12.3", - "serde", + "dlopen2_derive", + "libc", + "once_cell", + "winapi", ] [[package]] -name = "indexmap" -version = "2.11.1" +name = "dlopen2_derive" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921" +checksum = "788160fb30de9cdd857af31c6a2675904b16ece8fc2737b2c7127ba368c9d0f4" dependencies = [ - "equivalent", - "hashbrown 0.15.5", - "serde", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "infer" -version = "0.19.0" +name = "downcast-rs" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" -dependencies = [ - "cfb", -] +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" [[package]] -name = "instant" -version = "0.1.13" +name = "dpi" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" dependencies = [ - "cfg-if", + "serde", ] [[package]] -name = "io-uring" -version = "0.7.10" +name = "dtoa" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "libc", + "dtoa", ] [[package]] -name = "ipnet" -version = "2.11.0" +name = "dunce" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] -name = "iri-string" -version = "0.7.8" +name = "dyn-clone" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "memchr", - "serde", + "der 0.7.10", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] -name = "is-docker" -version = "0.2.0" +name = "ed25519" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "928bae27f42bc99b60d9ac7334e3a21d10ad8f1835a4e12ec3ec0464765ed1b3" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "once_cell", + "pkcs8 0.10.2", + "signature 2.2.0", ] [[package]] -name = "is-wsl" -version = "0.4.0" +name = "ed25519-dalek" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" dependencies = [ - "is-docker", - "once_cell", + "curve25519-dalek", + "ed25519", + "rand_core 0.6.4", + "serde", + "sha2 0.10.9", + "subtle", + "zeroize", ] [[package]] -name = "itoa" -version = "1.0.15" +name = "either" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] -name = "javascriptcore-rs" -version = "1.1.2" +name = "elliptic-curve" +version = "0.13.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ - "bitflags 1.3.2", - "glib", - "javascriptcore-rs-sys", + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff", + "generic-array 0.14.7", + "group", + "hkdf", + "pem-rfc7468 0.7.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", ] [[package]] -name = "javascriptcore-rs-sys" -version = "1.1.1" +name = "embed-resource" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" +checksum = "4c6d81016d6c977deefb2ef8d8290da019e27cc26167e102185da528e6c0ab38" dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", + "cc", + "memchr", + "rustc_version", + "toml 0.9.5", + "vswhom", + "winreg 0.55.0", ] [[package]] -name = "jni" -version = "0.21.1" +name = "embed_plist" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ - "cesu8", "cfg-if", - "combine", - "jni-sys", - "log", - "thiserror 1.0.69", - "walkdir", - "windows-sys 0.45.0", ] [[package]] -name = "jni-sys" -version = "0.3.0" +name = "endi" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" [[package]] -name = "js-sys" -version = "0.3.78" +name = "enum_dispatch" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" dependencies = [ "once_cell", - "wasm-bindgen", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "json-patch" -version = "3.0.1" +name = "enumflags2" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" +checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" dependencies = [ - "jsonptr", + "enumflags2_derive", "serde", - "serde_json", - "thiserror 1.0.69", ] [[package]] -name = "jsonptr" -version = "0.6.3" +name = "enumflags2_derive" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" +checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ - "serde", - "serde_json", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "keyboard-types" -version = "0.7.0" +name = "equivalent" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" -dependencies = [ - "bitflags 2.9.4", - "serde", - "unicode-segmentation", -] +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] -name = "kuchikiki" -version = "0.8.8-speedreader" +name = "erased-serde" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" +checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" dependencies = [ - "cssparser", - "html5ever", - "indexmap 2.11.1", - "selectors", + "serde", + "typeid", ] [[package]] -name = "lazy_static" -version = "1.5.0" +name = "errno" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.0", +] [[package]] -name = "libappindicator" -version = "0.9.0" +name = "event-listener" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ - "glib", - "gtk", - "gtk-sys", - "libappindicator-sys", - "log", + "concurrent-queue", + "parking", + "pin-project-lite", ] [[package]] -name = "libappindicator-sys" -version = "0.9.0" +name = "event-listener-strategy" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ - "gtk-sys", - "libloading", - "once_cell", + "event-listener", + "pin-project-lite", ] [[package]] -name = "libc" -version = "0.2.175" +name = "fallible-iterator" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] -name = "libloading" -version = "0.7.4" +name = "fallible-iterator" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" [[package]] -name = "libredox" +name = "fallible-streaming-iterator" version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" -dependencies = [ - "bitflags 2.9.4", - "libc", - "redox_syscall 0.5.17", -] +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] -name = "litemap" -version = "0.8.0" +name = "fastrand" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] -name = "lock_api" -version = "0.4.13" +name = "faststr" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "1ca7d44d22004409a61c393afb3369c8f7bb74abcae49fe249ee01dcc3002113" dependencies = [ - "autocfg", - "scopeguard", + "bytes", + "rkyv", + "serde", + "simdutf8", ] [[package]] -name = "log" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" - -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - -[[package]] -name = "markup5ever" -version = "0.14.1" +name = "fdeflate" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" dependencies = [ - "log", - "phf 0.11.3", - "phf_codegen 0.11.3", - "string_cache", - "string_cache_codegen", - "tendril", + "simd-adler32", ] [[package]] -name = "match_token" -version = "0.1.0" +name = "ff" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", + "rand_core 0.6.4", + "subtle", ] [[package]] -name = "matches" -version = "0.1.10" +name = "fiat-crypto" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] -name = "md-5" -version = "0.10.6" +name = "field-offset" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" dependencies = [ - "cfg-if", - "digest", + "memoffset", + "rustc_version", ] [[package]] -name = "memchr" -version = "2.7.5" +name = "filedescriptor" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d" +dependencies = [ + "libc", + "thiserror 1.0.69", + "winapi", +] [[package]] -name = "memoffset" -version = "0.9.1" +name = "filetime" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ - "autocfg", + "cfg-if", + "libc", + "libredox", ] [[package]] -name = "mime" -version = "0.3.17" +name = "find-msvc-tools" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] -name = "miniz_oxide" -version = "0.8.9" +name = "flate2" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ - "adler2", - "simd-adler32", + "crc32fast", + "miniz_oxide", ] [[package]] -name = "mio" -version = "1.0.4" +name = "fnv" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" -dependencies = [ - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", -] +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "muda" -version = "0.17.1" +name = "foreign-types" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" dependencies = [ - "crossbeam-channel", - "dpi", - "gtk", - "keyboard-types", - "objc2 0.6.2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "once_cell", - "png", - "serde", - "thiserror 2.0.16", - "windows-sys 0.60.2", + "foreign-types-shared 0.1.1", ] [[package]] -name = "ndk" -version = "0.9.0" +name = "foreign-types" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ - "bitflags 2.9.4", - "jni-sys", - "log", - "ndk-sys", - "num_enum", - "raw-window-handle", - "thiserror 1.0.69", + "foreign-types-macros", + "foreign-types-shared 0.3.1", ] [[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.6.0+11769913" +name = "foreign-types-macros" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ - "jni-sys", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "new_debug_unreachable" -version = "1.0.6" +name = "foreign-types-shared" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" [[package]] -name = "nodrop" -version = "0.1.14" +name = "foreign-types-shared" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] -name = "nu-ansi-term" -version = "0.50.1" +name = "form_urlencoded" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ - "windows-sys 0.52.0", + "percent-encoding", ] [[package]] -name = "num-conv" -version = "0.1.0" +name = "fs_extra" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] -name = "num-traits" -version = "0.2.19" +name = "futf" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" dependencies = [ - "autocfg", + "mac", + "new_debug_unreachable", ] [[package]] -name = "num_enum" -version = "0.7.4" +name = "futures" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ - "num_enum_derive", - "rustversion", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] -name = "num_enum_derive" -version = "0.7.4" +name = "futures-channel" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ - "proc-macro-crate 2.0.2", "proc-macro2", "quote", "syn 2.0.106", ] [[package]] -name = "objc-sys" -version = "0.3.5" +name = "futures-sink" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] -name = "objc2" -version = "0.5.2" +name = "futures-task" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ - "objc-sys", - "objc2-encode", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", ] [[package]] -name = "objc2" -version = "0.6.2" +name = "fxhash" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" dependencies = [ - "objc2-encode", - "objc2-exception-helper", + "byteorder", ] [[package]] -name = "objc2-app-kit" -version = "0.3.1" +name = "gdk" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" +checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" dependencies = [ - "bitflags 2.9.4", - "block2 0.6.1", + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", "libc", - "objc2 0.6.2", - "objc2-cloud-kit", - "objc2-core-data", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-core-image", - "objc2-foundation 0.3.1", - "objc2-quartz-core 0.3.1", + "pango", ] [[package]] -name = "objc2-cloud-kit" -version = "0.3.1" +name = "gdk-pixbuf" +version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17614fdcd9b411e6ff1117dfb1d0150f908ba83a7df81b1f118005fe0a8ea15d" +checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" dependencies = [ - "bitflags 2.9.4", - "objc2 0.6.2", - "objc2-foundation 0.3.1", + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", + "once_cell", ] [[package]] -name = "objc2-core-data" -version = "0.3.1" +name = "gdk-pixbuf-sys" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291fbbf7d29287518e8686417cf7239c74700fd4b607623140a7d4a3c834329d" +checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" dependencies = [ - "bitflags 2.9.4", - "objc2 0.6.2", - "objc2-foundation 0.3.1", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", ] [[package]] -name = "objc2-core-foundation" -version = "0.3.1" +name = "gdk-sys" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" dependencies = [ - "bitflags 2.9.4", - "dispatch2", - "objc2 0.6.2", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", ] [[package]] -name = "objc2-core-graphics" -version = "0.3.1" +name = "gdkwayland-sys" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" +checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" dependencies = [ - "bitflags 2.9.4", - "dispatch2", - "objc2 0.6.2", - "objc2-core-foundation", - "objc2-io-surface", + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps", ] [[package]] -name = "objc2-core-image" -version = "0.3.1" +name = "gdkx11" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b3dc0cc4386b6ccf21c157591b34a7f44c8e75b064f85502901ab2188c007e" +checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" dependencies = [ - "objc2 0.6.2", - "objc2-foundation 0.3.1", + "gdk", + "gdkx11-sys", + "gio", + "glib", + "libc", + "x11", ] [[package]] -name = "objc2-encode" -version = "4.1.0" +name = "gdkx11-sys" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" +checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] [[package]] -name = "objc2-exception-helper" -version = "0.1.1" +name = "generic-array" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ - "cc", + "typenum", + "version_check", + "zeroize", ] [[package]] -name = "objc2-foundation" -version = "0.2.2" +name = "generic-array" +version = "1.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +checksum = "eaf57c49a95fd1fe24b90b3033bee6dc7e8f1288d51494cb44e627c295e38542" dependencies = [ - "bitflags 2.9.4", - "block2 0.5.1", + "generic-array 0.14.7", + "rustversion", + "typenum", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", "libc", - "objc2 0.5.2", + "wasi 0.9.0+wasi-snapshot-preview1", ] [[package]] -name = "objc2-foundation" -version = "0.3.1" +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.5+wasi-0.2.4", + "wasm-bindgen", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[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 1.0.69", +] + +[[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 = "glib" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +dependencies = [ + "bitflags 2.9.4", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "once_cell", + "smallvec", + "thiserror 1.0.69", +] + +[[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.0", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[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 = "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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" +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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "h2" +version = "0.3.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.11.1", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" +dependencies = [ + "cfg-if", + "crunchy", + "zerocopy 0.8.27", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "hax-lib" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d9ba66d1739c68e0219b2b2238b5c4145f491ebf181b9c6ab561a19352ae86" +dependencies = [ + "hax-lib-macros", + "num-bigint", + "num-traits", +] + +[[package]] +name = "hax-lib-macros" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ba777a231a58d1bce1d68313fa6b6afcc7966adef23d60f45b8a2b9b688bf1" +dependencies = [ + "hax-lib-macros-types", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "hax-lib-macros-types" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "867e19177d7425140b417cd27c2e05320e727ee682e98368f88b7194e80ad515" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[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 0.10.7", +] + +[[package]] +name = "home" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" +dependencies = [ + "windows-sys 0.61.0", +] + +[[package]] +name = "html5ever" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c" +dependencies = [ + "log", + "mac", + "markup5ever", + "match_token", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[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.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.3.1", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "http-range-header" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hybrid-array" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b229d73f5803b562cc26e4da0396c8610a4ee209f4fac8fa4f8d709166dc45" +dependencies = [ + "typenum", +] + +[[package]] +name = "hyper" +version = "0.14.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.10", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "399c78f9338483cb7e630c8474b07268983c6bd5acee012e4211f9f7bb21b070" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.32", + "log", + "rustls 0.22.4", + "rustls-native-certs 0.7.3", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.25.0", + "webpki-roots 0.26.11", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http 1.3.1", + "hyper 1.7.0", + "hyper-util", + "rustls 0.23.37", + "rustls-pki-types", + "tokio", + "tokio-rustls 0.26.4", + "tower-service", + "webpki-roots 1.0.6", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper 0.14.32", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "hyper-util" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "hyper 1.7.0", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2 0.6.0", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.61.2", +] + +[[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 = "ico" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" +dependencies = [ + "byteorder", + "png", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[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.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921" +dependencies = [ + "equivalent", + "hashbrown 0.15.5", + "serde", +] + +[[package]] +name = "infer" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" +dependencies = [ + "cfb", +] + +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "block-padding", + "generic-array 0.14.7", +] + +[[package]] +name = "internal-russh-forked-ssh-key" +version = "0.6.16+upstream-0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe44f2bbd99fcb302e246e2d6bcf51aeda346d02a365f80296a07a8c711b6da6" +dependencies = [ + "argon2", + "bcrypt-pbkdf", + "digest 0.11.1", + "ecdsa", + "ed25519-dalek", + "hex", + "hmac", + "num-bigint-dig", + "p256", + "p384", + "p521", + "rand_core 0.6.4", + "rsa", + "sec1", + "sha1 0.10.6", + "sha1 0.11.0-rc.5", + "sha2 0.10.9", + "signature 2.2.0", + "signature 3.0.0-rc.6", + "ssh-cipher", + "ssh-encoding", + "subtle", + "zeroize", +] + +[[package]] +name = "io-uring" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" +dependencies = [ + "bitflags 2.9.4", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[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.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.61.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_terminal_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" + +[[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.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[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 1.0.69", + "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.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +dependencies = [ + "getrandom 0.3.3", + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "json-patch" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" +dependencies = [ + "jsonptr", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jsonptr" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags 2.9.4", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "kuchikiki" +version = "0.8.8-speedreader" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" +dependencies = [ + "cssparser", + "html5ever", + "indexmap 2.11.1", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin", +] + +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + +[[package]] +name = "libappindicator" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" +dependencies = [ + "glib", + "gtk", + "gtk-sys", + "libappindicator-sys", + "log", +] + +[[package]] +name = "libappindicator-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" +dependencies = [ + "gtk-sys", + "libloading 0.7.4", + "once_cell", +] + +[[package]] +name = "libc" +version = "0.2.175" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" + +[[package]] +name = "libcrux-intrinsics" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc9ee7ef66569dd7516454fe26de4e401c0c62073929803486b96744594b9632" +dependencies = [ + "core-models", + "hax-lib", +] + +[[package]] +name = "libcrux-ml-kem" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb6a88086bf11bd2ec90926c749c4a427f2e59841437dbdede8cde8a96334ab" +dependencies = [ + "hax-lib", + "libcrux-intrinsics", + "libcrux-platform", + "libcrux-secrets", + "libcrux-sha3", + "libcrux-traits", + "rand 0.9.2", + "tls_codec", +] + +[[package]] +name = "libcrux-platform" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db82d058aa76ea315a3b2092f69dfbd67ddb0e462038a206e1dcd73f058c0778" +dependencies = [ + "libc", +] + +[[package]] +name = "libcrux-secrets" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4dbbf6bc9f2bc0f20dc3bea3e5c99adff3bdccf6d2a40488963da69e2ec307" +dependencies = [ + "hax-lib", +] + +[[package]] +name = "libcrux-sha3" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2400bec764d1c75b8a496d5747cffe32f1fb864a12577f0aca2f55a92021c962" +dependencies = [ + "hax-lib", + "libcrux-intrinsics", + "libcrux-platform", + "libcrux-traits", +] + +[[package]] +name = "libcrux-traits" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9adfd58e79d860f6b9e40e35127bfae9e5bd3ade33201d1347459011a2add034" +dependencies = [ + "libcrux-secrets", + "rand 0.9.2", +] + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libloading" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" +dependencies = [ + "cfg-if", + "windows-link 0.2.0", +] + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "libredox" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +dependencies = [ + "bitflags 2.9.4", + "libc", + "redox_syscall", +] + +[[package]] +name = "libsql" +version = "0.9.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2329faffc510cc3c6b4f00169a39177cc7099d3ed7647fc92f7cf26e53a8d976" +dependencies = [ + "anyhow", + "async-stream", + "async-trait", + "base64 0.21.7", + "bincode", + "bitflags 2.9.4", + "bytes", + "chrono", + "crc32fast", + "fallible-iterator 0.3.0", + "futures", + "http 0.2.12", + "hyper 0.14.32", + "hyper-rustls 0.25.0", + "libsql-hrana", + "libsql-sqlite3-parser", + "libsql-sys", + "libsql_replication", + "parking_lot", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "tokio-util", + "tonic", + "tonic-web", + "tower 0.4.13", + "tower-http 0.4.4", + "tracing", + "uuid", + "zerocopy 0.7.35", +] + +[[package]] +name = "libsql-ffi" +version = "0.9.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cd1c1662822495393327856774f6803be25d85bfdcd5b9d4af35458f5daaf75" +dependencies = [ + "bindgen", + "cc", + "cmake", + "glob", +] + +[[package]] +name = "libsql-hrana" +version = "0.9.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "646d0aa75e412769018422f0da798f72e93bd51964f0b2ddad4317aa779ae444" +dependencies = [ + "base64 0.21.7", + "bytes", + "prost", + "serde", +] + +[[package]] +name = "libsql-rusqlite" +version = "0.9.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a4ce3a78c6e3c2b23b02ab6272df8340e1c53380497979d456882254f348d5f" +dependencies = [ + "bitflags 2.9.4", + "fallible-iterator 0.2.0", + "fallible-streaming-iterator", + "hashlink", + "libsql-ffi", + "smallvec", +] + +[[package]] +name = "libsql-sqlite3-parser" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15a90128c708356af8f7d767c9ac2946692c9112b4f74f07b99a01a60680e413" +dependencies = [ + "bitflags 2.9.4", + "cc", + "fallible-iterator 0.3.0", + "indexmap 2.11.1", + "log", + "memchr", + "phf 0.11.3", + "phf_codegen 0.11.3", + "phf_shared 0.11.3", + "uncased", +] + +[[package]] +name = "libsql-sys" +version = "0.9.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a3c326fcfc36fe7578238d5ee6b58c529f8c76372acd61ec50267529cdaff95" +dependencies = [ + "bytes", + "libsql-ffi", + "libsql-rusqlite", + "once_cell", + "tracing", + "zerocopy 0.7.35", +] + +[[package]] +name = "libsql_replication" +version = "0.9.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d9a2e469ac8400659bd31f81a745908bcc5cb6b40be2f2ff8de90b15bec5501" +dependencies = [ + "aes", + "async-stream", + "async-trait", + "bytes", + "cbc", + "libsql-rusqlite", + "libsql-sys", + "parking_lot", + "prost", + "serde", + "thiserror 1.0.69", + "tokio", + "tokio-stream", + "tokio-util", + "tonic", + "tracing", + "uuid", + "zerocopy 0.7.35", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" + +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "markup5ever" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18" +dependencies = [ + "log", + "phf 0.11.3", + "phf_codegen 0.11.3", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "match_token" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest 0.10.7", +] + +[[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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "minisign-verify" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22f9645cb765ea72b8111f36c522475d2daa0d22c957a9826437e97534bc4e9e" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "muda" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a" +dependencies = [ + "crossbeam-channel", + "dpi", + "gtk", + "keyboard-types", + "objc2 0.6.2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation 0.3.1", + "once_cell", + "png", + "serde", + "thiserror 2.0.16", + "windows-sys 0.60.2", +] + +[[package]] +name = "munge" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c" +dependencies = [ + "munge_macro", +] + +[[package]] +name = "munge_macro" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe 0.1.6", + "openssl-sys", + "schannel", + "security-framework 2.11.1", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.9.4", + "jni-sys", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[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.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.9.4", + "cfg-if", + "cfg_aliases 0.1.1", + "libc", +] + +[[package]] +name = "nix" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" +dependencies = [ + "bitflags 2.9.4", + "cfg-if", + "cfg_aliases 0.2.1", + "libc", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.9.4", + "cfg-if", + "cfg_aliases 0.2.1", + "libc", + "memoffset", +] + +[[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 = "ntapi" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "serde", + "smallvec", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc" +dependencies = [ + "objc2-encode", + "objc2-exception-helper", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" +dependencies = [ + "bitflags 2.9.4", + "block2 0.6.1", + "objc2 0.6.2", + "objc2-core-foundation", + "objc2-foundation 0.3.1", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +dependencies = [ + "bitflags 2.9.4", + "dispatch2", + "objc2 0.6.2", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" +dependencies = [ + "bitflags 2.9.4", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-exception-helper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" +dependencies = [ + "cc", +] + +[[package]] +name = "objc2-foundation" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +dependencies = [ + "bitflags 2.9.4", + "block2 0.5.1", + "libc", + "objc2 0.5.2", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +dependencies = [ + "bitflags 2.9.4", + "block2 0.6.1", + "libc", + "objc2 0.6.2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a" +dependencies = [ + "libc", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-metal" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +dependencies = [ + "bitflags 2.9.4", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", +] + +[[package]] +name = "objc2-osa-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26bb88504b5a050dbba515d2414607bf5e57dd56b107bc5f0351197a3e7bdc5d" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.2", + "objc2-app-kit", + "objc2-foundation 0.3.1", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +dependencies = [ + "bitflags 2.9.4", + "block2 0.5.1", + "objc2 0.5.2", + "objc2-foundation 0.2.2", + "objc2-metal", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25b1312ad7bc8a0e92adae17aa10f90aae1fb618832f9b993b022b591027daed" +dependencies = [ + "bitflags 2.9.4", + "objc2 0.6.2", + "objc2-core-foundation", + "objc2-foundation 0.3.1", +] + +[[package]] +name = "objc2-web-kit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91672909de8b1ce1c2252e95bbee8c1649c9ad9d14b9248b3d7b4c47903c47ad" +dependencies = [ + "bitflags 2.9.4", + "block2 0.6.1", + "objc2 0.6.2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation 0.3.1", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" + +[[package]] +name = "oorandom" +version = "11.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "open" +version = "5.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95" +dependencies = [ + "dunce", + "is-wsl", + "libc", + "pathdiff", +] + +[[package]] +name = "openssl" +version = "0.10.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" +dependencies = [ + "bitflags 2.9.4", + "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.106", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-probe" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" + +[[package]] +name = "openssl-sys" +version = "0.9.110" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" +dependencies = [ + "cc", + "libc", + "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-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.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db335f4760b14ead6290116f2427bf33a14d4f0617d49f78a246de10c1831224" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "osakit" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b" +dependencies = [ + "objc2 0.6.2", + "objc2-foundation 0.3.1", + "objc2-osa-kit", + "serde", + "serde_json", + "thiserror 2.0.16", +] + +[[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 0.10.9", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2 0.10.9", +] + +[[package]] +name = "p521" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" +dependencies = [ + "base16ct 0.2.0", + "ecdsa", + "elliptic-curve", + "primeorder", + "rand_core 0.6.4", + "sha2 0.10.9", +] + +[[package]] +name = "pageant" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b537f975f6d8dcf48db368d7ec209d583b015713b5df0f5d92d2631e4ff5595" +dependencies = [ + "byteorder", + "bytes", + "delegate", + "futures", + "log", + "rand 0.8.5", + "sha2 0.10.9", + "thiserror 1.0.69", + "tokio", + "windows 0.62.1", + "windows-strings 0.5.0", +] + +[[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 = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "pastey" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" + +[[package]] +name = "pathdiff" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac", +] + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "pem-rfc7468" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_shared 0.8.0", +] + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_shared 0.13.1", + "serde", +] + +[[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.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", +] + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.5", +] + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher 1.0.1", + "uncased", +] + +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher 1.0.1", +] + +[[package]] +name = "pin-project" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkcs1" +version = "0.8.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986d2e952779af96ea048f160fd9194e1751b4faea78bcf3ceb456efe008088e" +dependencies = [ + "der 0.8.0", + "spki 0.8.0-rc.4", +] + +[[package]] +name = "pkcs5" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" +dependencies = [ + "aes", + "cbc", + "der 0.7.10", + "pbkdf2", + "scrypt", + "sha2 0.10.9", + "spki 0.7.3", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.10", + "pkcs5", + "rand_core 0.6.4", + "spki 0.7.3", +] + +[[package]] +name = "pkcs8" +version = "0.11.0-rc.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12922b6296c06eb741b02d7b5161e3aaa22864af38dfa025a1a3ba3f68c84577" +dependencies = [ + "der 0.8.0", + "spki 0.8.0-rc.4", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "plist" +version = "1.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1" +dependencies = [ + "base64 0.22.1", + "indexmap 2.11.1", + "quick-xml", + "serde", + "time", +] + +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "polling" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi", + "pin-project-lite", + "rustix 1.1.2", + "windows-sys 0.60.2", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-pty" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a596a2b3d2752d94f51fac2d4a96737b8705dddd311a32b9af47211f08671e" +dependencies = [ + "anyhow", + "bitflags 1.3.2", + "downcast-rs", + "filedescriptor", + "lazy_static", + "libc", + "log", + "nix 0.28.0", + "serial2", + "shared_library", + "shell-words", + "winapi", + "winreg 0.10.1", +] + +[[package]] +name = "postgres-native-tls" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac73153d92e4bde922bd6f1dfba7f1ab8132266c031153b55e20a1521cd36d49" +dependencies = [ + "native-tls", + "tokio", + "tokio-native-tls", + "tokio-postgres", +] + +[[package]] +name = "postgres-protocol" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbef655056b916eb868048276cfd5d6a7dea4f81560dfd047f97c8c6fe3fcfd4" +dependencies = [ + "base64 0.22.1", + "byteorder", + "bytes", + "fallible-iterator 0.2.0", + "hmac", + "md-5", + "memchr", + "rand 0.9.2", + "sha2 0.10.9", + "stringprep", +] + +[[package]] +name = "postgres-types" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef4605b7c057056dd35baeb6ac0c0338e4975b1f2bef0f65da953285eb007095" +dependencies = [ + "bytes", + "fallible-iterator 0.2.0", + "postgres-protocol", +] + +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "zerovec", +] + +[[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.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ - "bitflags 2.9.4", - "block2 0.6.1", - "libc", - "objc2 0.6.2", - "objc2-core-foundation", + "zerocopy 0.8.27", ] [[package]] -name = "objc2-io-surface" -version = "0.3.1" +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ - "bitflags 2.9.4", - "objc2 0.6.2", - "objc2-core-foundation", + "proc-macro2", + "syn 2.0.106", ] [[package]] -name = "objc2-javascript-core" -version = "0.3.1" +name = "primeorder" +version = "0.13.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9052cb1bb50a4c161d934befcf879526fb87ae9a68858f241e693ca46225cf5a" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" dependencies = [ - "objc2 0.6.2", - "objc2-core-foundation", + "elliptic-curve", ] [[package]] -name = "objc2-metal" -version = "0.2.2" +name = "proc-macro-crate" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" dependencies = [ - "bitflags 2.9.4", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", + "once_cell", + "toml_edit 0.19.15", ] [[package]] -name = "objc2-quartz-core" -version = "0.2.2" +name = "proc-macro-crate" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "bitflags 2.9.4", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", + "toml_edit 0.20.7", ] [[package]] -name = "objc2-quartz-core" -version = "0.3.1" +name = "proc-macro-crate" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ffb6a0cd5f182dc964334388560b12a57f7b74b3e2dec5e2722aa2dfb2ccd5" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" dependencies = [ - "bitflags 2.9.4", - "objc2 0.6.2", - "objc2-foundation 0.3.1", + "toml_edit 0.22.27", ] [[package]] -name = "objc2-security" -version = "0.3.1" +name = "proc-macro-error" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1f8e0ef3ab66b08c42644dcb34dba6ec0a574bbd8adbb8bdbdc7a2779731a44" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ - "bitflags 2.9.4", - "objc2 0.6.2", - "objc2-core-foundation", + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", ] [[package]] -name = "objc2-ui-kit" -version = "0.3.1" +name = "proc-macro-error-attr" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b1312ad7bc8a0e92adae17aa10f90aae1fb618832f9b993b022b591027daed" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "bitflags 2.9.4", - "objc2 0.6.2", - "objc2-core-foundation", - "objc2-foundation 0.3.1", + "proc-macro2", + "quote", + "version_check", ] [[package]] -name = "objc2-web-kit" -version = "0.3.1" +name = "proc-macro-error-attr2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91672909de8b1ce1c2252e95bbee8c1649c9ad9d14b9248b3d7b4c47903c47ad" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" dependencies = [ - "bitflags 2.9.4", - "block2 0.6.1", - "objc2 0.6.2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "objc2-javascript-core", - "objc2-security", + "proc-macro2", + "quote", ] [[package]] -name = "object" -version = "0.36.7" +name = "proc-macro-error2" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" dependencies = [ - "memchr", + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "once_cell" -version = "1.21.3" +name = "proc-macro-hack" +version = "0.5.20+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] -name = "open" -version = "5.3.2" +name = "proc-macro2" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ - "dunce", - "is-wsl", - "libc", - "pathdiff", + "unicode-ident", ] [[package]] -name = "option-ext" -version = "0.2.0" +name = "prost" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" +dependencies = [ + "bytes", + "prost-derive", +] [[package]] -name = "os_pipe" -version = "1.2.2" +name = "prost-derive" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db335f4760b14ead6290116f2427bf33a14d4f0617d49f78a246de10c1831224" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ - "libc", - "windows-sys 0.59.0", + "anyhow", + "itertools 0.12.1", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "pango" -version = "0.18.3" +name = "ptr_meta" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" dependencies = [ - "gio", - "glib", - "libc", - "once_cell", - "pango-sys", + "ptr_meta_derive", ] [[package]] -name = "pango-sys" -version = "0.18.0" +name = "ptr_meta_derive" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "parking_lot" -version = "0.11.2" +name = "quick-xml" +version = "0.38.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89" dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", + "memchr", ] [[package]] -name = "parking_lot" -version = "0.12.4" +name = "quinn" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ - "lock_api", - "parking_lot_core 0.9.11", + "bytes", + "cfg_aliases 0.2.1", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash 2.1.2", + "rustls 0.23.37", + "socket2 0.6.0", + "thiserror 2.0.16", + "tokio", + "tracing", + "web-time", ] [[package]] -name = "parking_lot_core" -version = "0.8.6" +name = "quinn-proto" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "bytes", + "getrandom 0.3.3", + "lru-slab", + "rand 0.9.2", + "ring", + "rustc-hash 2.1.2", + "rustls 0.23.37", + "rustls-pki-types", + "slab", + "thiserror 2.0.16", + "tinyvec", + "tracing", + "web-time", ] [[package]] -name = "parking_lot_core" -version = "0.9.11" +name = "quinn-udp" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ - "cfg-if", + "cfg_aliases 0.2.1", "libc", - "redox_syscall 0.5.17", - "smallvec", - "windows-targets 0.52.6", + "once_cell", + "socket2 0.6.0", + "tracing", + "windows-sys 0.60.2", ] [[package]] -name = "pathdiff" -version = "0.2.3" +name = "quote" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] [[package]] -name = "percent-encoding" -version = "2.3.2" +name = "r-efi" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" [[package]] -name = "phf" -version = "0.8.0" +name = "rancor" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" dependencies = [ - "phf_shared 0.8.0", + "ptr_meta", ] [[package]] -name = "phf" -version = "0.10.1" +name = "rand" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" dependencies = [ - "phf_macros 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", ] [[package]] -name = "phf" -version = "0.11.3" +name = "rand" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "phf_macros 0.11.3", - "phf_shared 0.11.3", + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", ] [[package]] -name = "phf_codegen" -version = "0.8.0" +name = "rand" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "phf_generator 0.8.0", - "phf_shared 0.8.0", + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] -name = "phf_codegen" -version = "0.11.3" +name = "rand_chacha" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", + "ppv-lite86", + "rand_core 0.5.1", ] [[package]] -name = "phf_generator" -version = "0.8.0" +name = "rand_chacha" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ - "phf_shared 0.8.0", - "rand 0.7.3", + "ppv-lite86", + "rand_core 0.6.4", ] [[package]] -name = "phf_generator" -version = "0.10.0" +name = "rand_chacha" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ - "phf_shared 0.10.0", - "rand 0.8.5", + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] -name = "phf_generator" -version = "0.11.3" +name = "rand_core" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" dependencies = [ - "phf_shared 0.11.3", - "rand 0.8.5", + "getrandom 0.1.16", ] [[package]] -name = "phf_macros" -version = "0.10.0" +name = "rand_core" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.109", + "getrandom 0.2.16", ] [[package]] -name = "phf_macros" -version = "0.11.3" +name = "rand_core" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", - "proc-macro2", - "quote", - "syn 2.0.106", + "getrandom 0.3.3", ] [[package]] -name = "phf_shared" -version = "0.8.0" +name = "rand_core" +version = "0.10.0-rc-3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher 0.3.11", -] +checksum = "f66ee92bc15280519ef199a274fe0cafff4245d31bc39aaa31c011ad56cb1f05" [[package]] -name = "phf_shared" -version = "0.10.0" +name = "rand_hc" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" dependencies = [ - "siphasher 0.3.11", + "rand_core 0.5.1", ] [[package]] -name = "phf_shared" -version = "0.11.3" +name = "rand_pcg" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" dependencies = [ - "siphasher 1.0.1", + "rand_core 0.5.1", ] [[package]] -name = "pin-project-lite" -version = "0.2.16" +name = "raw-window-handle" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] -name = "pin-utils" -version = "0.1.0" +name = "rayon" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +dependencies = [ + "either", + "rayon-core", +] [[package]] -name = "pkg-config" -version = "0.3.32" +name = "rayon-core" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] [[package]] -name = "plist" -version = "1.7.4" +name = "redox_syscall" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ - "base64 0.22.1", - "indexmap 2.11.1", - "quick-xml", - "serde", - "time", + "bitflags 2.9.4", ] [[package]] -name = "png" -version = "0.17.16" +name = "redox_users" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", + "getrandom 0.2.16", + "libredox", + "thiserror 2.0.16", ] [[package]] -name = "postgres-protocol" -version = "0.6.8" +name = "ref-cast" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76ff0abab4a9b844b93ef7b81f1efc0a366062aaef2cd702c76256b5dc075c54" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" dependencies = [ - "base64 0.22.1", - "byteorder", - "bytes", - "fallible-iterator", - "hmac", - "md-5", - "memchr", - "rand 0.9.2", - "sha2", - "stringprep", + "ref-cast-impl", ] [[package]] -name = "postgres-types" -version = "0.2.9" +name = "ref-cast-impl" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613283563cd90e1dfc3518d548caee47e0e725455ed619881f5cf21f36de4b48" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" dependencies = [ - "bytes", - "fallible-iterator", - "postgres-protocol", + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] -name = "potential_utf" -version = "0.1.3" +name = "regex" +version = "1.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" dependencies = [ - "zerovec", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] -name = "powerfmt" -version = "0.2.0" +name = "regex-automata" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] [[package]] -name = "ppv-lite86" -version = "0.2.21" +name = "regex-syntax" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] +checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" [[package]] -name = "precomputed-hash" -version = "0.1.1" +name = "rend" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" [[package]] -name = "proc-macro-crate" -version = "1.3.1" +name = "reqwest" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "once_cell", - "toml_edit 0.19.15", + "base64 0.22.1", + "bytes", + "futures-core", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.7.0", + "hyper-rustls 0.27.7", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls 0.23.37", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "tokio", + "tokio-rustls 0.26.4", + "tower 0.5.2", + "tower-http 0.6.8", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 1.0.6", ] [[package]] -name = "proc-macro-crate" -version = "2.0.2" +name = "reqwest" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" dependencies = [ - "toml_datetime 0.6.3", - "toml_edit 0.20.2", + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "hyper 1.7.0", + "hyper-rustls 0.27.7", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "rustls 0.23.37", + "rustls-pki-types", + "rustls-platform-verifier", + "serde", + "serde_json", + "sync_wrapper 1.0.2", + "tokio", + "tokio-rustls 0.26.4", + "tokio-util", + "tower 0.5.2", + "tower-http 0.6.8", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "rfc6979" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", + "hmac", + "subtle", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "rfd" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672" dependencies = [ - "proc-macro2", - "quote", - "version_check", + "block2 0.6.1", + "dispatch2", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc2 0.6.2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation 0.3.1", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.60.2", ] [[package]] -name = "proc-macro-hack" -version = "0.5.20+deprecated" +name = "ring" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] [[package]] -name = "proc-macro2" -version = "1.0.101" +name = "rkyv" +version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" dependencies = [ - "unicode-ident", + "bytes", + "hashbrown 0.16.1", + "indexmap 2.11.1", + "munge", + "ptr_meta", + "rancor", + "rend", + "rkyv_derive", + "tinyvec", + "uuid", ] [[package]] -name = "proc-macros" -version = "1.0.0" +name = "rkyv_derive" +version = "0.8.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" dependencies = [ "proc-macro2", "quote", @@ -2665,271 +5518,377 @@ dependencies = [ ] [[package]] -name = "quick-xml" -version = "0.38.3" +name = "rsa" +version = "0.10.0-rc.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89" +checksum = "c9a2b1eacbc34fbaf77f6f1db1385518446008d49b9f9f59dc9d1340fce4ca9e" dependencies = [ - "memchr", + "const-oid 0.10.2", + "crypto-bigint 0.7.0-rc.18", + "crypto-primes", + "digest 0.11.1", + "pkcs1", + "pkcs8 0.11.0-rc.11", + "rand_core 0.10.0-rc-3", + "sha2 0.11.0-rc.5", + "signature 3.0.0-rc.6", + "spki 0.8.0-rc.4", + "zeroize", ] [[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +name = "rsql" +version = "1.1.5" dependencies = [ - "proc-macro2", + "csv", + "deadpool-postgres", + "futures-util", + "libsql", + "native-tls", + "portable-pty", + "postgres-native-tls", + "rayon", + "rsql-core", + "russh", + "serde", + "serde_json", + "sonic-rs", + "sysinfo", + "tauri", + "tauri-build", + "tauri-plugin-dialog", + "tauri-plugin-fs", + "tauri-plugin-opener", + "tauri-plugin-process", + "tauri-plugin-shell", + "tauri-plugin-updater", + "thiserror 2.0.16", + "tokio", + "tokio-postgres", + "tracing", + "tracing-subscriber", ] [[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rand" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +name = "rsql-bench" +version = "1.1.5" dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc", - "rand_pcg", + "criterion", + "rsql-core", + "rsql-proxy", + "serde_json", + "sonic-rs", + "tokio-postgres", + "uuid", ] [[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +name = "rsql-core" +version = "1.1.5" dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", + "csv", + "deadpool-postgres", + "futures-util", + "libsql", + "native-tls", + "portable-pty", + "postgres-native-tls", + "rayon", + "russh", + "serde", + "serde_json", + "sonic-rs", + "sysinfo", + "tempfile", + "thiserror 2.0.16", + "tokio", + "tokio-postgres", + "tracing", + "uuid", ] [[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +name = "rsql-proxy" +version = "1.1.5" dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", + "axum 0.8.9", + "clap", + "futures-util", + "reqwest 0.12.28", + "rsql-core", + "serde", + "serde_json", + "sonic-rs", + "tempfile", + "tokio", + "tokio-postgres", + "tokio-tungstenite 0.24.0", + "tower 0.5.2", + "tower-http 0.6.8", + "tracing", + "tracing-subscriber", + "uuid", ] [[package]] -name = "rand_chacha" -version = "0.2.2" +name = "russh" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +checksum = "afe62631a04a1f4d71a14b99505483b95ff97c503b67d876c042fce659186956" dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", + "aes", + "aws-lc-rs", + "bitflags 2.9.4", + "block-padding", + "byteorder", + "bytes", + "cbc", + "ctr", + "curve25519-dalek", + "data-encoding", + "delegate", + "der 0.7.10", + "digest 0.10.7", + "ecdsa", + "ed25519-dalek", + "elliptic-curve", + "enum_dispatch", + "flate2", + "futures", + "generic-array 1.3.5", + "getrandom 0.2.16", + "hex-literal", + "hmac", + "home", + "inout", + "internal-russh-forked-ssh-key", + "libcrux-ml-kem", + "log", + "md5", + "num-bigint", + "p256", + "p384", + "p521", + "pageant", + "pbkdf2", + "pkcs1", + "pkcs5", + "pkcs8 0.10.2", + "rand 0.9.2", + "rand_core 0.10.0-rc-3", + "rsa", + "russh-cryptovec", + "russh-util", + "sec1", + "sha1 0.10.6", + "sha2 0.10.9", + "signature 2.2.0", + "spki 0.7.3", + "ssh-encoding", + "subtle", + "thiserror 1.0.69", + "tokio", + "typenum", + "zeroize", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "russh-cryptovec" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "4fb0ed583ff0f6b4aa44c7867dd7108df01b30571ee9423e250b4cc939f8c6cf" dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", + "libc", + "log", + "nix 0.29.0", + "ssh-encoding", + "winapi", ] [[package]] -name = "rand_chacha" -version = "0.9.0" +name = "russh-util" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +checksum = "668424a5dde0bcb45b55ba7de8476b93831b4aa2fa6947e145f3b053e22c60b6" dependencies = [ - "ppv-lite86", - "rand_core 0.9.3", + "chrono", + "tokio", + "wasm-bindgen", + "wasm-bindgen-futures", ] [[package]] -name = "rand_core" -version = "0.5.1" +name = "rustc-demangle" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" [[package]] -name = "rand_core" -version = "0.6.4" +name = "rustc-hash" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] -name = "rand_core" -version = "0.9.3" +name = "rustc-hash" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.3", -] +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] -name = "rand_hc" -version = "0.2.0" +name = "rustc_version" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "rand_core 0.5.1", + "semver", ] [[package]] -name = "rand_pcg" -version = "0.2.1" +name = "rustix" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "rand_core 0.5.1", + "bitflags 2.9.4", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", ] [[package]] -name = "raw-window-handle" -version = "0.6.2" +name = "rustix" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags 2.9.4", + "errno", + "libc", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.0", +] [[package]] -name = "redox_syscall" -version = "0.2.16" +name = "rustls" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ - "bitflags 1.3.2", + "log", + "ring", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "subtle", + "zeroize", ] [[package]] -name = "redox_syscall" -version = "0.5.17" +name = "rustls" +version = "0.23.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" dependencies = [ - "bitflags 2.9.4", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki 0.103.9", + "subtle", + "zeroize", ] [[package]] -name = "redox_users" -version = "0.5.2" +name = "rustls-native-certs" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" dependencies = [ - "getrandom 0.2.16", - "libredox", - "thiserror 2.0.16", + "openssl-probe 0.1.6", + "rustls-pemfile", + "rustls-pki-types", + "schannel", + "security-framework 2.11.1", ] [[package]] -name = "ref-cast" -version = "1.0.24" +name = "rustls-native-certs" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" dependencies = [ - "ref-cast-impl", + "openssl-probe 0.2.1", + "rustls-pki-types", + "schannel", + "security-framework 3.5.1", ] [[package]] -name = "ref-cast-impl" -version = "1.0.24" +name = "rustls-pemfile" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", + "rustls-pki-types", ] [[package]] -name = "regex" -version = "1.11.2" +name = "rustls-pki-types" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", + "web-time", + "zeroize", ] [[package]] -name = "regex-automata" -version = "0.4.10" +name = "rustls-platform-verifier" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", + "core-foundation 0.10.1", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls 0.23.37", + "rustls-native-certs 0.8.3", + "rustls-platform-verifier-android", + "rustls-webpki 0.103.9", + "security-framework 3.5.1", + "security-framework-sys", + "webpki-root-certs", + "windows-sys 0.61.0", ] [[package]] -name = "regex-syntax" -version = "0.8.6" +name = "rustls-platform-verifier-android" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] -name = "reqwest" -version = "0.12.23" +name = "rustls-webpki" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ - "base64 0.22.1", - "bytes", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-util", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", + "ring", + "rustls-pki-types", + "untrusted 0.9.0", ] [[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - -[[package]] -name = "rustc_version" -version = "0.4.1" +name = "rustls-webpki" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ - "semver", + "ring", + "rustls-pki-types", + "untrusted 0.9.0", ] [[package]] @@ -2940,9 +5899,18 @@ checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "salsa20" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] [[package]] name = "same-file" @@ -2953,6 +5921,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.0", +] + [[package]] name = "schemars" version = "0.8.22" @@ -3010,6 +5987,67 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scrypt" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" +dependencies = [ + "pbkdf2", + "salsa20", + "sha2 0.10.9", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.10", + "generic-array 0.14.7", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.9.4", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" +dependencies = [ + "bitflags 2.9.4", + "core-foundation 0.10.1", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "selectors" version = "0.24.0" @@ -3039,10 +6077,11 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -3057,11 +6096,20 @@ dependencies = [ "typeid", ] +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -3081,14 +6129,26 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", ] [[package]] @@ -3164,6 +6224,27 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "serdect" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af4a3e75ebd5599b30d4de5768e00b5095d518a79fefc3ecbaf77e665d1ec06" +dependencies = [ + "base16ct 1.0.0", + "serde", +] + +[[package]] +name = "serial2" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1401f562d358cdfdbdf8946e51a7871ede1db68bd0fd99bedc79e400241550" +dependencies = [ + "cfg-if", + "libc", + "winapi", +] + [[package]] name = "serialize-to-javascript" version = "0.1.2" @@ -3196,6 +6277,28 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha1" +version = "0.11.0-rc.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b167252f3c126be0d8926639c4c4706950f01445900c4b3db0fd7e89fcb750a" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.11.1", +] + [[package]] name = "sha2" version = "0.10.9" @@ -3204,7 +6307,18 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0-rc.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.11.1", ] [[package]] @@ -3227,6 +6341,22 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "shared_library" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "shell-words" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" + [[package]] name = "shlex" version = "1.3.0" @@ -3263,12 +6393,38 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "3.0.0-rc.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a96996ccff7dfa16f052bd995b4cecc72af22c35138738dc029f0ead6608d" +dependencies = [ + "digest 0.11.1", + "rand_core 0.10.0-rc-3", +] + [[package]] name = "simd-adler32" version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "siphasher" version = "0.3.11" @@ -3287,22 +6443,6 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" -[[package]] -name = "sled" -version = "0.34.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" -dependencies = [ - "crc32fast", - "crossbeam-epoch", - "crossbeam-utils", - "fs2", - "fxhash", - "libc", - "log", - "parking_lot 0.11.2", -] - [[package]] name = "smallvec" version = "1.15.1" @@ -3336,21 +6476,60 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08" dependencies = [ "bytemuck", - "cfg_aliases", - "core-graphics", - "foreign-types", + "cfg_aliases 0.2.1", + "core-graphics 0.24.0", + "foreign-types 0.5.0", "js-sys", "log", "objc2 0.5.2", "objc2-foundation 0.2.2", - "objc2-quartz-core 0.2.2", + "objc2-quartz-core", "raw-window-handle", - "redox_syscall 0.5.17", + "redox_syscall", "wasm-bindgen", "web-sys", "windows-sys 0.59.0", ] +[[package]] +name = "sonic-number" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5661364b38abad49cf1ade6631fcc35d2ccf882a7d68616b4228b7717feb5fba" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "sonic-rs" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16b39f36452a4fa6f14a481b02e9ba5c6842c6a44d0545da967eca122f2eed9" +dependencies = [ + "ahash", + "bumpalo", + "bytes", + "cfg-if", + "faststr", + "itoa", + "ref-cast", + "serde", + "simdutf8", + "sonic-number", + "sonic-simd", + "thiserror 2.0.16", + "zmij", +] + +[[package]] +name = "sonic-simd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f944718c33623919878cf74b4c9361eb3024f635733922b26722b14cd3f8cc" +dependencies = [ + "cfg-if", +] + [[package]] name = "soup3" version = "0.5.0" @@ -3377,12 +6556,73 @@ dependencies = [ "system-deps", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.10", +] + +[[package]] +name = "spki" +version = "0.8.0-rc.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8baeff88f34ed0691978ec34440140e1572b68c7dd4a495fd14a3dc1944daa80" +dependencies = [ + "base64ct", + "der 0.8.0", +] + +[[package]] +name = "ssh-cipher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" +dependencies = [ + "aes", + "aes-gcm", + "cbc", + "chacha20", + "cipher", + "ctr", + "poly1305", + "ssh-encoding", + "subtle", +] + +[[package]] +name = "ssh-encoding" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" +dependencies = [ + "base64ct", + "bytes", + "pem-rfc7468 0.7.0", + "sha2 0.10.9", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "string_cache" version = "0.8.9" @@ -3390,7 +6630,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ "new_debug_unreachable", - "parking_lot 0.12.4", + "parking_lot", "phf_shared 0.11.3", "precomputed-hash", "serde", @@ -3464,6 +6704,12 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "sync_wrapper" version = "1.0.2" @@ -3484,6 +6730,20 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "sysinfo" +version = "0.38.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d03c61d2a49c649a15c407338afe7accafde9dac869995dccb73e5f7ef7d9034" +dependencies = [ + "libc", + "memchr", + "ntapi", + "objc2-core-foundation", + "objc2-io-kit", + "windows 0.62.1", +] + [[package]] name = "system-deps" version = "6.2.2" @@ -3493,29 +6753,28 @@ dependencies = [ "cfg-expr", "heck 0.5.0", "pkg-config", - "toml 0.8.2", + "toml 0.8.23", "version-compare", ] [[package]] name = "tao" -version = "0.34.3" +version = "0.34.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "959469667dbcea91e5485fc48ba7dd6023face91bb0f1a14681a70f99847c3f7" +checksum = "6e06d52c379e63da659a483a958110bbde891695a0ecb53e48cc7786d5eda7bb" dependencies = [ "bitflags 2.9.4", "block2 0.6.1", - "core-foundation", - "core-graphics", + "core-foundation 0.10.1", + "core-graphics 0.25.0", "crossbeam-channel", - "dispatch", + "dispatch2", "dlopen2", "dpi", "gdkwayland-sys", "gdkx11-sys", "gtk", "jni", - "lazy_static", "libc", "log", "ndk", @@ -3525,14 +6784,13 @@ dependencies = [ "objc2-app-kit", "objc2-foundation 0.3.1", "once_cell", - "parking_lot 0.12.4", + "parking_lot", "raw-window-handle", - "scopeguard", "tao-macros", "unicode-segmentation", "url", - "windows", - "windows-core", + "windows 0.61.3", + "windows-core 0.61.2", "windows-version", "x11-dl", ] @@ -3548,6 +6806,17 @@ dependencies = [ "syn 2.0.106", ] +[[package]] +name = "tar" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +dependencies = [ + "filetime", + "libc", + "xattr", +] + [[package]] name = "target-lexicon" version = "0.12.16" @@ -3556,9 +6825,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.8.5" +version = "2.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d1d3b3dc4c101ac989fd7db77e045cc6d91a25349cd410455cb5c57d510c1c" +checksum = "da77cc00fb9028caf5b5d4650f75e31f1ef3693459dfca7f7e506d1ecef0ba2d" dependencies = [ "anyhow", "bytes", @@ -3570,7 +6839,7 @@ dependencies = [ "glob", "gtk", "heck 0.5.0", - "http", + "http 1.3.1", "jni", "libc", "log", @@ -3584,7 +6853,7 @@ dependencies = [ "percent-encoding", "plist", "raw-window-handle", - "reqwest", + "reqwest 0.13.2", "serde", "serde_json", "serde_repr", @@ -3599,18 +6868,17 @@ dependencies = [ "tokio", "tray-icon", "url", - "urlpattern", "webkit2gtk", "webview2-com", "window-vibrancy", - "windows", + "windows 0.61.3", ] [[package]] name = "tauri-build" -version = "2.4.1" +version = "2.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c432ccc9ff661803dab74c6cd78de11026a578a9307610bbc39d3c55be7943f" +checksum = "4bbc990d1dbf57a8e1c7fa2327f2a614d8b757805603c1b9ba5c81bade09fd4d" dependencies = [ "anyhow", "cargo_toml", @@ -3630,9 +6898,9 @@ dependencies = [ [[package]] name = "tauri-codegen" -version = "2.4.0" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ab3a62cf2e6253936a8b267c2e95839674e7439f104fa96ad0025e149d54d8a" +checksum = "d4a24476afd977c5d5d169f72425868613d82747916dd29e0a357c84c4bd6d29" dependencies = [ "base64 0.22.1", "brotli", @@ -3645,7 +6913,7 @@ dependencies = [ "semver", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "syn 2.0.106", "tauri-utils", "thiserror 2.0.16", @@ -3657,9 +6925,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.4.0" +version = "2.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4368ea8094e7045217edb690f493b55b30caf9f3e61f79b4c24b6db91f07995e" +checksum = "d39b349a98dadaffebb73f0a40dcd1f23c999211e5a2e744403db384d0c33de7" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -3671,9 +6939,9 @@ dependencies = [ [[package]] name = "tauri-plugin" -version = "2.4.0" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9946a3cede302eac0c6eb6c6070ac47b1768e326092d32efbb91f21ed58d978f" +checksum = "ddde7d51c907b940fb573006cdda9a642d6a7c8153657e88f8a5c3c9290cd4aa" dependencies = [ "anyhow", "glob", @@ -3683,29 +6951,79 @@ dependencies = [ "serde_json", "tauri-utils", "toml 0.9.5", - "walkdir", + "walkdir", +] + +[[package]] +name = "tauri-plugin-dialog" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9204b425d9be8d12aa60c2a83a289cf7d1caae40f57f336ed1155b3a5c0e359b" +dependencies = [ + "log", + "raw-window-handle", + "rfd", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-plugin-fs", + "thiserror 2.0.16", + "url", +] + +[[package]] +name = "tauri-plugin-fs" +version = "2.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed390cc669f937afeb8b28032ce837bac8ea023d975a2e207375ec05afaf1804" +dependencies = [ + "anyhow", + "dunce", + "glob", + "percent-encoding", + "schemars 0.8.22", + "serde", + "serde_json", + "serde_repr", + "tauri", + "tauri-plugin", + "tauri-utils", + "thiserror 2.0.16", + "toml 0.9.5", + "url", ] [[package]] -name = "tauri-plugin-fs" -version = "2.4.2" +name = "tauri-plugin-opener" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "315784ec4be45e90a987687bae7235e6be3d6e9e350d2b75c16b8a4bf22c1db7" +checksum = "786156aa8e89e03d271fbd3fe642207da8e65f3c961baa9e2930f332bf80a1f5" dependencies = [ - "anyhow", "dunce", "glob", - "percent-encoding", + "objc2-app-kit", + "objc2-foundation 0.3.1", + "open", "schemars 0.8.22", "serde", "serde_json", - "serde_repr", "tauri", "tauri-plugin", - "tauri-utils", "thiserror 2.0.16", - "toml 0.9.5", "url", + "windows 0.61.3", + "zbus", +] + +[[package]] +name = "tauri-plugin-process" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d55511a7bf6cd70c8767b02c97bf8134fa434daf3926cfc1be0a0f94132d165a" +dependencies = [ + "tauri", + "tauri-plugin", ] [[package]] @@ -3729,16 +7047,49 @@ dependencies = [ "tokio", ] +[[package]] +name = "tauri-plugin-updater" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fe8e9bebd88fc222938ffdfbdcfa0307081423bd01e3252fc337d8bde81fc61" +dependencies = [ + "base64 0.22.1", + "dirs", + "flate2", + "futures-util", + "http 1.3.1", + "infer", + "log", + "minisign-verify", + "osakit", + "percent-encoding", + "reqwest 0.13.2", + "rustls 0.23.37", + "semver", + "serde", + "serde_json", + "tar", + "tauri", + "tauri-plugin", + "tempfile", + "thiserror 2.0.16", + "time", + "tokio", + "url", + "windows-sys 0.60.2", + "zip", +] + [[package]] name = "tauri-runtime" -version = "2.8.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4cfc9ad45b487d3fded5a4731a567872a4812e9552e3964161b08edabf93846" +checksum = "2826d79a3297ed08cd6ea7f412644ef58e32969504bc4fbd8d7dbeabc4445ea2" dependencies = [ "cookie", "dpi", "gtk", - "http", + "http 1.3.1", "jni", "objc2 0.6.2", "objc2-ui-kit", @@ -3751,22 +7102,21 @@ dependencies = [ "url", "webkit2gtk", "webview2-com", - "windows", + "windows 0.61.3", ] [[package]] name = "tauri-runtime-wry" -version = "2.8.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fe9d48bd122ff002064e88cfcd7027090d789c4302714e68fcccba0f4b7807" +checksum = "e11ea2e6f801d275fdd890d6c9603736012742a1c33b96d0db788c9cdebf7f9e" dependencies = [ "gtk", - "http", + "http 1.3.1", "jni", "log", "objc2 0.6.2", "objc2-app-kit", - "objc2-foundation 0.3.1", "once_cell", "percent-encoding", "raw-window-handle", @@ -3777,15 +7127,15 @@ dependencies = [ "url", "webkit2gtk", "webview2-com", - "windows", + "windows 0.61.3", "wry", ] [[package]] name = "tauri-utils" -version = "2.7.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41a3852fdf9a4f8fbeaa63dc3e9a85284dd6ef7200751f0bd66ceee30c93f212" +checksum = "219a1f983a2af3653f75b5747f76733b0da7ff03069c7a41901a5eb3ace4557d" dependencies = [ "anyhow", "brotli", @@ -3794,7 +7144,7 @@ dependencies = [ "dunce", "glob", "html5ever", - "http", + "http 1.3.1", "infer", "json-patch", "kuchikiki", @@ -3829,6 +7179,19 @@ dependencies = [ "toml 0.9.5", ] +[[package]] +name = "tempfile" +version = "3.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix 1.1.2", + "windows-sys 0.61.0", +] + [[package]] name = "tendril" version = "0.4.3" @@ -3929,6 +7292,16 @@ dependencies = [ "zerovec", ] +[[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.10.0" @@ -3944,6 +7317,27 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tls_codec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de2e01245e2bb89d6f05801c564fa27624dbd7b1846859876c7dad82e90bf6b" +dependencies = [ + "tls_codec_derive", + "zeroize", +] + +[[package]] +name = "tls_codec_derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2e76690929402faae40aebdda620a2c0e25dd6d3b9afe48867dfd95991f4bd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "tokio" version = "1.47.1" @@ -3955,38 +7349,128 @@ dependencies = [ "io-uring", "libc", "mio", + "parking_lot", "pin-project-lite", + "signal-hook-registry", "slab", "socket2 0.6.0", + "tokio-macros", "windows-sys 0.59.0", ] +[[package]] +name = "tokio-io-timeout" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bd86198d9ee903fedd2f9a2e72014287c0d9167e4ae43b5853007205dda1b76" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[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-postgres" -version = "0.7.13" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c95d533c83082bb6490e0189acaa0bbeef9084e60471b696ca6988cd0541fb0" +checksum = "2b40d66d9b2cfe04b628173409368e58247e8eddbbd3b0e6c6ba1d09f20f6c9e" dependencies = [ "async-trait", "byteorder", "bytes", - "fallible-iterator", + "fallible-iterator 0.2.0", "futures-channel", "futures-util", "log", - "parking_lot 0.12.4", + "parking_lot", "percent-encoding", - "phf 0.11.3", + "phf 0.13.1", "pin-project-lite", "postgres-protocol", "postgres-types", "rand 0.9.2", - "socket2 0.5.10", + "socket2 0.6.0", "tokio", "tokio-util", "whoami", ] +[[package]] +name = "tokio-rustls" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" +dependencies = [ + "rustls 0.22.4", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls 0.23.37", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc5f74e248dc973e0dbb7b74c7e0d6fcc301c694ff50049504004ef4d0cdcd9" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.24.0", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f72a05e828585856dacd553fba484c242c46e391fb0e58917c942ee9202915c" +dependencies = [ + "futures-util", + "log", + "tokio", + "tungstenite 0.29.0", +] + [[package]] name = "tokio-util" version = "0.7.16" @@ -4002,14 +7486,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.2" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned 0.6.9", - "toml_datetime 0.6.3", - "toml_edit 0.20.2", + "toml_datetime 0.6.11", + "toml_edit 0.22.27", ] [[package]] @@ -4029,9 +7513,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" dependencies = [ "serde", ] @@ -4052,21 +7536,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ "indexmap 2.11.1", - "toml_datetime 0.6.3", + "toml_datetime 0.6.11", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.11.1", + "toml_datetime 0.6.11", "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ "indexmap 2.11.1", "serde", "serde_spanned 0.6.9", - "toml_datetime 0.6.3", - "winnow 0.5.40", + "toml_datetime 0.6.11", + "winnow 0.7.13", ] [[package]] @@ -4084,6 +7579,73 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" +[[package]] +name = "tonic" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" +dependencies = [ + "async-stream", + "async-trait", + "axum 0.6.20", + "base64 0.21.7", + "bytes", + "h2", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "tokio", + "tokio-stream", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-web" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc3b0e1cedbf19fdfb78ef3d672cb9928e0a91a9cb4629cc0c916e8cff8aaaa1" +dependencies = [ + "base64 0.21.7", + "bytes", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", + "pin-project", + "tokio-stream", + "tonic", + "tower-http 0.4.4", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower" version = "0.5.2" @@ -4093,28 +7655,59 @@ dependencies = [ "futures-core", "futures-util", "pin-project-lite", - "sync_wrapper", + "sync_wrapper 1.0.2", "tokio", "tower-layer", "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +dependencies = [ + "bitflags 2.9.4", + "bytes", + "futures-core", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "http-range-header 0.3.1", + "pin-project-lite", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", ] [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "bitflags 2.9.4", "bytes", + "futures-core", "futures-util", - "http", - "http-body", + "http 1.3.1", + "http-body 1.0.1", + "http-body-util", + "http-range-header 0.4.2", + "httpdate", "iri-string", + "mime", + "mime_guess", + "percent-encoding", "pin-project-lite", - "tower", + "tokio", + "tokio-util", + "tower 0.5.2", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -4135,6 +7728,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -4178,10 +7772,14 @@ version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ + "matchers", "nu-ansi-term", + "once_cell", + "regex-automata", "sharded-slab", "smallvec", "thread_local", + "tracing", "tracing-core", "tracing-log", ] @@ -4214,6 +7812,40 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "tungstenite" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e5b8366ee7a95b16d32197d0b2604b43a0be89dc5fac9f8e96ccafbaedda8a" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http 1.3.1", + "httparse", + "log", + "rand 0.8.5", + "sha1 0.10.6", + "thiserror 1.0.69", + "utf-8", +] + +[[package]] +name = "tungstenite" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c01152af293afb9c7c2a57e4b559c5620b421f6d133261c60dd2d0cdb38e6b8" +dependencies = [ + "bytes", + "data-encoding", + "http 1.3.1", + "httparse", + "log", + "rand 0.9.2", + "sha1 0.10.6", + "thiserror 2.0.16", +] + [[package]] name = "typeid" version = "1.0.3" @@ -4221,10 +7853,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] -name = "typenum" -version = "1.18.0" +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "uds_windows" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" +dependencies = [ + "memoffset", + "tempfile", + "winapi", +] + +[[package]] +name = "uncased" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" +dependencies = [ + "version_check", +] [[package]] name = "unic-char-property" @@ -4267,6 +7919,12 @@ dependencies = [ "unic-common", ] +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + [[package]] name = "unicode-bidi" version = "0.3.18" @@ -4300,6 +7958,28 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common 0.1.6", + "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 = "url" version = "2.5.7" @@ -4336,6 +8016,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.18.1" @@ -4354,6 +8040,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" +[[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.2.0" @@ -4443,9 +8135,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.101" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" +checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" dependencies = [ "cfg-if", "once_cell", @@ -4454,27 +8146,14 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.106", - "wasm-bindgen-shared", -] - [[package]] name = "wasm-bindgen-futures" -version = "0.4.51" +version = "0.4.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca85039a9b469b38336411d6d6ced91f3fc87109a2a27b0c197663f5144dffe" +checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" dependencies = [ "cfg-if", + "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -4483,9 +8162,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.101" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" +checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4493,31 +8172,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.101" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" +checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn 2.0.106", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.101" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" +checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" dependencies = [ "unicode-ident", ] [[package]] name = "wasm-streams" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" dependencies = [ "futures-util", "js-sys", @@ -4528,9 +8207,19 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.78" +version = "0.3.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", @@ -4538,9 +8227,9 @@ dependencies = [ [[package]] name = "webkit2gtk" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" +checksum = "a1027150013530fb2eaf806408df88461ae4815a45c541c8975e61d6f2fc4793" dependencies = [ "bitflags 1.3.2", "cairo-rs", @@ -4562,9 +8251,9 @@ dependencies = [ [[package]] name = "webkit2gtk-sys" -version = "2.0.1" +version = "2.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" +checksum = "916a5f65c2ef0dfe12fff695960a2ec3d4565359fdbb2e9943c974e06c734ea5" dependencies = [ "bitflags 1.3.2", "cairo-sys-rs", @@ -4580,6 +8269,33 @@ dependencies = [ "system-deps", ] +[[package]] +name = "webpki-root-certs" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "webpki-roots" +version = "0.26.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" +dependencies = [ + "webpki-roots 1.0.6", +] + +[[package]] +name = "webpki-roots" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "webview2-com" version = "0.38.0" @@ -4588,8 +8304,8 @@ checksum = "d4ba622a989277ef3886dd5afb3e280e3dd6d974b766118950a08f8f678ad6a4" dependencies = [ "webview2-com-macros", "webview2-com-sys", - "windows", - "windows-core", + "windows 0.61.3", + "windows-core 0.61.2", "windows-implement", "windows-interface", ] @@ -4612,8 +8328,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36695906a1b53a3bf5c4289621efedac12b73eeb0b89e7e1a89b517302d5d75c" dependencies = [ "thiserror 2.0.16", - "windows", - "windows-core", + "windows 0.61.3", + "windows-core 0.61.2", +] + +[[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.44", ] [[package]] @@ -4679,11 +8407,23 @@ version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ - "windows-collections", - "windows-core", - "windows-future", + "windows-collections 0.2.0", + "windows-core 0.61.2", + "windows-future 0.2.1", "windows-link 0.1.3", - "windows-numerics", + "windows-numerics 0.2.0", +] + +[[package]] +name = "windows" +version = "0.62.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e6c4a1f363c8210c6f77ba24f645c61c6fb941eccf013da691f7e09515b8ac" +dependencies = [ + "windows-collections 0.3.1", + "windows-core 0.62.1", + "windows-future 0.3.1", + "windows-numerics 0.3.0", ] [[package]] @@ -4692,7 +8432,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core", + "windows-core 0.61.2", +] + +[[package]] +name = "windows-collections" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123e712f464a8a60ce1a13f4c446d2d43ab06464cb5842ff68f5c71b6fb7852e" +dependencies = [ + "windows-core 0.62.1", ] [[package]] @@ -4704,8 +8453,21 @@ dependencies = [ "windows-implement", "windows-interface", "windows-link 0.1.3", - "windows-result", - "windows-strings", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-core" +version = "0.62.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.0", + "windows-result 0.4.0", + "windows-strings 0.5.0", ] [[package]] @@ -4714,16 +8476,27 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ - "windows-core", + "windows-core 0.61.2", "windows-link 0.1.3", - "windows-threading", + "windows-threading 0.1.0", +] + +[[package]] +name = "windows-future" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f3db6b24b120200d649cd4811b4947188ed3a8d2626f7075146c5d178a9a4a" +dependencies = [ + "windows-core 0.62.1", + "windows-link 0.2.0", + "windows-threading 0.2.0", ] [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", @@ -4732,9 +8505,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", @@ -4759,10 +8532,20 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-core", + "windows-core 0.61.2", "windows-link 0.1.3", ] +[[package]] +name = "windows-numerics" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ce3498fe0aba81e62e477408383196b4b0363db5e0c27646f932676283b43d8" +dependencies = [ + "windows-core 0.62.1", + "windows-link 0.2.0", +] + [[package]] name = "windows-result" version = "0.3.4" @@ -4772,6 +8555,15 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-result" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" +dependencies = [ + "windows-link 0.2.0", +] + [[package]] name = "windows-strings" version = "0.4.2" @@ -4781,6 +8573,15 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-strings" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" +dependencies = [ + "windows-link 0.2.0", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -4883,6 +8684,15 @@ dependencies = [ "windows-link 0.1.3", ] +[[package]] +name = "windows-threading" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab47f085ad6932defa48855254c758cdd0e2f2d48e62a34118a268d8f345e118" +dependencies = [ + "windows-link 0.2.0", +] + [[package]] name = "windows-version" version = "0.1.5" @@ -5044,6 +8854,18 @@ name = "winnow" version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" +dependencies = [ + "winapi", +] [[package]] name = "winreg" @@ -5069,9 +8891,9 @@ checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "wry" -version = "0.53.3" +version = "0.54.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31f0e9642a0d061f6236c54ccae64c2722a7879ad4ec7dff59bd376d446d8e90" +checksum = "bb26159b420aa77684589a744ae9a9461a95395b848764ad12290a14d960a11a" dependencies = [ "base64 0.22.1", "block2 0.6.1", @@ -5083,7 +8905,7 @@ dependencies = [ "gdkx11", "gtk", "html5ever", - "http", + "http 1.3.1", "javascriptcore-rs", "jni", "kuchikiki", @@ -5098,7 +8920,7 @@ dependencies = [ "once_cell", "percent-encoding", "raw-window-handle", - "sha2", + "sha2 0.10.9", "soup3", "tao-macros", "thiserror 2.0.16", @@ -5106,8 +8928,8 @@ dependencies = [ "webkit2gtk", "webkit2gtk-sys", "webview2-com", - "windows", - "windows-core", + "windows 0.61.3", + "windows-core 0.61.2", "windows-version", "x11-dl", ] @@ -5133,6 +8955,16 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "xattr" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" +dependencies = [ + "libc", + "rustix 1.1.2", +] + [[package]] name = "yoke" version = "0.8.0" @@ -5157,13 +8989,94 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zbus" +version = "5.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d07e46d035fb8e375b2ce63ba4e4ff90a7f73cf2ffb0138b29e1158d2eaadf7" +dependencies = [ + "async-broadcast", + "async-executor", + "async-io", + "async-lock", + "async-process", + "async-recursion", + "async-task", + "async-trait", + "blocking", + "enumflags2", + "event-listener", + "futures-core", + "futures-lite", + "hex", + "nix 0.30.1", + "ordered-stream", + "serde", + "serde_repr", + "tracing", + "uds_windows", + "windows-sys 0.60.2", + "winnow 0.7.13", + "zbus_macros", + "zbus_names", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "5.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57e797a9c847ed3ccc5b6254e8bcce056494b375b511b3d6edcec0aeb4defaca" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.106", + "zbus_names", + "zvariant", + "zvariant_utils", +] + +[[package]] +name = "zbus_names" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" +dependencies = [ + "serde", + "static_assertions", + "winnow 0.7.13", + "zvariant", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive 0.7.35", +] + [[package]] name = "zerocopy" version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ - "zerocopy-derive", + "zerocopy-derive 0.8.27", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] @@ -5198,6 +9111,26 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "zerotrie" version = "0.2.2" @@ -5230,3 +9163,61 @@ dependencies = [ "quote", "syn 2.0.106", ] + +[[package]] +name = "zip" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa8cd6af31c3b31c6631b8f483848b91589021b28fffe50adada48d4f4d2ed1" +dependencies = [ + "arbitrary", + "crc32fast", + "indexmap 2.11.1", + "memchr", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + +[[package]] +name = "zvariant" +version = "5.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "999dd3be73c52b1fccd109a4a81e4fcd20fab1d3599c8121b38d04e1419498db" +dependencies = [ + "endi", + "enumflags2", + "serde", + "winnow 0.7.13", + "zvariant_derive", + "zvariant_utils", +] + +[[package]] +name = "zvariant_derive" +version = "5.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6643fd0b26a46d226bd90d3f07c1b5321fe9bb7f04673cb37ac6d6883885b68e" +dependencies = [ + "proc-macro-crate 3.3.0", + "proc-macro2", + "quote", + "syn 2.0.106", + "zvariant_utils", +] + +[[package]] +name = "zvariant_utils" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6949d142f89f6916deca2232cf26a8afacf2b9fdc35ce766105e104478be599" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "syn 2.0.106", + "winnow 0.7.13", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..70cfc10 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,40 @@ +[workspace] +members = ["crates/rsql-bench", "crates/rsql-core", "crates/rsql-proxy", "crates/rsql-tauri"] +resolver = "3" + +[workspace.package] +version = "1.1.5" +edition = "2024" +authors = ["rust-dd"] +description = "Modern SQL Client" + +[workspace.dependencies] +axum = { version = "0.8", features = ["ws", "macros"] } +clap = { version = "4.5", features = ["derive", "env"] } +criterion = { version = "0.5", features = ["html_reports"] } +csv = "1.3" +deadpool-postgres = "0.14.1" +futures-util = "0.3" +libsql = "0.9.29" +native-tls = "0.2" +portable-pty = "0.9.0" +postgres-native-tls = "0.5" +rayon = "1.11.0" +russh = "0.57" +serde = { version = "1", features = ["derive"] } +serde_json = "1" +sonic-rs = "0.5" +sysinfo = "0.38.3" +thiserror = "2" +tokio = "1.47.1" +tokio-postgres = "0.7.13" +tower = "0.5" +tower-http = { version = "0.6", features = ["fs", "trace"] } +tracing = "0.1.41" +tracing-subscriber = { version = "0.3.20", features = ["fmt", "env-filter"] } +uuid = { version = "1", features = ["v7", "serde"] } + +[profile.release] +codegen-units = 1 +lto = true +strip = "symbols" diff --git a/README.md b/README.md index 49ad2e4..af21536 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,62 @@ Planned features, roughly in priority order: --- +## Docker (Browser Build) + +The same RSQL frontend that ships in the Tauri desktop app is also available as a one-command Docker image. The image bundles a Rust WebSocket proxy that exposes every backend command over WS, so the full feature set works in a browser. + +```bash +docker run -d \ + -p 8080:8080 \ + -v rsql-data:/data \ + ghcr.io/rust-dd/rsql:latest +# open http://localhost:8080 +``` + +All connection data, query history, and workspaces persist in the named volume `rsql-data` mounted at `/data`. + +### Environment variables + +| Variable | Default | Description | +|----------|---------|-------------| +| `RSQL_BIND` | `0.0.0.0:8080` | Listen address. Override to `127.0.0.1:8080` for loopback-only. | +| `RSQL_DIST_DIR` | `/app/dist` | Static asset directory (frontend bundle). Leave default. | +| `RSQL_STATE_PATH` | `/data/rsql.db` | libsql state file path. Keep on a mounted volume to persist across restarts. | +| `RSQL_DISABLE_TERMINAL` | _unset_ | Set to `1` to disable the built-in PTY terminal. Recommended for any container reachable from outside `127.0.0.1`. | +| `RUST_LOG` | `info,rsql_proxy=info` | tracing-subscriber env filter. | + +### Security + +The image listens on `0.0.0.0:8080` so it works out of the box with `docker run -p`. **The proxy is designed for trusted networks (a developer laptop, a private network)**. Do not expose it to the public internet without putting an auth layer in front (oauth2-proxy, Caddy with basic auth, Cloudflare Access, etc.). + +The built-in terminal spawns a real PTY inside the container. If your container is reachable from any untrusted source, set `RSQL_DISABLE_TERMINAL=1`. + +### Tags + +- `latest` — most recent release. +- `vX.Y.Z` — pinned to a specific release tag (matches `release.yml`). +- `X.Y.Z` — same image, version-only tag. + +### Multi-arch + +Images are published for `linux/amd64` and `linux/arm64`. `docker pull` picks the right variant automatically. + +--- + +## Performance + +RSQL ships a Criterion-based microbench suite for the packed-binary path and the proxy's WS framing. The exit gate for the browser/proxy build is **scroll FPS within 10% of the desktop Tauri build on a 1M-row query**. + +Run the bench suite: + +```bash +cargo bench -p rsql-bench +``` + +Reports land under `target/criterion///report/index.html`. See [BENCHMARKS.md](./BENCHMARKS.md) for methodology, hardware fingerprint, captured numbers, and the manual 1M-row scroll FPS procedure. + +--- + ## Development ```bash diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 0000000..4425d7c --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,194 @@ +# RSQL — Feature Roadmap + +A prioritizált lista a tervezett feature-ökről. A kutatás a DataGrip, DBeaver, TablePlus, Beekeeper Studio feature listáin és a fejlesztői közösség visszajelzésein alapul. + +--- + +## Tier 1 — Magas hatás, gyors megvalósítás + +### 1. Safe Mode / Production Guard +**Effort:** Alacsony | **Impact:** Nagyon magas + +- Szín-kódolt connection-ök: piros = production, sárga = staging, zöld = development +- Az ablak titlebar / chrome a connection színét veszi fel — egy pillantásra látni, hol vagy +- Production connection-ök read-only módba állíthatók (csak SELECT/EXPLAIN engedélyezett) +- DML/DDL futtatáshoz explicit Cmd+Shift+Enter szükséges + preview az érintett sorokról +- "Code review" panel: az összes pending módosítás diff-ként jelenik meg commit előtt (mint TablePlus) + +**Miért:** A TablePlus legjobban szeretett feature-je. Minden fejlesztő félelme, hogy production-ön futtat véletlenül DELETE-et. + +--- + +### 2. AI-Powered Text-to-SQL (Cmd+I) +**Effort:** Közepes | **Impact:** Nagyon magas + +- Natural language → SQL a jelenlegi schema context-tel +- A Rust backend introspect-álja az `information_schema`-t és `pg_catalog`-ot, kompakt schema leírást küld az LLM-nek +- Támogatott provider-ek: OpenAI, Anthropic Claude, **Ollama (lokális modellek)** — user saját API kulcsot ad meg +- Inline prompt az editorban (Cmd+I) vagy dedikált chat panel +- Jobb-klikk akciók: "Explain this query in English", "Suggest indexes for this query" +- Lokális modell támogatás az igazi differenciátor — a legtöbb competitor csak cloud API-t támogat + +**Miért:** 2025-2026-ban ez a #1 trend a database tooling-ban. DataGrip, Beekeeper Studio, Chat2DB mind szállítja. + +--- + +### 3. Inline Charts / Data Visualization +**Effort:** Alacsony | **Impact:** Magas + +- Új "Chart" tab a results panelen (Grid / Record / History / **Chart**) +- Auto-detect: numerikus oszlop = Y tengely, kategorikus/timestamp = X tengely +- Chart típusok: bar, line, pie, scatter +- Lightweight lib: `recharts` vagy `visx` (React + D3) +- Export PNG/SVG +- Aggregate query → azonnali vizualizáció, nem kell CSV-be exportálni és spreadsheet-ben chart-olni + +**Miért:** Fejlesztők napi szinten futtatnak COUNT/SUM/AVG query-ket és az eredményt spreadsheet-be másolják chart-hoz. + +--- + +### 4. Query Parameterization +**Effort:** Alacsony | **Impact:** Közepes-Magas + +- `$1`, `:param_name`, `?` placeholder detektálás az SQL-ben +- Parameter input panel az editor felett/mellett +- Típus kiválasztás (text, int, boolean, date, stb.) +- Native PostgreSQL parameterized execution (`tokio-postgres` támogatja natívan) — nem string interpoláció +- Parameter set-ek menthetők a saved query-k mellett +- SQL injection is megelőzhető a tool-on belül + +**Miért:** Application kódból jövő query-k teszteléséhez elengedhetetlen. DataGrip tudja, a legtöbb más tool nem. + +--- + +## Tier 2 — Erős feature-ök, közepes effort + +### 5. Visual Query Builder +**Effort:** Közepes-Magas | **Impact:** Magas + +- Canvas ahol a schema browser-ből húzhatók táblák +- Oszlopok megjelennek, FK vonalak automatikusan +- JOIN-ok létrehozása vonalak húzásával +- SELECT oszlopok kiválasztása checkbox-szal +- WHERE feltételek form field-ekkel +- Real-time SQL generálás split pane-ben — a user szerkesztheti közvetlenül +- Kiindulópont: a meglévő `erd-diagram.tsx` component + +**Miért:** Ismeretlen, 50+ táblás schema-knál nagyon hasznos az onboarding-hoz. Navicat és DBeaver Pro feature. + +--- + +### 6. Multi-Format Import (Excel, Parquet, JSON) +**Effort:** Közepes | **Impact:** Magas + +- **Excel (.xlsx)** — Rust `calamine` crate +- **Parquet** — Rust `arrow` / `parquet` crate-ek +- **JSON array** — `sonic-rs` (már van a projektben) +- Column mapping UI (mint a meglévő CSV importnál) +- Preview az első N sorból +- Bulk insert `COPY` protokollal +- **Parquet támogatás az igazi differenciátor** — szinte egyetlen GUI client sem kezeli natívan, pedig a data engineering pipeline-okban mindenhol van + +**Miért:** A CSV importon túl a valós workflow-kban Excel és Parquet fájlok is jönnek. + +--- + +### 7. Schema Migration Script Generation +**Effort:** Közepes | **Impact:** Magas + +- A meglévő `schema-diff-panel.tsx` kimenetéből generálható futtatható migration script +- `ALTER TABLE`, `CREATE INDEX`, `DROP CONSTRAINT` stb. helyes sorrendben (dependency-aware) +- Kiválasztható, melyik változások kerüljenek be +- Flyway/Liquibase-kompatibilis output formátum opció +- Másolás vágólapra vagy mentés `.sql` fájlba +- Opcionálisan: `migrations/` mappa konvenció integráció + +**Miért:** A schema diff vizuális, de a fejlesztőknek futtatható SQL kell. DataGrip csinálja, a legtöbb más tool nem. + +--- + +### 8. Backup & Restore GUI +**Effort:** Alacsony-Közepes | **Impact:** Közepes + +- `pg_dump` / `pg_restore` wrapper +- Form UI: formátum (custom/plain/directory), schema-only / data-only, compression level, specific tables +- Progress streaming a Rust child process kimenetéből +- Backup history +- Feltétel: `pg_dump` elérhető legyen a rendszeren + +**Miért:** pgAdmin az egyetlen GUI ami csinálja. Mindenki más terminálba kényszerül. + +--- + +## Tier 3 — Egyedi differenciátorok + +### 9. RLS Policy Editor +**Effort:** Közepes | **Impact:** Közepes | **Differenciáció:** Nagyon magas + +- Vizuális editor Row-Level Security policy-khez +- Per-tábla policy lista: role, operation (SELECT/INSERT/UPDATE/DELETE/ALL), USING/WITH CHECK expression +- Form: role kiválasztás, operation, expression editor autocomplete-tel (oszlopnevek, `current_user`, `current_setting()`) +- Preview: generált `CREATE POLICY` / `ALTER POLICY` statement +- **Egyetlen GUI client sem csinálja jól** — Supabase/multi-tenant app fejlesztőknek kritikus + +**Miért:** Az RLS egyre elterjedtebb (különösen Supabase-nél), de raw SQL-ben kezelni fájdalmas. + +--- + +### 10. Local DuckDB / PGLite Execution +**Effort:** Közepes | **Impact:** Közepes | **Differenciáció:** Nagyon magas + +- "Local" connection típus — nincs szükség PostgreSQL szerverre +- CSV/Parquet/JSON fájl drag-and-drop → automatikus DuckDB virtual table +- SQL futtatás lokálisan, offline +- Scratchpad mód: gyors adat-exploráció fájlokból anélkül, hogy importálni kellene PostgreSQL-be +- DuckDB C API hívható Rust-ból; PGLite már a website kódbázisban van + +**Miért:** Data engineer-ek és analyst-ek gyakran csak meg akarnak nézni egy fájlt SQL-ben, anélkül hogy teljes DB-t állítanának be. + +--- + +### 11. Vim-Style Keyboard Navigation +**Effort:** Alacsony | **Impact:** Közepes | **Differenciáció:** Magas + +- Monaco vim mode (`monaco-vim` extension — drop-in) +- Grid navigáció: arrow keys, Enter = szerkesztés, Escape = mégse, Tab = következő cella +- Schema browser: j/k navigáció, Enter = kibontás +- Keyboard shortcuts referencia panel (Cmd+?) +- Customizable key bindings + +**Miért:** Power user-ek HN-en és Reddit-en folyamatosan kérik. Egyetlen competitor sem teljesen keyboard-navigálható. + +--- + +### 12. Multi-Database Support +**Effort:** Magas | **Impact:** Nagyon magas | **Differenciáció:** Alacsony (elvárt) + +- A `crates/rsql-core/src/drivers/pgsql/` struktúra már kész az extensibility-re (`mod.rs` + submodules), és `crates/rsql-tauri/` csak a Tauri wrappereket tartalmazza +- **MySQL** — `mysql_async` crate +- **SQLite** — `rusqlite` crate +- **Redis** — `redis` crate +- Minden driver egy közös trait-et implementál +- A frontend adaptálja a schema browser-t és az editor autocomplete-et az aktív driver alapján + +**Miért:** A legtöbb fejlesztő többféle adatbázissal dolgozik. DBeaver 80+-t támogat, DataGrip ~53-at. Ez drasztikusan növelné a user base-t. + +--- + +## Saved Queries / Snippet Library +> **Megjegyzés:** Jelenleg a `QueryStore` (Zustand) és a `queries` SQLite tábla már támogatja a query mentést. A UI továbbfejleszthető: mappa struktúra, tag-ek, import/export JSON-ként megosztáshoz. + +## Transactional Data Editing with Diff Review +> **Megjegyzés:** Az inline editing (`results-grid.tsx`) már generál UPDATE/DELETE-et. A továbbfejlesztés: change buffering (nem azonnali commit), diff preview panel, és egyetlen tranzakcióban commitolás Cmd+S-re. + +--- + +## Kutatási források + +- [DataGrip Features](https://www.jetbrains.com/datagrip/features/) +- [DBeaver Features](https://dbeaver.io/features/) +- [TablePlus](https://tableplus.com/) +- [Beekeeper Studio](https://www.beekeeperstudio.io/) +- [Evil Martians: 100 Dev Tool Landing Pages Study](https://evilmartians.com/chronicles/we-studied-100-devtool-landing-pages-here-is-what-actually-works-in-2025) +- Reddit r/PostgreSQL, r/database, HN fejlesztői visszajelzések +- Bytebase, DbVisualizer, pgMustard összehasonlító cikkek diff --git a/crates/rsql-bench/Cargo.toml b/crates/rsql-bench/Cargo.toml new file mode 100644 index 0000000..8aa7c70 --- /dev/null +++ b/crates/rsql-bench/Cargo.toml @@ -0,0 +1,29 @@ +[package] +name = "rsql-bench" +version.workspace = true +edition.workspace = true +authors.workspace = true +publish = false + +[dependencies] + +[dev-dependencies] +criterion = { workspace = true } +rsql-core = { path = "../rsql-core" } +rsql-proxy = { path = "../rsql-proxy" } +serde_json = { workspace = true } +sonic-rs = { workspace = true } +tokio-postgres = { workspace = true } +uuid = { workspace = true } + +[[bench]] +name = "pack_rows" +harness = false + +[[bench]] +name = "protocol_frames" +harness = false + +[[bench]] +name = "process_simple_messages" +harness = false diff --git a/crates/rsql-bench/benches/.gitkeep b/crates/rsql-bench/benches/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/crates/rsql-bench/benches/pack_rows.rs b/crates/rsql-bench/benches/pack_rows.rs new file mode 100644 index 0000000..b8012f0 --- /dev/null +++ b/crates/rsql-bench/benches/pack_rows.rs @@ -0,0 +1,37 @@ +use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; +use rsql_core::drivers::pgsql::query_execution::pack_rows_vec; + +fn make_rows(n: usize, cols: usize) -> Vec> { + let mut out = Vec::with_capacity(n); + for r in 0..n { + let mut row = Vec::with_capacity(cols); + for c in 0..cols { + row.push(format!("r{r}c{c}_xyz_0123456789")); + } + out.push(row); + } + out +} + +fn bench_pack_rows(c: &mut Criterion) { + let mut group = c.benchmark_group("pack_rows_vec"); + group.sample_size(20); + for size in [1_000usize, 10_000, 100_000, 1_000_000] { + let rows = make_rows(size, 10); + let bytes: u64 = rows + .iter() + .map(|r| r.iter().map(|s| s.len() as u64).sum::()) + .sum(); + group.throughput(Throughput::Bytes(bytes)); + group.bench_with_input(BenchmarkId::from_parameter(size), &rows, |b, rows| { + b.iter(|| { + let packed = pack_rows_vec(rows); + std::hint::black_box(packed); + }); + }); + } + group.finish(); +} + +criterion_group!(benches, bench_pack_rows); +criterion_main!(benches); diff --git a/crates/rsql-bench/benches/process_simple_messages.rs b/crates/rsql-bench/benches/process_simple_messages.rs new file mode 100644 index 0000000..50451b1 --- /dev/null +++ b/crates/rsql-bench/benches/process_simple_messages.rs @@ -0,0 +1,53 @@ +use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; +use rsql_core::drivers::pgsql::query_execution::{pack_rows_vec, process_simple_messages}; + +// Synthesise a (columns, rows) pair directly. `SimpleQueryMessage::Row` / +// `CommandComplete` constructors are private to tokio_postgres, so feeding +// `process_simple_messages` synthetic input requires a live PG connection. +// The realistic hot path that follows it (`pack_rows_vec`) is covered here; +// the message-decoding loop itself is a single mem copy per cell, not +// representative of the WS workload bottleneck. +fn synth_rows(rows: usize, cols: usize) -> (Vec, Vec>) { + let columns = (0..cols).map(|c| format!("col_{c}")).collect::>(); + let mut data = Vec::with_capacity(rows); + for r in 0..rows { + let row = (0..cols) + .map(|c| format!("r{r}c{c}_val_abcdefghij")) + .collect::>(); + data.push(row); + } + (columns, data) +} + +fn bench_full_pack(c: &mut Criterion) { + let mut group = c.benchmark_group("pack_full_resultset"); + group.sample_size(20); + for &rows in &[1_000usize, 100_000, 1_000_000] { + let (_cols, data) = synth_rows(rows, 10); + let bytes: u64 = data + .iter() + .map(|r| r.iter().map(|s| s.len() as u64).sum::()) + .sum(); + group.throughput(Throughput::Bytes(bytes)); + group.bench_with_input(BenchmarkId::from_parameter(rows), &data, |b, data| { + b.iter(|| { + let packed = pack_rows_vec(data); + std::hint::black_box(packed); + }); + }); + } + group.finish(); +} + +fn bench_setup_overhead(c: &mut Criterion) { + c.bench_function("synth_rows_setup_1m", |b| { + b.iter(|| { + let (cols, rows) = synth_rows(1_000_000, 10); + std::hint::black_box((cols, rows)); + }); + }); + let _ = process_simple_messages; +} + +criterion_group!(benches, bench_full_pack, bench_setup_overhead); +criterion_main!(benches); diff --git a/crates/rsql-bench/benches/protocol_frames.rs b/crates/rsql-bench/benches/protocol_frames.rs new file mode 100644 index 0000000..0580bf0 --- /dev/null +++ b/crates/rsql-bench/benches/protocol_frames.rs @@ -0,0 +1,71 @@ +use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; +use rsql_proxy::protocol::{Outbound, parse_text}; +use serde_json::json; +use uuid::Uuid; + +fn small_payload() -> serde_json::Value { + json!({"status": "ok", "rows": 1, "elapsed_ms": 12.4}) +} + +fn large_payload(rows: usize) -> serde_json::Value { + let mut data: Vec = Vec::with_capacity(rows); + for i in 0..rows { + data.push(json!({"id": i, "name": format!("user_{i}"), "score": (i as f64) * 1.7})); + } + json!({"columns": ["id", "name", "score"], "data": data}) +} + +fn binary_payload(bytes: usize) -> Vec { + (0..bytes).map(|i| (i % 251) as u8).collect() +} + +fn bench_encode(c: &mut Criterion) { + let mut group = c.benchmark_group("protocol_encode_text"); + let id = Uuid::now_v7(); + for (label, value) in [ + ("small", small_payload()), + ("1k_rows", large_payload(1_000)), + ("10k_rows", large_payload(10_000)), + ] { + group.bench_with_input(BenchmarkId::from_parameter(label), &value, |b, payload| { + b.iter(|| { + let frame = Outbound::response(id, payload.clone()); + let msg = frame.into_ws_message().expect("encode"); + std::hint::black_box(msg); + }); + }); + } + group.finish(); +} + +fn bench_encode_binary(c: &mut Criterion) { + let mut group = c.benchmark_group("protocol_encode_binary"); + let id = Uuid::now_v7(); + for size in [1_024usize, 65_536, 1_048_576] { + let payload = binary_payload(size); + group.throughput(Throughput::Bytes(size as u64)); + group.bench_with_input(BenchmarkId::from_parameter(size), &payload, |b, payload| { + b.iter(|| { + let frame = Outbound::binary(id, payload.clone()); + let msg = frame.into_ws_message().expect("encode"); + std::hint::black_box(msg); + }); + }); + } + group.finish(); +} + +fn bench_decode(c: &mut Criterion) { + let mut group = c.benchmark_group("protocol_decode_text"); + let request = r#"{"type":"request","id":"01928f5c-1234-7abc-9def-0123456789ab","cmd":"pgsql_run_query","payload":{"project_id":"p","sql":"SELECT 1"}}"#; + group.bench_function("typical_request", |b| { + b.iter(|| { + let inbound = parse_text(request).expect("parse"); + std::hint::black_box(inbound); + }); + }); + group.finish(); +} + +criterion_group!(benches, bench_encode, bench_encode_binary, bench_decode); +criterion_main!(benches); diff --git a/crates/rsql-bench/src/lib.rs b/crates/rsql-bench/src/lib.rs new file mode 100644 index 0000000..b148e2b --- /dev/null +++ b/crates/rsql-bench/src/lib.rs @@ -0,0 +1,2 @@ +//! Criterion microbenchmarks for rsql-core and rsql-proxy hot paths. +//! No public API — benches live under `benches/`. diff --git a/crates/rsql-core/Cargo.toml b/crates/rsql-core/Cargo.toml new file mode 100644 index 0000000..218309d --- /dev/null +++ b/crates/rsql-core/Cargo.toml @@ -0,0 +1,33 @@ +[package] +name = "rsql-core" +version.workspace = true +edition.workspace = true +authors.workspace = true +description = "Shared core for the rsql desktop and proxy builds" + +[lib] +path = "src/lib.rs" + +[dependencies] +serde.workspace = true +serde_json.workspace = true +sonic-rs.workspace = true +tokio.workspace = true +tokio-postgres.workspace = true +deadpool-postgres.workspace = true +postgres-native-tls.workspace = true +native-tls.workspace = true +tracing.workspace = true +libsql.workspace = true +thiserror.workspace = true +portable-pty.workspace = true +rayon.workspace = true +sysinfo.workspace = true +csv.workspace = true +futures-util.workspace = true +russh.workspace = true +uuid = { workspace = true } + +[dev-dependencies] +tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } +tempfile = "3" diff --git a/src-tauri/src/common.rs b/crates/rsql-core/src/common/mod.rs similarity index 87% rename from src-tauri/src/common.rs rename to crates/rsql-core/src/common/mod.rs index 498856f..3431b55 100644 --- a/src-tauri/src/common.rs +++ b/crates/rsql-core/src/common/mod.rs @@ -1,6 +1,5 @@ use std::collections::BTreeMap; -pub mod enums; pub mod pgsql; pub type BTreeVecStore = BTreeMap>; diff --git a/src-tauri/src/common/pgsql.rs b/crates/rsql-core/src/common/pgsql.rs similarity index 100% rename from src-tauri/src/common/pgsql.rs rename to crates/rsql-core/src/common/pgsql.rs diff --git a/src-tauri/src/drivers/mod.rs b/crates/rsql-core/src/drivers/mod.rs similarity index 100% rename from src-tauri/src/drivers/mod.rs rename to crates/rsql-core/src/drivers/mod.rs diff --git a/src-tauri/src/drivers/pgsql/commands/admin_commands.rs b/crates/rsql-core/src/drivers/pgsql/commands/admin.rs similarity index 56% rename from src-tauri/src/drivers/pgsql/commands/admin_commands.rs rename to crates/rsql-core/src/drivers/pgsql/commands/admin.rs index 60889df..86f9e56 100644 --- a/src-tauri/src/drivers/pgsql/commands/admin_commands.rs +++ b/crates/rsql-core/src/drivers/pgsql/commands/admin.rs @@ -1,123 +1,104 @@ use crate::AppState; -use crate::common::enums::AppError; -use crate::drivers::pgsql::{ - DbGrant, PgRole, SchemaObject, TableGrant, execute_query, extract_schema_objects, - import_csv_to_table, load_available_extensions, load_database_grants, load_enum_types, - load_extensions, load_pg_settings, load_roles, load_table_grants, parse_csv_preview, +use crate::drivers::pgsql::extensions::{ + load_available_extensions, load_enum_types, load_extensions, load_pg_settings, }; +use crate::drivers::pgsql::query_execution::execute_query; +use crate::drivers::pgsql::roles_schema_objects::{ + DbGrant, PgRole, SchemaObject, TableGrant, extract_schema_objects, import_csv_to_table, + load_database_grants, load_roles, load_table_grants, parse_csv_preview, +}; +use crate::error::AppError; -use tauri::ipc::Response; -use tauri::{Result, State}; - -use super::pool_connection::acquire_client; +use super::pool_helpers::acquire_client; -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_csv_preview(file_path: &str) -> Result<(Vec, Vec>)> { - parse_csv_preview(file_path, 5).await.map_err(Into::into) +pub async fn pgsql_csv_preview( + file_path: &str, +) -> Result<(Vec, Vec>), AppError> { + parse_csv_preview(file_path, 5).await } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_csv_import( + app_state: &AppState, project_id: &str, file_path: &str, schema: &str, table: &str, column_mapping: Vec<(usize, String)>, - app_state: State<'_, AppState>, -) -> Result { +) -> Result { let client = acquire_client(&app_state.clients, project_id).await?; - import_csv_to_table(&client, file_path, schema, table, &column_mapping) - .await - .map_err(Into::into) + import_csv_to_table(&client, file_path, schema, table, &column_mapping).await } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_load_roles( + app_state: &AppState, project_id: &str, - app_state: State<'_, AppState>, -) -> Result> { +) -> Result, AppError> { let client = acquire_client(&app_state.meta_clients, project_id).await?; - load_roles(&client).await.map_err(Into::into) + load_roles(&client).await } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_load_table_grants( + app_state: &AppState, project_id: &str, role_name: &str, - app_state: State<'_, AppState>, -) -> Result> { +) -> Result, AppError> { let client = acquire_client(&app_state.meta_clients, project_id).await?; - load_table_grants(&client, role_name) - .await - .map_err(Into::into) + load_table_grants(&client, role_name).await } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_load_database_grants( + app_state: &AppState, project_id: &str, role_name: &str, - app_state: State<'_, AppState>, -) -> Result> { +) -> Result, AppError> { let client = acquire_client(&app_state.meta_clients, project_id).await?; - load_database_grants(&client, role_name) - .await - .map_err(Into::into) + load_database_grants(&client, role_name).await } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_extract_schema_objects( + app_state: &AppState, project_id: &str, schema: &str, - app_state: State<'_, AppState>, -) -> Result> { +) -> Result, AppError> { let client = acquire_client(&app_state.meta_clients, project_id).await?; - extract_schema_objects(&client, schema) - .await - .map_err(Into::into) + extract_schema_objects(&client, schema).await } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_load_extensions( + app_state: &AppState, project_id: &str, - app_state: State<'_, AppState>, -) -> Result { +) -> Result { let client = acquire_client(&app_state.meta_clients, project_id).await?; let result = load_extensions(&client).await?; - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_load_available_extensions( + app_state: &AppState, project_id: &str, - app_state: State<'_, AppState>, -) -> Result { +) -> Result { let client = acquire_client(&app_state.meta_clients, project_id).await?; let result = load_available_extensions(&client).await?; - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_load_enum_types( + app_state: &AppState, project_id: &str, - app_state: State<'_, AppState>, -) -> Result { +) -> Result { let client = acquire_client(&app_state.meta_clients, project_id).await?; let result = load_enum_types(&client).await?; - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_table_action( + app_state: &AppState, project_id: &str, action: &str, schema: &str, table: &str, object_type: &str, - app_state: State<'_, AppState>, -) -> Result { +) -> Result { let client = acquire_client(&app_state.clients, project_id).await?; fn qi(name: &str) -> String { @@ -148,23 +129,20 @@ pub async fn pgsql_table_action( return Err(AppError::QueryFailed(format!( "Unknown action '{}' for object type '{}'", action, object_type - )) - .into()); + ))); } }; - execute_query(&client, &sql).await.map_err(|e| e)?; + execute_query(&client, &sql).await?; Ok(format!("{action} completed successfully.")) } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_load_pg_settings( + app_state: &AppState, project_id: &str, - app_state: State<'_, AppState>, -) -> Result { +) -> Result { let client = acquire_client(&app_state.meta_clients, project_id).await?; let result = load_pg_settings(&client).await?; - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) } diff --git a/src-tauri/src/drivers/pgsql/commands/pool_connection.rs b/crates/rsql-core/src/drivers/pgsql/commands/connection.rs similarity index 55% rename from src-tauri/src/drivers/pgsql/commands/pool_connection.rs rename to crates/rsql-core/src/drivers/pgsql/commands/connection.rs index 6d7e355..24e204e 100644 --- a/src-tauri/src/drivers/pgsql/commands/pool_connection.rs +++ b/crates/rsql-core/src/drivers/pgsql/commands/connection.rs @@ -1,156 +1,36 @@ -use std::{collections::BTreeMap, sync::Arc}; +use std::sync::Arc; -use deadpool_postgres::{Manager as PgManager, ManagerConfig, Pool, RecyclingMethod}; +use tokio_postgres::Config; use crate::AppState; -use crate::common::enums::{AppError, ProjectConnectionStatus}; -use crate::drivers::pgsql::get_pool; +use crate::error::{AppError, ProjectConnectionStatus}; -use native_tls::TlsConnector; -use postgres_native_tls::MakeTlsConnector; -use tauri::{AppHandle, Manager, Result}; -use tokio_postgres::{CancelToken, Config, NoTls}; +use super::pool_helpers::{create_pg_pool, full_error_chain}; -pub(crate) fn is_sqlite_lock_error(message: &str) -> bool { - let lower = message.to_ascii_lowercase(); - lower.contains("database is locked") || lower.contains("database busy") -} - -pub(crate) fn full_error_chain(e: &dyn std::error::Error) -> String { - let mut msg = e.to_string(); - let mut src = e.source(); - while let Some(cause) = src { - msg.push_str(": "); - msg.push_str(&cause.to_string()); - src = cause.source(); - } - msg -} - -pub(crate) fn create_pg_pool( - cfg: &Config, - use_ssl: bool, - max_size: usize, -) -> std::result::Result { - let manager_config = ManagerConfig { - recycling_method: RecyclingMethod::Custom("ROLLBACK".into()), - }; - - if use_ssl { - let tls_connector = TlsConnector::builder() - .build() - .map_err(|e| AppError::ConnectionFailed(e.to_string()))?; - let tls = MakeTlsConnector::new(tls_connector); - let manager = PgManager::from_config(cfg.clone(), tls, manager_config); - Pool::builder(manager) - .max_size(max_size) - .build() - .map_err(|e| AppError::ConnectionFailed(e.to_string())) - } else { - let manager = PgManager::from_config(cfg.clone(), NoTls, manager_config); - Pool::builder(manager) - .max_size(max_size) - .build() - .map_err(|e| AppError::ConnectionFailed(e.to_string())) - } -} - -pub(crate) async fn acquire_client( - pools_mutex: &tokio::sync::Mutex>>, - project_id: &str, -) -> std::result::Result { - let pool = { - let pools = pools_mutex.lock().await; - get_pool(&pools, project_id)? - }; - - pool.get() - .await - .map_err(|e| AppError::ConnectionFailed(e.to_string())) -} - -pub(crate) async fn apply_statement_timeout(client: &deadpool_postgres::Client, timeout_ms: u32) { - if timeout_ms > 0 { - client - .simple_query(&format!("SET statement_timeout = {}", timeout_ms)) - .await - .ok(); - } -} - -pub(crate) async fn reset_statement_timeout(client: &deadpool_postgres::Client, timeout_ms: u32) { - if timeout_ms > 0 { - client.simple_query("RESET statement_timeout").await.ok(); - } -} - -pub(crate) async fn set_cancel_token( - app_state: &AppState, - project_id: &str, - token: CancelToken, -) -> std::result::Result<(), AppError> { - let mut cancel_tokens = app_state.cancel_tokens.lock().await; - cancel_tokens.insert(project_id.to_string(), token); - Ok(()) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_test_connection(key: [&str; 6]) -> Result { - let user = key[0]; - let password = key[1]; - let database = key[2]; - let host = key[3]; - let port: u16 = key[4].parse().unwrap_or(5432); - let use_ssl = key[5] == "true"; - - let mut cfg = Config::new(); - cfg.user(user) - .password(password) - .dbname(database) - .host(host) - .port(port); - - let pool = create_pg_pool(&cfg, use_ssl, 1)?; - let client = pool - .get() - .await - .map_err(|e| AppError::ConnectionFailed(full_error_chain(&e)))?; - - let row = client - .query_one("SELECT version()", &[]) - .await - .map_err(|e| AppError::ConnectionFailed(e.to_string()))?; - - let version: String = row.get(0); - Ok(version) -} - -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_connector( + state: &AppState, project_id: &str, key: Option<[&str; 6]>, ssh: Option>, - app: AppHandle, -) -> Result { - let app_state = app.state::(); +) -> Result { { - let clients = app_state.clients.lock().await; + let clients = state.clients.lock().await; if clients.contains_key(project_id) { return Ok(ProjectConnectionStatus::Connected); } } let (user, password, database, host, port_str, use_ssl) = match key { - Some(key) => ( - key[0].to_string(), - key[1].to_string(), - key[2].to_string(), - key[3].to_string(), - key[4].to_string(), - key[5] == "true", + Some(k) => ( + k[0].to_string(), + k[1].to_string(), + k[2].to_string(), + k[3].to_string(), + k[4].to_string(), + k[5] == "true", ), None => { - let conn = app_state + let conn = state .local_db .connect() .map_err(|e| AppError::DatabaseError(e.to_string()))?; @@ -178,7 +58,6 @@ pub async fn pgsql_connector( }; let (effective_host, effective_port_str) = if let Some(ref ssh_params) = ssh { - // ssh_params: [ssh_host, ssh_port, ssh_user, ssh_password, ssh_key_path] if ssh_params.len() >= 3 && !ssh_params[0].is_empty() { let ssh_host = &ssh_params[0]; let ssh_port: u16 = ssh_params[1].parse().unwrap_or(22); @@ -192,7 +71,7 @@ pub async fn pgsql_connector( .filter(|s| !s.is_empty()) .map(|s| s.as_str()); - app_state.ssh_tunnels.lock().await.remove(project_id); + state.ssh_tunnels.lock().await.remove(project_id); let tunnel = crate::ssh::start_tunnel( ssh_host, @@ -207,7 +86,7 @@ pub async fn pgsql_connector( .map_err(|e| AppError::ConnectionFailed(e))?; let local_port = tunnel.local_port; - app_state + state .ssh_tunnels .lock() .await @@ -233,46 +112,75 @@ pub async fn pgsql_connector( Ok(p) => Arc::new(p), Err(e) => { tracing::error!("Query pool creation failed: {:?}", e); - return Err(AppError::ConnectionFailed(full_error_chain(&e)).into()); + return Err(AppError::ConnectionFailed(full_error_chain(&e))); } }; let meta_pool = match create_pg_pool(&cfg, use_ssl, 8) { Ok(p) => Arc::new(p), Err(e) => { tracing::error!("Meta pool creation failed: {:?}", e); - return Err(AppError::ConnectionFailed(full_error_chain(&e)).into()); + return Err(AppError::ConnectionFailed(full_error_chain(&e))); } }; - // Validate connectivity eagerly so connector keeps previous fail/connected behavior. let query_client = match query_pool.get().await { Ok(c) => c, Err(e) => { tracing::error!("Query pool initial connection failed: {:?}", e); - return Err(AppError::ConnectionFailed(full_error_chain(&e)).into()); + return Err(AppError::ConnectionFailed(full_error_chain(&e))); } }; if let Err(e) = meta_pool.get().await { tracing::error!("Meta pool initial connection failed: {:?}", e); - return Err(AppError::ConnectionFailed(full_error_chain(&e)).into()); + return Err(AppError::ConnectionFailed(full_error_chain(&e))); } { - let mut clients = app_state.clients.lock().await; + let mut clients = state.clients.lock().await; clients.insert(project_id.to_string(), Arc::clone(&query_pool)); } { - let mut meta_clients = app_state.meta_clients.lock().await; + let mut meta_clients = state.meta_clients.lock().await; meta_clients.insert(project_id.to_string(), Arc::clone(&meta_pool)); } { - let mut cancel_tokens = app_state.cancel_tokens.lock().await; + let mut cancel_tokens = state.cancel_tokens.lock().await; cancel_tokens.insert(project_id.to_string(), query_client.cancel_token()); } { - let mut client_ssl = app_state.client_ssl.lock().await; + let mut client_ssl = state.client_ssl.lock().await; client_ssl.insert(project_id.to_string(), use_ssl); } Ok(ProjectConnectionStatus::Connected) } + +pub async fn pgsql_test_connection(key: [&str; 6]) -> Result { + let user = key[0]; + let password = key[1]; + let database = key[2]; + let host = key[3]; + let port: u16 = key[4].parse().unwrap_or(5432); + let use_ssl = key[5] == "true"; + + let mut cfg = Config::new(); + cfg.user(user) + .password(password) + .dbname(database) + .host(host) + .port(port); + + let pool = create_pg_pool(&cfg, use_ssl, 1)?; + let client = pool + .get() + .await + .map_err(|e| AppError::ConnectionFailed(full_error_chain(&e)))?; + + let row = client + .query_one("SELECT version()", &[]) + .await + .map_err(|e| AppError::ConnectionFailed(e.to_string()))?; + + let version: String = row.get(0); + Ok(version) +} diff --git a/crates/rsql-core/src/drivers/pgsql/commands/metadata.rs b/crates/rsql-core/src/drivers/pgsql/commands/metadata.rs new file mode 100644 index 0000000..740eea1 --- /dev/null +++ b/crates/rsql-core/src/drivers/pgsql/commands/metadata.rs @@ -0,0 +1,189 @@ +use crate::AppState; +use crate::common::pgsql::{PgsqlLoadColumns, PgsqlLoadSchemas, PgsqlLoadTables}; +use crate::drivers::pgsql::metadata_schema::{ + load_column_details, load_columns, load_constraints, load_databases, load_indexes, + load_policies, load_rules, load_schemas, load_tables, load_tablespaces, load_triggers, +}; +use crate::drivers::pgsql::metadata_views_functions::{ + load_functions, load_materialized_views, load_trigger_functions, load_views, +}; +use crate::drivers::pgsql::{ + ColumnDetail, ConstraintDetail, FunctionInfo, IndexDetail, PolicyDetail, RuleDetail, + TriggerDetail, get_pool, +}; +use crate::error::AppError; + +use super::pool_helpers::acquire_client; + +pub async fn pgsql_load_databases( + app_state: &AppState, + project_id: &str, +) -> Result, AppError> { + let pool = { + let pools = app_state.meta_clients.lock().await; + get_pool(&pools, project_id)? + }; + load_databases(&pool).await +} + +pub async fn pgsql_load_tablespaces( + app_state: &AppState, + project_id: &str, +) -> Result, AppError> { + let pool = { + let pools = app_state.meta_clients.lock().await; + get_pool(&pools, project_id)? + }; + load_tablespaces(&pool).await +} + +pub async fn pgsql_load_schemas( + app_state: &AppState, + project_id: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_schemas( + &client, + r#"SELECT schema_name FROM information_schema.schemata + WHERE schema_name NOT IN ('pg_catalog', 'information_schema') + ORDER BY schema_name"#, + ) + .await +} + +pub async fn pgsql_load_tables( + app_state: &AppState, + project_id: &str, + schema: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_tables( + &client, + r#"SELECT table_name, + pg_size_pretty(pg_total_relation_size('"' || table_schema || '"."' || table_name || '"')) AS size + FROM information_schema.tables + WHERE table_schema = $1 + ORDER BY table_name"#, + schema, + ) + .await +} + +pub async fn pgsql_load_columns( + app_state: &AppState, + project_id: &str, + schema: &str, + table: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_columns(&client, schema, table).await +} + +pub async fn pgsql_load_column_details( + app_state: &AppState, + project_id: &str, + schema: &str, + table: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_column_details(&client, schema, table).await +} + +pub async fn pgsql_load_indexes( + app_state: &AppState, + project_id: &str, + schema: &str, + table: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_indexes(&client, schema, table).await +} + +pub async fn pgsql_load_constraints( + app_state: &AppState, + project_id: &str, + schema: &str, + table: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_constraints(&client, schema, table).await +} + +pub async fn pgsql_load_triggers( + app_state: &AppState, + project_id: &str, + schema: &str, + table: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_triggers(&client, schema, table).await +} + +pub async fn pgsql_load_rules( + app_state: &AppState, + project_id: &str, + schema: &str, + table: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_rules(&client, schema, table).await +} + +pub async fn pgsql_load_policies( + app_state: &AppState, + project_id: &str, + schema: &str, + table: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_policies(&client, schema, table).await +} + +pub async fn pgsql_load_views( + app_state: &AppState, + project_id: &str, + schema: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_views(&client, schema).await +} + +pub async fn pgsql_load_materialized_views( + app_state: &AppState, + project_id: &str, + schema: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_materialized_views(&client, schema).await +} + +pub async fn pgsql_load_functions( + app_state: &AppState, + project_id: &str, + schema: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_functions(&client, schema).await +} + +pub async fn pgsql_load_trigger_functions( + app_state: &AppState, + project_id: &str, + schema: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + + load_trigger_functions(&client, schema).await +} diff --git a/crates/rsql-core/src/drivers/pgsql/commands/mod.rs b/crates/rsql-core/src/drivers/pgsql/commands/mod.rs new file mode 100644 index 0000000..5ad1793 --- /dev/null +++ b/crates/rsql-core/src/drivers/pgsql/commands/mod.rs @@ -0,0 +1,11 @@ +pub(crate) const SNAPSHOT_PAGE_WRITE_RETRIES: usize = 3; + +pub mod admin; +pub mod connection; +pub mod metadata; +pub mod object_info; +pub mod pool_helpers; +pub mod pubsub; +pub mod query; +pub mod snapshot_persistence; +pub mod statistics; diff --git a/crates/rsql-core/src/drivers/pgsql/commands/object_info.rs b/crates/rsql-core/src/drivers/pgsql/commands/object_info.rs new file mode 100644 index 0000000..24dcc21 --- /dev/null +++ b/crates/rsql-core/src/drivers/pgsql/commands/object_info.rs @@ -0,0 +1,50 @@ +use crate::AppState; +use crate::drivers::pgsql::ObjectStats; +use crate::drivers::pgsql::ddl_generation::generate_full_ddl; +use crate::drivers::pgsql::metadata_views_functions::{ + load_function_info, load_matview_info, load_view_info, +}; +use crate::error::AppError; + +use super::pool_helpers::acquire_client; + +pub async fn pgsql_view_info( + app_state: &AppState, + project_id: &str, + schema: &str, + view: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + load_view_info(&client, schema, view).await +} + +pub async fn pgsql_matview_info( + app_state: &AppState, + project_id: &str, + schema: &str, + matview: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + load_matview_info(&client, schema, matview).await +} + +pub async fn pgsql_function_info( + app_state: &AppState, + project_id: &str, + schema: &str, + func_name: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + load_function_info(&client, schema, func_name).await +} + +pub async fn pgsql_generate_ddl( + app_state: &AppState, + project_id: &str, + schema: &str, + name: &str, + object_type: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + generate_full_ddl(&client, schema, name, object_type).await +} diff --git a/crates/rsql-core/src/drivers/pgsql/commands/pool_helpers.rs b/crates/rsql-core/src/drivers/pgsql/commands/pool_helpers.rs new file mode 100644 index 0000000..6f42027 --- /dev/null +++ b/crates/rsql-core/src/drivers/pgsql/commands/pool_helpers.rs @@ -0,0 +1,93 @@ +use std::{collections::BTreeMap, sync::Arc}; + +use deadpool_postgres::{Manager as PgManager, ManagerConfig, Pool, RecyclingMethod}; +use native_tls::TlsConnector; +use postgres_native_tls::MakeTlsConnector; +use tokio_postgres::{CancelToken, Config, NoTls}; + +use crate::AppState; +use crate::drivers::pgsql::get_pool; +use crate::error::AppError; + +pub fn is_sqlite_lock_error(message: &str) -> bool { + let lower = message.to_ascii_lowercase(); + lower.contains("database is locked") || lower.contains("database busy") +} + +pub fn full_error_chain(e: &dyn std::error::Error) -> String { + let mut msg = e.to_string(); + let mut src = e.source(); + while let Some(cause) = src { + msg.push_str(": "); + msg.push_str(&cause.to_string()); + src = cause.source(); + } + msg +} + +pub fn create_pg_pool( + cfg: &Config, + use_ssl: bool, + max_size: usize, +) -> std::result::Result { + let manager_config = ManagerConfig { + recycling_method: RecyclingMethod::Custom("ROLLBACK".into()), + }; + + if use_ssl { + let tls_connector = TlsConnector::builder() + .build() + .map_err(|e| AppError::ConnectionFailed(e.to_string()))?; + let tls = MakeTlsConnector::new(tls_connector); + let manager = PgManager::from_config(cfg.clone(), tls, manager_config); + Pool::builder(manager) + .max_size(max_size) + .build() + .map_err(|e| AppError::ConnectionFailed(e.to_string())) + } else { + let manager = PgManager::from_config(cfg.clone(), NoTls, manager_config); + Pool::builder(manager) + .max_size(max_size) + .build() + .map_err(|e| AppError::ConnectionFailed(e.to_string())) + } +} + +pub async fn acquire_client( + pools_mutex: &tokio::sync::Mutex>>, + project_id: &str, +) -> std::result::Result { + let pool = { + let pools = pools_mutex.lock().await; + get_pool(&pools, project_id)? + }; + + pool.get() + .await + .map_err(|e| AppError::ConnectionFailed(e.to_string())) +} + +pub async fn apply_statement_timeout(client: &deadpool_postgres::Client, timeout_ms: u32) { + if timeout_ms > 0 { + client + .simple_query(&format!("SET statement_timeout = {}", timeout_ms)) + .await + .ok(); + } +} + +pub async fn reset_statement_timeout(client: &deadpool_postgres::Client, timeout_ms: u32) { + if timeout_ms > 0 { + client.simple_query("RESET statement_timeout").await.ok(); + } +} + +pub async fn set_cancel_token( + app_state: &AppState, + project_id: &str, + token: CancelToken, +) -> std::result::Result<(), AppError> { + let mut cancel_tokens = app_state.cancel_tokens.lock().await; + cancel_tokens.insert(project_id.to_string(), token); + Ok(()) +} diff --git a/src-tauri/src/drivers/pgsql/commands/pubsub_commands.rs b/crates/rsql-core/src/drivers/pgsql/commands/pubsub.rs similarity index 53% rename from src-tauri/src/drivers/pgsql/commands/pubsub_commands.rs rename to crates/rsql-core/src/drivers/pgsql/commands/pubsub.rs index 064b20d..96aac4a 100644 --- a/src-tauri/src/drivers/pgsql/commands/pubsub_commands.rs +++ b/crates/rsql-core/src/drivers/pgsql/commands/pubsub.rs @@ -1,25 +1,55 @@ +use std::sync::Arc; + use crate::AppState; -use crate::common::enums::AppError; -use crate::drivers::pgsql::discover_notify_channels; +use crate::drivers::pgsql::roles_schema_objects::discover_notify_channels; +use crate::error::AppError; +use crate::events::EventSink; use futures_util::StreamExt; use native_tls::TlsConnector; use postgres_native_tls::MakeTlsConnector; -use tauri::{AppHandle, Emitter, Manager, Result, State}; use tokio_postgres::{AsyncMessage, Config, NoTls}; -use super::pool_connection::acquire_client; +use super::pool_helpers::acquire_client; -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_listen_start(project_id: &str, channel: &str, app: AppHandle) -> Result { - let app_handle = app.clone(); - let app_state = app_handle.state::(); - let listen_key = format!("{}:{}", project_id, channel); +pub async fn pgsql_notify_send( + app_state: &AppState, + project_id: &str, + channel: &str, + payload: &str, +) -> Result { + let client = acquire_client(&app_state.clients, project_id).await?; + let sql = format!( + "SELECT pg_notify('{}', '{}')", + channel.replace('\'', "''"), + payload.replace('\'', "''"), + ); + client + .batch_execute(&sql) + .await + .map_err(|e| AppError::QueryFailed(e.to_string()))?; + Ok(true) +} + +pub async fn pgsql_discover_channels( + app_state: &AppState, + project_id: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + discover_notify_channels(&client).await +} +pub async fn listen_start( + app_state: &AppState, + project_id: &str, + channel: &str, + sink: Arc, +) -> Result { + let listen_key = format!("{project_id}:{channel}"); { let handles = app_state.notify_handles.lock().await; if handles.contains_key(&listen_key) { - return Ok(true); // Already listening + return Ok(true); } } @@ -35,18 +65,16 @@ pub async fn pgsql_listen_start(project_id: &str, channel: &str, app: AppHandle) ) .await .map_err(|e| AppError::DatabaseError(e.to_string()))?; - let row = rows .next() .await .map_err(|e| AppError::DatabaseError(e.to_string()))? .ok_or_else(|| AppError::ProjectNotFound(project_id.to_string()))?; - let mut cfg = Config::new(); - cfg.user(&row.get::(0).unwrap_or_default()) - .password(&row.get::(1).unwrap_or_default()) - .dbname(&row.get::(2).unwrap_or_default()) - .host(&row.get::(3).unwrap_or_default()) + cfg.user(row.get::(0).unwrap_or_default()) + .password(row.get::(1).unwrap_or_default()) + .dbname(row.get::(2).unwrap_or_default()) + .host(row.get::(3).unwrap_or_default()) .port( row.get::(4) .unwrap_or_default() @@ -58,28 +86,25 @@ pub async fn pgsql_listen_start(project_id: &str, channel: &str, app: AppHandle) }; let channel_owned = channel.to_string(); - let event_name = format!("pg-notify-{}", project_id); - + let event_name = format!("pg-notify-{project_id}"); let handle = tokio::spawn(async move { - async fn listen_loop( + async fn listen_loop( client: tokio_postgres::Client, - mut connection: tokio_postgres::Connection, + mut connection: tokio_postgres::Connection, channel: &str, event_name: &str, - app: &AppHandle, + sink: &Arc, ) where - S: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin, - T: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin, + Stream: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin, + TlsStream: tokio::io::AsyncRead + tokio::io::AsyncWrite + Unpin, + EVT: EventSink, { let listen_sql = format!("LISTEN \"{}\"", channel.replace('"', "\"\"")); if let Err(e) = client.batch_execute(&listen_sql).await { - tracing::error!("LISTEN command failed: {:?}", e); + tracing::error!("LISTEN command failed: {e:?}"); return; } - tracing::info!("LISTEN started on channel: {}", channel); - let mut stream = futures_util::stream::poll_fn(move |cx| connection.poll_message(cx)); - while let Some(msg) = stream.next().await { match msg { Ok(AsyncMessage::Notification(n)) => { @@ -87,16 +112,15 @@ pub async fn pgsql_listen_start(project_id: &str, channel: &str, app: AppHandle) "channel": n.channel(), "payload": n.payload(), }); - let _ = app.emit(event_name, payload); + sink.emit(event_name, &payload); } Ok(_) => {} Err(e) => { - tracing::error!("LISTEN stream error: {:?}", e); + tracing::error!("LISTEN stream error: {e:?}"); break; } } } - tracing::info!("LISTEN ended on channel: {}", channel); drop(client); } @@ -104,73 +128,35 @@ pub async fn pgsql_listen_start(project_id: &str, channel: &str, app: AppHandle) let tls_connector = match TlsConnector::builder().build() { Ok(c) => c, Err(e) => { - tracing::error!("LISTEN TLS error: {:?}", e); + tracing::error!("LISTEN TLS error: {e:?}"); return; } }; let tls = MakeTlsConnector::new(tls_connector); - match cfg.connect(tls).await { - Ok((client, connection)) => { - listen_loop(client, connection, &channel_owned, &event_name, &app).await; - } - Err(e) => tracing::error!("LISTEN connect error: {:?}", e), - } - } else { - match cfg.connect(NoTls).await { - Ok((client, connection)) => { - listen_loop(client, connection, &channel_owned, &event_name, &app).await; - } - Err(e) => tracing::error!("LISTEN connect error: {:?}", e), + if let Ok((client, connection)) = cfg.connect(tls).await { + listen_loop(client, connection, &channel_owned, &event_name, &sink).await; } + } else if let Ok((client, connection)) = cfg.connect(NoTls).await { + listen_loop(client, connection, &channel_owned, &event_name, &sink).await; } }); - { - let mut handles = app_state.notify_handles.lock().await; - handles.insert(listen_key, handle); - } - - Ok(true) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_listen_stop(project_id: &str, channel: &str, app: AppHandle) -> Result { - let app_state = app.state::(); - let listen_key = format!("{}:{}", project_id, channel); - - let mut handles = app_state.notify_handles.lock().await; - if let Some(handle) = handles.remove(&listen_key) { - handle.abort(); - } - + app_state + .notify_handles + .lock() + .await + .insert(listen_key, handle); Ok(true) } -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_notify_send( +pub async fn listen_stop( + app_state: &AppState, project_id: &str, channel: &str, - payload: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.clients, project_id).await?; - let sql = format!( - "SELECT pg_notify('{}', '{}')", - channel.replace('\'', "''"), - payload.replace('\'', "''"), - ); - client - .batch_execute(&sql) - .await - .map_err(|e| AppError::QueryFailed(e.to_string()))?; +) -> Result { + let listen_key = format!("{project_id}:{channel}"); + if let Some(handle) = app_state.notify_handles.lock().await.remove(&listen_key) { + handle.abort(); + } Ok(true) } - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_discover_channels( - project_id: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - discover_notify_channels(&client).await.map_err(Into::into) -} diff --git a/src-tauri/src/drivers/pgsql/commands/query_commands.rs b/crates/rsql-core/src/drivers/pgsql/commands/query.rs similarity index 58% rename from src-tauri/src/drivers/pgsql/commands/query_commands.rs rename to crates/rsql-core/src/drivers/pgsql/commands/query.rs index 20b019b..acd8260 100644 --- a/src-tauri/src/drivers/pgsql/commands/query_commands.rs +++ b/crates/rsql-core/src/drivers/pgsql/commands/query.rs @@ -1,18 +1,15 @@ -use crate::AppState; -use crate::common::enums::AppError; -use crate::drivers::pgsql::{ - close_virtual, execute_query, execute_query_packed, execute_query_streamed, execute_virtual, - fetch_virtual_page, -}; - use native_tls::TlsConnector; use postgres_native_tls::MakeTlsConnector; -use tauri::ipc::Response; -use tauri::{AppHandle, Manager, Result, State}; use tokio_postgres::NoTls; -use super::CELL_SEP; -use super::pool_connection::{ +use crate::AppState; +use crate::drivers::pgsql::CELL_SEP; +use crate::drivers::pgsql::query_execution::{ + close_virtual, execute_query, execute_query_packed, execute_virtual, fetch_virtual_page, +}; +use crate::error::AppError; + +use super::pool_helpers::{ acquire_client, apply_statement_timeout, reset_statement_timeout, set_cancel_token, }; use super::snapshot_persistence::{ @@ -20,22 +17,19 @@ use super::snapshot_persistence::{ snapshot_upsert_metadata, }; -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_run_query( + app_state: &AppState, project_id: &str, sql: &str, - app_state: State<'_, AppState>, -) -> Result { +) -> Result { let client = acquire_client(&app_state.clients, project_id).await?; - set_cancel_token(&app_state, project_id, client.cancel_token()).await?; + set_cancel_token(app_state, project_id, client.cancel_token()).await?; let result = execute_query(&client, sql).await?; - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) } -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_cancel_query(project_id: &str, app_state: State<'_, AppState>) -> Result { +pub async fn pgsql_cancel_query(app_state: &AppState, project_id: &str) -> Result { let cancel_token = { let cancel_tokens = app_state.cancel_tokens.lock().await; cancel_tokens @@ -68,15 +62,14 @@ pub async fn pgsql_cancel_query(project_id: &str, app_state: State<'_, AppState> Ok(true) } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_run_query_packed( + app_state: &AppState, project_id: &str, sql: &str, timeout_ms: Option, - app_state: State<'_, AppState>, -) -> Result { +) -> Result { let client = acquire_client(&app_state.clients, project_id).await?; - set_cancel_token(&app_state, project_id, client.cancel_token()).await?; + set_cancel_token(app_state, project_id, client.cancel_token()).await?; let timeout = timeout_ms.unwrap_or(0); apply_statement_timeout(&client, timeout).await; @@ -84,37 +77,19 @@ pub async fn pgsql_run_query_packed( reset_statement_timeout(&client, timeout).await; let result = result?; - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_run_query_streamed( - project_id: &str, - sql: &str, - stream_id: &str, - app: AppHandle, -) -> Result<()> { - let app_state = app.state::(); - let client = acquire_client(&app_state.clients, project_id).await?; - set_cancel_token(&app_state, project_id, client.cancel_token()).await?; - - execute_query_streamed(&client, sql, stream_id, &app) - .await - .map_err(Into::into) + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_execute_virtual( + app_state: &AppState, project_id: &str, sql: &str, query_id: &str, page_size: usize, timeout_ms: Option, - app_state: State<'_, AppState>, -) -> Result { +) -> Result { let client = acquire_client(&app_state.clients, project_id).await?; - set_cancel_token(&app_state, project_id, client.cancel_token()).await?; + set_cancel_token(app_state, project_id, client.cancel_token()).await?; let timeout = timeout_ms.unwrap_or(0); apply_statement_timeout(&client, timeout).await; @@ -128,7 +103,7 @@ pub async fn pgsql_execute_virtual( result.0.split(CELL_SEP).count() }; if let Err(e) = snapshot_upsert_metadata( - &app_state, project_id, query_id, sql, &result.0, result.1, page_size, col_count, + app_state, project_id, query_id, sql, &result.0, result.1, page_size, col_count, ) .await { @@ -138,7 +113,7 @@ pub async fn pgsql_execute_virtual( e ); } - if let Err(e) = snapshot_store_page(&app_state, query_id, 0, &result.2).await { + if let Err(e) = snapshot_store_page(app_state, query_id, 0, &result.2).await { tracing::warn!( "Failed to persist virtual snapshot first page for {}: {:?}", query_id, @@ -146,28 +121,24 @@ pub async fn pgsql_execute_virtual( ); } - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) } -#[tauri::command(rename_all = "snake_case")] pub async fn pgsql_fetch_page( + app_state: &AppState, query_id: &str, col_count: usize, offset: usize, limit: usize, - app_state: State<'_, AppState>, -) -> Result { +) -> Result { let page_index = if limit == 0 { 0 } else { offset / limit }; match fetch_virtual_page(&app_state.virtual_cache, query_id, col_count, offset, limit).await { Ok(packed) => { - if let Err(e) = snapshot_store_page(&app_state, query_id, page_index, &packed).await { + if let Err(e) = snapshot_store_page(app_state, query_id, page_index, &packed).await { tracing::warn!("Failed to persist fetched page for {}: {:?}", query_id, e); } - let json = - sonic_rs::to_string(&packed).map_err(|e| AppError::QueryFailed(e.to_string()))?; - return Ok(Response::new(json)); + return sonic_rs::to_string(&packed).map_err(|e| AppError::QueryFailed(e.to_string())); } Err(err) => { tracing::debug!( @@ -178,17 +149,15 @@ pub async fn pgsql_fetch_page( } } - if let Some(packed) = snapshot_load_page(&app_state, query_id, page_index).await? { - let json = - sonic_rs::to_string(&packed).map_err(|e| AppError::QueryFailed(e.to_string()))?; - return Ok(Response::new(json)); + if let Some(packed) = snapshot_load_page(app_state, query_id, page_index).await? { + return sonic_rs::to_string(&packed).map_err(|e| AppError::QueryFailed(e.to_string())); } - if restore_virtual_from_snapshot(&app_state, query_id).await? { + if restore_virtual_from_snapshot(app_state, query_id).await? { let packed = fetch_virtual_page(&app_state.virtual_cache, query_id, col_count, offset, limit) .await?; - if let Err(e) = snapshot_store_page(&app_state, query_id, page_index, &packed).await { + if let Err(e) = snapshot_store_page(app_state, query_id, page_index, &packed).await { tracing::warn!( "Failed to persist restored page for {} (page {}): {:?}", query_id, @@ -196,22 +165,18 @@ pub async fn pgsql_fetch_page( e ); } - let json = - sonic_rs::to_string(&packed).map_err(|e| AppError::QueryFailed(e.to_string()))?; - return Ok(Response::new(json)); + return sonic_rs::to_string(&packed).map_err(|e| AppError::QueryFailed(e.to_string())); } Err(AppError::QueryFailed(format!( "Virtual query {} not found in memory and no snapshot available", query_id - )) - .into()) + ))) } -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_close_virtual(query_id: &str, app_state: State<'_, AppState>) -> Result<()> { +pub async fn pgsql_close_virtual(app_state: &AppState, query_id: &str) -> Result<(), AppError> { close_virtual(&app_state.virtual_cache, query_id).await?; - if let Err(e) = snapshot_cleanup_query(&app_state, query_id).await { + if let Err(e) = snapshot_cleanup_query(app_state, query_id).await { tracing::warn!( "Failed to cleanup virtual snapshot for {}: {:?}", query_id, diff --git a/src-tauri/src/drivers/pgsql/commands/snapshot_persistence.rs b/crates/rsql-core/src/drivers/pgsql/commands/snapshot_persistence.rs similarity index 91% rename from src-tauri/src/drivers/pgsql/commands/snapshot_persistence.rs rename to crates/rsql-core/src/drivers/pgsql/commands/snapshot_persistence.rs index 3edccf5..ac442cc 100644 --- a/src-tauri/src/drivers/pgsql/commands/snapshot_persistence.rs +++ b/crates/rsql-core/src/drivers/pgsql/commands/snapshot_persistence.rs @@ -1,30 +1,31 @@ use std::time::{SystemTime, UNIX_EPOCH}; use crate::AppState; -use crate::common::enums::AppError; -use crate::drivers::pgsql::execute_virtual; +use crate::drivers::pgsql::CELL_SEP; +use crate::drivers::pgsql::query_execution::execute_virtual; +use crate::error::AppError; use tokio::time::{Duration, sleep}; -use super::pool_connection::{acquire_client, is_sqlite_lock_error, set_cancel_token}; -use super::{CELL_SEP, SNAPSHOT_PAGE_WRITE_RETRIES}; +use super::SNAPSHOT_PAGE_WRITE_RETRIES; +use super::pool_helpers::{acquire_client, is_sqlite_lock_error, set_cancel_token}; #[derive(Clone)] -pub(crate) struct VirtualSnapshotMeta { - pub(crate) project_id: String, - pub(crate) sql: String, - pub(crate) page_size: usize, - pub(crate) col_count: usize, +pub struct VirtualSnapshotMeta { + pub project_id: String, + pub sql: String, + pub page_size: usize, + pub col_count: usize, } -pub(crate) fn now_unix_secs() -> i64 { +pub fn now_unix_secs() -> i64 { SystemTime::now() .duration_since(UNIX_EPOCH) .map(|d| d.as_secs() as i64) .unwrap_or_default() } -pub(crate) async fn snapshot_upsert_metadata( +pub async fn snapshot_upsert_metadata( app_state: &AppState, project_id: &str, query_id: &str, @@ -60,7 +61,7 @@ pub(crate) async fn snapshot_upsert_metadata( Ok(()) } -pub(crate) async fn snapshot_store_page( +pub async fn snapshot_store_page( app_state: &AppState, query_id: &str, page_index: usize, @@ -108,7 +109,7 @@ pub(crate) async fn snapshot_store_page( Ok(()) } -pub(crate) async fn snapshot_load_page( +pub async fn snapshot_load_page( app_state: &AppState, query_id: &str, page_index: usize, @@ -143,7 +144,7 @@ pub(crate) async fn snapshot_load_page( } } -pub(crate) async fn snapshot_load_metadata( +pub async fn snapshot_load_metadata( app_state: &AppState, query_id: &str, ) -> std::result::Result, AppError> { @@ -197,7 +198,7 @@ pub(crate) async fn snapshot_load_metadata( })) } -pub(crate) async fn snapshot_cleanup_query( +pub async fn snapshot_cleanup_query( app_state: &AppState, query_id: &str, ) -> std::result::Result<(), AppError> { @@ -223,7 +224,7 @@ pub(crate) async fn snapshot_cleanup_query( Ok(()) } -pub(crate) async fn restore_virtual_from_snapshot( +pub async fn restore_virtual_from_snapshot( app_state: &AppState, query_id: &str, ) -> std::result::Result { diff --git a/crates/rsql-core/src/drivers/pgsql/commands/statistics.rs b/crates/rsql-core/src/drivers/pgsql/commands/statistics.rs new file mode 100644 index 0000000..52ca1c7 --- /dev/null +++ b/crates/rsql-core/src/drivers/pgsql/commands/statistics.rs @@ -0,0 +1,89 @@ +use crate::AppState; +use crate::drivers::pgsql::statistics_activity::{ + load_active_locks, load_activity, load_database_stats, load_fk_details, load_foreign_keys, + load_index_usage, load_table_bloat, load_table_statistics, load_table_stats, +}; +use crate::drivers::pgsql::{DbStat, FKDetail, ForeignKeyInfo, ObjectStats}; +use crate::error::AppError; + +use super::pool_helpers::acquire_client; + +pub async fn pgsql_load_activity( + app_state: &AppState, + project_id: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + let result = load_activity(&client).await?; + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) +} + +pub async fn pgsql_load_database_stats( + app_state: &AppState, + project_id: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + load_database_stats(&client).await +} + +pub async fn pgsql_load_table_stats( + app_state: &AppState, + project_id: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + let result = load_table_stats(&client).await?; + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) +} + +pub async fn pgsql_load_foreign_keys( + app_state: &AppState, + project_id: &str, + schema: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + load_foreign_keys(&client, schema).await +} + +pub async fn pgsql_table_statistics( + app_state: &AppState, + project_id: &str, + schema: &str, + table: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + load_table_statistics(&client, schema, table).await +} + +pub async fn pgsql_fk_details( + app_state: &AppState, + project_id: &str, + schema: &str, + table: &str, + direction: &str, +) -> Result, AppError> { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + load_fk_details(&client, schema, table, direction).await +} + +pub async fn pgsql_load_locks(app_state: &AppState, project_id: &str) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + let result = load_active_locks(&client).await?; + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) +} + +pub async fn pgsql_load_index_usage( + app_state: &AppState, + project_id: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + let result = load_index_usage(&client).await?; + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) +} + +pub async fn pgsql_load_table_bloat( + app_state: &AppState, + project_id: &str, +) -> Result { + let client = acquire_client(&app_state.meta_clients, project_id).await?; + let result = load_table_bloat(&client).await?; + sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string())) +} diff --git a/src-tauri/src/drivers/pgsql/ddl_generation.rs b/crates/rsql-core/src/drivers/pgsql/ddl_generation.rs similarity index 99% rename from src-tauri/src/drivers/pgsql/ddl_generation.rs rename to crates/rsql-core/src/drivers/pgsql/ddl_generation.rs index 841d8b5..c627d3d 100644 --- a/src-tauri/src/drivers/pgsql/ddl_generation.rs +++ b/crates/rsql-core/src/drivers/pgsql/ddl_generation.rs @@ -1,6 +1,6 @@ use tokio_postgres::{Client, SimpleQueryMessage}; -use crate::common::enums::AppError; +use crate::error::AppError; pub async fn generate_full_ddl( client: &Client, diff --git a/src-tauri/src/drivers/pgsql/extensions.rs b/crates/rsql-core/src/drivers/pgsql/extensions.rs similarity index 98% rename from src-tauri/src/drivers/pgsql/extensions.rs rename to crates/rsql-core/src/drivers/pgsql/extensions.rs index e720263..83b8832 100644 --- a/src-tauri/src/drivers/pgsql/extensions.rs +++ b/crates/rsql-core/src/drivers/pgsql/extensions.rs @@ -1,4 +1,4 @@ -use crate::common::enums::AppError; +use crate::error::AppError; pub async fn load_extensions( client: &deadpool_postgres::Client, diff --git a/src-tauri/src/drivers/pgsql/metadata_schema.rs b/crates/rsql-core/src/drivers/pgsql/metadata_schema.rs similarity index 99% rename from src-tauri/src/drivers/pgsql/metadata_schema.rs rename to crates/rsql-core/src/drivers/pgsql/metadata_schema.rs index f48a373..d5ec126 100644 --- a/src-tauri/src/drivers/pgsql/metadata_schema.rs +++ b/crates/rsql-core/src/drivers/pgsql/metadata_schema.rs @@ -2,8 +2,8 @@ use deadpool_postgres::Pool; use tokio::time as tokio_time; use tokio_postgres::Client; -use crate::common::enums::AppError; use crate::common::pgsql::{PgsqlLoadColumns, PgsqlLoadSchemas, PgsqlLoadTables}; +use crate::error::AppError; use super::{ColumnDetail, ConstraintDetail, IndexDetail, PolicyDetail, RuleDetail, TriggerDetail}; diff --git a/src-tauri/src/drivers/pgsql/metadata_views_functions.rs b/crates/rsql-core/src/drivers/pgsql/metadata_views_functions.rs similarity index 99% rename from src-tauri/src/drivers/pgsql/metadata_views_functions.rs rename to crates/rsql-core/src/drivers/pgsql/metadata_views_functions.rs index e3f6a88..24fb5d1 100644 --- a/src-tauri/src/drivers/pgsql/metadata_views_functions.rs +++ b/crates/rsql-core/src/drivers/pgsql/metadata_views_functions.rs @@ -1,6 +1,6 @@ use tokio_postgres::Client; -use crate::common::enums::AppError; +use crate::error::AppError; use super::{FunctionInfo, ObjectStats}; diff --git a/src-tauri/src/drivers/pgsql/mod.rs b/crates/rsql-core/src/drivers/pgsql/mod.rs similarity index 85% rename from src-tauri/src/drivers/pgsql/mod.rs rename to crates/rsql-core/src/drivers/pgsql/mod.rs index 7dcff7d..27b97da 100644 --- a/src-tauri/src/drivers/pgsql/mod.rs +++ b/crates/rsql-core/src/drivers/pgsql/mod.rs @@ -1,8 +1,3 @@ -use deadpool_postgres::Pool; -use std::sync::Arc; - -use crate::common::enums::AppError; - pub mod commands; pub mod ddl_generation; pub mod extensions; @@ -11,15 +6,12 @@ pub mod metadata_views_functions; pub mod query_execution; pub mod roles_schema_objects; pub mod statistics_activity; +pub mod streaming; + +use deadpool_postgres::Pool; +use std::sync::Arc; -pub use commands::*; -pub use ddl_generation::*; -pub use extensions::*; -pub use metadata_schema::*; -pub use metadata_views_functions::*; -pub use query_execution::*; -pub use roles_schema_objects::*; -pub use statistics_activity::*; +use crate::error::AppError; /// Safely get a pool Arc from the AppState client map. /// Returns a cloned Arc so the caller can drop the MutexGuard immediately. @@ -34,15 +26,15 @@ pub fn get_pool( } /// Cell separator for packed format (Unit Separator, ASCII 0x1F) -pub(crate) const CELL_SEP: char = '\x1F'; +pub const CELL_SEP: char = '\x1F'; /// Row separator for packed format (Record Separator, ASCII 0x1E) -pub(crate) const ROW_SEP: char = '\x1E'; +pub const ROW_SEP: char = '\x1E'; /// A cached query: pre-packed page strings for zero-copy serving. /// Each page is a single large String (~1-2 MB) so the OS reclaims RSS on drop. pub struct CachedQuery { - pub(crate) pages: Vec, - pub(crate) page_size: usize, + pub pages: Vec, + pub page_size: usize, } pub type VirtualCache = std::collections::BTreeMap; diff --git a/src-tauri/src/drivers/pgsql/query_execution/helpers.rs b/crates/rsql-core/src/drivers/pgsql/query_execution/helpers.rs similarity index 95% rename from src-tauri/src/drivers/pgsql/query_execution/helpers.rs rename to crates/rsql-core/src/drivers/pgsql/query_execution/helpers.rs index 35898f6..f779462 100644 --- a/src-tauri/src/drivers/pgsql/query_execution/helpers.rs +++ b/crates/rsql-core/src/drivers/pgsql/query_execution/helpers.rs @@ -5,7 +5,7 @@ use super::super::{CELL_SEP, ROW_SEP}; /// Process simple_query messages, returning the last result set that had rows. /// If no result set had rows but commands ran, returns synthetic "N rows affected". /// If nothing at all, returns empty vecs. -pub(crate) fn process_simple_messages( +pub fn process_simple_messages( messages: Vec, ) -> (Vec, Vec>) { let mut cur_columns: Vec = Vec::new(); @@ -65,7 +65,7 @@ pub(crate) fn process_simple_messages( /// Join string slices with a char separator — avoids .to_string() on the separator. #[inline] -pub(crate) fn join_sep(items: &[String], sep: char) -> String { +pub fn join_sep(items: &[String], sep: char) -> String { let total: usize = items.iter().map(|s| s.len()).sum::() + items.len(); let mut out = String::with_capacity(total); for (i, item) in items.iter().enumerate() { @@ -79,7 +79,7 @@ pub(crate) fn join_sep(items: &[String], sep: char) -> String { /// Pack a slice of rows (each row = Vec) into wire format. /// Pre-allocates capacity and writes directly — zero intermediate allocations. -pub(crate) fn pack_rows_vec(rows: &[Vec]) -> String { +pub fn pack_rows_vec(rows: &[Vec]) -> String { if rows.is_empty() { return String::new(); } diff --git a/src-tauri/src/drivers/pgsql/query_execution/mod.rs b/crates/rsql-core/src/drivers/pgsql/query_execution/mod.rs similarity index 70% rename from src-tauri/src/drivers/pgsql/query_execution/mod.rs rename to crates/rsql-core/src/drivers/pgsql/query_execution/mod.rs index 94f3a0c..c57cd65 100644 --- a/src-tauri/src/drivers/pgsql/query_execution/mod.rs +++ b/crates/rsql-core/src/drivers/pgsql/query_execution/mod.rs @@ -1,8 +1,7 @@ mod helpers; mod simple; -mod streaming; mod virtual_cache; +pub use helpers::*; pub use simple::*; -pub use streaming::*; pub use virtual_cache::*; diff --git a/src-tauri/src/drivers/pgsql/query_execution/simple.rs b/crates/rsql-core/src/drivers/pgsql/query_execution/simple.rs similarity index 98% rename from src-tauri/src/drivers/pgsql/query_execution/simple.rs rename to crates/rsql-core/src/drivers/pgsql/query_execution/simple.rs index 28cac88..8459343 100644 --- a/src-tauri/src/drivers/pgsql/query_execution/simple.rs +++ b/crates/rsql-core/src/drivers/pgsql/query_execution/simple.rs @@ -1,7 +1,7 @@ use std::time::Instant; use tokio_postgres::Client; -use crate::common::enums::AppError; +use crate::error::AppError; use super::super::{CELL_SEP, ROW_SEP}; use super::helpers::{join_sep, pack_rows_vec, process_simple_messages}; diff --git a/src-tauri/src/drivers/pgsql/query_execution/virtual_cache.rs b/crates/rsql-core/src/drivers/pgsql/query_execution/virtual_cache.rs similarity index 98% rename from src-tauri/src/drivers/pgsql/query_execution/virtual_cache.rs rename to crates/rsql-core/src/drivers/pgsql/query_execution/virtual_cache.rs index 83caeec..43b5615 100644 --- a/src-tauri/src/drivers/pgsql/query_execution/virtual_cache.rs +++ b/crates/rsql-core/src/drivers/pgsql/query_execution/virtual_cache.rs @@ -2,7 +2,7 @@ use rayon::prelude::*; use std::time::Instant; use tokio_postgres::Client; -use crate::common::enums::AppError; +use crate::error::AppError; use super::super::{CELL_SEP, CachedQuery, ROW_SEP, VirtualCache}; use super::helpers::{join_sep, pack_rows_vec, process_simple_messages}; diff --git a/src-tauri/src/drivers/pgsql/roles_schema_objects/csv_import.rs b/crates/rsql-core/src/drivers/pgsql/roles_schema_objects/csv_import.rs similarity index 98% rename from src-tauri/src/drivers/pgsql/roles_schema_objects/csv_import.rs rename to crates/rsql-core/src/drivers/pgsql/roles_schema_objects/csv_import.rs index deac3d5..6334835 100644 --- a/src-tauri/src/drivers/pgsql/roles_schema_objects/csv_import.rs +++ b/crates/rsql-core/src/drivers/pgsql/roles_schema_objects/csv_import.rs @@ -1,4 +1,4 @@ -use crate::common::enums::AppError; +use crate::error::AppError; pub async fn parse_csv_preview( file_path: &str, diff --git a/src-tauri/src/drivers/pgsql/roles_schema_objects/mod.rs b/crates/rsql-core/src/drivers/pgsql/roles_schema_objects/mod.rs similarity index 100% rename from src-tauri/src/drivers/pgsql/roles_schema_objects/mod.rs rename to crates/rsql-core/src/drivers/pgsql/roles_schema_objects/mod.rs diff --git a/src-tauri/src/drivers/pgsql/roles_schema_objects/roles_grants.rs b/crates/rsql-core/src/drivers/pgsql/roles_schema_objects/roles_grants.rs similarity index 99% rename from src-tauri/src/drivers/pgsql/roles_schema_objects/roles_grants.rs rename to crates/rsql-core/src/drivers/pgsql/roles_schema_objects/roles_grants.rs index b58265d..3fdfb14 100644 --- a/src-tauri/src/drivers/pgsql/roles_schema_objects/roles_grants.rs +++ b/crates/rsql-core/src/drivers/pgsql/roles_schema_objects/roles_grants.rs @@ -1,4 +1,4 @@ -use crate::common::enums::AppError; +use crate::error::AppError; #[derive(Debug, Clone, serde::Serialize)] pub struct PgRole { diff --git a/src-tauri/src/drivers/pgsql/roles_schema_objects/schema_objects.rs b/crates/rsql-core/src/drivers/pgsql/roles_schema_objects/schema_objects.rs similarity index 99% rename from src-tauri/src/drivers/pgsql/roles_schema_objects/schema_objects.rs rename to crates/rsql-core/src/drivers/pgsql/roles_schema_objects/schema_objects.rs index 0a3da18..5f755f1 100644 --- a/src-tauri/src/drivers/pgsql/roles_schema_objects/schema_objects.rs +++ b/crates/rsql-core/src/drivers/pgsql/roles_schema_objects/schema_objects.rs @@ -1,4 +1,4 @@ -use crate::common::enums::AppError; +use crate::error::AppError; #[derive(Debug, Clone, serde::Serialize)] pub struct SchemaObject { diff --git a/src-tauri/src/drivers/pgsql/statistics_activity/database.rs b/crates/rsql-core/src/drivers/pgsql/statistics_activity/database.rs similarity index 99% rename from src-tauri/src/drivers/pgsql/statistics_activity/database.rs rename to crates/rsql-core/src/drivers/pgsql/statistics_activity/database.rs index 577b5f8..06036d3 100644 --- a/src-tauri/src/drivers/pgsql/statistics_activity/database.rs +++ b/crates/rsql-core/src/drivers/pgsql/statistics_activity/database.rs @@ -1,6 +1,6 @@ use tokio_postgres::Client; -use crate::common::enums::AppError; +use crate::error::AppError; use super::super::DbStat; diff --git a/src-tauri/src/drivers/pgsql/statistics_activity/mod.rs b/crates/rsql-core/src/drivers/pgsql/statistics_activity/mod.rs similarity index 100% rename from src-tauri/src/drivers/pgsql/statistics_activity/mod.rs rename to crates/rsql-core/src/drivers/pgsql/statistics_activity/mod.rs diff --git a/src-tauri/src/drivers/pgsql/statistics_activity/objects.rs b/crates/rsql-core/src/drivers/pgsql/statistics_activity/objects.rs similarity index 99% rename from src-tauri/src/drivers/pgsql/statistics_activity/objects.rs rename to crates/rsql-core/src/drivers/pgsql/statistics_activity/objects.rs index 8f2606d..5e87316 100644 --- a/src-tauri/src/drivers/pgsql/statistics_activity/objects.rs +++ b/crates/rsql-core/src/drivers/pgsql/statistics_activity/objects.rs @@ -1,6 +1,6 @@ use tokio_postgres::Client; -use crate::common::enums::AppError; +use crate::error::AppError; use super::super::{FKDetail, ForeignKeyInfo, ObjectStats}; diff --git a/src-tauri/src/drivers/pgsql/query_execution/streaming.rs b/crates/rsql-core/src/drivers/pgsql/streaming.rs similarity index 71% rename from src-tauri/src/drivers/pgsql/query_execution/streaming.rs rename to crates/rsql-core/src/drivers/pgsql/streaming.rs index 9e362fb..3e6af92 100644 --- a/src-tauri/src/drivers/pgsql/query_execution/streaming.rs +++ b/crates/rsql-core/src/drivers/pgsql/streaming.rs @@ -1,12 +1,12 @@ +use std::sync::Arc; use std::time::Instant; use tokio_postgres::{Client, SimpleQueryMessage}; -use crate::common::enums::AppError; +use crate::drivers::pgsql::CELL_SEP; +use crate::drivers::pgsql::query_execution::{join_sep, pack_rows_vec, process_simple_messages}; +use crate::error::AppError; +use crate::events::EventSink; -use super::super::CELL_SEP; -use super::helpers::{join_sep, pack_rows_vec, process_simple_messages}; - -/// Events emitted during streamed query execution. #[derive(serde::Serialize, Clone)] #[serde(tag = "type")] pub enum QueryStreamEvent { @@ -18,35 +18,27 @@ pub enum QueryStreamEvent { Done { elapsed: f32, capped: bool }, } -/// Maximum rows to send to the frontend to prevent OOM in the webview. const MAX_STREAM_ROWS: usize = 500_000; const CURSOR_FETCH_SIZE: usize = 10_000; -/// Stream query results using a PostgreSQL cursor. -/// Fetches rows in batches from the server — never loads the full result into Rust memory. -/// Caps at MAX_STREAM_ROWS to protect the webview from OOM. -pub async fn execute_query_streamed( +pub async fn execute_query_streamed( client: &Client, sql: &str, stream_id: &str, - app: &tauri::AppHandle, + sink: &Arc, ) -> Result<(), AppError> { - use tauri::Emitter; - let start = Instant::now(); - let event_name = format!("query-stream-{}", stream_id); + let event_name = format!("query-stream-{stream_id}"); - // Begin transaction + declare cursor for memory-efficient streaming client .batch_execute("BEGIN") .await .map_err(|e| AppError::QueryFailed(e.to_string()))?; - let cursor_sql = format!("DECLARE _rsql_cur NO SCROLL CURSOR FOR {}", sql); + let cursor_sql = format!("DECLARE _rsql_cur NO SCROLL CURSOR FOR {sql}"); match client.batch_execute(&cursor_sql).await { Ok(_) => { - // Cursor-based fetch loop using simple_query for zero type conversion - let fetch_sql = format!("FETCH {} FROM _rsql_cur", CURSOR_FETCH_SIZE); + let fetch_sql = format!("FETCH {CURSOR_FETCH_SIZE} FROM _rsql_cur"); let mut total_sent: usize = 0; let mut columns_sent = false; let mut capped = false; @@ -87,9 +79,9 @@ pub async fn execute_query_streamed( if !columns_sent && let Some(cols) = batch_columns { let header = join_sep(&cols, CELL_SEP); - let _ = app.emit( + sink.emit( &event_name, - QueryStreamEvent::Columns { + &QueryStreamEvent::Columns { columns: header, total_rows: 0, }, @@ -98,7 +90,7 @@ pub async fn execute_query_streamed( } let packed = pack_rows_vec(&batch_rows); - let _ = app.emit(&event_name, QueryStreamEvent::Chunk { data: packed }); + sink.emit(&event_name, &QueryStreamEvent::Chunk { data: packed }); total_sent += batch_rows.len(); if total_sent >= MAX_STREAM_ROWS { @@ -108,9 +100,9 @@ pub async fn execute_query_streamed( } if !columns_sent { - let _ = app.emit( + sink.emit( &event_name, - QueryStreamEvent::Columns { + &QueryStreamEvent::Columns { columns: String::new(), total_rows: 0, }, @@ -121,13 +113,11 @@ pub async fn execute_query_streamed( client.batch_execute("COMMIT").await.ok(); let elapsed = start.elapsed().as_millis() as f32; - let _ = app.emit(&event_name, QueryStreamEvent::Done { elapsed, capped }); + sink.emit(&event_name, &QueryStreamEvent::Done { elapsed, capped }); } - Err(_cursor_err) => { - // DECLARE CURSOR failed (non-SELECT query like INSERT/UPDATE/DDL) + Err(_) => { client.batch_execute("ROLLBACK").await.ok(); - // Re-execute with simple_query for multi-statement support let messages = client .simple_query(sql) .await @@ -136,31 +126,31 @@ pub async fn execute_query_streamed( let (columns, rows) = process_simple_messages(messages); if columns.is_empty() { - let _ = app.emit( + sink.emit( &event_name, - QueryStreamEvent::Columns { + &QueryStreamEvent::Columns { columns: String::new(), total_rows: 0, }, ); } else { let header = join_sep(&columns, CELL_SEP); - let _ = app.emit( + sink.emit( &event_name, - QueryStreamEvent::Columns { + &QueryStreamEvent::Columns { columns: header, total_rows: rows.len(), }, ); let packed = pack_rows_vec(&rows); - let _ = app.emit(&event_name, QueryStreamEvent::Chunk { data: packed }); + sink.emit(&event_name, &QueryStreamEvent::Chunk { data: packed }); } let elapsed = start.elapsed().as_millis() as f32; - let _ = app.emit( + sink.emit( &event_name, - QueryStreamEvent::Done { + &QueryStreamEvent::Done { elapsed, capped: false, }, diff --git a/src-tauri/src/common/enums.rs b/crates/rsql-core/src/error.rs similarity index 88% rename from src-tauri/src/common/enums.rs rename to crates/rsql-core/src/error.rs index d6f8f3e..3f58a02 100644 --- a/src-tauri/src/common/enums.rs +++ b/crates/rsql-core/src/error.rs @@ -42,8 +42,8 @@ pub enum AppError { SerializationError(String), } -impl From for tauri::Error { - fn from(e: AppError) -> Self { - tauri::Error::Io(std::io::Error::other(e.to_string())) +impl Serialize for AppError { + fn serialize(&self, serializer: S) -> Result { + serializer.serialize_str(&self.to_string()) } } diff --git a/crates/rsql-core/src/events.rs b/crates/rsql-core/src/events.rs new file mode 100644 index 0000000..fde9032 --- /dev/null +++ b/crates/rsql-core/src/events.rs @@ -0,0 +1,43 @@ +pub trait EventSink: Send + Sync + 'static { + fn emit(&self, event: &str, payload: &T); +} + +pub fn emit_typed(sink: &S, event: &str, payload: &T) { + sink.emit(event, payload); +} + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::{Arc, Mutex}; + + struct RecordingSink { + log: Mutex>, + } + + impl EventSink for RecordingSink { + fn emit(&self, event: &str, payload: &T) { + let value = serde_json::to_value(payload).expect("serialize"); + self.log.lock().unwrap().push((event.to_string(), value)); + } + } + + #[test] + fn emit_forwards_to_sink() { + #[derive(serde::Serialize)] + struct Probe { + n: u32, + label: &'static str, + } + + let sink = Arc::new(RecordingSink { + log: Mutex::new(Vec::new()), + }); + emit_typed(&*sink, "probe", &Probe { n: 7, label: "hi" }); + + let log = sink.log.lock().unwrap(); + assert_eq!(log.len(), 1); + assert_eq!(log[0].0, "probe"); + assert_eq!(log[0].1, serde_json::json!({"n": 7, "label": "hi"})); + } +} diff --git a/crates/rsql-core/src/lib.rs b/crates/rsql-core/src/lib.rs new file mode 100644 index 0000000..9f36c2b --- /dev/null +++ b/crates/rsql-core/src/lib.rs @@ -0,0 +1,14 @@ +//! rsql-core: shared business logic for the rsql desktop and proxy builds. +//! Pure Rust — no Tauri, no axum. + +pub mod common; +pub mod drivers; +pub mod error; +pub mod events; +pub mod ssh; +pub mod state; +pub mod terminal; +pub mod utils; + +pub use events::{EventSink, emit_typed}; +pub use state::AppState; diff --git a/src-tauri/src/ssh.rs b/crates/rsql-core/src/ssh.rs similarity index 100% rename from src-tauri/src/ssh.rs rename to crates/rsql-core/src/ssh.rs diff --git a/crates/rsql-core/src/state/bootstrap.rs b/crates/rsql-core/src/state/bootstrap.rs new file mode 100644 index 0000000..fd647a5 --- /dev/null +++ b/crates/rsql-core/src/state/bootstrap.rs @@ -0,0 +1,117 @@ +use std::{collections::BTreeMap, sync::Arc}; +use tokio::sync::Mutex; + +use super::AppState; +use crate::error::AppError; +use crate::utils::ResourceMonitor; + +pub async fn bootstrap(db_path: &str) -> Result { + let db = libsql::Builder::new_local(db_path) + .build() + .await + .map_err(|e| AppError::DatabaseError(e.to_string()))?; + + let conn = db + .connect() + .map_err(|e| AppError::DatabaseError(e.to_string()))?; + + conn.execute( + "CREATE TABLE IF NOT EXISTS projects ( + id TEXT PRIMARY KEY, + driver TEXT NOT NULL DEFAULT 'PGSQL', + username TEXT NOT NULL DEFAULT '', + password TEXT NOT NULL DEFAULT '', + database TEXT NOT NULL DEFAULT '', + host TEXT NOT NULL DEFAULT '', + port TEXT NOT NULL DEFAULT '', + ssl TEXT NOT NULL DEFAULT 'false' + )", + (), + ) + .await + .map_err(|e| AppError::DatabaseError(e.to_string()))?; + + conn.execute( + "CREATE TABLE IF NOT EXISTS queries ( + id TEXT PRIMARY KEY, + sql TEXT NOT NULL DEFAULT '' + )", + (), + ) + .await + .map_err(|e| AppError::DatabaseError(e.to_string()))?; + + conn.execute( + "CREATE TABLE IF NOT EXISTS workspaces ( + name TEXT PRIMARY KEY, + tabs TEXT NOT NULL DEFAULT '[]' + )", + (), + ) + .await + .map_err(|e| AppError::DatabaseError(e.to_string()))?; + + conn.execute( + "CREATE TABLE IF NOT EXISTS virtual_query_snapshots ( + query_id TEXT PRIMARY KEY, + project_id TEXT NOT NULL, + sql TEXT NOT NULL, + columns_packed TEXT NOT NULL DEFAULT '', + total_rows INTEGER NOT NULL DEFAULT 0, + page_size INTEGER NOT NULL DEFAULT 0, + col_count INTEGER NOT NULL DEFAULT 0, + created_at INTEGER NOT NULL + )", + (), + ) + .await + .map_err(|e| AppError::DatabaseError(e.to_string()))?; + + conn.execute( + "CREATE TABLE IF NOT EXISTS virtual_query_pages ( + query_id TEXT NOT NULL, + page_index INTEGER NOT NULL, + packed_page TEXT NOT NULL DEFAULT '', + PRIMARY KEY (query_id, page_index) + )", + (), + ) + .await + .map_err(|e| AppError::DatabaseError(e.to_string()))?; + + conn.execute( + "DELETE FROM virtual_query_pages + WHERE query_id NOT IN (SELECT query_id FROM virtual_query_snapshots)", + (), + ) + .await + .ok(); + + for col in [ + "ssh_enabled", + "ssh_host", + "ssh_port", + "ssh_user", + "ssh_password", + "ssh_key_path", + ] { + conn.execute( + &format!("ALTER TABLE projects ADD COLUMN {col} TEXT NOT NULL DEFAULT ''"), + (), + ) + .await + .ok(); + } + + Ok(AppState { + clients: Arc::new(Mutex::new(BTreeMap::new())), + meta_clients: Arc::new(Mutex::new(BTreeMap::new())), + cancel_tokens: Arc::new(Mutex::new(BTreeMap::new())), + client_ssl: Arc::new(Mutex::new(BTreeMap::new())), + local_db: db, + resource_monitor: Arc::new(Mutex::new(ResourceMonitor::new())), + virtual_cache: Arc::new(Mutex::new(BTreeMap::new())), + notify_handles: Arc::new(Mutex::new(BTreeMap::new())), + ssh_tunnels: Arc::new(Mutex::new(BTreeMap::new())), + }) +} diff --git a/crates/rsql-core/src/state/mod.rs b/crates/rsql-core/src/state/mod.rs new file mode 100644 index 0000000..507d8d6 --- /dev/null +++ b/crates/rsql-core/src/state/mod.rs @@ -0,0 +1,27 @@ +pub mod bootstrap; +pub mod project; +pub mod query; +pub mod workspace; + +pub use bootstrap::bootstrap; + +use deadpool_postgres::Pool; +use std::{collections::BTreeMap, sync::Arc}; +use tokio::sync::Mutex; +use tokio_postgres::CancelToken; + +use crate::drivers::pgsql::VirtualCache; +use crate::ssh::SshTunnel; +use crate::utils::ResourceMonitor; + +pub struct AppState { + pub clients: Arc>>>, + pub meta_clients: Arc>>>, + pub cancel_tokens: Arc>>, + pub client_ssl: Arc>>, + pub local_db: libsql::Database, + pub resource_monitor: Arc>, + pub virtual_cache: Arc>, + pub notify_handles: Arc>>>, + pub ssh_tunnels: Arc>>, +} diff --git a/src-tauri/src/dbs/project.rs b/crates/rsql-core/src/state/project.rs similarity index 83% rename from src-tauri/src/dbs/project.rs rename to crates/rsql-core/src/state/project.rs index bd480f1..b5e1a4d 100644 --- a/src-tauri/src/dbs/project.rs +++ b/crates/rsql-core/src/state/project.rs @@ -1,13 +1,9 @@ -use crate::AppState; use crate::common::BTreeVecStore; -use crate::common::enums::AppError; +use crate::error::AppError; use std::collections::BTreeMap; -use tauri::{Result, State}; -#[tauri::command(rename_all = "snake_case")] -pub async fn project_db_select(app_state: State<'_, AppState>) -> Result { - let conn = app_state - .local_db +pub async fn project_db_select(local_db: &libsql::Database) -> Result { + let conn = local_db .connect() .map_err(|e| AppError::DatabaseError(e.to_string()))?; @@ -77,14 +73,12 @@ pub async fn project_db_select(app_state: State<'_, AppState>) -> Result, - app_state: State<'_, AppState>, -) -> Result<()> { - let conn = app_state - .local_db +) -> Result<(), AppError> { + let conn = local_db .connect() .map_err(|e| AppError::DatabaseError(e.to_string()))?; @@ -116,10 +110,11 @@ pub async fn project_db_insert( Ok(()) } -#[tauri::command(rename_all = "snake_case")] -pub async fn project_db_delete(project_id: &str, app_state: State<'_, AppState>) -> Result<()> { - let conn = app_state - .local_db +pub async fn project_db_delete( + local_db: &libsql::Database, + project_id: &str, +) -> Result<(), AppError> { + let conn = local_db .connect() .map_err(|e| AppError::DatabaseError(e.to_string()))?; @@ -130,7 +125,6 @@ pub async fn project_db_delete(project_id: &str, app_state: State<'_, AppState>) .await .map_err(|e| AppError::DatabaseError(e.to_string()))?; - // Remove persisted virtual snapshots tied to this project. conn.execute( "DELETE FROM virtual_query_pages WHERE query_id IN ( @@ -147,11 +141,5 @@ pub async fn project_db_delete(project_id: &str, app_state: State<'_, AppState>) .await .map_err(|e| AppError::DatabaseError(e.to_string()))?; - // Best-effort cleanup for in-memory connection state. - app_state.clients.lock().await.remove(project_id); - app_state.meta_clients.lock().await.remove(project_id); - app_state.cancel_tokens.lock().await.remove(project_id); - app_state.client_ssl.lock().await.remove(project_id); - Ok(()) } diff --git a/src-tauri/src/dbs/query.rs b/crates/rsql-core/src/state/query.rs similarity index 65% rename from src-tauri/src/dbs/query.rs rename to crates/rsql-core/src/state/query.rs index 6ae7a90..2966a38 100644 --- a/src-tauri/src/dbs/query.rs +++ b/crates/rsql-core/src/state/query.rs @@ -1,12 +1,10 @@ -use crate::AppState; -use crate::common::enums::AppError; +use crate::error::AppError; use std::collections::BTreeMap; -use tauri::{AppHandle, Manager, Result, State}; -#[tauri::command(rename_all = "snake_case")] -pub async fn query_db_select(app_state: State<'_, AppState>) -> Result> { - let conn = app_state - .local_db +pub async fn query_db_select( + local_db: &libsql::Database, +) -> Result, AppError> { + let conn = local_db .connect() .map_err(|e| AppError::DatabaseError(e.to_string()))?; @@ -32,11 +30,12 @@ pub async fn query_db_select(app_state: State<'_, AppState>) -> Result Result<()> { - let app_state = app.state::(); - let conn = app_state - .local_db +pub async fn query_db_insert( + local_db: &libsql::Database, + query_id: &str, + sql: &str, +) -> Result<(), AppError> { + let conn = local_db .connect() .map_err(|e| AppError::DatabaseError(e.to_string()))?; @@ -50,10 +49,8 @@ pub async fn query_db_insert(query_id: &str, sql: &str, app: AppHandle) -> Resul Ok(()) } -#[tauri::command(rename_all = "snake_case")] -pub async fn query_db_delete(query_id: &str, app_state: State<'_, AppState>) -> Result<()> { - let conn = app_state - .local_db +pub async fn query_db_delete(local_db: &libsql::Database, query_id: &str) -> Result<(), AppError> { + let conn = local_db .connect() .map_err(|e| AppError::DatabaseError(e.to_string()))?; diff --git a/src-tauri/src/dbs/workspace.rs b/crates/rsql-core/src/state/workspace.rs similarity index 67% rename from src-tauri/src/dbs/workspace.rs rename to crates/rsql-core/src/state/workspace.rs index 5a6ea44..14239bd 100644 --- a/src-tauri/src/dbs/workspace.rs +++ b/crates/rsql-core/src/state/workspace.rs @@ -1,11 +1,11 @@ -use crate::AppState; -use crate::common::enums::AppError; -use tauri::{Result, State}; +use crate::error::AppError; -#[tauri::command(rename_all = "snake_case")] -pub async fn workspace_save(name: &str, tabs: &str, app_state: State<'_, AppState>) -> Result<()> { - let conn = app_state - .local_db +pub async fn workspace_save( + local_db: &libsql::Database, + name: &str, + tabs: &str, +) -> Result<(), AppError> { + let conn = local_db .connect() .map_err(|e| AppError::DatabaseError(e.to_string()))?; @@ -19,10 +19,10 @@ pub async fn workspace_save(name: &str, tabs: &str, app_state: State<'_, AppStat Ok(()) } -#[tauri::command(rename_all = "snake_case")] -pub async fn workspace_load_all(app_state: State<'_, AppState>) -> Result> { - let conn = app_state - .local_db +pub async fn workspace_load_all( + local_db: &libsql::Database, +) -> Result, AppError> { + let conn = local_db .connect() .map_err(|e| AppError::DatabaseError(e.to_string()))?; @@ -48,10 +48,8 @@ pub async fn workspace_load_all(app_state: State<'_, AppState>) -> Result) -> Result<()> { - let conn = app_state - .local_db +pub async fn workspace_delete(local_db: &libsql::Database, name: &str) -> Result<(), AppError> { + let conn = local_db .connect() .map_err(|e| AppError::DatabaseError(e.to_string()))?; diff --git a/crates/rsql-core/src/terminal/mod.rs b/crates/rsql-core/src/terminal/mod.rs new file mode 100644 index 0000000..45f04b8 --- /dev/null +++ b/crates/rsql-core/src/terminal/mod.rs @@ -0,0 +1,74 @@ +pub mod session; + +pub use session::TerminalRegistry; + +use portable_pty::{CommandBuilder, PtySize, native_pty_system}; +use std::io::Read; +use std::sync::Arc; + +use crate::error::AppError; +use crate::events::EventSink; + +pub async fn spawn( + registry: &TerminalRegistry, + sink: Arc, + id: String, + cols: u16, + rows: u16, +) -> Result<(), AppError> { + let pty_system = native_pty_system(); + let pair = pty_system + .openpty(PtySize { + rows, + cols, + pixel_width: 0, + pixel_height: 0, + }) + .map_err(|e| AppError::QueryFailed(e.to_string()))?; + + let mut cmd = CommandBuilder::new_default_prog(); + cmd.env("TERM", "xterm-256color"); + + pair.slave + .spawn_command(cmd) + .map_err(|e| AppError::QueryFailed(e.to_string()))?; + drop(pair.slave); + + let writer = pair + .master + .take_writer() + .map_err(|e| AppError::QueryFailed(e.to_string()))?; + let mut reader = pair + .master + .try_clone_reader() + .map_err(|e| AppError::QueryFailed(e.to_string()))?; + + let session = session::TerminalSession { + writer, + master: pair.master, + }; + registry.insert(id.clone(), session).await; + + let terminal_id = id; + let reader_sink = sink; + std::thread::spawn(move || { + let mut buf = [0u8; 4096]; + loop { + match reader.read(&mut buf) { + Ok(0) => { + let event = format!("terminal-exit-{terminal_id}"); + reader_sink.emit(&event, &serde_json::Value::Null); + break; + } + Ok(n) => { + let data = String::from_utf8_lossy(&buf[..n]).to_string(); + let event = format!("terminal-data-{terminal_id}"); + reader_sink.emit(&event, &data); + } + Err(_) => break, + } + } + }); + + Ok(()) +} diff --git a/crates/rsql-core/src/terminal/session.rs b/crates/rsql-core/src/terminal/session.rs new file mode 100644 index 0000000..43c7ce8 --- /dev/null +++ b/crates/rsql-core/src/terminal/session.rs @@ -0,0 +1,76 @@ +use portable_pty::{MasterPty, PtySize}; +use std::{collections::HashMap, io::Write, sync::Arc}; +use tokio::sync::Mutex; + +use crate::error::AppError; + +pub(crate) struct TerminalSession { + pub(crate) writer: Box, + pub(crate) master: Box, +} + +#[derive(Clone)] +pub struct TerminalRegistry { + inner: Arc>>, +} + +impl Default for TerminalRegistry { + fn default() -> Self { + Self { + inner: Arc::new(Mutex::new(HashMap::new())), + } + } +} + +impl TerminalRegistry { + pub fn new() -> Self { + Self::default() + } + + pub(crate) async fn insert(&self, id: String, session: TerminalSession) { + self.inner.lock().await.insert(id, session); + } + + pub async fn write(&self, id: &str, bytes: &[u8]) -> Result<(), AppError> { + let mut sessions = self.inner.lock().await; + let session = sessions + .get_mut(id) + .ok_or_else(|| AppError::QueryFailed(format!("terminal not found: {id}")))?; + session + .writer + .write_all(bytes) + .map_err(|e| AppError::QueryFailed(e.to_string()))?; + session + .writer + .flush() + .map_err(|e| AppError::QueryFailed(e.to_string()))?; + Ok(()) + } + + pub async fn resize(&self, id: &str, cols: u16, rows: u16) -> Result<(), AppError> { + let sessions = self.inner.lock().await; + let session = sessions + .get(id) + .ok_or_else(|| AppError::QueryFailed(format!("terminal not found: {id}")))?; + session + .master + .resize(PtySize { + rows, + cols, + pixel_width: 0, + pixel_height: 0, + }) + .map_err(|e| AppError::QueryFailed(e.to_string()))?; + Ok(()) + } + + pub async fn kill(&self, id: &str) -> Result<(), AppError> { + self.inner.lock().await.remove(id); + Ok(()) + } + + /// Drop all sessions; their reader threads exit on next read after the master PTY is dropped. + pub async fn drain_all(&self) { + self.inner.lock().await.clear(); + } +} diff --git a/crates/rsql-core/src/utils/diff.rs b/crates/rsql-core/src/utils/diff.rs new file mode 100644 index 0000000..05a628e --- /dev/null +++ b/crates/rsql-core/src/utils/diff.rs @@ -0,0 +1,80 @@ +use rayon::prelude::*; +use std::collections::HashSet; + +const ROW_SEP: char = '\x1E'; + +fn parse_packed_rows(packed: &str) -> Vec<&str> { + if packed.is_empty() { + return Vec::new(); + } + let parts: Vec<&str> = packed.split(ROW_SEP).collect(); + if parts.len() > 1 { + parts[1..].to_vec() + } else { + Vec::new() + } +} + +fn pack_rows(header: &str, rows: &[&str]) -> String { + if rows.is_empty() { + return header.to_string(); + } + let mut result = + String::with_capacity(header.len() + rows.iter().map(|r| r.len() + 1).sum::()); + result.push_str(header); + for row in rows { + result.push(ROW_SEP); + result.push_str(row); + } + result +} + +pub fn compute_diff(pinned_packed: &str, current_packed: &str) -> (String, String, usize) { + let pinned_rows = parse_packed_rows(pinned_packed); + let current_rows = parse_packed_rows(current_packed); + + let pinned_set: HashSet<&str> = pinned_rows.iter().copied().collect(); + let current_set: HashSet<&str> = current_rows.iter().copied().collect(); + + let (added, removed, unchanged_count) = if current_rows.len() > 5000 || pinned_rows.len() > 5000 + { + let added: Vec<&str> = current_rows + .par_iter() + .filter(|r| !pinned_set.contains(*r)) + .copied() + .collect(); + let removed: Vec<&str> = pinned_rows + .par_iter() + .filter(|r| !current_set.contains(*r)) + .copied() + .collect(); + let unchanged: usize = current_rows + .par_iter() + .filter(|r| pinned_set.contains(*r)) + .count(); + (added, removed, unchanged) + } else { + let added: Vec<&str> = current_rows + .iter() + .filter(|r| !pinned_set.contains(*r)) + .copied() + .collect(); + let removed: Vec<&str> = pinned_rows + .iter() + .filter(|r| !current_set.contains(*r)) + .copied() + .collect(); + let unchanged: usize = current_rows + .iter() + .filter(|r| pinned_set.contains(*r)) + .count(); + (added, removed, unchanged) + }; + + let header = pinned_packed.split(ROW_SEP).next().unwrap_or(""); + ( + pack_rows(header, &added), + pack_rows(header, &removed), + unchanged_count, + ) +} diff --git a/crates/rsql-core/src/utils/mod.rs b/crates/rsql-core/src/utils/mod.rs new file mode 100644 index 0000000..73db876 --- /dev/null +++ b/crates/rsql-core/src/utils/mod.rs @@ -0,0 +1,132 @@ +use std::collections::HashSet; +use std::time::Instant; + +use sysinfo::{Networks, Pid, ProcessRefreshKind, ProcessesToUpdate, System, get_current_pid}; + +pub mod diff; + +#[derive(serde::Serialize, Clone, Debug)] +pub struct SystemResourceUsage { + pub app_cpu_percent: f32, + pub app_memory_rss_mb: u64, + pub app_process_count: usize, + pub network_rx_mbps: f32, + pub network_tx_mbps: f32, + pub db_connections_in_use: usize, + pub db_connections_open: usize, + pub db_connections_max: usize, + pub db_connections_waiting: usize, +} + +pub struct ResourceMonitor { + system: System, + networks: Networks, + last_sample_at: Instant, + app_pid: Pid, +} + +impl ResourceMonitor { + pub fn new() -> Self { + let app_pid = get_current_pid().unwrap_or_else(|_| Pid::from_u32(std::process::id())); + let mut system = System::new_all(); + system.refresh_processes(ProcessesToUpdate::All, true); + let mut networks = Networks::new_with_refreshed_list(); + networks.refresh(true); + + Self { + system, + networks, + last_sample_at: Instant::now(), + app_pid, + } + } + + pub fn sample(&mut self) -> SystemResourceUsage { + self.system.refresh_processes_specifics( + ProcessesToUpdate::All, + true, + ProcessRefreshKind::nothing().with_cpu().with_memory(), + ); + self.networks.refresh(true); + let dt = self.last_sample_at.elapsed().as_secs_f32().max(0.001); + self.last_sample_at = Instant::now(); + + let processes = self.system.processes(); + let mut included = HashSet::new(); + included.insert(self.app_pid); + + let mut changed = true; + while changed { + changed = false; + for (pid, process) in processes { + if included.contains(pid) { + continue; + } + if let Some(parent) = process.parent() + && included.contains(&parent) + { + included.insert(*pid); + changed = true; + } + } + } + + let mut total_cpu = 0.0f32; + let mut total_rss = 0u64; + for pid in &included { + if let Some(process) = processes.get(pid) { + total_cpu += process.cpu_usage(); + total_rss = total_rss.saturating_add(process.memory()); + } + } + + let mut rx_bytes: u64 = 0; + let mut tx_bytes: u64 = 0; + for (_iface, net) in &self.networks { + rx_bytes = rx_bytes.saturating_add(net.received()); + tx_bytes = tx_bytes.saturating_add(net.transmitted()); + } + let network_rx_mbps = (rx_bytes as f32 * 8.0) / dt / 1_000_000.0; + let network_tx_mbps = (tx_bytes as f32 * 8.0) / dt / 1_000_000.0; + + SystemResourceUsage { + app_cpu_percent: total_cpu, + app_memory_rss_mb: total_rss / (1024 * 1024), + app_process_count: included.len(), + network_rx_mbps, + network_tx_mbps, + db_connections_in_use: 0, + db_connections_open: 0, + db_connections_max: 0, + db_connections_waiting: 0, + } + } +} + +impl Default for ResourceMonitor { + fn default() -> Self { + Self::new() + } +} + +/// Aggregate pool-stats from a deadpool pool map. +/// Returns (open, available, max, waiting). +pub async fn pool_stats( + pools: &tokio::sync::Mutex< + std::collections::BTreeMap>, + >, +) -> (usize, usize, usize, usize) { + let clients = pools.lock().await; + let mut open = 0usize; + let mut available = 0usize; + let mut max = 0usize; + let mut waiting = 0usize; + for pool in clients.values() { + let status = pool.status(); + open = open.saturating_add(status.size); + available = available.saturating_add(status.available); + max = max.saturating_add(status.max_size); + waiting = waiting.saturating_add(status.waiting); + } + (open, available, max, waiting) +} diff --git a/crates/rsql-core/tests/state_smoke.rs b/crates/rsql-core/tests/state_smoke.rs new file mode 100644 index 0000000..d964a60 --- /dev/null +++ b/crates/rsql-core/tests/state_smoke.rs @@ -0,0 +1,137 @@ +use rsql_core::state::project; + +#[tokio::test] +async fn project_roundtrip() { + // Use a temp file path rather than ":memory:" because libsql's in-memory + // databases are scoped per-connection, and the project_* helpers open + // their own connections internally. + let tmp_dir = std::env::temp_dir(); + let db_path = tmp_dir.join(format!("rsql_core_state_smoke_{}.db", std::process::id())); + let _ = std::fs::remove_file(&db_path); + + let db = libsql::Builder::new_local(&db_path) + .build() + .await + .expect("open db"); + + let conn = db.connect().expect("connect"); + conn.execute( + "CREATE TABLE projects ( + id TEXT PRIMARY KEY, + driver TEXT NOT NULL DEFAULT 'PGSQL', + username TEXT NOT NULL DEFAULT '', + password TEXT NOT NULL DEFAULT '', + database TEXT NOT NULL DEFAULT '', + host TEXT NOT NULL DEFAULT '', + port TEXT NOT NULL DEFAULT '', + ssl TEXT NOT NULL DEFAULT 'false', + ssh_enabled TEXT NOT NULL DEFAULT '', + ssh_host TEXT NOT NULL DEFAULT '', + ssh_port TEXT NOT NULL DEFAULT '', + ssh_user TEXT NOT NULL DEFAULT '', + ssh_password TEXT NOT NULL DEFAULT '', + ssh_key_path TEXT NOT NULL DEFAULT '' + )", + (), + ) + .await + .expect("create projects table"); + + conn.execute( + "CREATE TABLE virtual_query_snapshots ( + query_id TEXT PRIMARY KEY, + project_id TEXT NOT NULL, + sql TEXT NOT NULL, + columns_packed TEXT NOT NULL DEFAULT '', + total_rows INTEGER NOT NULL DEFAULT 0, + page_size INTEGER NOT NULL DEFAULT 0, + col_count INTEGER NOT NULL DEFAULT 0, + created_at INTEGER NOT NULL + )", + (), + ) + .await + .expect("create snapshots table"); + conn.execute( + "CREATE TABLE virtual_query_pages ( + query_id TEXT NOT NULL, + page_index INTEGER NOT NULL, + packed_page TEXT NOT NULL DEFAULT '', + PRIMARY KEY (query_id, page_index) + )", + (), + ) + .await + .expect("create pages table"); + + let details = vec![ + "PGSQL".to_string(), + "user".to_string(), + "pass".to_string(), + "db".to_string(), + "localhost".to_string(), + "5432".to_string(), + "false".to_string(), + String::new(), + String::new(), + String::new(), + String::new(), + String::new(), + String::new(), + ]; + + project::project_db_insert(&db, "p1", details.clone()) + .await + .expect("insert"); + + let projects = project::project_db_select(&db).await.expect("select"); + assert_eq!(projects.len(), 1); + assert!(projects.contains_key("p1")); + + project::project_db_delete(&db, "p1").await.expect("delete"); + + let projects = project::project_db_select(&db) + .await + .expect("select after delete"); + assert_eq!(projects.len(), 0); + + drop(conn); + drop(db); + let _ = std::fs::remove_file(&db_path); +} + +#[tokio::test] +async fn bootstrap_creates_tables() { + let tmp = tempfile::NamedTempFile::new().unwrap(); + let path = tmp.path().to_string_lossy().to_string(); + let state = rsql_core::state::bootstrap(&path) + .await + .expect("bootstrap should succeed"); + + let conn = state.local_db.connect().unwrap(); + let mut rows = conn + .query( + "SELECT name FROM sqlite_master WHERE type='table' ORDER BY name", + (), + ) + .await + .unwrap(); + + let mut names = Vec::new(); + while let Some(row) = rows.next().await.unwrap() { + names.push(row.get::(0).unwrap()); + } + + for required in [ + "projects", + "queries", + "workspaces", + "virtual_query_snapshots", + "virtual_query_pages", + ] { + assert!( + names.contains(&required.to_string()), + "missing table: {required}" + ); + } +} diff --git a/crates/rsql-proxy/Cargo.toml b/crates/rsql-proxy/Cargo.toml new file mode 100644 index 0000000..0d61418 --- /dev/null +++ b/crates/rsql-proxy/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "rsql-proxy" +version.workspace = true +edition.workspace = true +authors.workspace = true +description = "rsql-proxy: WebSocket bridge for the browser/hosted RSQL build" + +[lib] +name = "rsql_proxy" +path = "src/lib.rs" + +[[bin]] +name = "rsql-proxy" +path = "src/main.rs" + +[dependencies] +axum = { workspace = true } +tower = { workspace = true } +tower-http = { workspace = true } +tokio = { workspace = true, features = ["rt-multi-thread", "macros", "signal", "net"] } +tracing = { workspace = true } +tracing-subscriber = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +sonic-rs = { workspace = true } +clap = { workspace = true } +futures-util = { workspace = true } +rsql-core = { path = "../rsql-core" } +uuid = { workspace = true } +tokio-postgres = { workspace = true } + +[dev-dependencies] +reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } +tokio-tungstenite = "0.24" +tokio = { workspace = true, features = ["macros", "rt-multi-thread", "time"] } +tempfile = "3" +serde_json = { workspace = true } diff --git a/crates/rsql-proxy/Dockerfile b/crates/rsql-proxy/Dockerfile new file mode 100644 index 0000000..2247192 --- /dev/null +++ b/crates/rsql-proxy/Dockerfile @@ -0,0 +1,47 @@ +# syntax=docker/dockerfile:1.7 + +# ============================================================ +# Stage 1: frontend — build the web bundle +# ============================================================ +FROM node:24-alpine AS frontend +WORKDIR /app + +COPY package.json yarn.lock ./ +RUN yarn install --frozen-lockfile + +COPY . . +RUN VITE_BUILD_TARGET=web yarn build + +# ============================================================ +# Stage 2: rust-build — compile rsql-proxy against musl +# ============================================================ +FROM rust:1.89-alpine AS rust-build +RUN apk add --no-cache musl-dev openssl-dev openssl-libs-static pkgconfig + +WORKDIR /build +ENV CARGO_NET_GIT_FETCH_WITH_CLI=true \ + OPENSSL_STATIC=1 \ + OPENSSL_NO_VENDOR=1 + +COPY Cargo.toml Cargo.lock ./ +COPY crates ./crates + +RUN cargo build --release --bin rsql-proxy + +# ============================================================ +# Stage 3: runtime — minimal Alpine + binary + dist +# ============================================================ +FROM alpine:3.20 +RUN apk add --no-cache ca-certificates + +COPY --from=rust-build /build/target/release/rsql-proxy /usr/local/bin/rsql-proxy +COPY --from=frontend /app/dist /app/dist + +ENV RSQL_BIND=0.0.0.0:8080 \ + RSQL_DIST_DIR=/app/dist \ + RSQL_STATE_PATH=/data/rsql.db \ + RUST_LOG=info,rsql_proxy=info + +VOLUME /data +EXPOSE 8080 +ENTRYPOINT ["rsql-proxy"] diff --git a/crates/rsql-proxy/src/dispatch/mod.rs b/crates/rsql-proxy/src/dispatch/mod.rs new file mode 100644 index 0000000..642c066 --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/mod.rs @@ -0,0 +1,57 @@ +pub mod pgsql_meta; +mod pgsql_meta_admin; +mod pgsql_meta_connection; +mod pgsql_meta_metadata; +mod pgsql_meta_objects; +mod pgsql_meta_statistics; +pub mod pgsql_pubsub; +pub mod pgsql_query; +pub mod state_cmds; +pub mod terminal_cmds; +pub mod utils_cmds; + +use uuid::Uuid; + +use crate::protocol::{Outbound, Request}; +use crate::session::ProxySession; + +pub async fn dispatch(session: &ProxySession, req: Request) -> Outbound { + let Request { id, cmd, payload } = req; + let result = route(session, &cmd, payload, id).await; + match result { + Ok(out) => out, + Err(message) => Outbound::error(id, message), + } +} + +async fn route( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + match cmd { + "project_db_select" | "project_db_insert" | "project_db_delete" | "query_db_select" + | "query_db_insert" | "query_db_delete" | "workspace_save" | "workspace_load_all" + | "workspace_delete" => state_cmds::handle(session, cmd, payload, id).await, + "system_resource_usage" | "compute_diff" => { + utils_cmds::handle(session, cmd, payload, id).await + } + "pgsql_run_query" + | "pgsql_run_query_packed" + | "pgsql_execute_virtual" + | "pgsql_fetch_page" + | "pgsql_close_virtual" + | "pgsql_cancel_query" + | "pgsql_run_query_streamed" => pgsql_query::handle(session, cmd, payload, id).await, + "pgsql_listen_start" + | "pgsql_listen_stop" + | "pgsql_notify_send" + | "pgsql_discover_channels" => pgsql_pubsub::handle(session, cmd, payload, id).await, + "terminal_spawn" | "terminal_write" | "terminal_resize" | "terminal_kill" => { + terminal_cmds::handle(session, cmd, payload, id).await + } + c if c.starts_with("pgsql_") => pgsql_meta::handle(session, c, payload, id).await, + _ => Err(format!("unknown command: {cmd}")), + } +} diff --git a/crates/rsql-proxy/src/dispatch/pgsql_meta.rs b/crates/rsql-proxy/src/dispatch/pgsql_meta.rs new file mode 100644 index 0000000..2af1af8 --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/pgsql_meta.rs @@ -0,0 +1,67 @@ +use uuid::Uuid; + +use crate::protocol::Outbound; +use crate::session::ProxySession; + +pub async fn handle( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + match cmd { + "pgsql_test_connection" | "pgsql_connector" => { + super::pgsql_meta_connection::handle(session, cmd, payload, id).await + } + + "pgsql_load_databases" + | "pgsql_load_tablespaces" + | "pgsql_load_schemas" + | "pgsql_load_tables" + | "pgsql_load_columns" + | "pgsql_load_column_details" + | "pgsql_load_indexes" + | "pgsql_load_constraints" + | "pgsql_load_triggers" + | "pgsql_load_rules" + | "pgsql_load_policies" + | "pgsql_load_views" + | "pgsql_load_materialized_views" + | "pgsql_load_functions" + | "pgsql_load_trigger_functions" => { + super::pgsql_meta_metadata::handle(session, cmd, payload, id).await + } + + "pgsql_load_activity" + | "pgsql_load_database_stats" + | "pgsql_load_table_stats" + | "pgsql_load_foreign_keys" + | "pgsql_table_statistics" + | "pgsql_fk_details" + | "pgsql_load_locks" + | "pgsql_load_index_usage" + | "pgsql_load_table_bloat" => { + super::pgsql_meta_statistics::handle(session, cmd, payload, id).await + } + + "pgsql_view_info" | "pgsql_matview_info" | "pgsql_function_info" | "pgsql_generate_ddl" => { + super::pgsql_meta_objects::handle(session, cmd, payload, id).await + } + + "pgsql_csv_preview" + | "pgsql_csv_import" + | "pgsql_load_roles" + | "pgsql_load_table_grants" + | "pgsql_load_database_grants" + | "pgsql_extract_schema_objects" + | "pgsql_load_extensions" + | "pgsql_load_available_extensions" + | "pgsql_load_enum_types" + | "pgsql_table_action" + | "pgsql_load_pg_settings" => { + super::pgsql_meta_admin::handle(session, cmd, payload, id).await + } + + _ => Err(format!("pgsql_meta: unknown command: {cmd}")), + } +} diff --git a/crates/rsql-proxy/src/dispatch/pgsql_meta_admin.rs b/crates/rsql-proxy/src/dispatch/pgsql_meta_admin.rs new file mode 100644 index 0000000..751e5e4 --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/pgsql_meta_admin.rs @@ -0,0 +1,142 @@ +use rsql_core::drivers::pgsql::commands::admin; +use rsql_core::error::AppError; +use serde::Deserialize; +use uuid::Uuid; + +use crate::protocol::Outbound; +use crate::session::ProxySession; + +pub async fn handle( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + let state = session.app_state.as_ref(); + let json_resp = |value: serde_json::Value| Ok(Outbound::response(id, value)); + + macro_rules! call_pid_only { + ($fn:ident) => {{ + #[derive(Deserialize)] + struct Args { + project_id: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = admin::$fn(state, &a.project_id).await.map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + }}; + } + + match cmd { + "pgsql_csv_preview" => { + #[derive(Deserialize)] + struct Args { + file_path: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = admin::pgsql_csv_preview(&a.file_path) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_csv_import" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + file_path: String, + schema: String, + table: String, + column_mapping: Vec<(usize, String)>, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = admin::pgsql_csv_import( + state, + &a.project_id, + &a.file_path, + &a.schema, + &a.table, + a.column_mapping, + ) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_roles" => call_pid_only!(pgsql_load_roles), + + "pgsql_load_table_grants" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + role_name: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = admin::pgsql_load_table_grants(state, &a.project_id, &a.role_name) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_database_grants" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + role_name: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = admin::pgsql_load_database_grants(state, &a.project_id, &a.role_name) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_extract_schema_objects" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = admin::pgsql_extract_schema_objects(state, &a.project_id, &a.schema) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_extensions" => call_pid_only!(pgsql_load_extensions), + "pgsql_load_available_extensions" => call_pid_only!(pgsql_load_available_extensions), + "pgsql_load_enum_types" => call_pid_only!(pgsql_load_enum_types), + + "pgsql_table_action" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + action: String, + schema: String, + table: String, + object_type: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = admin::pgsql_table_action( + state, + &a.project_id, + &a.action, + &a.schema, + &a.table, + &a.object_type, + ) + .await + .map_err(stringify)?; + json_resp(serde_json::Value::String(v)) + } + + "pgsql_load_pg_settings" => call_pid_only!(pgsql_load_pg_settings), + + _ => unreachable!("pgsql_meta_admin: unexpected command {cmd}"), + } +} + +fn stringify(e: AppError) -> String { + e.to_string() +} diff --git a/crates/rsql-proxy/src/dispatch/pgsql_meta_connection.rs b/crates/rsql-proxy/src/dispatch/pgsql_meta_connection.rs new file mode 100644 index 0000000..82a0c2f --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/pgsql_meta_connection.rs @@ -0,0 +1,89 @@ +use rsql_core::drivers::pgsql::commands::connection; +use rsql_core::error::AppError; +use serde::Deserialize; +use uuid::Uuid; + +use crate::protocol::Outbound; +use crate::session::ProxySession; + +pub async fn handle( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + let state = session.app_state.as_ref(); + let json_resp = |value: serde_json::Value| Ok(Outbound::response(id, value)); + + match cmd { + "pgsql_test_connection" => { + #[derive(Deserialize)] + struct Args { + key: Vec, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + if a.key.len() != 6 { + return Err(format!( + "pgsql_test_connection: key must have 6 elements, got {}", + a.key.len() + )); + } + let key: [&str; 6] = [ + &a.key[0], &a.key[1], &a.key[2], &a.key[3], &a.key[4], &a.key[5], + ]; + let v = connection::pgsql_test_connection(key) + .await + .map_err(stringify)?; + json_resp(serde_json::Value::String(v)) + } + + "pgsql_connector" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + key: Option>, + ssh: Option>, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let key: Option<[String; 6]> = match a.key { + None => None, + Some(v) => { + if v.len() != 6 { + return Err(format!( + "pgsql_connector: key must have 6 elements, got {}", + v.len() + )); + } + Some([ + v[0].clone(), + v[1].clone(), + v[2].clone(), + v[3].clone(), + v[4].clone(), + v[5].clone(), + ]) + } + }; + let key_ref: Option<[&str; 6]> = key.as_ref().map(|k| { + [ + k[0].as_str(), + k[1].as_str(), + k[2].as_str(), + k[3].as_str(), + k[4].as_str(), + k[5].as_str(), + ] + }); + let v = connection::pgsql_connector(state, &a.project_id, key_ref, a.ssh) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + _ => unreachable!("pgsql_meta_connection: unexpected command {cmd}"), + } +} + +fn stringify(e: AppError) -> String { + e.to_string() +} diff --git a/crates/rsql-proxy/src/dispatch/pgsql_meta_metadata.rs b/crates/rsql-proxy/src/dispatch/pgsql_meta_metadata.rs new file mode 100644 index 0000000..a4a110c --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/pgsql_meta_metadata.rs @@ -0,0 +1,206 @@ +use rsql_core::drivers::pgsql::commands::metadata; +use rsql_core::error::AppError; +use serde::Deserialize; +use uuid::Uuid; + +use crate::protocol::Outbound; +use crate::session::ProxySession; + +pub async fn handle( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + let state = session.app_state.as_ref(); + let json_resp = |value: serde_json::Value| Ok(Outbound::response(id, value)); + + macro_rules! call_pid_only { + ($fn:ident) => {{ + #[derive(Deserialize)] + struct Args { + project_id: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::$fn(state, &a.project_id) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + }}; + } + + match cmd { + "pgsql_load_databases" => call_pid_only!(pgsql_load_databases), + "pgsql_load_tablespaces" => call_pid_only!(pgsql_load_tablespaces), + "pgsql_load_schemas" => call_pid_only!(pgsql_load_schemas), + + "pgsql_load_tables" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_tables(state, &a.project_id, &a.schema) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_columns" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + table: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_columns(state, &a.project_id, &a.schema, &a.table) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_column_details" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + table: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_column_details(state, &a.project_id, &a.schema, &a.table) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_indexes" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + table: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_indexes(state, &a.project_id, &a.schema, &a.table) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_constraints" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + table: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_constraints(state, &a.project_id, &a.schema, &a.table) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_triggers" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + table: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_triggers(state, &a.project_id, &a.schema, &a.table) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_rules" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + table: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_rules(state, &a.project_id, &a.schema, &a.table) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_policies" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + table: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_policies(state, &a.project_id, &a.schema, &a.table) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_views" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_views(state, &a.project_id, &a.schema) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_materialized_views" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_materialized_views(state, &a.project_id, &a.schema) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_functions" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_functions(state, &a.project_id, &a.schema) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_load_trigger_functions" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = metadata::pgsql_load_trigger_functions(state, &a.project_id, &a.schema) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + _ => unreachable!("pgsql_meta_metadata: unexpected command {cmd}"), + } +} + +fn stringify(e: AppError) -> String { + e.to_string() +} diff --git a/crates/rsql-proxy/src/dispatch/pgsql_meta_objects.rs b/crates/rsql-proxy/src/dispatch/pgsql_meta_objects.rs new file mode 100644 index 0000000..ded658d --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/pgsql_meta_objects.rs @@ -0,0 +1,88 @@ +use rsql_core::drivers::pgsql::commands::object_info; +use rsql_core::error::AppError; +use serde::Deserialize; +use uuid::Uuid; + +use crate::protocol::Outbound; +use crate::session::ProxySession; + +pub async fn handle( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + let state = session.app_state.as_ref(); + let json_resp = |value: serde_json::Value| Ok(Outbound::response(id, value)); + + match cmd { + "pgsql_view_info" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + view: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = object_info::pgsql_view_info(state, &a.project_id, &a.schema, &a.view) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_matview_info" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + matview: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = object_info::pgsql_matview_info(state, &a.project_id, &a.schema, &a.matview) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_function_info" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + func_name: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = object_info::pgsql_function_info(state, &a.project_id, &a.schema, &a.func_name) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_generate_ddl" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + name: String, + object_type: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = object_info::pgsql_generate_ddl( + state, + &a.project_id, + &a.schema, + &a.name, + &a.object_type, + ) + .await + .map_err(stringify)?; + json_resp(serde_json::Value::String(v)) + } + + _ => unreachable!("pgsql_meta_objects: unexpected command {cmd}"), + } +} + +fn stringify(e: AppError) -> String { + e.to_string() +} diff --git a/crates/rsql-proxy/src/dispatch/pgsql_meta_statistics.rs b/crates/rsql-proxy/src/dispatch/pgsql_meta_statistics.rs new file mode 100644 index 0000000..57de498 --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/pgsql_meta_statistics.rs @@ -0,0 +1,94 @@ +use rsql_core::drivers::pgsql::commands::statistics; +use rsql_core::error::AppError; +use serde::Deserialize; +use uuid::Uuid; + +use crate::protocol::Outbound; +use crate::session::ProxySession; + +pub async fn handle( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + let state = session.app_state.as_ref(); + let json_resp = |value: serde_json::Value| Ok(Outbound::response(id, value)); + + macro_rules! call_pid_only { + ($fn:ident) => {{ + #[derive(Deserialize)] + struct Args { + project_id: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = statistics::$fn(state, &a.project_id) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + }}; + } + + match cmd { + "pgsql_load_activity" => call_pid_only!(pgsql_load_activity), + "pgsql_load_database_stats" => call_pid_only!(pgsql_load_database_stats), + "pgsql_load_table_stats" => call_pid_only!(pgsql_load_table_stats), + "pgsql_load_locks" => call_pid_only!(pgsql_load_locks), + "pgsql_load_index_usage" => call_pid_only!(pgsql_load_index_usage), + "pgsql_load_table_bloat" => call_pid_only!(pgsql_load_table_bloat), + + "pgsql_load_foreign_keys" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = statistics::pgsql_load_foreign_keys(state, &a.project_id, &a.schema) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_table_statistics" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + table: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = statistics::pgsql_table_statistics(state, &a.project_id, &a.schema, &a.table) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + "pgsql_fk_details" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + schema: String, + table: String, + direction: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = statistics::pgsql_fk_details( + state, + &a.project_id, + &a.schema, + &a.table, + &a.direction, + ) + .await + .map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + + _ => unreachable!("pgsql_meta_statistics: unexpected command {cmd}"), + } +} + +fn stringify(e: AppError) -> String { + e.to_string() +} diff --git a/crates/rsql-proxy/src/dispatch/pgsql_pubsub.rs b/crates/rsql-proxy/src/dispatch/pgsql_pubsub.rs new file mode 100644 index 0000000..0fe9d36 --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/pgsql_pubsub.rs @@ -0,0 +1,75 @@ +use rsql_core::drivers::pgsql::commands::pubsub; +use rsql_core::error::AppError; +use serde::Deserialize; +use uuid::Uuid; + +use crate::protocol::Outbound; +use crate::session::ProxySession; + +pub async fn handle( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + let state = session.app_state.as_ref(); + + match cmd { + "pgsql_listen_start" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + channel: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = pubsub::listen_start(state, &a.project_id, &a.channel, session.sink.clone()) + .await + .map_err(stringify)?; + Ok(Outbound::response(id, serde_json::Value::Bool(v))) + } + "pgsql_listen_stop" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + channel: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = pubsub::listen_stop(state, &a.project_id, &a.channel) + .await + .map_err(stringify)?; + Ok(Outbound::response(id, serde_json::Value::Bool(v))) + } + "pgsql_notify_send" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + channel: String, + payload: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = pubsub::pgsql_notify_send(state, &a.project_id, &a.channel, &a.payload) + .await + .map_err(stringify)?; + Ok(Outbound::response(id, serde_json::Value::Bool(v))) + } + "pgsql_discover_channels" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = pubsub::pgsql_discover_channels(state, &a.project_id) + .await + .map_err(stringify)?; + Ok(Outbound::response( + id, + serde_json::to_value(v).map_err(|e| e.to_string())?, + )) + } + _ => Err(format!("pgsql_pubsub: unknown command: {cmd}")), + } +} + +fn stringify(e: AppError) -> String { + e.to_string() +} diff --git a/crates/rsql-proxy/src/dispatch/pgsql_query.rs b/crates/rsql-proxy/src/dispatch/pgsql_query.rs new file mode 100644 index 0000000..845141d --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/pgsql_query.rs @@ -0,0 +1,138 @@ +use rsql_core::drivers::pgsql::commands::{pool_helpers, query}; +use rsql_core::drivers::pgsql::streaming::execute_query_streamed; +use rsql_core::error::AppError; +use rsql_core::events::EventSink; +use serde::Deserialize; +use uuid::Uuid; + +use crate::protocol::Outbound; +use crate::session::ProxySession; + +pub async fn handle( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + let state = session.app_state.as_ref(); + + match cmd { + "pgsql_run_query" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + sql: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let s = query::pgsql_run_query(state, &a.project_id, &a.sql) + .await + .map_err(stringify)?; + Ok(Outbound::binary(id, s.into_bytes())) + } + "pgsql_run_query_packed" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + sql: String, + timeout_ms: Option, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let s = query::pgsql_run_query_packed(state, &a.project_id, &a.sql, a.timeout_ms) + .await + .map_err(stringify)?; + Ok(Outbound::binary(id, s.into_bytes())) + } + "pgsql_execute_virtual" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + sql: String, + query_id: String, + page_size: usize, + timeout_ms: Option, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let s = query::pgsql_execute_virtual( + state, + &a.project_id, + &a.sql, + &a.query_id, + a.page_size, + a.timeout_ms, + ) + .await + .map_err(stringify)?; + Ok(Outbound::binary(id, s.into_bytes())) + } + "pgsql_fetch_page" => { + #[derive(Deserialize)] + struct Args { + query_id: String, + col_count: usize, + offset: usize, + limit: usize, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let s = query::pgsql_fetch_page(state, &a.query_id, a.col_count, a.offset, a.limit) + .await + .map_err(stringify)?; + Ok(Outbound::binary(id, s.into_bytes())) + } + "pgsql_close_virtual" => { + #[derive(Deserialize)] + struct Args { + query_id: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + query::pgsql_close_virtual(state, &a.query_id) + .await + .map_err(stringify)?; + Ok(Outbound::response(id, serde_json::Value::Null)) + } + "pgsql_cancel_query" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let v = query::pgsql_cancel_query(state, &a.project_id) + .await + .map_err(stringify)?; + Ok(Outbound::response(id, serde_json::Value::Bool(v))) + } + "pgsql_run_query_streamed" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + sql: String, + stream_id: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let client = pool_helpers::acquire_client(&state.clients, &a.project_id) + .await + .map_err(stringify)?; + let token = client.cancel_token(); + pool_helpers::set_cancel_token(state, &a.project_id, token.clone()) + .await + .map_err(stringify)?; + session.record_cancel_token(id, token).await; + + let sink = session.sink.clone(); + let sql = a.sql.clone(); + let stream_id = a.stream_id.clone(); + tokio::spawn(async move { + if let Err(e) = execute_query_streamed(&client, &sql, &stream_id, &sink).await { + let err_payload = + serde_json::json!({"type": "error", "message": e.to_string()}); + sink.emit(&format!("query-stream-{stream_id}"), &err_payload); + } + }); + Ok(Outbound::response(id, serde_json::Value::Null)) + } + _ => Err(format!("pgsql_query: unknown command: {cmd}")), + } +} + +fn stringify(e: AppError) -> String { + e.to_string() +} diff --git a/crates/rsql-proxy/src/dispatch/state_cmds.rs b/crates/rsql-proxy/src/dispatch/state_cmds.rs new file mode 100644 index 0000000..0bb21b1 --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/state_cmds.rs @@ -0,0 +1,124 @@ +use rsql_core::state::{project, query, workspace}; +use serde::Deserialize; +use uuid::Uuid; + +use crate::protocol::Outbound; +use crate::session::ProxySession; + +pub async fn handle( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + let db = &session.app_state.local_db; + let json_resp = |value: serde_json::Value| Ok(Outbound::response(id, value)); + + match cmd { + "project_db_select" => { + let v = project::project_db_select(db).await.map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + "project_db_insert" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + project_details: Vec, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + project::project_db_insert(db, &a.project_id, a.project_details) + .await + .map_err(stringify)?; + json_resp(serde_json::Value::Null) + } + "project_db_delete" => { + #[derive(Deserialize)] + struct Args { + project_id: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + project::project_db_delete(db, &a.project_id) + .await + .map_err(stringify)?; + session.app_state.clients.lock().await.remove(&a.project_id); + session + .app_state + .meta_clients + .lock() + .await + .remove(&a.project_id); + session + .app_state + .cancel_tokens + .lock() + .await + .remove(&a.project_id); + session + .app_state + .client_ssl + .lock() + .await + .remove(&a.project_id); + json_resp(serde_json::Value::Null) + } + "query_db_select" => { + let v = query::query_db_select(db).await.map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + "query_db_insert" => { + #[derive(Deserialize)] + struct Args { + query_id: String, + sql: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + query::query_db_insert(db, &a.query_id, &a.sql) + .await + .map_err(stringify)?; + json_resp(serde_json::Value::Null) + } + "query_db_delete" => { + #[derive(Deserialize)] + struct Args { + query_id: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + query::query_db_delete(db, &a.query_id) + .await + .map_err(stringify)?; + json_resp(serde_json::Value::Null) + } + "workspace_save" => { + #[derive(Deserialize)] + struct Args { + name: String, + tabs: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + workspace::workspace_save(db, &a.name, &a.tabs) + .await + .map_err(stringify)?; + json_resp(serde_json::Value::Null) + } + "workspace_load_all" => { + let v = workspace::workspace_load_all(db).await.map_err(stringify)?; + json_resp(serde_json::to_value(v).map_err(|e| e.to_string())?) + } + "workspace_delete" => { + #[derive(Deserialize)] + struct Args { + name: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + workspace::workspace_delete(db, &a.name) + .await + .map_err(stringify)?; + json_resp(serde_json::Value::Null) + } + _ => Err(format!("state_cmds: unknown command: {cmd}")), + } +} + +fn stringify(e: rsql_core::error::AppError) -> String { + e.to_string() +} diff --git a/crates/rsql-proxy/src/dispatch/terminal_cmds.rs b/crates/rsql-proxy/src/dispatch/terminal_cmds.rs new file mode 100644 index 0000000..2759cd8 --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/terminal_cmds.rs @@ -0,0 +1,93 @@ +use rsql_core::error::AppError; +use rsql_core::terminal; +use serde::Deserialize; +use std::sync::OnceLock; +use uuid::Uuid; + +use crate::protocol::Outbound; +use crate::session::ProxySession; + +static DISABLED: OnceLock = OnceLock::new(); + +pub fn is_terminal_disabled() -> bool { + *DISABLED.get_or_init(|| { + std::env::var("RSQL_DISABLE_TERMINAL") + .map(|v| matches!(v.as_str(), "1" | "true" | "TRUE" | "yes" | "YES")) + .unwrap_or(false) + }) +} + +pub async fn handle( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + if is_terminal_disabled() { + return Err("terminal disabled by RSQL_DISABLE_TERMINAL".to_string()); + } + match cmd { + "terminal_spawn" => { + #[derive(Deserialize)] + struct Args { + id: String, + cols: u16, + rows: u16, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + terminal::spawn( + &session.terminals, + session.sink.clone(), + a.id, + a.cols, + a.rows, + ) + .await + .map_err(stringify)?; + Ok(Outbound::response(id, serde_json::Value::Null)) + } + "terminal_write" => { + #[derive(Deserialize)] + struct Args { + id: String, + data: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + session + .terminals + .write(&a.id, a.data.as_bytes()) + .await + .map_err(stringify)?; + Ok(Outbound::response(id, serde_json::Value::Null)) + } + "terminal_resize" => { + #[derive(Deserialize)] + struct Args { + id: String, + cols: u16, + rows: u16, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + session + .terminals + .resize(&a.id, a.cols, a.rows) + .await + .map_err(stringify)?; + Ok(Outbound::response(id, serde_json::Value::Null)) + } + "terminal_kill" => { + #[derive(Deserialize)] + struct Args { + id: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + session.terminals.kill(&a.id).await.map_err(stringify)?; + Ok(Outbound::response(id, serde_json::Value::Null)) + } + _ => Err(format!("terminal_cmds: unknown command: {cmd}")), + } +} + +fn stringify(e: AppError) -> String { + e.to_string() +} diff --git a/crates/rsql-proxy/src/dispatch/utils_cmds.rs b/crates/rsql-proxy/src/dispatch/utils_cmds.rs new file mode 100644 index 0000000..a6c79c7 --- /dev/null +++ b/crates/rsql-proxy/src/dispatch/utils_cmds.rs @@ -0,0 +1,49 @@ +use rsql_core::utils::{diff, pool_stats}; +use serde::Deserialize; +use uuid::Uuid; + +use crate::protocol::Outbound; +use crate::session::ProxySession; + +pub async fn handle( + session: &ProxySession, + cmd: &str, + payload: serde_json::Value, + id: Uuid, +) -> Result { + match cmd { + "system_resource_usage" => { + let mut usage = { + let mut monitor = session.app_state.resource_monitor.lock().await; + monitor.sample() + }; + let (q_open, q_avail, q_max, q_wait) = pool_stats(&session.app_state.clients).await; + let (m_open, m_avail, m_max, m_wait) = + pool_stats(&session.app_state.meta_clients).await; + let total_open = q_open.saturating_add(m_open); + let total_avail = q_avail.saturating_add(m_avail); + usage.db_connections_open = total_open; + usage.db_connections_max = q_max.saturating_add(m_max); + usage.db_connections_waiting = q_wait.saturating_add(m_wait); + usage.db_connections_in_use = total_open.saturating_sub(total_avail); + Ok(Outbound::response( + id, + serde_json::to_value(usage).map_err(|e| e.to_string())?, + )) + } + "compute_diff" => { + #[derive(Deserialize)] + struct Args { + pinned_packed: String, + current_packed: String, + } + let a: Args = serde_json::from_value(payload).map_err(|e| e.to_string())?; + let (a_out, b_out, count) = diff::compute_diff(&a.pinned_packed, &a.current_packed); + Ok(Outbound::response( + id, + serde_json::json!([a_out, b_out, count]), + )) + } + _ => Err(format!("utils_cmds: unknown command: {cmd}")), + } +} diff --git a/crates/rsql-proxy/src/event_sink.rs b/crates/rsql-proxy/src/event_sink.rs new file mode 100644 index 0000000..d8cc251 --- /dev/null +++ b/crates/rsql-proxy/src/event_sink.rs @@ -0,0 +1,29 @@ +use rsql_core::events::EventSink; +use tokio::sync::mpsc::UnboundedSender; + +use crate::protocol::Outbound; + +pub struct ProxyEventSink { + tx: UnboundedSender, +} + +impl ProxyEventSink { + pub fn new(tx: UnboundedSender) -> Self { + Self { tx } + } +} + +impl EventSink for ProxyEventSink { + fn emit(&self, event: &str, payload: &T) { + let value = match serde_json::to_value(payload) { + Ok(v) => v, + Err(e) => { + tracing::error!(error = %e, event, "ProxyEventSink serialize failed"); + return; + } + }; + if let Err(e) = self.tx.send(Outbound::event(event, value)) { + tracing::debug!(error = %e, "ProxyEventSink: receiver closed"); + } + } +} diff --git a/crates/rsql-proxy/src/health.rs b/crates/rsql-proxy/src/health.rs new file mode 100644 index 0000000..f6ec535 --- /dev/null +++ b/crates/rsql-proxy/src/health.rs @@ -0,0 +1,13 @@ +use axum::{Json, Router, routing::get}; +use serde_json::{Value, json}; + +pub fn routes() -> Router { + Router::new().route("/health", get(handler)) +} + +async fn handler() -> Json { + Json(json!({ + "status": "ok", + "version": env!("CARGO_PKG_VERSION"), + })) +} diff --git a/crates/rsql-proxy/src/lib.rs b/crates/rsql-proxy/src/lib.rs new file mode 100644 index 0000000..7566f17 --- /dev/null +++ b/crates/rsql-proxy/src/lib.rs @@ -0,0 +1,35 @@ +//! rsql-proxy: WebSocket bridge for browser/hosted RSQL. + +pub mod dispatch; +pub mod event_sink; +pub mod health; +pub mod protocol; +pub mod session; +pub mod static_serve; +pub mod ws; + +use axum::Router; +use rsql_core::AppState; +use std::path::PathBuf; +use std::sync::Arc; +use tower_http::trace::TraceLayer; + +pub struct ProxyConfig { + pub app_state: Arc, + pub dist_dir: Option, +} + +pub fn router(config: ProxyConfig) -> Router { + let ws_state = ws::WsState { + app_state: config.app_state, + }; + let mut app = Router::new() + .merge(health::routes()) + .merge(ws::routes(ws_state)); + + if let Some(dir) = config.dist_dir { + app = app.merge(static_serve::routes(dir)); + } + + app.layer(TraceLayer::new_for_http()) +} diff --git a/crates/rsql-proxy/src/main.rs b/crates/rsql-proxy/src/main.rs new file mode 100644 index 0000000..d46c41b --- /dev/null +++ b/crates/rsql-proxy/src/main.rs @@ -0,0 +1,117 @@ +use clap::Parser; +use rsql_proxy::ProxyConfig; +use std::{net::SocketAddr, path::PathBuf, sync::Arc}; +use tokio::net::TcpListener; +use tracing_subscriber::EnvFilter; + +#[derive(Parser, Debug)] +#[command( + name = "rsql-proxy", + version, + about = "rsql-proxy: WebSocket bridge for browser/hosted RSQL" +)] +struct Args { + #[arg(long, env = "RSQL_BIND", default_value = "127.0.0.1:8080")] + addr: SocketAddr, + #[arg(long, env = "RSQL_DIST_DIR", default_value = "dist")] + dist_dir: String, + #[arg(long, env = "RSQL_STATE_PATH", default_value = "proxy.db")] + state_path: String, +} + +#[tokio::main] +async fn main() { + let args = Args::parse(); + tracing_subscriber::fmt() + .with_env_filter( + EnvFilter::try_from_default_env() + .unwrap_or_else(|_| EnvFilter::new("info,rsql_proxy=debug")), + ) + .with_target(false) + .init(); + + let listener = TcpListener::bind(args.addr) + .await + .expect("failed to bind listener"); + + let app_state = rsql_core::state::bootstrap(&args.state_path) + .await + .expect("AppState bootstrap failed"); + let app_state = Arc::new(app_state); + + tracing::info!( + version = env!("CARGO_PKG_VERSION"), + addr = %listener.local_addr().unwrap(), + dist = %args.dist_dir, + state = %args.state_path, + "rsql-proxy listening" + ); + + let config = ProxyConfig { + app_state, + dist_dir: Some(PathBuf::from(args.dist_dir)), + }; + + axum::serve(listener, rsql_proxy::router(config)) + .with_graceful_shutdown(shutdown_signal()) + .await + .expect("axum::serve failed"); +} + +async fn shutdown_signal() { + tokio::signal::ctrl_c().await.expect("ctrl-c handler"); + tracing::info!("shutdown signal received"); +} + +#[cfg(test)] +mod tests { + use super::*; + use clap::Parser; + + fn parse_clean() -> Args { + Args::try_parse_from(["rsql-proxy"]).unwrap() + } + + #[test] + fn defaults_apply_when_no_env() { + unsafe { + std::env::remove_var("RSQL_BIND"); + std::env::remove_var("RSQL_DIST_DIR"); + std::env::remove_var("RSQL_STATE_PATH"); + } + let args = parse_clean(); + assert_eq!(args.addr.to_string(), "127.0.0.1:8080"); + assert_eq!(args.dist_dir, "dist"); + assert_eq!(args.state_path, "proxy.db"); + } + + #[test] + fn env_overrides_default() { + unsafe { + std::env::set_var("RSQL_BIND", "0.0.0.0:9999"); + std::env::set_var("RSQL_DIST_DIR", "/srv/dist"); + std::env::set_var("RSQL_STATE_PATH", "/data/rsql.db"); + } + let args = parse_clean(); + assert_eq!(args.addr.to_string(), "0.0.0.0:9999"); + assert_eq!(args.dist_dir, "/srv/dist"); + assert_eq!(args.state_path, "/data/rsql.db"); + unsafe { + std::env::remove_var("RSQL_BIND"); + std::env::remove_var("RSQL_DIST_DIR"); + std::env::remove_var("RSQL_STATE_PATH"); + } + } + + #[test] + fn cli_arg_beats_env() { + unsafe { + std::env::set_var("RSQL_BIND", "0.0.0.0:9999"); + } + let args = Args::try_parse_from(["rsql-proxy", "--addr", "127.0.0.1:7000"]).unwrap(); + assert_eq!(args.addr.to_string(), "127.0.0.1:7000"); + unsafe { + std::env::remove_var("RSQL_BIND"); + } + } +} diff --git a/crates/rsql-proxy/src/protocol.rs b/crates/rsql-proxy/src/protocol.rs new file mode 100644 index 0000000..5a9ac5c --- /dev/null +++ b/crates/rsql-proxy/src/protocol.rs @@ -0,0 +1,166 @@ +use axum::extract::ws::Message; +use serde::{Deserialize, Serialize}; +use sonic_rs; +use uuid::Uuid; + +pub const BINARY_ID_LEN: usize = 16; + +#[derive(Debug, Deserialize)] +#[serde(tag = "type", rename_all = "lowercase")] +pub enum Inbound { + Request(Request), + Cancel(Cancel), + #[serde(skip)] + BinaryChunk { + id: Uuid, + payload: Vec, + }, +} + +#[derive(Debug, Deserialize)] +pub struct Request { + pub id: Uuid, + pub cmd: String, + #[serde(default)] + pub payload: serde_json::Value, +} + +#[derive(Debug, Deserialize)] +pub struct Cancel { + pub id: Uuid, +} + +#[derive(Debug, Serialize, Clone)] +#[serde(tag = "type", rename_all = "lowercase")] +pub enum OutboundFrame { + Response { + id: Uuid, + payload: serde_json::Value, + #[serde(skip_serializing_if = "Option::is_none")] + end: Option, + }, + Error { + id: Uuid, + message: String, + #[serde(skip_serializing_if = "Option::is_none")] + code: Option, + }, + Event { + event: String, + payload: serde_json::Value, + }, +} + +#[derive(Debug, Clone)] +pub enum Outbound { + Text(OutboundFrame), + Binary { id: Uuid, payload: Vec }, +} + +impl Outbound { + pub fn response(id: Uuid, payload: serde_json::Value) -> Self { + Outbound::Text(OutboundFrame::Response { + id, + payload, + end: Some(true), + }) + } + + pub fn error(id: Uuid, message: impl Into) -> Self { + Outbound::Text(OutboundFrame::Error { + id, + message: message.into(), + code: None, + }) + } + + pub fn event(event: impl Into, payload: serde_json::Value) -> Self { + Outbound::Text(OutboundFrame::Event { + event: event.into(), + payload, + }) + } + + pub fn binary(id: Uuid, payload: Vec) -> Self { + Outbound::Binary { id, payload } + } + + pub fn into_ws_message(self) -> Result { + match self { + Outbound::Text(frame) => Ok(Message::Text(sonic_rs::to_string(&frame)?.into())), + Outbound::Binary { id, payload } => { + let mut buf = Vec::with_capacity(BINARY_ID_LEN + payload.len()); + buf.extend_from_slice(id.as_bytes()); + buf.extend_from_slice(&payload); + Ok(Message::Binary(buf.into())) + } + } + } +} + +pub fn parse_text(text: &str) -> Result { + sonic_rs::from_str(text) +} + +pub fn parse_binary(bytes: &[u8]) -> Option<(Uuid, &[u8])> { + if bytes.len() < BINARY_ID_LEN { + return None; + } + let id_bytes: [u8; 16] = bytes[..BINARY_ID_LEN].try_into().ok()?; + let id = Uuid::from_bytes(id_bytes); + Some((id, &bytes[BINARY_ID_LEN..])) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn parse_request_text() { + let raw = r#"{"type":"request","id":"01933e44-de63-7c80-8000-000000000000","cmd":"workspace_save","payload":{"name":"a","tabs":"[]"}}"#; + let parsed = parse_text(raw).expect("parse"); + match parsed { + Inbound::Request(req) => { + assert_eq!(req.cmd, "workspace_save"); + assert_eq!(req.payload["name"], "a"); + } + _ => panic!("expected request"), + } + } + + #[test] + fn parse_cancel_text() { + let raw = r#"{"type":"cancel","id":"01933e44-de63-7c80-8000-000000000000"}"#; + let parsed = parse_text(raw).expect("parse"); + assert!(matches!(parsed, Inbound::Cancel(_))); + } + + #[test] + fn binary_frame_roundtrip() { + let id = Uuid::now_v7(); + let payload = b"row1\x1Frow2".to_vec(); + let frame = Outbound::binary(id, payload.clone()); + let msg = frame.into_ws_message().unwrap(); + let bytes: Vec = match msg { + Message::Binary(b) => b.to_vec(), + _ => panic!("expected binary"), + }; + let (parsed_id, parsed_payload) = parse_binary(&bytes).unwrap(); + assert_eq!(parsed_id, id); + assert_eq!(parsed_payload, payload.as_slice()); + } + + #[test] + fn response_serializes_with_end_flag() { + let id = Uuid::now_v7(); + let frame = Outbound::response(id, serde_json::json!({"ok": true})); + let msg = frame.into_ws_message().unwrap(); + let s = match msg { + Message::Text(t) => t.to_string(), + _ => panic!("text"), + }; + assert!(s.contains("\"type\":\"response\"")); + assert!(s.contains("\"end\":true")); + assert!(s.contains(&id.to_string())); + } +} diff --git a/crates/rsql-proxy/src/session.rs b/crates/rsql-proxy/src/session.rs new file mode 100644 index 0000000..5494910 --- /dev/null +++ b/crates/rsql-proxy/src/session.rs @@ -0,0 +1,57 @@ +use rsql_core::AppState; +use rsql_core::terminal::TerminalRegistry; +use std::collections::HashMap; +use std::sync::Arc; +use tokio::sync::Mutex; +use tokio::sync::mpsc::UnboundedSender; +use tokio_postgres::CancelToken; +use uuid::Uuid; + +use crate::event_sink::ProxyEventSink; +use crate::protocol::Outbound; + +#[derive(Clone)] +pub struct ProxySession { + pub app_state: Arc, + pub terminals: TerminalRegistry, + pub sink: Arc, + pub outbound: UnboundedSender, + pub cancel_tokens: Arc>>, +} + +impl ProxySession { + pub fn new(app_state: Arc, outbound: UnboundedSender) -> Self { + let sink = Arc::new(ProxyEventSink::new(outbound.clone())); + Self { + app_state, + terminals: TerminalRegistry::new(), + sink, + outbound, + cancel_tokens: Arc::new(Mutex::new(HashMap::new())), + } + } + + pub async fn record_cancel_token(&self, id: Uuid, token: CancelToken) { + self.cancel_tokens.lock().await.insert(id, token); + } + + pub async fn trip_cancel(&self, id: Uuid) { + if let Some(token) = self.cancel_tokens.lock().await.remove(&id) { + let _ = token.cancel_query(tokio_postgres::NoTls).await; + } + } + + pub async fn cleanup(&self) { + self.terminals.drain_all().await; + { + let mut handles = self.app_state.notify_handles.lock().await; + let drained: Vec<_> = handles.iter().map(|(k, _)| k.clone()).collect(); + for key in drained { + if let Some(h) = handles.remove(&key) { + h.abort(); + } + } + } + self.cancel_tokens.lock().await.clear(); + } +} diff --git a/crates/rsql-proxy/src/static_serve.rs b/crates/rsql-proxy/src/static_serve.rs new file mode 100644 index 0000000..e2d2d53 --- /dev/null +++ b/crates/rsql-proxy/src/static_serve.rs @@ -0,0 +1,9 @@ +use axum::Router; +use std::path::PathBuf; +use tower_http::services::{ServeDir, ServeFile}; + +pub fn routes(dist_dir: PathBuf) -> Router { + let index = dist_dir.join("index.html"); + let serve_dir = ServeDir::new(&dist_dir).fallback(ServeFile::new(&index)); + Router::new().fallback_service(serve_dir) +} diff --git a/crates/rsql-proxy/src/ws.rs b/crates/rsql-proxy/src/ws.rs new file mode 100644 index 0000000..e61917a --- /dev/null +++ b/crates/rsql-proxy/src/ws.rs @@ -0,0 +1,120 @@ +use axum::{ + Router, + extract::{ + State, WebSocketUpgrade, + ws::{Message, WebSocket}, + }, + response::IntoResponse, + routing::get, +}; +use futures_util::StreamExt; +use rsql_core::AppState; +use std::sync::Arc; +use std::time::Duration; +use tokio::sync::mpsc; +use tokio::time::{Instant, interval, sleep_until}; + +use crate::dispatch::dispatch; +use crate::protocol::{self, Inbound, Outbound}; +use crate::session::ProxySession; + +#[derive(Clone)] +pub struct WsState { + pub app_state: Arc, +} + +pub fn routes(state: WsState) -> Router { + Router::new().route("/ws", get(upgrade)).with_state(state) +} + +async fn upgrade(ws: WebSocketUpgrade, State(state): State) -> impl IntoResponse { + ws.on_upgrade(move |socket| run(socket, state.app_state)) +} + +async fn run(socket: WebSocket, app_state: Arc) { + let (outbound_tx, mut outbound_rx) = mpsc::unbounded_channel::(); + let session = ProxySession::new(app_state, outbound_tx.clone()); + + let (mut sender, mut receiver) = socket.split(); + + let (ping_tx, mut ping_rx) = mpsc::unbounded_channel::>(); + let writer = tokio::spawn(async move { + loop { + tokio::select! { + Some(msg) = outbound_rx.recv() => { + match msg.into_ws_message() { + Ok(ws_msg) => { + if futures_util::SinkExt::send(&mut sender, ws_msg).await.is_err() { + break; + } + } + Err(e) => tracing::warn!(error = %e, "encode outbound failed"), + } + } + Some(payload) = ping_rx.recv() => { + if futures_util::SinkExt::send(&mut sender, Message::Ping(payload.into())).await.is_err() { + break; + } + } + else => break, + } + } + }); + + let mut ping_timer = interval(Duration::from_secs(30)); + ping_timer.tick().await; + let mut pong_deadline: Option = None; + + loop { + tokio::select! { + biased; + _ = ping_timer.tick() => { + let payload = b"rsql".to_vec(); + if ping_tx.send(payload).is_err() { + break; + } + pong_deadline = Some(Instant::now() + Duration::from_secs(10)); + } + _ = async { + if let Some(d) = pong_deadline { + sleep_until(d).await; + } else { + futures_util::future::pending::<()>().await; + } + }, if pong_deadline.is_some() => { + tracing::info!("WS pong deadline missed, closing"); + break; + } + maybe_msg = receiver.next() => { + let Some(Ok(msg)) = maybe_msg else { break }; + match msg { + Message::Text(t) => match protocol::parse_text(&t) { + Ok(Inbound::Request(req)) => { + let session_clone = session.clone(); + let tx_clone = outbound_tx.clone(); + tokio::spawn(async move { + let out = dispatch(&session_clone, req).await; + let _ = tx_clone.send(out); + }); + } + Ok(Inbound::Cancel(c)) => { + let session_clone = session.clone(); + tokio::spawn(async move { session_clone.trip_cancel(c.id).await; }); + } + Ok(Inbound::BinaryChunk { .. }) => {} + Err(e) => tracing::warn!(error = %e, "ignored malformed JSON frame"), + }, + Message::Binary(_b) => {} + Message::Pong(_) => { pong_deadline = None; } + Message::Ping(_) => {} + Message::Close(_) => break, + } + } + } + } + + session.cleanup().await; + drop(outbound_tx); + drop(ping_tx); + let _ = writer.await; +} diff --git a/crates/rsql-proxy/tests/common/mod.rs b/crates/rsql-proxy/tests/common/mod.rs new file mode 100644 index 0000000..2101c70 --- /dev/null +++ b/crates/rsql-proxy/tests/common/mod.rs @@ -0,0 +1,27 @@ +use rsql_proxy::ProxyConfig; +use std::{net::SocketAddr, sync::Arc}; +use tempfile::NamedTempFile; +use tokio::net::TcpListener; + +pub async fn spawn_test_server() -> (SocketAddr, NamedTempFile) { + let listener = TcpListener::bind("127.0.0.1:0").await.expect("bind"); + let addr = listener.local_addr().expect("local_addr"); + + let tmp_db = NamedTempFile::new().expect("tempfile"); + let app_state = rsql_core::state::bootstrap(&tmp_db.path().to_string_lossy()) + .await + .expect("bootstrap"); + let config = ProxyConfig { + app_state: Arc::new(app_state), + dist_dir: None, + }; + + tokio::spawn(async move { + axum::serve(listener, rsql_proxy::router(config)) + .await + .expect("serve"); + }); + + tokio::time::sleep(std::time::Duration::from_millis(50)).await; + (addr, tmp_db) +} diff --git a/crates/rsql-proxy/tests/dispatch_smoke.rs b/crates/rsql-proxy/tests/dispatch_smoke.rs new file mode 100644 index 0000000..74d0dc3 --- /dev/null +++ b/crates/rsql-proxy/tests/dispatch_smoke.rs @@ -0,0 +1,72 @@ +mod common; + +use futures_util::{SinkExt, StreamExt}; +use serde_json::json; +use tokio_tungstenite::{connect_async, tungstenite::Message}; +use uuid::Uuid; + +#[tokio::test] +async fn workspace_roundtrip_over_ws() { + let (addr, _tmp) = common::spawn_test_server().await; + let url = format!("ws://{addr}/ws"); + let (mut ws, _) = connect_async(url).await.unwrap(); + + let save_id = Uuid::now_v7(); + let save_req = json!({ + "type": "request", + "id": save_id.to_string(), + "cmd": "workspace_save", + "payload": { "name": "ws-test", "tabs": "[]" } + }); + ws.send(Message::Text(save_req.to_string().into())) + .await + .unwrap(); + + let resp = next_text(&mut ws).await; + assert_eq!(resp["type"], "response"); + assert_eq!(resp["id"], save_id.to_string()); + + let load_id = Uuid::now_v7(); + let load_req = json!({ + "type": "request", + "id": load_id.to_string(), + "cmd": "workspace_load_all", + "payload": {} + }); + ws.send(Message::Text(load_req.to_string().into())) + .await + .unwrap(); + + let resp = next_text(&mut ws).await; + assert_eq!(resp["type"], "response"); + let arr = resp["payload"].as_array().unwrap(); + assert!(arr.iter().any(|t| t[0] == "ws-test" && t[1] == "[]")); +} + +async fn next_text(ws: &mut S) -> serde_json::Value +where + S: StreamExt> + Unpin, +{ + loop { + match ws.next().await.unwrap().unwrap() { + Message::Text(t) => return serde_json::from_str(&t).unwrap(), + Message::Ping(_) | Message::Pong(_) => continue, + other => panic!("unexpected: {other:?}"), + } + } +} + +#[tokio::test(flavor = "multi_thread")] +async fn terminal_spawn_returns_error_when_disabled_env_set() { + unsafe { + std::env::set_var("RSQL_DISABLE_TERMINAL", "1"); + } + use rsql_proxy::dispatch::terminal_cmds::is_terminal_disabled; + assert!( + is_terminal_disabled(), + "RSQL_DISABLE_TERMINAL=1 must be honored" + ); + unsafe { + std::env::remove_var("RSQL_DISABLE_TERMINAL"); + } +} diff --git a/crates/rsql-proxy/tests/health.rs b/crates/rsql-proxy/tests/health.rs new file mode 100644 index 0000000..e075655 --- /dev/null +++ b/crates/rsql-proxy/tests/health.rs @@ -0,0 +1,10 @@ +mod common; + +#[tokio::test] +async fn health_returns_ok_with_version() { + let (addr, _tmp) = common::spawn_test_server().await; + let url = format!("http://{addr}/health"); + let resp: serde_json::Value = reqwest::get(&url).await.unwrap().json().await.unwrap(); + assert_eq!(resp["status"], "ok"); + assert!(resp["version"].is_string()); +} diff --git a/crates/rsql-proxy/tests/integration_pg.rs b/crates/rsql-proxy/tests/integration_pg.rs new file mode 100644 index 0000000..edc7a59 --- /dev/null +++ b/crates/rsql-proxy/tests/integration_pg.rs @@ -0,0 +1,68 @@ +//! Run manually with: +//! RSQL_TEST_PG_KEY="user,pw,db,host,5432,false" cargo test -p rsql-proxy --test integration_pg -- --ignored + +mod common; + +use futures_util::{SinkExt, StreamExt}; +use serde_json::json; +use tokio_tungstenite::{connect_async, tungstenite::Message}; +use uuid::Uuid; + +fn pg_key() -> Option> { + std::env::var("RSQL_TEST_PG_KEY") + .ok() + .map(|s| s.split(',').map(|p| p.to_string()).collect()) +} + +#[tokio::test] +#[ignore] +async fn pgsql_run_query_binary_frame() { + let Some(key) = pg_key() else { + eprintln!("skipping: RSQL_TEST_PG_KEY not set"); + return; + }; + let (addr, _tmp) = common::spawn_test_server().await; + let (mut ws, _) = connect_async(format!("ws://{addr}/ws")).await.unwrap(); + + let id = Uuid::now_v7(); + ws.send(Message::Text( + json!({ + "type": "request", + "id": id.to_string(), + "cmd": "pgsql_connector", + "payload": { "project_id": "p", "key": key, "ssh": null } + }) + .to_string() + .into(), + )) + .await + .unwrap(); + let _ = ws.next().await; + + let id = Uuid::now_v7(); + ws.send(Message::Text( + json!({ + "type": "request", + "id": id.to_string(), + "cmd": "pgsql_run_query_packed", + "payload": { "project_id": "p", "sql": "SELECT 1 AS x", "timeout_ms": null } + }) + .to_string() + .into(), + )) + .await + .unwrap(); + + loop { + match ws.next().await.unwrap().unwrap() { + Message::Binary(b) => { + assert!(b.len() > 16); + let id_bytes: [u8; 16] = b[..16].try_into().unwrap(); + assert_eq!(Uuid::from_bytes(id_bytes), id); + return; + } + Message::Text(_) | Message::Ping(_) | Message::Pong(_) => continue, + other => panic!("unexpected: {other:?}"), + } + } +} diff --git a/crates/rsql-proxy/tests/protocol.rs b/crates/rsql-proxy/tests/protocol.rs new file mode 100644 index 0000000..7daeca9 --- /dev/null +++ b/crates/rsql-proxy/tests/protocol.rs @@ -0,0 +1,24 @@ +use rsql_proxy::protocol::{Inbound, Outbound, parse_binary, parse_text}; +use uuid::Uuid; + +#[test] +fn binary_frame_includes_id_prefix() { + let id = Uuid::now_v7(); + let frame = Outbound::binary(id, b"hello".to_vec()); + let msg = frame.into_ws_message().unwrap(); + let bytes = match msg { + axum::extract::ws::Message::Binary(b) => b.to_vec(), + _ => panic!("expected binary"), + }; + let (parsed_id, payload) = parse_binary(&bytes).unwrap(); + assert_eq!(parsed_id, id); + assert_eq!(payload, b"hello"); +} + +#[test] +fn cancel_frame_parses() { + let id = Uuid::now_v7(); + let raw = format!(r#"{{"type":"cancel","id":"{id}"}}"#); + let parsed = parse_text(&raw).unwrap(); + assert!(matches!(parsed, Inbound::Cancel(c) if c.id == id)); +} diff --git a/crates/rsql-proxy/tests/session_lifecycle.rs b/crates/rsql-proxy/tests/session_lifecycle.rs new file mode 100644 index 0000000..099069c --- /dev/null +++ b/crates/rsql-proxy/tests/session_lifecycle.rs @@ -0,0 +1,33 @@ +mod common; + +use futures_util::{SinkExt, StreamExt}; +use serde_json::json; +use tokio_tungstenite::{connect_async, tungstenite::Message}; +use uuid::Uuid; + +#[tokio::test] +async fn closing_ws_does_not_panic() { + let (addr, _tmp) = common::spawn_test_server().await; + let url = format!("ws://{addr}/ws"); + let (mut ws, _) = connect_async(url).await.unwrap(); + + let id = Uuid::now_v7(); + let req = json!({ + "type": "request", + "id": id.to_string(), + "cmd": "workspace_save", + "payload": { "name": "ephemeral", "tabs": "[]" } + }); + ws.send(Message::Text(req.to_string().into())) + .await + .unwrap(); + let _ = ws.next().await; + + ws.send(Message::Close(None)).await.ok(); + drop(ws); + + tokio::time::sleep(std::time::Duration::from_millis(100)).await; + let url = format!("ws://{addr}/ws"); + let (_ws2, response) = connect_async(url).await.unwrap(); + assert_eq!(response.status().as_u16(), 101); +} diff --git a/crates/rsql-proxy/tests/ws_echo.rs b/crates/rsql-proxy/tests/ws_echo.rs new file mode 100644 index 0000000..0909106 --- /dev/null +++ b/crates/rsql-proxy/tests/ws_echo.rs @@ -0,0 +1,11 @@ +mod common; + +use tokio_tungstenite::connect_async; + +#[tokio::test] +async fn ws_upgrade_succeeds() { + let (addr, _tmp) = common::spawn_test_server().await; + let url = format!("ws://{addr}/ws"); + let (_ws, response) = connect_async(url).await.expect("connect"); + assert_eq!(response.status().as_u16(), 101); +} diff --git a/src-tauri/.gitignore b/crates/rsql-tauri/.gitignore similarity index 100% rename from src-tauri/.gitignore rename to crates/rsql-tauri/.gitignore diff --git a/crates/rsql-tauri/Cargo.toml b/crates/rsql-tauri/Cargo.toml new file mode 100644 index 0000000..70193a5 --- /dev/null +++ b/crates/rsql-tauri/Cargo.toml @@ -0,0 +1,42 @@ +[package] +name = "rsql" +version.workspace = true +edition.workspace = true +authors.workspace = true +description.workspace = true + +[lib] +name = "rsql_lib" +crate-type = ["staticlib", "cdylib", "rlib"] + +[build-dependencies] +tauri-build = { version = "2", features = [] } + +[dependencies] +tauri = { version = "2", features = [] } +tauri-plugin-opener = "2" +tauri-plugin-shell = "2.3.1" +tauri-plugin-fs = "2.4.2" +tauri-plugin-dialog = "2.6.0" +tauri-plugin-process = "2.3.1" +tauri-plugin-updater = "2.10.0" + +serde.workspace = true +serde_json.workspace = true +sonic-rs.workspace = true +tokio.workspace = true +tokio-postgres.workspace = true +deadpool-postgres.workspace = true +postgres-native-tls.workspace = true +native-tls.workspace = true +tracing.workspace = true +tracing-subscriber.workspace = true +libsql.workspace = true +thiserror.workspace = true +portable-pty.workspace = true +rayon.workspace = true +sysinfo.workspace = true +csv.workspace = true +futures-util.workspace = true +russh.workspace = true +rsql-core = { path = "../rsql-core" } diff --git a/src-tauri/build.rs b/crates/rsql-tauri/build.rs similarity index 100% rename from src-tauri/build.rs rename to crates/rsql-tauri/build.rs diff --git a/src-tauri/capabilities/default.json b/crates/rsql-tauri/capabilities/default.json similarity index 100% rename from src-tauri/capabilities/default.json rename to crates/rsql-tauri/capabilities/default.json diff --git a/src-tauri/icons/128x128.png b/crates/rsql-tauri/icons/128x128.png similarity index 100% rename from src-tauri/icons/128x128.png rename to crates/rsql-tauri/icons/128x128.png diff --git a/src-tauri/icons/128x128@2x.png b/crates/rsql-tauri/icons/128x128@2x.png similarity index 100% rename from src-tauri/icons/128x128@2x.png rename to crates/rsql-tauri/icons/128x128@2x.png diff --git a/src-tauri/icons/32x32.png b/crates/rsql-tauri/icons/32x32.png similarity index 100% rename from src-tauri/icons/32x32.png rename to crates/rsql-tauri/icons/32x32.png diff --git a/src-tauri/icons/Square107x107Logo.png b/crates/rsql-tauri/icons/Square107x107Logo.png similarity index 100% rename from src-tauri/icons/Square107x107Logo.png rename to crates/rsql-tauri/icons/Square107x107Logo.png diff --git a/src-tauri/icons/Square142x142Logo.png b/crates/rsql-tauri/icons/Square142x142Logo.png similarity index 100% rename from src-tauri/icons/Square142x142Logo.png rename to crates/rsql-tauri/icons/Square142x142Logo.png diff --git a/src-tauri/icons/Square150x150Logo.png b/crates/rsql-tauri/icons/Square150x150Logo.png similarity index 100% rename from src-tauri/icons/Square150x150Logo.png rename to crates/rsql-tauri/icons/Square150x150Logo.png diff --git a/src-tauri/icons/Square284x284Logo.png b/crates/rsql-tauri/icons/Square284x284Logo.png similarity index 100% rename from src-tauri/icons/Square284x284Logo.png rename to crates/rsql-tauri/icons/Square284x284Logo.png diff --git a/src-tauri/icons/Square30x30Logo.png b/crates/rsql-tauri/icons/Square30x30Logo.png similarity index 100% rename from src-tauri/icons/Square30x30Logo.png rename to crates/rsql-tauri/icons/Square30x30Logo.png diff --git a/src-tauri/icons/Square310x310Logo.png b/crates/rsql-tauri/icons/Square310x310Logo.png similarity index 100% rename from src-tauri/icons/Square310x310Logo.png rename to crates/rsql-tauri/icons/Square310x310Logo.png diff --git a/src-tauri/icons/Square44x44Logo.png b/crates/rsql-tauri/icons/Square44x44Logo.png similarity index 100% rename from src-tauri/icons/Square44x44Logo.png rename to crates/rsql-tauri/icons/Square44x44Logo.png diff --git a/src-tauri/icons/Square71x71Logo.png b/crates/rsql-tauri/icons/Square71x71Logo.png similarity index 100% rename from src-tauri/icons/Square71x71Logo.png rename to crates/rsql-tauri/icons/Square71x71Logo.png diff --git a/src-tauri/icons/Square89x89Logo.png b/crates/rsql-tauri/icons/Square89x89Logo.png similarity index 100% rename from src-tauri/icons/Square89x89Logo.png rename to crates/rsql-tauri/icons/Square89x89Logo.png diff --git a/src-tauri/icons/StoreLogo.png b/crates/rsql-tauri/icons/StoreLogo.png similarity index 100% rename from src-tauri/icons/StoreLogo.png rename to crates/rsql-tauri/icons/StoreLogo.png diff --git a/src-tauri/icons/icon.icns b/crates/rsql-tauri/icons/icon.icns similarity index 100% rename from src-tauri/icons/icon.icns rename to crates/rsql-tauri/icons/icon.icns diff --git a/src-tauri/icons/icon.ico b/crates/rsql-tauri/icons/icon.ico similarity index 100% rename from src-tauri/icons/icon.ico rename to crates/rsql-tauri/icons/icon.ico diff --git a/src-tauri/icons/icon.png b/crates/rsql-tauri/icons/icon.png similarity index 100% rename from src-tauri/icons/icon.png rename to crates/rsql-tauri/icons/icon.png diff --git a/crates/rsql-tauri/src/app_setup.rs b/crates/rsql-tauri/src/app_setup.rs new file mode 100644 index 0000000..38482a3 --- /dev/null +++ b/crates/rsql-tauri/src/app_setup.rs @@ -0,0 +1,99 @@ +use tauri::Manager; +use tauri::menu::{AboutMetadata, MenuBuilder, SubmenuBuilder}; + +use crate::LOCAL_DB_NAME; + +pub fn setup_app(app: &mut tauri::App) -> Result<(), Box> { + #[cfg(desktop)] + if let Some(pubkey) = option_env!("TAURI_UPDATER_PUBLIC_KEY") { + app.handle() + .plugin(tauri_plugin_updater::Builder::new().pubkey(pubkey).build())?; + } else { + tracing::info!( + "Updater disabled because TAURI_UPDATER_PUBLIC_KEY was not set at build time" + ); + } + + let app_handle = app.handle().clone(); + + tauri::async_runtime::block_on(async move { + let db_path = if cfg!(debug_assertions) { + LOCAL_DB_NAME.to_string() + } else { + let app_dir = app_handle + .path() + .app_data_dir() + .expect("Failed to resolve app data directory"); + std::fs::create_dir_all(&app_dir).ok(); + app_dir.join(LOCAL_DB_NAME).to_string_lossy().to_string() + }; + + let state = rsql_core::state::bootstrap(&db_path) + .await + .expect("AppState bootstrap failed"); + app_handle.manage(state); + + let terminal_state = rsql_core::terminal::TerminalRegistry::new(); + app_handle.manage(terminal_state); + }); + + let handle = app.handle(); + + let app_menu = SubmenuBuilder::new(handle, "RSQL") + .about(Some(AboutMetadata { + name: Some("RSQL".into()), + version: Some(env!("CARGO_PKG_VERSION").into()), + copyright: Some("\u{00a9} 2025 rust-dd".into()), + comments: Some( + "Modern SQL client for PostgreSQL.\nBuilt with Tauri, React, and Rust.".into(), + ), + website: Some("https://github.com/rust-dd/rust-sql".into()), + website_label: Some("GitHub".into()), + ..Default::default() + })) + .separator() + .services() + .separator() + .hide() + .hide_others() + .show_all() + .separator() + .quit() + .build()?; + + let edit_menu = SubmenuBuilder::new(handle, "Edit") + .undo() + .redo() + .separator() + .cut() + .copy() + .paste() + .select_all() + .build()?; + + let view_menu = SubmenuBuilder::new(handle, "View").fullscreen().build()?; + + let window_menu = SubmenuBuilder::new(handle, "Window") + .minimize() + .maximize() + .separator() + .close_window() + .build()?; + + let menu = MenuBuilder::new(handle) + .items(&[&app_menu, &edit_menu, &view_menu, &window_menu]) + .build()?; + + handle.set_menu(menu)?; + + #[cfg(debug_assertions)] + { + let window = app + .get_webview_window("main") + .expect("main window not found"); + window.open_devtools(); + window.close_devtools(); + } + + Ok(()) +} diff --git a/crates/rsql-tauri/src/commands.rs b/crates/rsql-tauri/src/commands.rs new file mode 100644 index 0000000..6decfa7 --- /dev/null +++ b/crates/rsql-tauri/src/commands.rs @@ -0,0 +1,75 @@ +use rsql_core::AppState; +use rsql_core::common::BTreeVecStore; +use rsql_core::error::AppError; +use std::collections::BTreeMap; +use tauri::{AppHandle, Manager, State}; + +#[tauri::command(rename_all = "snake_case")] +pub async fn project_db_select(app_state: State<'_, AppState>) -> Result { + rsql_core::state::project::project_db_select(&app_state.local_db).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn project_db_insert( + project_id: &str, + project_details: Vec, + app_state: State<'_, AppState>, +) -> Result<(), AppError> { + rsql_core::state::project::project_db_insert(&app_state.local_db, project_id, project_details) + .await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn project_db_delete( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result<(), AppError> { + rsql_core::state::project::project_db_delete(&app_state.local_db, project_id).await?; + app_state.clients.lock().await.remove(project_id); + app_state.meta_clients.lock().await.remove(project_id); + app_state.cancel_tokens.lock().await.remove(project_id); + app_state.client_ssl.lock().await.remove(project_id); + Ok(()) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn query_db_select( + app_state: State<'_, AppState>, +) -> Result, AppError> { + rsql_core::state::query::query_db_select(&app_state.local_db).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn query_db_insert(query_id: &str, sql: &str, app: AppHandle) -> Result<(), AppError> { + let app_state = app.state::(); + rsql_core::state::query::query_db_insert(&app_state.local_db, query_id, sql).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn query_db_delete( + query_id: &str, + app_state: State<'_, AppState>, +) -> Result<(), AppError> { + rsql_core::state::query::query_db_delete(&app_state.local_db, query_id).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn workspace_save( + name: &str, + tabs: &str, + app_state: State<'_, AppState>, +) -> Result<(), AppError> { + rsql_core::state::workspace::workspace_save(&app_state.local_db, name, tabs).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn workspace_load_all( + app_state: State<'_, AppState>, +) -> Result, AppError> { + rsql_core::state::workspace::workspace_load_all(&app_state.local_db).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn workspace_delete(name: &str, app_state: State<'_, AppState>) -> Result<(), AppError> { + rsql_core::state::workspace::workspace_delete(&app_state.local_db, name).await +} diff --git a/crates/rsql-tauri/src/drivers/mod.rs b/crates/rsql-tauri/src/drivers/mod.rs new file mode 100644 index 0000000..c23eeb7 --- /dev/null +++ b/crates/rsql-tauri/src/drivers/mod.rs @@ -0,0 +1 @@ +pub mod pgsql; diff --git a/crates/rsql-tauri/src/drivers/pgsql/commands/admin_commands.rs b/crates/rsql-tauri/src/drivers/pgsql/commands/admin_commands.rs new file mode 100644 index 0000000..d00123d --- /dev/null +++ b/crates/rsql-tauri/src/drivers/pgsql/commands/admin_commands.rs @@ -0,0 +1,125 @@ +use rsql_core::AppState; +use rsql_core::drivers::pgsql::commands::admin; +use rsql_core::drivers::pgsql::roles_schema_objects::{DbGrant, PgRole, SchemaObject, TableGrant}; +use rsql_core::error::AppError; + +use tauri::State; +use tauri::ipc::Response; + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_csv_preview( + file_path: &str, +) -> Result<(Vec, Vec>), AppError> { + admin::pgsql_csv_preview(file_path).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_csv_import( + project_id: &str, + file_path: &str, + schema: &str, + table: &str, + column_mapping: Vec<(usize, String)>, + app_state: State<'_, AppState>, +) -> Result { + admin::pgsql_csv_import( + app_state.inner(), + project_id, + file_path, + schema, + table, + column_mapping, + ) + .await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_roles( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + admin::pgsql_load_roles(app_state.inner(), project_id).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_table_grants( + project_id: &str, + role_name: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + admin::pgsql_load_table_grants(app_state.inner(), project_id, role_name).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_database_grants( + project_id: &str, + role_name: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + admin::pgsql_load_database_grants(app_state.inner(), project_id, role_name).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_extract_schema_objects( + project_id: &str, + schema: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + admin::pgsql_extract_schema_objects(app_state.inner(), project_id, schema).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_extensions( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result { + let json = admin::pgsql_load_extensions(app_state.inner(), project_id).await?; + Ok(Response::new(json)) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_available_extensions( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result { + let json = admin::pgsql_load_available_extensions(app_state.inner(), project_id).await?; + Ok(Response::new(json)) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_enum_types( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result { + let json = admin::pgsql_load_enum_types(app_state.inner(), project_id).await?; + Ok(Response::new(json)) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_table_action( + project_id: &str, + action: &str, + schema: &str, + table: &str, + object_type: &str, + app_state: State<'_, AppState>, +) -> Result { + admin::pgsql_table_action( + app_state.inner(), + project_id, + action, + schema, + table, + object_type, + ) + .await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_pg_settings( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result { + let json = admin::pgsql_load_pg_settings(app_state.inner(), project_id).await?; + Ok(Response::new(json)) +} diff --git a/crates/rsql-tauri/src/drivers/pgsql/commands/metadata_commands.rs b/crates/rsql-tauri/src/drivers/pgsql/commands/metadata_commands.rs new file mode 100644 index 0000000..bdb59a2 --- /dev/null +++ b/crates/rsql-tauri/src/drivers/pgsql/commands/metadata_commands.rs @@ -0,0 +1,151 @@ +use rsql_core::AppState; +use rsql_core::common::pgsql::{PgsqlLoadColumns, PgsqlLoadSchemas, PgsqlLoadTables}; +use rsql_core::drivers::pgsql::commands::metadata; +use rsql_core::drivers::pgsql::{ + ColumnDetail, ConstraintDetail, FunctionInfo, IndexDetail, PolicyDetail, RuleDetail, + TriggerDetail, +}; +use rsql_core::error::AppError; + +use tauri::{AppHandle, Manager, State}; + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_databases( + project_id: &str, + app: AppHandle, +) -> Result, AppError> { + let app_state = app.state::(); + metadata::pgsql_load_databases(app_state.inner(), project_id).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_tablespaces( + project_id: &str, + app: AppHandle, +) -> Result, AppError> { + let app_state = app.state::(); + metadata::pgsql_load_tablespaces(app_state.inner(), project_id).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_schemas( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result { + metadata::pgsql_load_schemas(app_state.inner(), project_id).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_tables( + project_id: &str, + schema: &str, + app_state: State<'_, AppState>, +) -> Result { + metadata::pgsql_load_tables(app_state.inner(), project_id, schema).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_columns( + project_id: &str, + schema: &str, + table: &str, + app_state: State<'_, AppState>, +) -> Result { + metadata::pgsql_load_columns(app_state.inner(), project_id, schema, table).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_column_details( + project_id: &str, + schema: &str, + table: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + metadata::pgsql_load_column_details(app_state.inner(), project_id, schema, table).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_indexes( + project_id: &str, + schema: &str, + table: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + metadata::pgsql_load_indexes(app_state.inner(), project_id, schema, table).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_constraints( + project_id: &str, + schema: &str, + table: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + metadata::pgsql_load_constraints(app_state.inner(), project_id, schema, table).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_triggers( + project_id: &str, + schema: &str, + table: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + metadata::pgsql_load_triggers(app_state.inner(), project_id, schema, table).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_rules( + project_id: &str, + schema: &str, + table: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + metadata::pgsql_load_rules(app_state.inner(), project_id, schema, table).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_policies( + project_id: &str, + schema: &str, + table: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + metadata::pgsql_load_policies(app_state.inner(), project_id, schema, table).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_views( + project_id: &str, + schema: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + metadata::pgsql_load_views(app_state.inner(), project_id, schema).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_materialized_views( + project_id: &str, + schema: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + metadata::pgsql_load_materialized_views(app_state.inner(), project_id, schema).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_functions( + project_id: &str, + schema: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + metadata::pgsql_load_functions(app_state.inner(), project_id, schema).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_trigger_functions( + project_id: &str, + schema: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + metadata::pgsql_load_trigger_functions(app_state.inner(), project_id, schema).await +} diff --git a/src-tauri/src/drivers/pgsql/commands/mod.rs b/crates/rsql-tauri/src/drivers/pgsql/commands/mod.rs similarity index 75% rename from src-tauri/src/drivers/pgsql/commands/mod.rs rename to crates/rsql-tauri/src/drivers/pgsql/commands/mod.rs index a417f43..86abb13 100644 --- a/src-tauri/src/drivers/pgsql/commands/mod.rs +++ b/crates/rsql-tauri/src/drivers/pgsql/commands/mod.rs @@ -1,13 +1,9 @@ -pub(crate) const CELL_SEP: char = '\x1F'; -pub(crate) const SNAPSHOT_PAGE_WRITE_RETRIES: usize = 3; - pub mod admin_commands; pub mod metadata_commands; pub mod object_info_commands; pub mod pool_connection; pub mod pubsub_commands; pub mod query_commands; -pub mod snapshot_persistence; pub mod statistics_commands; pub use admin_commands::*; diff --git a/crates/rsql-tauri/src/drivers/pgsql/commands/object_info_commands.rs b/crates/rsql-tauri/src/drivers/pgsql/commands/object_info_commands.rs new file mode 100644 index 0000000..3ed4aad --- /dev/null +++ b/crates/rsql-tauri/src/drivers/pgsql/commands/object_info_commands.rs @@ -0,0 +1,47 @@ +use rsql_core::AppState; +use rsql_core::drivers::pgsql::ObjectStats; +use rsql_core::drivers::pgsql::commands::object_info; +use rsql_core::error::AppError; + +use tauri::State; + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_view_info( + project_id: &str, + schema: &str, + view: &str, + app_state: State<'_, AppState>, +) -> Result { + object_info::pgsql_view_info(app_state.inner(), project_id, schema, view).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_matview_info( + project_id: &str, + schema: &str, + matview: &str, + app_state: State<'_, AppState>, +) -> Result { + object_info::pgsql_matview_info(app_state.inner(), project_id, schema, matview).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_function_info( + project_id: &str, + schema: &str, + func_name: &str, + app_state: State<'_, AppState>, +) -> Result { + object_info::pgsql_function_info(app_state.inner(), project_id, schema, func_name).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_generate_ddl( + project_id: &str, + schema: &str, + name: &str, + object_type: &str, + app_state: State<'_, AppState>, +) -> Result { + object_info::pgsql_generate_ddl(app_state.inner(), project_id, schema, name, object_type).await +} diff --git a/crates/rsql-tauri/src/drivers/pgsql/commands/pool_connection.rs b/crates/rsql-tauri/src/drivers/pgsql/commands/pool_connection.rs new file mode 100644 index 0000000..969cf1f --- /dev/null +++ b/crates/rsql-tauri/src/drivers/pgsql/commands/pool_connection.rs @@ -0,0 +1,25 @@ +use rsql_core::AppState; +use rsql_core::drivers::pgsql::commands::connection; +use rsql_core::error::{AppError, ProjectConnectionStatus}; + +use tauri::{AppHandle, Manager}; + +pub(crate) use rsql_core::drivers::pgsql::commands::pool_helpers::{ + acquire_client, set_cancel_token, +}; + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_test_connection(key: [&str; 6]) -> Result { + connection::pgsql_test_connection(key).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_connector( + project_id: &str, + key: Option<[&str; 6]>, + ssh: Option>, + app: AppHandle, +) -> Result { + let app_state = app.state::(); + connection::pgsql_connector(app_state.inner(), project_id, key, ssh).await +} diff --git a/crates/rsql-tauri/src/drivers/pgsql/commands/pubsub_commands.rs b/crates/rsql-tauri/src/drivers/pgsql/commands/pubsub_commands.rs new file mode 100644 index 0000000..79ec11a --- /dev/null +++ b/crates/rsql-tauri/src/drivers/pgsql/commands/pubsub_commands.rs @@ -0,0 +1,44 @@ +use rsql_core::AppState; +use rsql_core::drivers::pgsql::commands::pubsub; +use rsql_core::error::AppError; +use tauri::{AppHandle, Manager, State}; + +use crate::event_sink::TauriEventSink; + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_listen_start( + project_id: &str, + channel: &str, + app: AppHandle, +) -> Result { + let app_state = app.state::(); + let sink = TauriEventSink::new(app.clone()); + pubsub::listen_start(app_state.inner(), project_id, channel, sink).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_listen_stop( + project_id: &str, + channel: &str, + app_state: State<'_, AppState>, +) -> Result { + pubsub::listen_stop(app_state.inner(), project_id, channel).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_notify_send( + project_id: &str, + channel: &str, + payload: &str, + app_state: State<'_, AppState>, +) -> Result { + pubsub::pgsql_notify_send(app_state.inner(), project_id, channel, payload).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_discover_channels( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + pubsub::pgsql_discover_channels(app_state.inner(), project_id).await +} diff --git a/crates/rsql-tauri/src/drivers/pgsql/commands/query_commands.rs b/crates/rsql-tauri/src/drivers/pgsql/commands/query_commands.rs new file mode 100644 index 0000000..0a6c76d --- /dev/null +++ b/crates/rsql-tauri/src/drivers/pgsql/commands/query_commands.rs @@ -0,0 +1,97 @@ +use rsql_core::AppState; +use rsql_core::drivers::pgsql::commands::query; +use rsql_core::error::AppError; + +use tauri::ipc::Response; +use tauri::{AppHandle, Manager, State}; + +use rsql_core::drivers::pgsql::streaming::execute_query_streamed; + +use super::pool_connection::{acquire_client, set_cancel_token}; + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_run_query( + project_id: &str, + sql: &str, + app_state: State<'_, AppState>, +) -> Result { + let json = query::pgsql_run_query(app_state.inner(), project_id, sql).await?; + Ok(Response::new(json)) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_cancel_query( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result { + query::pgsql_cancel_query(app_state.inner(), project_id).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_run_query_packed( + project_id: &str, + sql: &str, + timeout_ms: Option, + app_state: State<'_, AppState>, +) -> Result { + let json = + query::pgsql_run_query_packed(app_state.inner(), project_id, sql, timeout_ms).await?; + Ok(Response::new(json)) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_run_query_streamed( + project_id: &str, + sql: &str, + stream_id: &str, + app: AppHandle, +) -> Result<(), AppError> { + let app_state = app.state::(); + let client = acquire_client(&app_state.clients, project_id).await?; + set_cancel_token(&app_state, project_id, client.cancel_token()).await?; + + let sink = crate::event_sink::TauriEventSink::new(app.clone()); + execute_query_streamed(&client, sql, stream_id, &sink).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_execute_virtual( + project_id: &str, + sql: &str, + query_id: &str, + page_size: usize, + timeout_ms: Option, + app_state: State<'_, AppState>, +) -> Result { + let json = query::pgsql_execute_virtual( + app_state.inner(), + project_id, + sql, + query_id, + page_size, + timeout_ms, + ) + .await?; + Ok(Response::new(json)) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_fetch_page( + query_id: &str, + col_count: usize, + offset: usize, + limit: usize, + app_state: State<'_, AppState>, +) -> Result { + let json = + query::pgsql_fetch_page(app_state.inner(), query_id, col_count, offset, limit).await?; + Ok(Response::new(json)) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_close_virtual( + query_id: &str, + app_state: State<'_, AppState>, +) -> Result<(), AppError> { + query::pgsql_close_virtual(app_state.inner(), query_id).await +} diff --git a/crates/rsql-tauri/src/drivers/pgsql/commands/statistics_commands.rs b/crates/rsql-tauri/src/drivers/pgsql/commands/statistics_commands.rs new file mode 100644 index 0000000..10cc3f7 --- /dev/null +++ b/crates/rsql-tauri/src/drivers/pgsql/commands/statistics_commands.rs @@ -0,0 +1,90 @@ +use rsql_core::AppState; +use rsql_core::drivers::pgsql::commands::statistics; +use rsql_core::drivers::pgsql::{DbStat, FKDetail, ForeignKeyInfo, ObjectStats}; +use rsql_core::error::AppError; + +use tauri::State; +use tauri::ipc::Response; + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_activity( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result { + let json = statistics::pgsql_load_activity(app_state.inner(), project_id).await?; + Ok(Response::new(json)) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_database_stats( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + statistics::pgsql_load_database_stats(app_state.inner(), project_id).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_table_stats( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result { + let json = statistics::pgsql_load_table_stats(app_state.inner(), project_id).await?; + Ok(Response::new(json)) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_foreign_keys( + project_id: &str, + schema: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + statistics::pgsql_load_foreign_keys(app_state.inner(), project_id, schema).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_table_statistics( + project_id: &str, + schema: &str, + table: &str, + app_state: State<'_, AppState>, +) -> Result { + statistics::pgsql_table_statistics(app_state.inner(), project_id, schema, table).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_fk_details( + project_id: &str, + schema: &str, + table: &str, + direction: &str, + app_state: State<'_, AppState>, +) -> Result, AppError> { + statistics::pgsql_fk_details(app_state.inner(), project_id, schema, table, direction).await +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_locks( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result { + let json = statistics::pgsql_load_locks(app_state.inner(), project_id).await?; + Ok(Response::new(json)) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_index_usage( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result { + let json = statistics::pgsql_load_index_usage(app_state.inner(), project_id).await?; + Ok(Response::new(json)) +} + +#[tauri::command(rename_all = "snake_case")] +pub async fn pgsql_load_table_bloat( + project_id: &str, + app_state: State<'_, AppState>, +) -> Result { + let json = statistics::pgsql_load_table_bloat(app_state.inner(), project_id).await?; + Ok(Response::new(json)) +} diff --git a/crates/rsql-tauri/src/drivers/pgsql/mod.rs b/crates/rsql-tauri/src/drivers/pgsql/mod.rs new file mode 100644 index 0000000..6cd26d6 --- /dev/null +++ b/crates/rsql-tauri/src/drivers/pgsql/mod.rs @@ -0,0 +1,3 @@ +pub mod commands; + +pub use commands::*; diff --git a/crates/rsql-tauri/src/event_sink.rs b/crates/rsql-tauri/src/event_sink.rs new file mode 100644 index 0000000..a5b2b55 --- /dev/null +++ b/crates/rsql-tauri/src/event_sink.rs @@ -0,0 +1,21 @@ +use rsql_core::events::EventSink; +use std::sync::Arc; +use tauri::{AppHandle, Emitter}; + +pub struct TauriEventSink { + app: AppHandle, +} + +impl TauriEventSink { + pub fn new(app: AppHandle) -> Arc { + Arc::new(Self { app }) + } +} + +impl EventSink for TauriEventSink { + fn emit(&self, event: &str, payload: &T) { + if let Err(e) = self.app.emit(event, payload) { + tracing::warn!(event, error = %e, "TauriEventSink emit failed"); + } + } +} diff --git a/src-tauri/src/lib.rs b/crates/rsql-tauri/src/lib.rs similarity index 100% rename from src-tauri/src/lib.rs rename to crates/rsql-tauri/src/lib.rs diff --git a/src-tauri/src/main.rs b/crates/rsql-tauri/src/main.rs similarity index 76% rename from src-tauri/src/main.rs rename to crates/rsql-tauri/src/main.rs index 0e6e1a3..1f5b1e5 100644 --- a/src-tauri/src/main.rs +++ b/crates/rsql-tauri/src/main.rs @@ -2,33 +2,16 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] mod app_setup; -mod common; -mod dbs; +mod commands; mod drivers; -mod ssh; +mod event_sink; mod terminal; mod utils; const LOCAL_DB_NAME: &str = "rsql.db"; -use deadpool_postgres::Pool; -use std::{collections::BTreeMap, sync::Arc}; -use tokio::sync::Mutex; -use tokio_postgres::CancelToken; use tracing::Level; -pub struct AppState { - pub clients: Arc>>>, - pub meta_clients: Arc>>>, - pub cancel_tokens: Arc>>, - pub client_ssl: Arc>>, - pub local_db: libsql::Database, - pub resource_monitor: Arc>, - pub virtual_cache: Arc>, - pub notify_handles: Arc>>>, - pub ssh_tunnels: Arc>>, -} - fn main() { tracing_subscriber::fmt() .with_file(true) @@ -44,15 +27,15 @@ fn main() { .plugin(tauri_plugin_process::init()) .setup(app_setup::setup_app) .invoke_handler(tauri::generate_handler![ - dbs::project::project_db_select, - dbs::project::project_db_insert, - dbs::project::project_db_delete, - dbs::query::query_db_select, - dbs::query::query_db_insert, - dbs::query::query_db_delete, - dbs::workspace::workspace_save, - dbs::workspace::workspace_load_all, - dbs::workspace::workspace_delete, + commands::project_db_select, + commands::project_db_insert, + commands::project_db_delete, + commands::query_db_select, + commands::query_db_insert, + commands::query_db_delete, + commands::workspace_save, + commands::workspace_load_all, + commands::workspace_delete, drivers::pgsql::pgsql_test_connection, drivers::pgsql::pgsql_connector, drivers::pgsql::pgsql_load_databases, diff --git a/crates/rsql-tauri/src/terminal.rs b/crates/rsql-tauri/src/terminal.rs new file mode 100644 index 0000000..3bfaba8 --- /dev/null +++ b/crates/rsql-tauri/src/terminal.rs @@ -0,0 +1,51 @@ +use rsql_core::terminal::TerminalRegistry; +use tauri::{AppHandle, State}; + +use crate::event_sink::TauriEventSink; + +#[tauri::command] +pub async fn terminal_spawn( + app: AppHandle, + terminal_state: State<'_, TerminalRegistry>, + id: String, + cols: u16, + rows: u16, +) -> Result<(), String> { + let sink = TauriEventSink::new(app); + rsql_core::terminal::spawn(terminal_state.inner(), sink, id, cols, rows) + .await + .map_err(|e| e.to_string()) +} + +#[tauri::command] +pub async fn terminal_write( + terminal_state: State<'_, TerminalRegistry>, + id: String, + data: String, +) -> Result<(), String> { + terminal_state + .write(&id, data.as_bytes()) + .await + .map_err(|e| e.to_string()) +} + +#[tauri::command] +pub async fn terminal_resize( + terminal_state: State<'_, TerminalRegistry>, + id: String, + cols: u16, + rows: u16, +) -> Result<(), String> { + terminal_state + .resize(&id, cols, rows) + .await + .map_err(|e| e.to_string()) +} + +#[tauri::command] +pub async fn terminal_kill( + terminal_state: State<'_, TerminalRegistry>, + id: String, +) -> Result<(), String> { + terminal_state.kill(&id).await.map_err(|e| e.to_string()) +} diff --git a/crates/rsql-tauri/src/utils.rs b/crates/rsql-tauri/src/utils.rs new file mode 100644 index 0000000..54b0950 --- /dev/null +++ b/crates/rsql-tauri/src/utils.rs @@ -0,0 +1,31 @@ +use rsql_core::AppState; +use rsql_core::utils::{SystemResourceUsage, pool_stats}; +use tauri::State; + +#[tauri::command(rename_all = "snake_case")] +pub async fn system_resource_usage( + app_state: State<'_, AppState>, +) -> Result { + let mut usage = { + let mut monitor = app_state.resource_monitor.lock().await; + monitor.sample() + }; + + let (q_open, q_available, q_max, q_waiting) = pool_stats(&app_state.clients).await; + let (m_open, m_available, m_max, m_waiting) = pool_stats(&app_state.meta_clients).await; + + let total_open = q_open.saturating_add(m_open); + let total_available = q_available.saturating_add(m_available); + + usage.db_connections_open = total_open; + usage.db_connections_max = q_max.saturating_add(m_max); + usage.db_connections_waiting = q_waiting.saturating_add(m_waiting); + usage.db_connections_in_use = total_open.saturating_sub(total_available); + + Ok(usage) +} + +#[tauri::command(rename_all = "snake_case")] +pub fn compute_diff(pinned_packed: String, current_packed: String) -> (String, String, usize) { + rsql_core::utils::diff::compute_diff(&pinned_packed, ¤t_packed) +} diff --git a/src-tauri/tauri.conf.json b/crates/rsql-tauri/tauri.conf.json similarity index 96% rename from src-tauri/tauri.conf.json rename to crates/rsql-tauri/tauri.conf.json index e5350aa..9547de9 100644 --- a/src-tauri/tauri.conf.json +++ b/crates/rsql-tauri/tauri.conf.json @@ -7,7 +7,7 @@ "beforeDevCommand": "yarn dev", "devUrl": "http://localhost:1420", "beforeBuildCommand": "yarn build", - "frontendDist": "../dist" + "frontendDist": "../../dist" }, "app": { "windows": [ diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 0000000..2d00d15 --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,132 @@ +# RSQL Architecture + +This document describes the runtime shape of RSQL after WASM-support phases P1–P6. For the original design rationale, see [`superpowers/specs/2026-05-16-wasm-support-design.md`](./superpowers/specs/2026-05-16-wasm-support-design.md). + +## Build targets + +RSQL ships in two build targets that share one React frontend and one Rust core: + +| Target | Backend | Bundle | IPC | +|------------------|----------------------------------|-----------------------|-------------------------------------| +| Desktop (Tauri) | `crates/rsql-tauri` (bin `rsql`) | Vite, target=`tauri` | Tauri `invoke` + `listen` | +| Web (Docker) | `crates/rsql-proxy` | Vite, target=`web` | WebSocket + JSON / binary frames | + +Both targets call into the same `crates/rsql-core` library. No code is duplicated between the two binaries. + +## Cargo workspace + +``` +crates/ + rsql-core/ # pure-Rust business logic (no Tauri, no axum) + rsql-tauri/ # desktop binary (package name: rsql) + rsql-proxy/ # web binary (Axum + WS bridge) + rsql-bench/ # Criterion benchmarks (dev-only) +``` + +- `rsql-core` is the **only** crate allowed to grow new feature code. New PG commands, terminal logic, SSH tunnels — all land here as `pub async fn`s with no transport knowledge. +- `rsql-tauri` and `rsql-proxy` are **thin transports**. They translate Tauri/WS messages into rsql-core function calls and back. Per `scripts/check-rsql-core-purity.sh`, `rsql-core` may not import Tauri or axum. + +## Frontend Transport layer + +`src/lib/transport/` abstracts the two IPC mechanisms behind a single `Transport` interface: + +```ts +interface Transport { + invoke(command: string, args?: Record): Promise; + listen(event: string, handler: (payload: T) => void): Promise; +} +``` + +Two implementations: +- `TauriTransport` (`tauri-transport.ts`) wraps `@tauri-apps/api/core::invoke` and `/event::listen`. +- `WebSocketTransport` (`websocket-transport.ts`) speaks the proxy's WS protocol (see below). It exposes the same `Transport` surface and manages reconnect, pending-request maps, and the JSON ⇄ binary frame split. + +A `runtime.ts` helper detects the build target via `isTauriRuntime()` (Tauri global) + `__RSQL_BUILD_TARGET__` define-injected by Vite, and `index.ts` picks the right Transport at module load. + +Every callsite in the frontend uses `transport.invoke(...)` / `transport.listen(...)`. There are zero direct `@tauri-apps/api` imports outside `src/lib/platform/` (which holds the platform adapter layer — dialogs, updater). + +## WebSocket protocol (rsql-proxy) + +Endpoint: `GET /ws` on the same port as the static SPA (`127.0.0.1:8080` by default). + +### Inbound (client → proxy) + +JSON-tagged with `type` discriminator (lowercase): + +```jsonc +{ "type": "request", "id": "", "cmd": "", "payload": { ... } } +{ "type": "cancel", "id": "" } +``` + +### Outbound (proxy → client) + +JSON-tagged text frames: +```jsonc +{ "type": "response", "id": "", "payload": ..., "end": true } +{ "type": "error", "id": "", "message": "...", "code": 0 } +{ "type": "event", "event": "terminal-data", "payload": ... } +``` + +Binary frames carry packed query results to keep the perf-critical path zero-copy: +``` +[16 bytes UUID][\x1F-cell-sep \x1E-row-sep packed UTF-8 payload] +``` + +The frontend's `parseBinaryFrame` strips the UUID and dispatches the bytes to the original `invoke` promise's `Vec` resolver, which the existing `unpackRows()` helper in `src/lib/pgsql.ts` consumes — identical handling to the Tauri `tauri::ipc::Response` zero-copy path. + +## Dispatch flow + +``` +Browser ──invoke("pgsql_run_query", args)─→ WebSocketTransport.dispatch + │ assigns request UUID + ▼ + Axum /ws ──Inbound::Request─→ ws.rs main loop + │ spawn handler + ▼ + dispatch/::handle + │ + ▼ + rsql_core::drivers::pgsql::commands::query::pgsql_run_query + │ + ▼ + Outbound::binary(uuid, packed) + │ + ▼ + Axum /ws ──Message::Binary───── ws.rs writer task + │ + ▼ +WebSocketTransport.handleMessage ──resolves Promise>─→ pgsql.ts unpackRows +``` + +Streaming responses (`pgsql_run_query_streamed`) use the same channel: the dispatched handler holds a `ProxyEventSink` and emits multiple `Outbound::Text({type:"event"})` frames before the final `Outbound::Text({type:"response", end:true})`. + +The desktop path is the same after the first hop: Tauri `invoke` ↔ `rsql-tauri`'s command wrappers ↔ `rsql-core`. Both transports converge in `rsql-core`, by design. + +## Event sink abstraction + +`rsql_core::events::EventSink` is a generic trait (non-object-safe, sync) that lets PG streaming + terminal + LISTEN/NOTIFY emit events without knowing whether they're flowing to a Tauri `AppHandle` or a WS `mpsc::UnboundedSender`. Implementations: +- `TauriEventSink` in `crates/rsql-tauri/src/event_sink.rs` +- `ProxyEventSink` in `crates/rsql-proxy/src/event_sink.rs` + +The pull-up to `rsql-core` of `terminal.rs` and `pgsql/streaming.rs` (P3) eliminated the need for either binary to hold transport-specific code. + +## State + +All user state — saved connections, query history, workspaces, SSH configs — lives in libsql. The schema is bootstrapped in `rsql_core::state::bootstrap(db_path)` (5 tables + 6 ALTER TABLEs for SSH columns). Both binaries call this on startup. + +The desktop build stores the DB in the Tauri `app_data_dir`; the proxy stores it at `RSQL_STATE_PATH` (default `/data/rsql.db` in the Docker image, persisted via `VOLUME /data`). + +## Performance hot paths + +See [`../BENCHMARKS.md`](../BENCHMARKS.md). The three Criterion-covered paths are: +- `pack_rows_vec` (rsql-core) +- `Outbound::into_ws_message` / `parse_text` (rsql-proxy) +- `process_simple_messages` followed by `pack_rows_vec` (the full pack pipeline) + +The 10% scroll-FPS gate (web vs desktop on 1M rows) is the spec exit criterion for Phase 7. + +## Security boundaries + +- The proxy binds to `127.0.0.1:8080` by default (`RSQL_BIND` override). The Docker image keeps this default; users who expose `0.0.0.0` accept the risk explicitly. +- `RSQL_DISABLE_TERMINAL=1` removes the PTY commands from the dispatch table (returns `Err` for every `terminal_*` request). +- The web build's `Transport.invoke` is identical to the desktop's; there is no privileged path that's available only to one side. diff --git a/package.json b/package.json index d5d9f0a..7376fe1 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,14 @@ "type": "module", "scripts": { "dev": "vite", + "dev:web": "VITE_BUILD_TARGET=web vite", + "dev:proxy": "cargo run -p rsql-proxy -- --addr 127.0.0.1:8080 --dist-dir dist --state-path /tmp/rsql-dev.db", "build": "tsc && vite build", "preview": "vite preview", - "tauri": "tauri", + "tauri": "cd crates/rsql-tauri && tauri", + "proxy": "cargo run -p rsql-proxy", + "proxy:build": "yarn build && cargo build -p rsql-proxy --release", + "proxy:release": "yarn build && cargo run -p rsql-proxy --release", "format": "biome format --write .", "lint": "biome lint .", "check": "biome check --write .", diff --git a/scripts/check-rsql-core-purity.sh b/scripts/check-rsql-core-purity.sh new file mode 100755 index 0000000..d4a1f1e --- /dev/null +++ b/scripts/check-rsql-core-purity.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Fails if rsql-core gains a forbidden dependency (tauri/axum/tokio-tungstenite). +# The rsql-core crate must remain a pure-Rust library so it can be reused by +# both the desktop Tauri bin and the upcoming rsql-proxy WebSocket bin. + +set -euo pipefail + +cd "$(dirname "$0")/.." + +forbidden_patterns='^[│ ]*(tauri[- ]|axum[- ]|tokio-tungstenite[- ])' + +if cargo tree -p rsql-core --depth 99 2>/dev/null | grep -E "$forbidden_patterns" >/dev/null; then + echo "FAIL: rsql-core has a forbidden dependency." + cargo tree -p rsql-core --depth 99 | grep -E "$forbidden_patterns" || true + exit 1 +fi + +echo "OK: rsql-core is pure-Rust (no tauri/axum/tokio-tungstenite deps)." diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock deleted file mode 100644 index 3fc52d9..0000000 --- a/src-tauri/Cargo.lock +++ /dev/null @@ -1,8571 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "aead" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" -dependencies = [ - "crypto-common 0.1.6", - "generic-array 0.14.7", -] - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -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.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "getrandom 0.3.3", - "once_cell", - "version_check", - "zerocopy 0.8.27", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[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.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[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 = "anyhow" -version = "1.0.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" - -[[package]] -name = "arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" -dependencies = [ - "derive_arbitrary", -] - -[[package]] -name = "argon2" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" -dependencies = [ - "base64ct", - "blake2", - "cpufeatures", - "password-hash", -] - -[[package]] -name = "async-broadcast" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" -dependencies = [ - "event-listener", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-channel" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "pin-project-lite", - "slab", -] - -[[package]] -name = "async-io" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19634d6336019ef220f09fd31168ce5c184b295cbf80345437cc36094ef223ca" -dependencies = [ - "async-lock", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix 1.1.2", - "slab", - "windows-sys 0.60.2", -] - -[[package]] -name = "async-lock" -version = "3.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-process" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65daa13722ad51e6ab1a1b9c01299142bc75135b337923cfa10e79bbbd669f00" -dependencies = [ - "async-channel", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "rustix 1.1.2", -] - -[[package]] -name = "async-recursion" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "async-signal" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f567af260ef69e1d52c2b560ce0ea230763e6fbb9214a85d768760a920e3e3c1" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix 1.1.2", - "signal-hook-registry", - "slab", - "windows-sys 0.60.2", -] - -[[package]] -name = "async-stream" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" -dependencies = [ - "async-stream-impl", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-stream-impl" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "atk" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" -dependencies = [ - "atk-sys", - "glib", - "libc", -] - -[[package]] -name = "atk-sys" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" -dependencies = [ - "glib-sys", - "gobject-sys", - "libc", - "system-deps", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "aws-lc-rs" -version = "1.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94bffc006df10ac2a68c83692d734a465f8ee6c5b384d8545a636f81d858f4bf" -dependencies = [ - "aws-lc-sys", - "untrusted 0.7.1", - "zeroize", -] - -[[package]] -name = "aws-lc-sys" -version = "0.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4321e568ed89bb5a7d291a7f37997c2c0df89809d7b6d12062c81ddb54aa782e" -dependencies = [ - "cc", - "cmake", - "dunce", - "fs_extra", -] - -[[package]] -name = "axum" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" -dependencies = [ - "async-trait", - "axum-core", - "bitflags 1.3.2", - "bytes", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.32", - "itoa", - "matchit", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "sync_wrapper 0.1.2", - "tower 0.4.13", - "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.12", - "http-body 0.4.6", - "mime", - "rustversion", - "tower-layer", - "tower-service", -] - -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base16ct" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "base64ct" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" - -[[package]] -name = "bcrypt-pbkdf" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6aeac2e1fe888769f34f05ac343bbef98b14d1ffb292ab69d4608b3abc86f2a2" -dependencies = [ - "blowfish", - "pbkdf2", - "sha2 0.10.9", -] - -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bindgen" -version = "0.66.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7" -dependencies = [ - "bitflags 2.9.4", - "cexpr", - "clang-sys", - "lazy_static", - "lazycell", - "log", - "peeking_take_while", - "prettyplease", - "proc-macro2", - "quote", - "regex", - "rustc-hash", - "shlex", - "syn 2.0.106", - "which", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" -dependencies = [ - "serde", -] - -[[package]] -name = "blake2" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" -dependencies = [ - "digest 0.10.7", -] - -[[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 = "block-buffer" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array 0.14.7", -] - -[[package]] -name = "block2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" -dependencies = [ - "objc2 0.5.2", -] - -[[package]] -name = "block2" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2" -dependencies = [ - "objc2 0.6.2", -] - -[[package]] -name = "blocking" -version = "1.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e83f8d02be6967315521be875afa792a316e28d57b5a2d401897e2a7921b7f21" -dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[package]] -name = "blowfish" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" -dependencies = [ - "byteorder", - "cipher", -] - -[[package]] -name = "brotli" -version = "8.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - -[[package]] -name = "bumpalo" -version = "3.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" - -[[package]] -name = "bytemuck" -version = "1.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" -dependencies = [ - "serde", -] - -[[package]] -name = "cairo-rs" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" -dependencies = [ - "bitflags 2.9.4", - "cairo-sys-rs", - "glib", - "libc", - "once_cell", - "thiserror 1.0.69", -] - -[[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.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0b03af37dad7a14518b7691d81acb0f8222604ad3d1b02f6b4bed5188c0cd5" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-platform" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" -dependencies = [ - "camino", - "cargo-platform", - "semver", - "serde", - "serde_json", - "thiserror 2.0.16", -] - -[[package]] -name = "cargo_toml" -version = "0.22.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" -dependencies = [ - "serde", - "toml 0.9.5", -] - -[[package]] -name = "cbc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" -dependencies = [ - "cipher", -] - -[[package]] -name = "cc" -version = "1.2.56" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" -dependencies = [ - "find-msvc-tools", - "jobserver", - "libc", - "shlex", -] - -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - -[[package]] -name = "cexpr" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" -dependencies = [ - "nom", -] - -[[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.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" -dependencies = [ - "smallvec", - "target-lexicon", -] - -[[package]] -name = "cfg-if" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" - -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - -[[package]] -name = "chrono" -version = "0.4.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" -dependencies = [ - "iana-time-zone", - "js-sys", - "num-traits", - "serde", - "wasm-bindgen", - "windows-link 0.2.0", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common 0.1.6", - "inout", -] - -[[package]] -name = "clang-sys" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" -dependencies = [ - "glob", - "libc", - "libloading 0.8.9", -] - -[[package]] -name = "cmake" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" -dependencies = [ - "cc", -] - -[[package]] -name = "cmov" -version = "0.5.0-pre.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5417da527aa9bf6a1e10a781231effd1edd3ee82f27d5f8529ac9b279babce96" - -[[package]] -name = "combine" -version = "4.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" -dependencies = [ - "bytes", - "memchr", -] - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "const-oid" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" -dependencies = [ - "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" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "core-graphics" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" -dependencies = [ - "bitflags 2.9.4", - "core-foundation 0.10.1", - "core-graphics-types", - "foreign-types 0.5.0", - "libc", -] - -[[package]] -name = "core-graphics" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" -dependencies = [ - "bitflags 2.9.4", - "core-foundation 0.10.1", - "core-graphics-types", - "foreign-types 0.5.0", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" -dependencies = [ - "bitflags 2.9.4", - "core-foundation 0.10.1", - "libc", -] - -[[package]] -name = "core-models" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0940496e5c83c54f3b753d5317daec82e8edac71c33aaa1f666d76f518de2444" -dependencies = [ - "hax-lib", - "pastey", - "rand 0.9.2", -] - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -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-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[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-bigint" -version = "0.7.0-rc.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37387ceb32048ff590f2cbd24d8b05fffe63c3f69a5cfa089d4f722ca4385a19" -dependencies = [ - "ctutils", - "num-traits", - "rand_core 0.10.0-rc-3", - "serdect", - "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", - "typenum", -] - -[[package]] -name = "crypto-common" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" -dependencies = [ - "hybrid-array", -] - -[[package]] -name = "crypto-primes" -version = "0.7.0-pre.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79c98a281f9441200b24e3151407a629bfbe720399186e50516da939195e482" -dependencies = [ - "crypto-bigint 0.7.0-rc.18", - "libm", - "rand_core 0.10.0-rc-3", -] - -[[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", - "matches", - "phf 0.10.1", - "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.106", -] - -[[package]] -name = "csv" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52cd9d68cf7efc6ddfaaee42e7288d3a99d613d4b50f76ce9827ae0c6e14f938" -dependencies = [ - "csv-core", - "itoa", - "ryu", - "serde_core", -] - -[[package]] -name = "csv-core" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "704a3c26996a80471189265814dbc2c257598b96b8a7feae2d31ace646bb9782" -dependencies = [ - "memchr", -] - -[[package]] -name = "ctor" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" -dependencies = [ - "quote", - "syn 2.0.106", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "ctutils" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758e5ed90be3c8abff7f9a6f37ab7f6d8c59c2210d448b81f3f508134aec84e4" -dependencies = [ - "cmov", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "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.106", -] - -[[package]] -name = "darling" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.106", -] - -[[package]] -name = "darling_macro" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "data-encoding" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" - -[[package]] -name = "deadpool" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0be2b1d1d6ec8d846f05e137292d0b89133caf95ef33695424c09568bdd39b1b" -dependencies = [ - "deadpool-runtime", - "lazy_static", - "num_cpus", - "tokio", -] - -[[package]] -name = "deadpool-postgres" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d697d376cbfa018c23eb4caab1fd1883dd9c906a8c034e8d9a3cb06a7e0bef9" -dependencies = [ - "async-trait", - "deadpool", - "getrandom 0.2.16", - "tokio", - "tokio-postgres", - "tracing", -] - -[[package]] -name = "deadpool-runtime" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" -dependencies = [ - "tokio", -] - -[[package]] -name = "delegate" -version = "0.13.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780eb241654bf097afb00fc5f054a09b687dad862e485fdcf8399bb056565370" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid 0.9.6", - "pem-rfc7468 0.7.0", - "zeroize", -] - -[[package]] -name = "der" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" -dependencies = [ - "const-oid 0.10.2", - "pem-rfc7468 1.0.0", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" -dependencies = [ - "powerfmt", - "serde", -] - -[[package]] -name = "derive_arbitrary" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "derive_more" -version = "0.99.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 2.0.106", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid 0.9.6", - "crypto-common 0.1.6", - "subtle", -] - -[[package]] -name = "digest" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "285743a676ccb6b3e116bc14cc69319b957867930ae9c4822f8e0f54509d7243" -dependencies = [ - "block-buffer 0.12.0", - "const-oid 0.10.2", - "crypto-common 0.2.1", -] - -[[package]] -name = "dirs" -version = "6.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" -dependencies = [ - "dirs-sys", -] - -[[package]] -name = "dirs-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" -dependencies = [ - "libc", - "option-ext", - "redox_users", - "windows-sys 0.61.0", -] - -[[package]] -name = "dispatch2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" -dependencies = [ - "bitflags 2.9.4", - "block2 0.6.1", - "libc", - "objc2 0.6.2", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "dlopen2" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b54f373ccf864bf587a89e880fb7610f8d73f3045f13580948ccbcaff26febff" -dependencies = [ - "dlopen2_derive", - "libc", - "once_cell", - "winapi", -] - -[[package]] -name = "dlopen2_derive" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "788160fb30de9cdd857af31c6a2675904b16ece8fc2737b2c7127ba368c9d0f4" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - -[[package]] -name = "dpi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" -dependencies = [ - "serde", -] - -[[package]] -name = "dtoa" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6add3b8cff394282be81f3fc1a0605db594ed69890078ca6e2cab1c408bcf04" - -[[package]] -name = "dtoa-short" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" -dependencies = [ - "dtoa", -] - -[[package]] -name = "dunce" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" - -[[package]] -name = "dyn-clone" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der 0.7.10", - "digest 0.10.7", - "elliptic-curve", - "rfc6979", - "signature 2.2.0", - "spki 0.7.3", -] - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8 0.10.2", - "signature 2.2.0", -] - -[[package]] -name = "ed25519-dalek" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" -dependencies = [ - "curve25519-dalek", - "ed25519", - "rand_core 0.6.4", - "serde", - "sha2 0.10.9", - "subtle", - "zeroize", -] - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.5", - "digest 0.10.7", - "ff", - "generic-array 0.14.7", - "group", - "hkdf", - "pem-rfc7468 0.7.0", - "pkcs8 0.10.2", - "rand_core 0.6.4", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "embed-resource" -version = "3.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6d81016d6c977deefb2ef8d8290da019e27cc26167e102185da528e6c0ab38" -dependencies = [ - "cc", - "memchr", - "rustc_version", - "toml 0.9.5", - "vswhom", - "winreg 0.55.0", -] - -[[package]] -name = "embed_plist" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" - -[[package]] -name = "encoding_rs" -version = "0.8.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "endi" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" - -[[package]] -name = "enum_dispatch" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" -dependencies = [ - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "enumflags2" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" -dependencies = [ - "enumflags2_derive", - "serde", -] - -[[package]] -name = "enumflags2_derive" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "equivalent" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" - -[[package]] -name = "erased-serde" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7" -dependencies = [ - "serde", - "typeid", -] - -[[package]] -name = "errno" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" -dependencies = [ - "libc", - "windows-sys 0.61.0", -] - -[[package]] -name = "event-listener" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fallible-iterator" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - -[[package]] -name = "fastrand" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" - -[[package]] -name = "faststr" -version = "0.2.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca7d44d22004409a61c393afb3369c8f7bb74abcae49fe249ee01dcc3002113" -dependencies = [ - "bytes", - "rkyv", - "serde", - "simdutf8", -] - -[[package]] -name = "fdeflate" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" -dependencies = [ - "simd-adler32", -] - -[[package]] -name = "ff" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[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 = "filedescriptor" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e40758ed24c9b2eeb76c35fb0aebc66c626084edd827e07e1552279814c6682d" -dependencies = [ - "libc", - "thiserror 1.0.69", - "winapi", -] - -[[package]] -name = "filetime" -version = "0.2.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" -dependencies = [ - "cfg-if", - "libc", - "libredox", -] - -[[package]] -name = "find-msvc-tools" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "flate2" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" -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 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.106", -] - -[[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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "fs_extra" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" - -[[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.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-lite" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" -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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" -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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" -dependencies = [ - "gdk-sys", - "glib-sys", - "gobject-sys", - "libc", - "pkg-config", - "system-deps", -] - -[[package]] -name = "gdkx11" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" -dependencies = [ - "gdk", - "gdkx11-sys", - "gio", - "glib", - "libc", - "x11", -] - -[[package]] -name = "gdkx11-sys" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" -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", - "zeroize", -] - -[[package]] -name = "generic-array" -version = "1.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaf57c49a95fd1fe24b90b3033bee6dc7e8f1288d51494cb44e627c295e38542" -dependencies = [ - "generic-array 0.14.7", - "rustversion", - "typenum", -] - -[[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.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "libc", - "r-efi", - "wasi 0.14.5+wasi-0.2.4", -] - -[[package]] -name = "ghash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" -dependencies = [ - "opaque-debug", - "polyval", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[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 1.0.69", -] - -[[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 = "glib" -version = "0.18.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" -dependencies = [ - "bitflags 2.9.4", - "futures-channel", - "futures-core", - "futures-executor", - "futures-task", - "futures-util", - "gio-sys", - "glib-macros", - "glib-sys", - "gobject-sys", - "libc", - "memchr", - "once_cell", - "smallvec", - "thiserror 1.0.69", -] - -[[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.0", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" - -[[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 = "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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" -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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" -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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d" -dependencies = [ - "proc-macro-crate 1.3.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "h2" -version = "0.3.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0beca50380b1fc32983fc1cb4587bfa4bb9e78fc259aad4a0032d2080309222d" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.11.1", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] - -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" - -[[package]] -name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" - -[[package]] -name = "hashlink" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" -dependencies = [ - "hashbrown 0.14.5", -] - -[[package]] -name = "hax-lib" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d9ba66d1739c68e0219b2b2238b5c4145f491ebf181b9c6ab561a19352ae86" -dependencies = [ - "hax-lib-macros", - "num-bigint", - "num-traits", -] - -[[package]] -name = "hax-lib-macros" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ba777a231a58d1bce1d68313fa6b6afcc7966adef23d60f45b8a2b9b688bf1" -dependencies = [ - "hax-lib-macros-types", - "proc-macro-error2", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "hax-lib-macros-types" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "867e19177d7425140b417cd27c2e05320e727ee682e98368f88b7194e80ad515" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "serde_json", - "uuid", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hermit-abi" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hex-literal" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" - -[[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 0.10.7", -] - -[[package]] -name = "home" -version = "0.5.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" -dependencies = [ - "windows-sys 0.61.0", -] - -[[package]] -name = "html5ever" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c" -dependencies = [ - "log", - "mac", - "markup5ever", - "match_token", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[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.12", - "pin-project-lite", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http 1.3.1", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http 1.3.1", - "http-body 1.0.1", - "pin-project-lite", -] - -[[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.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - -[[package]] -name = "hybrid-array" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b229d73f5803b562cc26e4da0396c8610a4ee209f4fac8fa4f8d709166dc45" -dependencies = [ - "typenum", -] - -[[package]] -name = "hyper" -version = "0.14.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.5.10", - "tokio", - "tower-service", - "tracing", - "want", -] - -[[package]] -name = "hyper" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "http 1.3.1", - "http-body 1.0.1", - "httparse", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "399c78f9338483cb7e630c8474b07268983c6bd5acee012e4211f9f7bb21b070" -dependencies = [ - "futures-util", - "http 0.2.12", - "hyper 0.14.32", - "log", - "rustls 0.22.4", - "rustls-native-certs 0.7.3", - "rustls-pki-types", - "tokio", - "tokio-rustls 0.25.0", - "webpki-roots 0.26.11", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http 1.3.1", - "hyper 1.7.0", - "hyper-util", - "rustls 0.23.37", - "rustls-pki-types", - "tokio", - "tokio-rustls 0.26.4", - "tower-service", -] - -[[package]] -name = "hyper-timeout" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" -dependencies = [ - "hyper 0.14.32", - "pin-project-lite", - "tokio", - "tokio-io-timeout", -] - -[[package]] -name = "hyper-util" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "hyper 1.7.0", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2 0.6.0", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core 0.61.2", -] - -[[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 = "ico" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" -dependencies = [ - "byteorder", - "png", -] - -[[package]] -name = "icu_collections" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" - -[[package]] -name = "icu_provider" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" -dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[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.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206a8042aec68fa4a62e8d3f7aa4ceb508177d9324faf261e1959e495b7a1921" -dependencies = [ - "equivalent", - "hashbrown 0.15.5", - "serde", -] - -[[package]] -name = "infer" -version = "0.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" -dependencies = [ - "cfb", -] - -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "block-padding", - "generic-array 0.14.7", -] - -[[package]] -name = "internal-russh-forked-ssh-key" -version = "0.6.16+upstream-0.6.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe44f2bbd99fcb302e246e2d6bcf51aeda346d02a365f80296a07a8c711b6da6" -dependencies = [ - "argon2", - "bcrypt-pbkdf", - "digest 0.11.1", - "ecdsa", - "ed25519-dalek", - "hex", - "hmac", - "num-bigint-dig", - "p256", - "p384", - "p521", - "rand_core 0.6.4", - "rsa", - "sec1", - "sha1 0.10.6", - "sha1 0.11.0-rc.5", - "sha2 0.10.9", - "signature 2.2.0", - "signature 3.0.0-rc.6", - "ssh-cipher", - "ssh-encoding", - "subtle", - "zeroize", -] - -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "libc", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" -dependencies = [ - "memchr", - "serde", -] - -[[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-wsl" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "173609498df190136aa7dea1a91db051746d339e18476eed5ca40521f02d7aa5" -dependencies = [ - "is-docker", - "once_cell", -] - -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[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 1.0.69", - "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.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" -dependencies = [ - "getrandom 0.3.3", - "libc", -] - -[[package]] -name = "js-sys" -version = "0.3.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "json-patch" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" -dependencies = [ - "jsonptr", - "serde", - "serde_json", - "thiserror 1.0.69", -] - -[[package]] -name = "jsonptr" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "keyboard-types" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" -dependencies = [ - "bitflags 2.9.4", - "serde", - "unicode-segmentation", -] - -[[package]] -name = "kuchikiki" -version = "0.8.8-speedreader" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" -dependencies = [ - "cssparser", - "html5ever", - "indexmap 2.11.1", - "selectors", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] - -[[package]] -name = "lazycell" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" - -[[package]] -name = "libappindicator" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" -dependencies = [ - "glib", - "gtk", - "gtk-sys", - "libappindicator-sys", - "log", -] - -[[package]] -name = "libappindicator-sys" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" -dependencies = [ - "gtk-sys", - "libloading 0.7.4", - "once_cell", -] - -[[package]] -name = "libc" -version = "0.2.175" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" - -[[package]] -name = "libcrux-intrinsics" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc9ee7ef66569dd7516454fe26de4e401c0c62073929803486b96744594b9632" -dependencies = [ - "core-models", - "hax-lib", -] - -[[package]] -name = "libcrux-ml-kem" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6a88086bf11bd2ec90926c749c4a427f2e59841437dbdede8cde8a96334ab" -dependencies = [ - "hax-lib", - "libcrux-intrinsics", - "libcrux-platform", - "libcrux-secrets", - "libcrux-sha3", - "libcrux-traits", - "rand 0.9.2", - "tls_codec", -] - -[[package]] -name = "libcrux-platform" -version = "0.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db82d058aa76ea315a3b2092f69dfbd67ddb0e462038a206e1dcd73f058c0778" -dependencies = [ - "libc", -] - -[[package]] -name = "libcrux-secrets" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4dbbf6bc9f2bc0f20dc3bea3e5c99adff3bdccf6d2a40488963da69e2ec307" -dependencies = [ - "hax-lib", -] - -[[package]] -name = "libcrux-sha3" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2400bec764d1c75b8a496d5747cffe32f1fb864a12577f0aca2f55a92021c962" -dependencies = [ - "hax-lib", - "libcrux-intrinsics", - "libcrux-platform", - "libcrux-traits", -] - -[[package]] -name = "libcrux-traits" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9adfd58e79d860f6b9e40e35127bfae9e5bd3ade33201d1347459011a2add034" -dependencies = [ - "libcrux-secrets", - "rand 0.9.2", -] - -[[package]] -name = "libloading" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" -dependencies = [ - "cfg-if", - "winapi", -] - -[[package]] -name = "libloading" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" -dependencies = [ - "cfg-if", - "windows-link 0.2.0", -] - -[[package]] -name = "libm" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" - -[[package]] -name = "libredox" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" -dependencies = [ - "bitflags 2.9.4", - "libc", - "redox_syscall", -] - -[[package]] -name = "libsql" -version = "0.9.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2329faffc510cc3c6b4f00169a39177cc7099d3ed7647fc92f7cf26e53a8d976" -dependencies = [ - "anyhow", - "async-stream", - "async-trait", - "base64 0.21.7", - "bincode", - "bitflags 2.9.4", - "bytes", - "chrono", - "crc32fast", - "fallible-iterator 0.3.0", - "futures", - "http 0.2.12", - "hyper 0.14.32", - "hyper-rustls 0.25.0", - "libsql-hrana", - "libsql-sqlite3-parser", - "libsql-sys", - "libsql_replication", - "parking_lot", - "serde", - "serde_json", - "thiserror 1.0.69", - "tokio", - "tokio-stream", - "tokio-util", - "tonic", - "tonic-web", - "tower 0.4.13", - "tower-http 0.4.4", - "tracing", - "uuid", - "zerocopy 0.7.35", -] - -[[package]] -name = "libsql-ffi" -version = "0.9.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cd1c1662822495393327856774f6803be25d85bfdcd5b9d4af35458f5daaf75" -dependencies = [ - "bindgen", - "cc", - "cmake", - "glob", -] - -[[package]] -name = "libsql-hrana" -version = "0.9.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "646d0aa75e412769018422f0da798f72e93bd51964f0b2ddad4317aa779ae444" -dependencies = [ - "base64 0.21.7", - "bytes", - "prost", - "serde", -] - -[[package]] -name = "libsql-rusqlite" -version = "0.9.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a4ce3a78c6e3c2b23b02ab6272df8340e1c53380497979d456882254f348d5f" -dependencies = [ - "bitflags 2.9.4", - "fallible-iterator 0.2.0", - "fallible-streaming-iterator", - "hashlink", - "libsql-ffi", - "smallvec", -] - -[[package]] -name = "libsql-sqlite3-parser" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15a90128c708356af8f7d767c9ac2946692c9112b4f74f07b99a01a60680e413" -dependencies = [ - "bitflags 2.9.4", - "cc", - "fallible-iterator 0.3.0", - "indexmap 2.11.1", - "log", - "memchr", - "phf 0.11.3", - "phf_codegen 0.11.3", - "phf_shared 0.11.3", - "uncased", -] - -[[package]] -name = "libsql-sys" -version = "0.9.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a3c326fcfc36fe7578238d5ee6b58c529f8c76372acd61ec50267529cdaff95" -dependencies = [ - "bytes", - "libsql-ffi", - "libsql-rusqlite", - "once_cell", - "tracing", - "zerocopy 0.7.35", -] - -[[package]] -name = "libsql_replication" -version = "0.9.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9a2e469ac8400659bd31f81a745908bcc5cb6b40be2f2ff8de90b15bec5501" -dependencies = [ - "aes", - "async-stream", - "async-trait", - "bytes", - "cbc", - "libsql-rusqlite", - "libsql-sys", - "parking_lot", - "prost", - "serde", - "thiserror 1.0.69", - "tokio", - "tokio-stream", - "tokio-util", - "tonic", - "tracing", - "uuid", - "zerocopy 0.7.35", -] - -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - -[[package]] -name = "linux-raw-sys" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" - -[[package]] -name = "litemap" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" - -[[package]] -name = "lock_api" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" - -[[package]] -name = "mac" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" - -[[package]] -name = "markup5ever" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18" -dependencies = [ - "log", - "phf 0.11.3", - "phf_codegen 0.11.3", - "string_cache", - "string_cache_codegen", - "tendril", -] - -[[package]] -name = "match_token" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - -[[package]] -name = "md-5" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" -dependencies = [ - "cfg-if", - "digest 0.10.7", -] - -[[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.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" - -[[package]] -name = "memoffset" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - -[[package]] -name = "minisign-verify" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22f9645cb765ea72b8111f36c522475d2daa0d22c957a9826437e97534bc4e9e" - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", - "simd-adler32", -] - -[[package]] -name = "mio" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" -dependencies = [ - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", -] - -[[package]] -name = "muda" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a" -dependencies = [ - "crossbeam-channel", - "dpi", - "gtk", - "keyboard-types", - "objc2 0.6.2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "once_cell", - "png", - "serde", - "thiserror 2.0.16", - "windows-sys 0.60.2", -] - -[[package]] -name = "munge" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c" -dependencies = [ - "munge_macro", -] - -[[package]] -name = "munge_macro" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "native-tls" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe 0.1.6", - "openssl-sys", - "schannel", - "security-framework 2.11.1", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "ndk" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" -dependencies = [ - "bitflags 2.9.4", - "jni-sys", - "log", - "ndk-sys", - "num_enum", - "raw-window-handle", - "thiserror 1.0.69", -] - -[[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.6.0+11769913" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" -dependencies = [ - "jni-sys", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - -[[package]] -name = "nix" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "cfg_aliases 0.1.1", - "libc", -] - -[[package]] -name = "nix" -version = "0.29.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "cfg_aliases 0.2.1", - "libc", -] - -[[package]] -name = "nix" -version = "0.30.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" -dependencies = [ - "bitflags 2.9.4", - "cfg-if", - "cfg_aliases 0.2.1", - "libc", - "memoffset", -] - -[[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 = "ntapi" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3b335231dfd352ffb0f8017f3b6027a4917f7df785ea2143d8af2adc66980ae" -dependencies = [ - "winapi", -] - -[[package]] -name = "nu-ansi-term" -version = "0.50.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a28e057d01f97e61255210fcff094d74ed0466038633e95017f5beb68e4399" -dependencies = [ - "windows-sys 0.52.0", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "num-bigint-dig" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" -dependencies = [ - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.8.5", - "serde", - "smallvec", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "num_cpus" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" -dependencies = [ - "hermit-abi", - "libc", -] - -[[package]] -name = "num_enum" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" -dependencies = [ - "num_enum_derive", - "rustversion", -] - -[[package]] -name = "num_enum_derive" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" -dependencies = [ - "proc-macro-crate 3.3.0", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "objc-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" - -[[package]] -name = "objc2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" -dependencies = [ - "objc-sys", - "objc2-encode", -] - -[[package]] -name = "objc2" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561f357ba7f3a2a61563a186a163d0a3a5247e1089524a3981d49adb775078bc" -dependencies = [ - "objc2-encode", - "objc2-exception-helper", -] - -[[package]] -name = "objc2-app-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" -dependencies = [ - "bitflags 2.9.4", - "block2 0.6.1", - "objc2 0.6.2", - "objc2-core-foundation", - "objc2-foundation 0.3.1", -] - -[[package]] -name = "objc2-core-foundation" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" -dependencies = [ - "bitflags 2.9.4", - "dispatch2", - "objc2 0.6.2", -] - -[[package]] -name = "objc2-core-graphics" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" -dependencies = [ - "bitflags 2.9.4", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-encode" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" - -[[package]] -name = "objc2-exception-helper" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" -dependencies = [ - "cc", -] - -[[package]] -name = "objc2-foundation" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" -dependencies = [ - "bitflags 2.9.4", - "block2 0.5.1", - "libc", - "objc2 0.5.2", -] - -[[package]] -name = "objc2-foundation" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" -dependencies = [ - "bitflags 2.9.4", - "block2 0.6.1", - "libc", - "objc2 0.6.2", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-io-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71c1c64d6120e51cd86033f67176b1cb66780c2efe34dec55176f77befd93c0a" -dependencies = [ - "libc", - "objc2-core-foundation", -] - -[[package]] -name = "objc2-metal" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" -dependencies = [ - "bitflags 2.9.4", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", -] - -[[package]] -name = "objc2-osa-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26bb88504b5a050dbba515d2414607bf5e57dd56b107bc5f0351197a3e7bdc5d" -dependencies = [ - "bitflags 2.9.4", - "objc2 0.6.2", - "objc2-app-kit", - "objc2-foundation 0.3.1", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" -dependencies = [ - "bitflags 2.9.4", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", -] - -[[package]] -name = "objc2-ui-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25b1312ad7bc8a0e92adae17aa10f90aae1fb618832f9b993b022b591027daed" -dependencies = [ - "bitflags 2.9.4", - "objc2 0.6.2", - "objc2-core-foundation", - "objc2-foundation 0.3.1", -] - -[[package]] -name = "objc2-web-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91672909de8b1ce1c2252e95bbee8c1649c9ad9d14b9248b3d7b4c47903c47ad" -dependencies = [ - "bitflags 2.9.4", - "block2 0.6.1", - "objc2 0.6.2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "open" -version = "5.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95" -dependencies = [ - "dunce", - "is-wsl", - "libc", - "pathdiff", -] - -[[package]] -name = "openssl" -version = "0.10.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" -dependencies = [ - "bitflags 2.9.4", - "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.106", -] - -[[package]] -name = "openssl-probe" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" - -[[package]] -name = "openssl-probe" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" - -[[package]] -name = "openssl-sys" -version = "0.9.110" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" -dependencies = [ - "cc", - "libc", - "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-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.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db335f4760b14ead6290116f2427bf33a14d4f0617d49f78a246de10c1831224" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "osakit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b" -dependencies = [ - "objc2 0.6.2", - "objc2-foundation 0.3.1", - "objc2-osa-kit", - "serde", - "serde_json", - "thiserror 2.0.16", -] - -[[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 0.10.9", -] - -[[package]] -name = "p384" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2 0.10.9", -] - -[[package]] -name = "p521" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" -dependencies = [ - "base16ct 0.2.0", - "ecdsa", - "elliptic-curve", - "primeorder", - "rand_core 0.6.4", - "sha2 0.10.9", -] - -[[package]] -name = "pageant" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b537f975f6d8dcf48db368d7ec209d583b015713b5df0f5d92d2631e4ff5595" -dependencies = [ - "byteorder", - "bytes", - "delegate", - "futures", - "log", - "rand 0.8.5", - "sha2 0.10.9", - "thiserror 1.0.69", - "tokio", - "windows 0.62.1", - "windows-strings 0.5.0", -] - -[[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 = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.6", -] - -[[package]] -name = "password-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "pastey" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35fb2e5f958ec131621fdd531e9fc186ed768cbe395337403ae56c17a74c68ec" - -[[package]] -name = "pathdiff" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" - -[[package]] -name = "pbkdf2" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" -dependencies = [ - "digest 0.10.7", - "hmac", -] - -[[package]] -name = "peeking_take_while" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "pem-rfc7468" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "phf" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" -dependencies = [ - "phf_shared 0.8.0", -] - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" -dependencies = [ - "phf_macros 0.11.3", - "phf_shared 0.11.3", -] - -[[package]] -name = "phf" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" -dependencies = [ - "phf_shared 0.13.1", - "serde", -] - -[[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.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", -] - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" -dependencies = [ - "phf_shared 0.11.3", - "rand 0.8.5", -] - -[[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "phf_shared" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" -dependencies = [ - "siphasher 0.3.11", -] - -[[package]] -name = "phf_shared" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" -dependencies = [ - "siphasher 0.3.11", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher 1.0.1", - "uncased", -] - -[[package]] -name = "phf_shared" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" -dependencies = [ - "siphasher 1.0.1", -] - -[[package]] -name = "pin-project" -version = "1.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[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.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkcs1" -version = "0.8.0-rc.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "986d2e952779af96ea048f160fd9194e1751b4faea78bcf3ceb456efe008088e" -dependencies = [ - "der 0.8.0", - "spki 0.8.0-rc.4", -] - -[[package]] -name = "pkcs5" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" -dependencies = [ - "aes", - "cbc", - "der 0.7.10", - "pbkdf2", - "scrypt", - "sha2 0.10.9", - "spki 0.7.3", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der 0.7.10", - "pkcs5", - "rand_core 0.6.4", - "spki 0.7.3", -] - -[[package]] -name = "pkcs8" -version = "0.11.0-rc.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12922b6296c06eb741b02d7b5161e3aaa22864af38dfa025a1a3ba3f68c84577" -dependencies = [ - "der 0.8.0", - "spki 0.8.0-rc.4", -] - -[[package]] -name = "pkg-config" -version = "0.3.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" - -[[package]] -name = "plist" -version = "1.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1" -dependencies = [ - "base64 0.22.1", - "indexmap 2.11.1", - "quick-xml", - "serde", - "time", -] - -[[package]] -name = "png" -version = "0.17.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" -dependencies = [ - "bitflags 1.3.2", - "crc32fast", - "fdeflate", - "flate2", - "miniz_oxide", -] - -[[package]] -name = "polling" -version = "3.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829" -dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix 1.1.2", - "windows-sys 0.60.2", -] - -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "portable-pty" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4a596a2b3d2752d94f51fac2d4a96737b8705dddd311a32b9af47211f08671e" -dependencies = [ - "anyhow", - "bitflags 1.3.2", - "downcast-rs", - "filedescriptor", - "lazy_static", - "libc", - "log", - "nix 0.28.0", - "serial2", - "shared_library", - "shell-words", - "winapi", - "winreg 0.10.1", -] - -[[package]] -name = "postgres-native-tls" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac73153d92e4bde922bd6f1dfba7f1ab8132266c031153b55e20a1521cd36d49" -dependencies = [ - "native-tls", - "tokio", - "tokio-native-tls", - "tokio-postgres", -] - -[[package]] -name = "postgres-protocol" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbef655056b916eb868048276cfd5d6a7dea4f81560dfd047f97c8c6fe3fcfd4" -dependencies = [ - "base64 0.22.1", - "byteorder", - "bytes", - "fallible-iterator 0.2.0", - "hmac", - "md-5", - "memchr", - "rand 0.9.2", - "sha2 0.10.9", - "stringprep", -] - -[[package]] -name = "postgres-types" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4605b7c057056dd35baeb6ac0c0338e4975b1f2bef0f65da953285eb007095" -dependencies = [ - "bytes", - "fallible-iterator 0.2.0", - "postgres-protocol", -] - -[[package]] -name = "potential_utf" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" -dependencies = [ - "zerovec", -] - -[[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.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy 0.8.27", -] - -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - -[[package]] -name = "prettyplease" -version = "0.2.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" -dependencies = [ - "proc-macro2", - "syn 2.0.106", -] - -[[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.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" -dependencies = [ - "toml_edit 0.20.7", -] - -[[package]] -name = "proc-macro-crate" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" -dependencies = [ - "toml_edit 0.22.27", -] - -[[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-error-attr2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" -dependencies = [ - "proc-macro2", - "quote", -] - -[[package]] -name = "proc-macro-error2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" -dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[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.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" -dependencies = [ - "bytes", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "ptr_meta" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79" -dependencies = [ - "ptr_meta_derive", -] - -[[package]] -name = "ptr_meta_derive" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "quick-xml" -version = "0.38.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a232e7487fc2ef313d96dde7948e7a3c05101870d8985e4fd8d26aedd27b89" -dependencies = [ - "memchr", -] - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rancor" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a063ea72381527c2a0561da9c80000ef822bdd7c3241b1cc1b12100e3df081ee" -dependencies = [ - "ptr_meta", -] - -[[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" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[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_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.3", -] - -[[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.16", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.3", -] - -[[package]] -name = "rand_core" -version = "0.10.0-rc-3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f66ee92bc15280519ef199a274fe0cafff4245d31bc39aaa31c011ad56cb1f05" - -[[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.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" - -[[package]] -name = "rayon" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - -[[package]] -name = "redox_syscall" -version = "0.5.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" -dependencies = [ - "bitflags 2.9.4", -] - -[[package]] -name = "redox_users" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" -dependencies = [ - "getrandom 0.2.16", - "libredox", - "thiserror 2.0.16", -] - -[[package]] -name = "ref-cast" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" -dependencies = [ - "ref-cast-impl", -] - -[[package]] -name = "ref-cast-impl" -version = "1.0.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "regex" -version = "1.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" - -[[package]] -name = "rend" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cadadef317c2f20755a64d7fdc48f9e7178ee6b0e1f7fce33fa60f1d68a276e6" - -[[package]] -name = "reqwest" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-core", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "hyper 1.7.0", - "hyper-rustls 0.27.7", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "rustls 0.23.37", - "rustls-pki-types", - "rustls-platform-verifier", - "serde", - "serde_json", - "sync_wrapper 1.0.2", - "tokio", - "tokio-rustls 0.26.4", - "tokio-util", - "tower 0.5.2", - "tower-http 0.6.8", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", -] - -[[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.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672" -dependencies = [ - "block2 0.6.1", - "dispatch2", - "glib-sys", - "gobject-sys", - "gtk-sys", - "js-sys", - "log", - "objc2 0.6.2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "raw-window-handle", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-sys 0.60.2", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.16", - "libc", - "untrusted 0.9.0", - "windows-sys 0.52.0", -] - -[[package]] -name = "rkyv" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a30e631b7f4a03dee9056b8ef6982e8ba371dd5bedb74d3ec86df4499132c70" -dependencies = [ - "bytes", - "hashbrown 0.16.1", - "indexmap 2.11.1", - "munge", - "ptr_meta", - "rancor", - "rend", - "rkyv_derive", - "tinyvec", - "uuid", -] - -[[package]] -name = "rkyv_derive" -version = "0.8.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8100bb34c0a1d0f907143db3149e6b4eea3c33b9ee8b189720168e818303986f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "rsa" -version = "0.10.0-rc.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a2b1eacbc34fbaf77f6f1db1385518446008d49b9f9f59dc9d1340fce4ca9e" -dependencies = [ - "const-oid 0.10.2", - "crypto-bigint 0.7.0-rc.18", - "crypto-primes", - "digest 0.11.1", - "pkcs1", - "pkcs8 0.11.0-rc.11", - "rand_core 0.10.0-rc-3", - "sha2 0.11.0-rc.5", - "signature 3.0.0-rc.6", - "spki 0.8.0-rc.4", - "zeroize", -] - -[[package]] -name = "rsql" -version = "1.1.5" -dependencies = [ - "csv", - "deadpool-postgres", - "futures-util", - "libsql", - "native-tls", - "portable-pty", - "postgres-native-tls", - "rayon", - "russh", - "serde", - "serde_json", - "sonic-rs", - "sysinfo", - "tauri", - "tauri-build", - "tauri-plugin-dialog", - "tauri-plugin-fs", - "tauri-plugin-opener", - "tauri-plugin-process", - "tauri-plugin-shell", - "tauri-plugin-updater", - "thiserror 2.0.16", - "tokio", - "tokio-postgres", - "tracing", - "tracing-subscriber", -] - -[[package]] -name = "russh" -version = "0.57.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afe62631a04a1f4d71a14b99505483b95ff97c503b67d876c042fce659186956" -dependencies = [ - "aes", - "aws-lc-rs", - "bitflags 2.9.4", - "block-padding", - "byteorder", - "bytes", - "cbc", - "ctr", - "curve25519-dalek", - "data-encoding", - "delegate", - "der 0.7.10", - "digest 0.10.7", - "ecdsa", - "ed25519-dalek", - "elliptic-curve", - "enum_dispatch", - "flate2", - "futures", - "generic-array 1.3.5", - "getrandom 0.2.16", - "hex-literal", - "hmac", - "home", - "inout", - "internal-russh-forked-ssh-key", - "libcrux-ml-kem", - "log", - "md5", - "num-bigint", - "p256", - "p384", - "p521", - "pageant", - "pbkdf2", - "pkcs1", - "pkcs5", - "pkcs8 0.10.2", - "rand 0.9.2", - "rand_core 0.10.0-rc-3", - "rsa", - "russh-cryptovec", - "russh-util", - "sec1", - "sha1 0.10.6", - "sha2 0.10.9", - "signature 2.2.0", - "spki 0.7.3", - "ssh-encoding", - "subtle", - "thiserror 1.0.69", - "tokio", - "typenum", - "zeroize", -] - -[[package]] -name = "russh-cryptovec" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb0ed583ff0f6b4aa44c7867dd7108df01b30571ee9423e250b4cc939f8c6cf" -dependencies = [ - "libc", - "log", - "nix 0.29.0", - "ssh-encoding", - "winapi", -] - -[[package]] -name = "russh-util" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668424a5dde0bcb45b55ba7de8476b93831b4aa2fa6947e145f3b053e22c60b6" -dependencies = [ - "chrono", - "tokio", - "wasm-bindgen", - "wasm-bindgen-futures", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - -[[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.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver", -] - -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.9.4", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - -[[package]] -name = "rustix" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" -dependencies = [ - "bitflags 2.9.4", - "errno", - "libc", - "linux-raw-sys 0.11.0", - "windows-sys 0.61.0", -] - -[[package]] -name = "rustls" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" -dependencies = [ - "log", - "ring", - "rustls-pki-types", - "rustls-webpki 0.102.8", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls" -version = "0.23.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4" -dependencies = [ - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki 0.103.9", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-native-certs" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" -dependencies = [ - "openssl-probe 0.1.6", - "rustls-pemfile", - "rustls-pki-types", - "schannel", - "security-framework 2.11.1", -] - -[[package]] -name = "rustls-native-certs" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" -dependencies = [ - "openssl-probe 0.2.1", - "rustls-pki-types", - "schannel", - "security-framework 3.5.1", -] - -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" -dependencies = [ - "zeroize", -] - -[[package]] -name = "rustls-platform-verifier" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" -dependencies = [ - "core-foundation 0.10.1", - "core-foundation-sys", - "jni", - "log", - "once_cell", - "rustls 0.23.37", - "rustls-native-certs 0.8.3", - "rustls-platform-verifier-android", - "rustls-webpki 0.103.9", - "security-framework 3.5.1", - "security-framework-sys", - "webpki-root-certs", - "windows-sys 0.61.0", -] - -[[package]] -name = "rustls-platform-verifier-android" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" - -[[package]] -name = "rustls-webpki" -version = "0.102.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted 0.9.0", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted 0.9.0", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" - -[[package]] -name = "salsa20" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" -dependencies = [ - "cipher", -] - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" -dependencies = [ - "windows-sys 0.61.0", -] - -[[package]] -name = "schemars" -version = "0.8.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" -dependencies = [ - "dyn-clone", - "indexmap 1.9.3", - "schemars_derive", - "serde", - "serde_json", - "url", - "uuid", -] - -[[package]] -name = "schemars" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" -dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", -] - -[[package]] -name = "schemars" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0" -dependencies = [ - "dyn-clone", - "ref-cast", - "serde", - "serde_json", -] - -[[package]] -name = "schemars_derive" -version = "0.8.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" -dependencies = [ - "proc-macro2", - "quote", - "serde_derive_internals", - "syn 2.0.106", -] - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "scrypt" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0516a385866c09368f0b5bcd1caff3366aace790fcd46e2bb032697bb172fd1f" -dependencies = [ - "pbkdf2", - "salsa20", - "sha2 0.10.9", -] - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct 0.2.0", - "der 0.7.10", - "generic-array 0.14.7", - "pkcs8 0.10.2", - "subtle", - "zeroize", -] - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.9.4", - "core-foundation 0.9.4", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework" -version = "3.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" -dependencies = [ - "bitflags 2.9.4", - "core-foundation 0.10.1", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[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", - "derive_more", - "fxhash", - "log", - "phf 0.8.0", - "phf_codegen 0.8.0", - "precomputed-hash", - "servo_arc", - "smallvec", -] - -[[package]] -name = "semver" -version = "1.0.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" -dependencies = [ - "serde", -] - -[[package]] -name = "serde" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" -dependencies = [ - "serde_core", - "serde_derive", -] - -[[package]] -name = "serde-untagged" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34836a629bcbc6f1afdf0907a744870039b1e14c0561cb26094fa683b158eff3" -dependencies = [ - "erased-serde", - "serde", - "typeid", -] - -[[package]] -name = "serde_core" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.228" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "serde_derive_internals" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "serde_json" -version = "1.0.149" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" -dependencies = [ - "itoa", - "memchr", - "serde", - "serde_core", - "zmij", -] - -[[package]] -name = "serde_repr" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_spanned" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40734c41988f7306bb04f0ecf60ec0f3f1caa34290e4e8ea471dcd3346483b83" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_with" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" -dependencies = [ - "base64 0.22.1", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.11.1", - "schemars 0.9.0", - "schemars 1.0.4", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "serdect" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9af4a3e75ebd5599b30d4de5768e00b5095d518a79fefc3ecbaf77e665d1ec06" -dependencies = [ - "base16ct 1.0.0", - "serde", -] - -[[package]] -name = "serial2" -version = "0.2.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e1401f562d358cdfdbdf8946e51a7871ede1db68bd0fd99bedc79e400241550" -dependencies = [ - "cfg-if", - "libc", - "winapi", -] - -[[package]] -name = "serialize-to-javascript" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5" -dependencies = [ - "serde", - "serde_json", - "serialize-to-javascript-impl", -] - -[[package]] -name = "serialize-to-javascript-impl" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[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 = "sha1" -version = "0.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha1" -version = "0.11.0-rc.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b167252f3c126be0d8926639c4c4706950f01445900c4b3db0fd7e89fcb750a" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.11.1", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha2" -version = "0.11.0-rc.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.11.1", -] - -[[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 = "shared_child" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7" -dependencies = [ - "libc", - "sigchld", - "windows-sys 0.60.2", -] - -[[package]] -name = "shared_library" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9e7e0f2bfae24d8a5b5a66c5b257a83c7412304311512a0c054cd5e619da11" -dependencies = [ - "lazy_static", - "libc", -] - -[[package]] -name = "shell-words" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "sigchld" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1" -dependencies = [ - "libc", - "os_pipe", - "signal-hook", -] - -[[package]] -name = "signal-hook" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" -dependencies = [ - "libc", - "signal-hook-registry", -] - -[[package]] -name = "signal-hook-registry" -version = "1.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "signature" -version = "3.0.0-rc.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a96996ccff7dfa16f052bd995b4cecc72af22c35138738dc029f0ead6608d" -dependencies = [ - "digest 0.11.1", - "rand_core 0.10.0-rc-3", -] - -[[package]] -name = "simd-adler32" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" - -[[package]] -name = "simdutf8" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" - -[[package]] -name = "siphasher" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" - -[[package]] -name = "siphasher" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" - -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "socket2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "softbuffer" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08" -dependencies = [ - "bytemuck", - "cfg_aliases 0.2.1", - "core-graphics 0.24.0", - "foreign-types 0.5.0", - "js-sys", - "log", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-quartz-core", - "raw-window-handle", - "redox_syscall", - "wasm-bindgen", - "web-sys", - "windows-sys 0.59.0", -] - -[[package]] -name = "sonic-number" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5661364b38abad49cf1ade6631fcc35d2ccf882a7d68616b4228b7717feb5fba" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "sonic-rs" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16b39f36452a4fa6f14a481b02e9ba5c6842c6a44d0545da967eca122f2eed9" -dependencies = [ - "ahash", - "bumpalo", - "bytes", - "cfg-if", - "faststr", - "itoa", - "ref-cast", - "serde", - "simdutf8", - "sonic-number", - "sonic-simd", - "thiserror 2.0.16", - "zmij", -] - -[[package]] -name = "sonic-simd" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9f944718c33623919878cf74b4c9361eb3024f635733922b26722b14cd3f8cc" -dependencies = [ - "cfg-if", -] - -[[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.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der 0.7.10", -] - -[[package]] -name = "spki" -version = "0.8.0-rc.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8baeff88f34ed0691978ec34440140e1572b68c7dd4a495fd14a3dc1944daa80" -dependencies = [ - "base64ct", - "der 0.8.0", -] - -[[package]] -name = "ssh-cipher" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caac132742f0d33c3af65bfcde7f6aa8f62f0e991d80db99149eb9d44708784f" -dependencies = [ - "aes", - "aes-gcm", - "cbc", - "chacha20", - "cipher", - "ctr", - "poly1305", - "ssh-encoding", - "subtle", -] - -[[package]] -name = "ssh-encoding" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb9242b9ef4108a78e8cd1a2c98e193ef372437f8c22be363075233321dd4a15" -dependencies = [ - "base64ct", - "bytes", - "pem-rfc7468 0.7.0", - "sha2 0.10.9", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "string_cache" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared 0.11.3", - "precomputed-hash", - "serde", -] - -[[package]] -name = "string_cache_codegen" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" -dependencies = [ - "phf_generator 0.11.3", - "phf_shared 0.11.3", - "proc-macro2", - "quote", -] - -[[package]] -name = "stringprep" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" -dependencies = [ - "unicode-bidi", - "unicode-normalization", - "unicode-properties", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "swift-rs" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7" -dependencies = [ - "base64 0.21.7", - "serde", - "serde_json", -] - -[[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.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "sysinfo" -version = "0.38.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d03c61d2a49c649a15c407338afe7accafde9dac869995dccb73e5f7ef7d9034" -dependencies = [ - "libc", - "memchr", - "ntapi", - "objc2-core-foundation", - "objc2-io-kit", - "windows 0.62.1", -] - -[[package]] -name = "system-deps" -version = "6.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" -dependencies = [ - "cfg-expr", - "heck 0.5.0", - "pkg-config", - "toml 0.8.23", - "version-compare", -] - -[[package]] -name = "tao" -version = "0.34.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d52c379e63da659a483a958110bbde891695a0ecb53e48cc7786d5eda7bb" -dependencies = [ - "bitflags 2.9.4", - "block2 0.6.1", - "core-foundation 0.10.1", - "core-graphics 0.25.0", - "crossbeam-channel", - "dispatch2", - "dlopen2", - "dpi", - "gdkwayland-sys", - "gdkx11-sys", - "gtk", - "jni", - "libc", - "log", - "ndk", - "ndk-context", - "ndk-sys", - "objc2 0.6.2", - "objc2-app-kit", - "objc2-foundation 0.3.1", - "once_cell", - "parking_lot", - "raw-window-handle", - "tao-macros", - "unicode-segmentation", - "url", - "windows 0.61.3", - "windows-core 0.61.2", - "windows-version", - "x11-dl", -] - -[[package]] -name = "tao-macros" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "tar" -version = "0.4.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" -dependencies = [ - "filetime", - "libc", - "xattr", -] - -[[package]] -name = "target-lexicon" -version = "0.12.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" - -[[package]] -name = "tauri" -version = "2.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da77cc00fb9028caf5b5d4650f75e31f1ef3693459dfca7f7e506d1ecef0ba2d" -dependencies = [ - "anyhow", - "bytes", - "cookie", - "dirs", - "dunce", - "embed_plist", - "getrandom 0.3.3", - "glob", - "gtk", - "heck 0.5.0", - "http 1.3.1", - "jni", - "libc", - "log", - "mime", - "muda", - "objc2 0.6.2", - "objc2-app-kit", - "objc2-foundation 0.3.1", - "objc2-ui-kit", - "objc2-web-kit", - "percent-encoding", - "plist", - "raw-window-handle", - "reqwest", - "serde", - "serde_json", - "serde_repr", - "serialize-to-javascript", - "swift-rs", - "tauri-build", - "tauri-macros", - "tauri-runtime", - "tauri-runtime-wry", - "tauri-utils", - "thiserror 2.0.16", - "tokio", - "tray-icon", - "url", - "webkit2gtk", - "webview2-com", - "window-vibrancy", - "windows 0.61.3", -] - -[[package]] -name = "tauri-build" -version = "2.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bbc990d1dbf57a8e1c7fa2327f2a614d8b757805603c1b9ba5c81bade09fd4d" -dependencies = [ - "anyhow", - "cargo_toml", - "dirs", - "glob", - "heck 0.5.0", - "json-patch", - "schemars 0.8.22", - "semver", - "serde", - "serde_json", - "tauri-utils", - "tauri-winres", - "toml 0.9.5", - "walkdir", -] - -[[package]] -name = "tauri-codegen" -version = "2.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a24476afd977c5d5d169f72425868613d82747916dd29e0a357c84c4bd6d29" -dependencies = [ - "base64 0.22.1", - "brotli", - "ico", - "json-patch", - "plist", - "png", - "proc-macro2", - "quote", - "semver", - "serde", - "serde_json", - "sha2 0.10.9", - "syn 2.0.106", - "tauri-utils", - "thiserror 2.0.16", - "time", - "url", - "uuid", - "walkdir", -] - -[[package]] -name = "tauri-macros" -version = "2.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39b349a98dadaffebb73f0a40dcd1f23c999211e5a2e744403db384d0c33de7" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.106", - "tauri-codegen", - "tauri-utils", -] - -[[package]] -name = "tauri-plugin" -version = "2.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddde7d51c907b940fb573006cdda9a642d6a7c8153657e88f8a5c3c9290cd4aa" -dependencies = [ - "anyhow", - "glob", - "plist", - "schemars 0.8.22", - "serde", - "serde_json", - "tauri-utils", - "toml 0.9.5", - "walkdir", -] - -[[package]] -name = "tauri-plugin-dialog" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9204b425d9be8d12aa60c2a83a289cf7d1caae40f57f336ed1155b3a5c0e359b" -dependencies = [ - "log", - "raw-window-handle", - "rfd", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "tauri-plugin-fs", - "thiserror 2.0.16", - "url", -] - -[[package]] -name = "tauri-plugin-fs" -version = "2.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed390cc669f937afeb8b28032ce837bac8ea023d975a2e207375ec05afaf1804" -dependencies = [ - "anyhow", - "dunce", - "glob", - "percent-encoding", - "schemars 0.8.22", - "serde", - "serde_json", - "serde_repr", - "tauri", - "tauri-plugin", - "tauri-utils", - "thiserror 2.0.16", - "toml 0.9.5", - "url", -] - -[[package]] -name = "tauri-plugin-opener" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "786156aa8e89e03d271fbd3fe642207da8e65f3c961baa9e2930f332bf80a1f5" -dependencies = [ - "dunce", - "glob", - "objc2-app-kit", - "objc2-foundation 0.3.1", - "open", - "schemars 0.8.22", - "serde", - "serde_json", - "tauri", - "tauri-plugin", - "thiserror 2.0.16", - "url", - "windows 0.61.3", - "zbus", -] - -[[package]] -name = "tauri-plugin-process" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d55511a7bf6cd70c8767b02c97bf8134fa434daf3926cfc1be0a0f94132d165a" -dependencies = [ - "tauri", - "tauri-plugin", -] - -[[package]] -name = "tauri-plugin-shell" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54777d0c0d8add34eea3ced84378619ef5b97996bd967d3038c668feefd21071" -dependencies = [ - "encoding_rs", - "log", - "open", - "os_pipe", - "regex", - "schemars 0.8.22", - "serde", - "serde_json", - "shared_child", - "tauri", - "tauri-plugin", - "thiserror 2.0.16", - "tokio", -] - -[[package]] -name = "tauri-plugin-updater" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe8e9bebd88fc222938ffdfbdcfa0307081423bd01e3252fc337d8bde81fc61" -dependencies = [ - "base64 0.22.1", - "dirs", - "flate2", - "futures-util", - "http 1.3.1", - "infer", - "log", - "minisign-verify", - "osakit", - "percent-encoding", - "reqwest", - "rustls 0.23.37", - "semver", - "serde", - "serde_json", - "tar", - "tauri", - "tauri-plugin", - "tempfile", - "thiserror 2.0.16", - "time", - "tokio", - "url", - "windows-sys 0.60.2", - "zip", -] - -[[package]] -name = "tauri-runtime" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2826d79a3297ed08cd6ea7f412644ef58e32969504bc4fbd8d7dbeabc4445ea2" -dependencies = [ - "cookie", - "dpi", - "gtk", - "http 1.3.1", - "jni", - "objc2 0.6.2", - "objc2-ui-kit", - "objc2-web-kit", - "raw-window-handle", - "serde", - "serde_json", - "tauri-utils", - "thiserror 2.0.16", - "url", - "webkit2gtk", - "webview2-com", - "windows 0.61.3", -] - -[[package]] -name = "tauri-runtime-wry" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e11ea2e6f801d275fdd890d6c9603736012742a1c33b96d0db788c9cdebf7f9e" -dependencies = [ - "gtk", - "http 1.3.1", - "jni", - "log", - "objc2 0.6.2", - "objc2-app-kit", - "once_cell", - "percent-encoding", - "raw-window-handle", - "softbuffer", - "tao", - "tauri-runtime", - "tauri-utils", - "url", - "webkit2gtk", - "webview2-com", - "windows 0.61.3", - "wry", -] - -[[package]] -name = "tauri-utils" -version = "2.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219a1f983a2af3653f75b5747f76733b0da7ff03069c7a41901a5eb3ace4557d" -dependencies = [ - "anyhow", - "brotli", - "cargo_metadata", - "ctor", - "dunce", - "glob", - "html5ever", - "http 1.3.1", - "infer", - "json-patch", - "kuchikiki", - "log", - "memchr", - "phf 0.11.3", - "proc-macro2", - "quote", - "regex", - "schemars 0.8.22", - "semver", - "serde", - "serde-untagged", - "serde_json", - "serde_with", - "swift-rs", - "thiserror 2.0.16", - "toml 0.9.5", - "url", - "urlpattern", - "uuid", - "walkdir", -] - -[[package]] -name = "tauri-winres" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd21509dd1fa9bd355dc29894a6ff10635880732396aa38c0066c1e6c1ab8074" -dependencies = [ - "embed-resource", - "toml 0.9.5", -] - -[[package]] -name = "tempfile" -version = "3.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53" -dependencies = [ - "fastrand", - "getrandom 0.3.3", - "once_cell", - "rustix 1.1.2", - "windows-sys 0.61.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 = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" -dependencies = [ - "thiserror-impl 2.0.16", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "thread_local" -version = "1.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "time" -version = "0.3.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83bde6f1ec10e72d583d91623c939f623002284ef622b87de38cfd546cbf2031" -dependencies = [ - "deranged", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" - -[[package]] -name = "time-macros" -version = "0.2.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" -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 = "tls_codec" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de2e01245e2bb89d6f05801c564fa27624dbd7b1846859876c7dad82e90bf6b" -dependencies = [ - "tls_codec_derive", - "zeroize", -] - -[[package]] -name = "tls_codec_derive" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d2e76690929402faae40aebdda620a2c0e25dd6d3b9afe48867dfd95991f4bd" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "tokio" -version = "1.47.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" -dependencies = [ - "backtrace", - "bytes", - "io-uring", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "slab", - "socket2 0.6.0", - "tokio-macros", - "windows-sys 0.59.0", -] - -[[package]] -name = "tokio-io-timeout" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd86198d9ee903fedd2f9a2e72014287c0d9167e4ae43b5853007205dda1b76" -dependencies = [ - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-macros" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[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-postgres" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b40d66d9b2cfe04b628173409368e58247e8eddbbd3b0e6c6ba1d09f20f6c9e" -dependencies = [ - "async-trait", - "byteorder", - "bytes", - "fallible-iterator 0.2.0", - "futures-channel", - "futures-util", - "log", - "parking_lot", - "percent-encoding", - "phf 0.13.1", - "pin-project-lite", - "postgres-protocol", - "postgres-types", - "rand 0.9.2", - "socket2 0.6.0", - "tokio", - "tokio-util", - "whoami", -] - -[[package]] -name = "tokio-rustls" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" -dependencies = [ - "rustls 0.22.4", - "rustls-pki-types", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" -dependencies = [ - "rustls 0.23.37", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_edit 0.22.27", -] - -[[package]] -name = "toml" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75129e1dc5000bfbaa9fee9d1b21f974f9fbad9daec557a521ee6e080825f6e8" -dependencies = [ - "indexmap 2.11.1", - "serde", - "serde_spanned 1.0.0", - "toml_datetime 0.7.0", - "toml_parser", - "toml_writer", - "winnow 0.7.13", -] - -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - -[[package]] -name = "toml_datetime" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bade1c3e902f58d73d3f294cd7f20391c1cb2fbcb643b73566bc773971df91e3" -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.11.1", - "toml_datetime 0.6.11", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.20.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" -dependencies = [ - "indexmap 2.11.1", - "toml_datetime 0.6.11", - "winnow 0.5.40", -] - -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap 2.11.1", - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "winnow 0.7.13", -] - -[[package]] -name = "toml_parser" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b551886f449aa90d4fe2bdaa9f4a2577ad2dde302c61ecf262d80b116db95c10" -dependencies = [ - "winnow 0.7.13", -] - -[[package]] -name = "toml_writer" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64" - -[[package]] -name = "tonic" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76c4eb7a4e9ef9d4763600161f12f5070b92a578e1b634db88a6887844c91a13" -dependencies = [ - "async-stream", - "async-trait", - "axum", - "base64 0.21.7", - "bytes", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.32", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost", - "tokio", - "tokio-stream", - "tower 0.4.13", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tonic-web" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc3b0e1cedbf19fdfb78ef3d672cb9928e0a91a9cb4629cc0c916e8cff8aaaa1" -dependencies = [ - "base64 0.21.7", - "bytes", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.32", - "pin-project", - "tokio-stream", - "tonic", - "tower-http 0.4.4", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand 0.8.5", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper 1.0.2", - "tokio", - "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 = [ - "bitflags 2.9.4", - "bytes", - "futures-core", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "http-range-header", - "pin-project-lite", - "tower 0.4.13", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-http" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" -dependencies = [ - "bitflags 2.9.4", - "bytes", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "iri-string", - "pin-project-lite", - "tower 0.5.2", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "log", - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", - "valuable", -] - -[[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.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" -dependencies = [ - "nu-ansi-term", - "sharded-slab", - "smallvec", - "thread_local", - "tracing-core", - "tracing-log", -] - -[[package]] -name = "tray-icon" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d92153331e7d02ec09137538996a7786fe679c629c279e82a6be762b7e6fe2" -dependencies = [ - "crossbeam-channel", - "dirs", - "libappindicator", - "muda", - "objc2 0.6.2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-core-graphics", - "objc2-foundation 0.3.1", - "once_cell", - "png", - "serde", - "thiserror 2.0.16", - "windows-sys 0.59.0", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typeid" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" - -[[package]] -name = "typenum" -version = "1.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" - -[[package]] -name = "uds_windows" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" -dependencies = [ - "memoffset", - "tempfile", - "winapi", -] - -[[package]] -name = "uncased" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" -dependencies = [ - "version_check", -] - -[[package]] -name = "unic-char-property" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" -dependencies = [ - "unic-char-range", -] - -[[package]] -name = "unic-char-range" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" - -[[package]] -name = "unic-common" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" - -[[package]] -name = "unic-ucd-ident" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" -dependencies = [ - "unic-char-property", - "unic-char-range", - "unic-ucd-version", -] - -[[package]] -name = "unic-ucd-version" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" -dependencies = [ - "unic-common", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5" - -[[package]] -name = "unicode-ident" -version = "1.0.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" - -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-properties" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" -dependencies = [ - "crypto-common 0.1.6", - "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 = "url" -version = "2.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "urlpattern" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" -dependencies = [ - "regex", - "serde", - "unic-ucd-ident", - "url", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "uuid" -version = "1.18.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" -dependencies = [ - "getrandom 0.3.3", - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "valuable" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" - -[[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.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "vswhom" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" -dependencies = [ - "libc", - "vswhom-sys", -] - -[[package]] -name = "vswhom-sys" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[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.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasi" -version = "0.14.5+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4494f6290a82f5fe584817a676a34b9d6763e8d9d18204009fb31dceca98fd4" -dependencies = [ - "wasip2", -] - -[[package]] -name = "wasip2" -version = "1.0.0+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03fa2761397e5bd52002cd7e73110c71af2109aca4e521a9f40473fe685b0a24" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasite" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" - -[[package]] -name = "wasm-bindgen" -version = "0.2.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" -dependencies = [ - "cfg-if", - "futures-util", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" -dependencies = [ - "bumpalo", - "proc-macro2", - "quote", - "syn 2.0.106", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.114" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wasm-streams" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1ec4f6517c9e11ae630e200b2b65d193279042e28edd4a2cda233e46670bbb" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "web-sys" -version = "0.3.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webkit2gtk" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1027150013530fb2eaf806408df88461ae4815a45c541c8975e61d6f2fc4793" -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.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "916a5f65c2ef0dfe12fff695960a2ec3d4565359fdbb2e9943c974e06c734ea5" -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 = "webpki-root-certs" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "804f18a4ac2676ffb4e8b5b5fa9ae38af06df08162314f96a68d2a363e21a8ca" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "webpki-roots" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" -dependencies = [ - "webpki-roots 1.0.6", -] - -[[package]] -name = "webpki-roots" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cfaf3c063993ff62e73cb4311efde4db1efb31ab78a3e5c457939ad5cc0bed" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "webview2-com" -version = "0.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4ba622a989277ef3886dd5afb3e280e3dd6d974b766118950a08f8f678ad6a4" -dependencies = [ - "webview2-com-macros", - "webview2-com-sys", - "windows 0.61.3", - "windows-core 0.61.2", - "windows-implement", - "windows-interface", -] - -[[package]] -name = "webview2-com-macros" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "webview2-com-sys" -version = "0.38.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36695906a1b53a3bf5c4289621efedac12b73eeb0b89e7e1a89b517302d5d75c" -dependencies = [ - "thiserror 2.0.16", - "windows 0.61.3", - "windows-core 0.61.2", -] - -[[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.44", -] - -[[package]] -name = "whoami" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4a4db5077702ca3015d3d02d74974948aba2ad9e12ab7df718ee64ccd7e97d" -dependencies = [ - "libredox", - "wasite", - "web-sys", -] - -[[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.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" -dependencies = [ - "windows-sys 0.61.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "window-vibrancy" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" -dependencies = [ - "objc2 0.6.2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "raw-window-handle", - "windows-sys 0.59.0", - "windows-version", -] - -[[package]] -name = "windows" -version = "0.61.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" -dependencies = [ - "windows-collections 0.2.0", - "windows-core 0.61.2", - "windows-future 0.2.1", - "windows-link 0.1.3", - "windows-numerics 0.2.0", -] - -[[package]] -name = "windows" -version = "0.62.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49e6c4a1f363c8210c6f77ba24f645c61c6fb941eccf013da691f7e09515b8ac" -dependencies = [ - "windows-collections 0.3.1", - "windows-core 0.62.1", - "windows-future 0.3.1", - "windows-numerics 0.3.0", -] - -[[package]] -name = "windows-collections" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" -dependencies = [ - "windows-core 0.61.2", -] - -[[package]] -name = "windows-collections" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123e712f464a8a60ce1a13f4c446d2d43ab06464cb5842ff68f5c71b6fb7852e" -dependencies = [ - "windows-core 0.62.1", -] - -[[package]] -name = "windows-core" -version = "0.61.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.4.2", -] - -[[package]] -name = "windows-core" -version = "0.62.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link 0.2.0", - "windows-result 0.4.0", - "windows-strings 0.5.0", -] - -[[package]] -name = "windows-future" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" -dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", - "windows-threading 0.1.0", -] - -[[package]] -name = "windows-future" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68f3db6b24b120200d649cd4811b4947188ed3a8d2626f7075146c5d178a9a4a" -dependencies = [ - "windows-core 0.62.1", - "windows-link 0.2.0", - "windows-threading 0.2.0", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-link" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" - -[[package]] -name = "windows-numerics" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" -dependencies = [ - "windows-core 0.61.2", - "windows-link 0.1.3", -] - -[[package]] -name = "windows-numerics" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ce3498fe0aba81e62e477408383196b4b0363db5e0c27646f932676283b43d8" -dependencies = [ - "windows-core 0.62.1", - "windows-link 0.2.0", -] - -[[package]] -name = "windows-result" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-result" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f" -dependencies = [ - "windows-link 0.2.0", -] - -[[package]] -name = "windows-strings" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-strings" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda" -dependencies = [ - "windows-link 0.2.0", -] - -[[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.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.3", -] - -[[package]] -name = "windows-sys" -version = "0.61.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" -dependencies = [ - "windows-link 0.2.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.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" -dependencies = [ - "windows-link 0.1.3", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - -[[package]] -name = "windows-threading" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" -dependencies = [ - "windows-link 0.1.3", -] - -[[package]] -name = "windows-threading" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab47f085ad6932defa48855254c758cdd0e2f2d48e62a34118a268d8f345e118" -dependencies = [ - "windows-link 0.2.0", -] - -[[package]] -name = "windows-version" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e061eb0a22b4a1d778ad70f7575ec7845490abb35b08fa320df7895882cacb" -dependencies = [ - "windows-link 0.2.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.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[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.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "winnow" -version = "0.5.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" -dependencies = [ - "memchr", -] - -[[package]] -name = "winnow" -version = "0.7.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" -dependencies = [ - "winapi", -] - -[[package]] -name = "winreg" -version = "0.55.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" -dependencies = [ - "cfg-if", - "windows-sys 0.59.0", -] - -[[package]] -name = "wit-bindgen" -version = "0.45.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36" - -[[package]] -name = "writeable" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" - -[[package]] -name = "wry" -version = "0.54.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb26159b420aa77684589a744ae9a9461a95395b848764ad12290a14d960a11a" -dependencies = [ - "base64 0.22.1", - "block2 0.6.1", - "cookie", - "crossbeam-channel", - "dirs", - "dpi", - "dunce", - "gdkx11", - "gtk", - "html5ever", - "http 1.3.1", - "javascriptcore-rs", - "jni", - "kuchikiki", - "libc", - "ndk", - "objc2 0.6.2", - "objc2-app-kit", - "objc2-core-foundation", - "objc2-foundation 0.3.1", - "objc2-ui-kit", - "objc2-web-kit", - "once_cell", - "percent-encoding", - "raw-window-handle", - "sha2 0.10.9", - "soup3", - "tao-macros", - "thiserror 2.0.16", - "url", - "webkit2gtk", - "webkit2gtk-sys", - "webview2-com", - "windows 0.61.3", - "windows-core 0.61.2", - "windows-version", - "x11-dl", -] - -[[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.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e45ad4206f6d2479085147f02bc2ef834ac85886624a23575ae137c8aa8156" -dependencies = [ - "libc", - "rustix 1.1.2", -] - -[[package]] -name = "yoke" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", - "synstructure", -] - -[[package]] -name = "zbus" -version = "5.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d07e46d035fb8e375b2ce63ba4e4ff90a7f73cf2ffb0138b29e1158d2eaadf7" -dependencies = [ - "async-broadcast", - "async-executor", - "async-io", - "async-lock", - "async-process", - "async-recursion", - "async-task", - "async-trait", - "blocking", - "enumflags2", - "event-listener", - "futures-core", - "futures-lite", - "hex", - "nix 0.30.1", - "ordered-stream", - "serde", - "serde_repr", - "tracing", - "uds_windows", - "windows-sys 0.60.2", - "winnow 0.7.13", - "zbus_macros", - "zbus_names", - "zvariant", -] - -[[package]] -name = "zbus_macros" -version = "5.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57e797a9c847ed3ccc5b6254e8bcce056494b375b511b3d6edcec0aeb4defaca" -dependencies = [ - "proc-macro-crate 3.3.0", - "proc-macro2", - "quote", - "syn 2.0.106", - "zbus_names", - "zvariant", - "zvariant_utils", -] - -[[package]] -name = "zbus_names" -version = "4.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" -dependencies = [ - "serde", - "static_assertions", - "winnow 0.7.13", - "zvariant", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive 0.7.35", -] - -[[package]] -name = "zerocopy" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" -dependencies = [ - "zerocopy-derive 0.8.27", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" -dependencies = [ - "zeroize_derive", -] - -[[package]] -name = "zeroize_derive" -version = "1.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "zip" -version = "4.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caa8cd6af31c3b31c6631b8f483848b91589021b28fffe50adada48d4f4d2ed1" -dependencies = [ - "arbitrary", - "crc32fast", - "indexmap 2.11.1", - "memchr", -] - -[[package]] -name = "zmij" -version = "1.0.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" - -[[package]] -name = "zvariant" -version = "5.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "999dd3be73c52b1fccd109a4a81e4fcd20fab1d3599c8121b38d04e1419498db" -dependencies = [ - "endi", - "enumflags2", - "serde", - "winnow 0.7.13", - "zvariant_derive", - "zvariant_utils", -] - -[[package]] -name = "zvariant_derive" -version = "5.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6643fd0b26a46d226bd90d3f07c1b5321fe9bb7f04673cb37ac6d6883885b68e" -dependencies = [ - "proc-macro-crate 3.3.0", - "proc-macro2", - "quote", - "syn 2.0.106", - "zvariant_utils", -] - -[[package]] -name = "zvariant_utils" -version = "3.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6949d142f89f6916deca2232cf26a8afacf2b9fdc35ce766105e104478be599" -dependencies = [ - "proc-macro2", - "quote", - "serde", - "syn 2.0.106", - "winnow 0.7.13", -] diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml deleted file mode 100644 index 1ff94c4..0000000 --- a/src-tauri/Cargo.toml +++ /dev/null @@ -1,45 +0,0 @@ -[package] -name = "rsql" -version = "1.1.5" -description = "Modern SQL Client" -authors = ["rust-dd"] -edition = "2024" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -# The `_lib` suffix may seem redundant but it is necessary -# to make the lib name unique and wouldn't conflict with the bin name. -# This seems to be only an issue on Windows, see https://github.com/rust-lang/cargo/issues/8519 -name = "rsql_lib" -crate-type = ["staticlib", "cdylib", "rlib"] - -[build-dependencies] -tauri-build = { version = "2", features = [] } - -[dependencies] -tauri = { version = "2", features = [] } -tauri-plugin-opener = "2" -serde = { version = "1", features = ["derive"] } -serde_json = "1" -sonic-rs = "0.5" -tokio = "1.47.1" -tokio-postgres = "0.7.13" -deadpool-postgres = "0.14.1" -postgres-native-tls = "0.5" -native-tls = "0.2" -tracing = "0.1.41" -tracing-subscriber = {version = "0.3.20", features = ["fmt"] } -libsql = "0.9.29" -tauri-plugin-shell = "2.3.1" -tauri-plugin-fs = "2.4.2" -thiserror = "2" -tauri-plugin-dialog = "2.6.0" -tauri-plugin-process = "2.3.1" -tauri-plugin-updater = "2.10.0" -portable-pty = "0.9.0" -rayon = "1.11.0" -sysinfo = "0.38.3" -csv = "1.3" -futures-util = "0.3" -russh = "0.57" diff --git a/src-tauri/src/app_setup.rs b/src-tauri/src/app_setup.rs deleted file mode 100644 index 3b95dd2..0000000 --- a/src-tauri/src/app_setup.rs +++ /dev/null @@ -1,209 +0,0 @@ -use std::{collections::BTreeMap, sync::Arc}; -use tauri::Manager; -use tauri::menu::{AboutMetadata, MenuBuilder, SubmenuBuilder}; -use tokio::sync::Mutex; - -use crate::{AppState, LOCAL_DB_NAME, terminal, utils}; - -pub fn setup_app(app: &mut tauri::App) -> Result<(), Box> { - #[cfg(desktop)] - if let Some(pubkey) = option_env!("TAURI_UPDATER_PUBLIC_KEY") { - app.handle() - .plugin(tauri_plugin_updater::Builder::new().pubkey(pubkey).build())?; - } else { - tracing::info!( - "Updater disabled because TAURI_UPDATER_PUBLIC_KEY was not set at build time" - ); - } - - let app_handle = app.handle().clone(); - - tauri::async_runtime::block_on(async move { - let db_path = if cfg!(debug_assertions) { - LOCAL_DB_NAME.to_string() - } else { - let app_dir = app_handle - .path() - .app_data_dir() - .expect("Failed to resolve app data directory"); - std::fs::create_dir_all(&app_dir).ok(); - app_dir.join(LOCAL_DB_NAME).to_string_lossy().to_string() - }; - - let db = libsql::Builder::new_local(&db_path) - .build() - .await - .expect("Failed to open local database"); - - let conn = db.connect().expect("Failed to create connection"); - conn.execute( - "CREATE TABLE IF NOT EXISTS projects ( - id TEXT PRIMARY KEY, - driver TEXT NOT NULL DEFAULT 'PGSQL', - username TEXT NOT NULL DEFAULT '', - password TEXT NOT NULL DEFAULT '', - database TEXT NOT NULL DEFAULT '', - host TEXT NOT NULL DEFAULT '', - port TEXT NOT NULL DEFAULT '', - ssl TEXT NOT NULL DEFAULT 'false' - )", - (), - ) - .await - .expect("Failed to create projects table"); - - conn.execute( - "CREATE TABLE IF NOT EXISTS queries ( - id TEXT PRIMARY KEY, - sql TEXT NOT NULL DEFAULT '' - )", - (), - ) - .await - .expect("Failed to create queries table"); - - conn.execute( - "CREATE TABLE IF NOT EXISTS workspaces ( - name TEXT PRIMARY KEY, - tabs TEXT NOT NULL DEFAULT '[]' - )", - (), - ) - .await - .expect("Failed to create workspaces table"); - - conn.execute( - "CREATE TABLE IF NOT EXISTS virtual_query_snapshots ( - query_id TEXT PRIMARY KEY, - project_id TEXT NOT NULL, - sql TEXT NOT NULL, - columns_packed TEXT NOT NULL DEFAULT '', - total_rows INTEGER NOT NULL DEFAULT 0, - page_size INTEGER NOT NULL DEFAULT 0, - col_count INTEGER NOT NULL DEFAULT 0, - created_at INTEGER NOT NULL - )", - (), - ) - .await - .expect("Failed to create virtual_query_snapshots table"); - - conn.execute( - "CREATE TABLE IF NOT EXISTS virtual_query_pages ( - query_id TEXT NOT NULL, - page_index INTEGER NOT NULL, - packed_page TEXT NOT NULL DEFAULT '', - PRIMARY KEY (query_id, page_index) - )", - (), - ) - .await - .expect("Failed to create virtual_query_pages table"); - - // Best-effort orphan cleanup in case app exited before tab-close cleanup. - conn.execute( - "DELETE FROM virtual_query_pages - WHERE query_id NOT IN (SELECT query_id FROM virtual_query_snapshots)", - (), - ) - .await - .ok(); - - for col in [ - "ssh_enabled", - "ssh_host", - "ssh_port", - "ssh_user", - "ssh_password", - "ssh_key_path", - ] { - conn.execute( - &format!( - "ALTER TABLE projects ADD COLUMN {} TEXT NOT NULL DEFAULT ''", - col - ), - (), - ) - .await - .ok(); // Ignore "column already exists" errors - } - - let state = AppState { - clients: Arc::new(Mutex::new(BTreeMap::new())), - meta_clients: Arc::new(Mutex::new(BTreeMap::new())), - cancel_tokens: Arc::new(Mutex::new(BTreeMap::new())), - client_ssl: Arc::new(Mutex::new(BTreeMap::new())), - local_db: db, - resource_monitor: Arc::new(Mutex::new(utils::ResourceMonitor::new())), - virtual_cache: Arc::new(Mutex::new(BTreeMap::new())), - notify_handles: Arc::new(Mutex::new(BTreeMap::new())), - ssh_tunnels: Arc::new(Mutex::new(BTreeMap::new())), - }; - app_handle.manage(state); - - let terminal_state = terminal::TerminalState { - sessions: Arc::new(Mutex::new(std::collections::HashMap::new())), - }; - app_handle.manage(terminal_state); - }); - - let handle = app.handle(); - - let app_menu = SubmenuBuilder::new(handle, "RSQL") - .about(Some(AboutMetadata { - name: Some("RSQL".into()), - version: Some(env!("CARGO_PKG_VERSION").into()), - copyright: Some("\u{00a9} 2025 rust-dd".into()), - comments: Some( - "Modern SQL client for PostgreSQL.\nBuilt with Tauri, React, and Rust.".into(), - ), - website: Some("https://github.com/rust-dd/rust-sql".into()), - website_label: Some("GitHub".into()), - ..Default::default() - })) - .separator() - .services() - .separator() - .hide() - .hide_others() - .show_all() - .separator() - .quit() - .build()?; - - let edit_menu = SubmenuBuilder::new(handle, "Edit") - .undo() - .redo() - .separator() - .cut() - .copy() - .paste() - .select_all() - .build()?; - - let view_menu = SubmenuBuilder::new(handle, "View").fullscreen().build()?; - - let window_menu = SubmenuBuilder::new(handle, "Window") - .minimize() - .maximize() - .separator() - .close_window() - .build()?; - - let menu = MenuBuilder::new(handle) - .items(&[&app_menu, &edit_menu, &view_menu, &window_menu]) - .build()?; - - handle.set_menu(menu)?; - - #[cfg(debug_assertions)] - { - let window = app - .get_webview_window("main") - .expect("main window not found"); - window.open_devtools(); - window.close_devtools(); - } - - Ok(()) -} diff --git a/src-tauri/src/dbs/mod.rs b/src-tauri/src/dbs/mod.rs deleted file mode 100644 index 8f815bb..0000000 --- a/src-tauri/src/dbs/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -pub mod project; -pub mod query; -pub mod workspace; diff --git a/src-tauri/src/drivers/pgsql/commands/metadata_commands.rs b/src-tauri/src/drivers/pgsql/commands/metadata_commands.rs deleted file mode 100644 index 343861e..0000000 --- a/src-tauri/src/drivers/pgsql/commands/metadata_commands.rs +++ /dev/null @@ -1,219 +0,0 @@ -use crate::AppState; -use crate::common::pgsql::{PgsqlLoadColumns, PgsqlLoadSchemas, PgsqlLoadTables}; -use crate::drivers::pgsql::{ - ColumnDetail, ConstraintDetail, FunctionInfo, IndexDetail, PolicyDetail, RuleDetail, - TriggerDetail, get_pool, load_column_details, load_columns, load_constraints, load_databases, - load_functions, load_indexes, load_materialized_views, load_policies, load_rules, load_schemas, - load_tables, load_tablespaces, load_trigger_functions, load_triggers, load_views, -}; - -use tauri::{AppHandle, Manager, Result, State}; - -use super::pool_connection::acquire_client; - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_databases(project_id: &str, app: AppHandle) -> Result> { - let app_state = app.state::(); - let pool = { - let pools = app_state.meta_clients.lock().await; - get_pool(&pools, project_id)? - }; - - load_databases(&pool).await.map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_tablespaces( - project_id: &str, - app: AppHandle, -) -> Result> { - let app_state = app.state::(); - let pool = { - let pools = app_state.meta_clients.lock().await; - get_pool(&pools, project_id)? - }; - - load_tablespaces(&pool).await.map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_schemas( - project_id: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_schemas( - &client, - r#"SELECT schema_name FROM information_schema.schemata - WHERE schema_name NOT IN ('pg_catalog', 'information_schema') - ORDER BY schema_name"#, - ) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_tables( - project_id: &str, - schema: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_tables( - &client, - r#"SELECT table_name, - pg_size_pretty(pg_total_relation_size('"' || table_schema || '"."' || table_name || '"')) AS size - FROM information_schema.tables - WHERE table_schema = $1 - ORDER BY table_name"#, - schema, - ) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_columns( - project_id: &str, - schema: &str, - table: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_columns(&client, schema, table) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_column_details( - project_id: &str, - schema: &str, - table: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_column_details(&client, schema, table) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_indexes( - project_id: &str, - schema: &str, - table: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_indexes(&client, schema, table) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_constraints( - project_id: &str, - schema: &str, - table: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_constraints(&client, schema, table) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_triggers( - project_id: &str, - schema: &str, - table: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_triggers(&client, schema, table) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_rules( - project_id: &str, - schema: &str, - table: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_rules(&client, schema, table).await.map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_policies( - project_id: &str, - schema: &str, - table: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_policies(&client, schema, table) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_views( - project_id: &str, - schema: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_views(&client, schema).await.map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_materialized_views( - project_id: &str, - schema: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_materialized_views(&client, schema) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_functions( - project_id: &str, - schema: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_functions(&client, schema).await.map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_trigger_functions( - project_id: &str, - schema: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_trigger_functions(&client, schema) - .await - .map_err(Into::into) -} diff --git a/src-tauri/src/drivers/pgsql/commands/object_info_commands.rs b/src-tauri/src/drivers/pgsql/commands/object_info_commands.rs deleted file mode 100644 index 97b2a08..0000000 --- a/src-tauri/src/drivers/pgsql/commands/object_info_commands.rs +++ /dev/null @@ -1,61 +0,0 @@ -use crate::AppState; -use crate::drivers::pgsql::{ - ObjectStats, generate_full_ddl, load_function_info, load_matview_info, load_view_info, -}; - -use tauri::{Result, State}; - -use super::pool_connection::acquire_client; - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_view_info( - project_id: &str, - schema: &str, - view: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - load_view_info(&client, schema, view) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_matview_info( - project_id: &str, - schema: &str, - matview: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - load_matview_info(&client, schema, matview) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_function_info( - project_id: &str, - schema: &str, - func_name: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - load_function_info(&client, schema, func_name) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_generate_ddl( - project_id: &str, - schema: &str, - name: &str, - object_type: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - generate_full_ddl(&client, schema, name, object_type) - .await - .map_err(Into::into) -} diff --git a/src-tauri/src/drivers/pgsql/commands/statistics_commands.rs b/src-tauri/src/drivers/pgsql/commands/statistics_commands.rs deleted file mode 100644 index 3c9485f..0000000 --- a/src-tauri/src/drivers/pgsql/commands/statistics_commands.rs +++ /dev/null @@ -1,117 +0,0 @@ -use crate::AppState; -use crate::common::enums::AppError; -use crate::drivers::pgsql::{ - DbStat, FKDetail, ForeignKeyInfo, ObjectStats, load_active_locks, load_activity, - load_database_stats, load_fk_details, load_foreign_keys, load_index_usage, load_table_bloat, - load_table_statistics, load_table_stats, -}; - -use tauri::ipc::Response; -use tauri::{Result, State}; - -use super::pool_connection::acquire_client; - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_activity( - project_id: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - let result = load_activity(&client).await?; - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_database_stats( - project_id: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_database_stats(&client).await.map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_table_stats( - project_id: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - let result = load_table_stats(&client).await?; - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_foreign_keys( - project_id: &str, - schema: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - - load_foreign_keys(&client, schema).await.map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_table_statistics( - project_id: &str, - schema: &str, - table: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - load_table_statistics(&client, schema, table) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_fk_details( - project_id: &str, - schema: &str, - table: &str, - direction: &str, - app_state: State<'_, AppState>, -) -> Result> { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - load_fk_details(&client, schema, table, direction) - .await - .map_err(Into::into) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_locks( - project_id: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - let result = load_active_locks(&client).await?; - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_index_usage( - project_id: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - let result = load_index_usage(&client).await?; - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn pgsql_load_table_bloat( - project_id: &str, - app_state: State<'_, AppState>, -) -> Result { - let client = acquire_client(&app_state.meta_clients, project_id).await?; - let result = load_table_bloat(&client).await?; - let json = sonic_rs::to_string(&result).map_err(|e| AppError::QueryFailed(e.to_string()))?; - Ok(Response::new(json)) -} diff --git a/src-tauri/src/terminal.rs b/src-tauri/src/terminal.rs deleted file mode 100644 index e5e1d4f..0000000 --- a/src-tauri/src/terminal.rs +++ /dev/null @@ -1,124 +0,0 @@ -use portable_pty::{CommandBuilder, MasterPty, PtySize, native_pty_system}; -use std::collections::HashMap; -use std::io::{Read, Write}; -use std::sync::Arc; -use tauri::{AppHandle, Emitter}; -use tokio::sync::Mutex; - -pub struct TerminalState { - pub sessions: Arc>>, -} - -pub(crate) struct TerminalSession { - writer: Box, - master: Box, -} - -#[tauri::command] -pub async fn terminal_spawn( - app: AppHandle, - terminal_state: tauri::State<'_, TerminalState>, - id: String, - cols: u16, - rows: u16, -) -> Result<(), String> { - let pty_system = native_pty_system(); - let pair = pty_system - .openpty(PtySize { - rows, - cols, - pixel_width: 0, - pixel_height: 0, - }) - .map_err(|e| e.to_string())?; - - let mut cmd = CommandBuilder::new_default_prog(); - cmd.env("TERM", "xterm-256color"); - - pair.slave.spawn_command(cmd).map_err(|e| e.to_string())?; - - // Drop the slave so we can detect when the child exits - drop(pair.slave); - - let writer = pair.master.take_writer().map_err(|e| e.to_string())?; - let mut reader = pair.master.try_clone_reader().map_err(|e| e.to_string())?; - - let session = TerminalSession { - writer, - master: pair.master, - }; - - terminal_state - .sessions - .lock() - .await - .insert(id.clone(), session); - - let terminal_id = id.clone(); - std::thread::spawn(move || { - let mut buf = [0u8; 4096]; - loop { - match reader.read(&mut buf) { - Ok(0) => { - // EOF - process exited - let _ = app.emit(&format!("terminal-exit-{}", terminal_id), ()); - break; - } - Ok(n) => { - let data = String::from_utf8_lossy(&buf[..n]).to_string(); - let _ = app.emit(&format!("terminal-data-{}", terminal_id), data); - } - Err(_) => break, - } - } - }); - - Ok(()) -} - -#[tauri::command] -pub async fn terminal_write( - terminal_state: tauri::State<'_, TerminalState>, - id: String, - data: String, -) -> Result<(), String> { - let mut sessions = terminal_state.sessions.lock().await; - let session = sessions.get_mut(&id).ok_or("Terminal not found")?; - session - .writer - .write_all(data.as_bytes()) - .map_err(|e| e.to_string())?; - session.writer.flush().map_err(|e| e.to_string())?; - Ok(()) -} - -#[tauri::command] -pub async fn terminal_resize( - terminal_state: tauri::State<'_, TerminalState>, - id: String, - cols: u16, - rows: u16, -) -> Result<(), String> { - let sessions = terminal_state.sessions.lock().await; - let session = sessions.get(&id).ok_or("Terminal not found")?; - session - .master - .resize(PtySize { - rows, - cols, - pixel_width: 0, - pixel_height: 0, - }) - .map_err(|e| e.to_string())?; - Ok(()) -} - -#[tauri::command] -pub async fn terminal_kill( - terminal_state: tauri::State<'_, TerminalState>, - id: String, -) -> Result<(), String> { - let mut sessions = terminal_state.sessions.lock().await; - sessions.remove(&id); - Ok(()) -} diff --git a/src-tauri/src/utils.rs b/src-tauri/src/utils.rs deleted file mode 100644 index c07dc36..0000000 --- a/src-tauri/src/utils.rs +++ /dev/null @@ -1,243 +0,0 @@ -use std::collections::HashSet; -use std::time::Instant; - -use rayon::prelude::*; -use sysinfo::{Networks, Pid, ProcessRefreshKind, ProcessesToUpdate, System, get_current_pid}; -use tauri::State; - -use crate::AppState; - -#[derive(serde::Serialize, Clone, Debug)] -pub struct SystemResourceUsage { - pub app_cpu_percent: f32, - pub app_memory_rss_mb: u64, - pub app_process_count: usize, - pub network_rx_mbps: f32, - pub network_tx_mbps: f32, - pub db_connections_in_use: usize, - pub db_connections_open: usize, - pub db_connections_max: usize, - pub db_connections_waiting: usize, -} - -pub struct ResourceMonitor { - system: System, - networks: Networks, - last_sample_at: Instant, - app_pid: Pid, -} - -impl ResourceMonitor { - pub fn new() -> Self { - let app_pid = get_current_pid().unwrap_or_else(|_| Pid::from_u32(std::process::id())); - let mut system = System::new_all(); - system.refresh_processes(ProcessesToUpdate::All, true); - let mut networks = Networks::new_with_refreshed_list(); - networks.refresh(true); - - Self { - system, - networks, - last_sample_at: Instant::now(), - app_pid, - } - } - - pub fn sample(&mut self) -> SystemResourceUsage { - self.system.refresh_processes_specifics( - ProcessesToUpdate::All, - true, - ProcessRefreshKind::nothing().with_cpu().with_memory(), - ); - self.networks.refresh(true); - let dt = self.last_sample_at.elapsed().as_secs_f32().max(0.001); - self.last_sample_at = Instant::now(); - - let processes = self.system.processes(); - let mut included = HashSet::new(); - included.insert(self.app_pid); - - let mut changed = true; - while changed { - changed = false; - for (pid, process) in processes { - if included.contains(pid) { - continue; - } - if let Some(parent) = process.parent() - && included.contains(&parent) - { - included.insert(*pid); - changed = true; - } - } - } - - let mut total_cpu = 0.0f32; - let mut total_rss = 0u64; - for pid in &included { - if let Some(process) = processes.get(pid) { - total_cpu += process.cpu_usage(); - total_rss = total_rss.saturating_add(process.memory()); - } - } - - let mut rx_bytes: u64 = 0; - let mut tx_bytes: u64 = 0; - for (_iface, net) in &self.networks { - rx_bytes = rx_bytes.saturating_add(net.received()); - tx_bytes = tx_bytes.saturating_add(net.transmitted()); - } - let network_rx_mbps = (rx_bytes as f32 * 8.0) / dt / 1_000_000.0; - let network_tx_mbps = (tx_bytes as f32 * 8.0) / dt / 1_000_000.0; - - SystemResourceUsage { - app_cpu_percent: total_cpu, - app_memory_rss_mb: total_rss / (1024 * 1024), - app_process_count: included.len(), - network_rx_mbps, - network_tx_mbps, - db_connections_in_use: 0, - db_connections_open: 0, - db_connections_max: 0, - db_connections_waiting: 0, - } - } -} - -#[tauri::command(rename_all = "snake_case")] -pub async fn system_resource_usage( - app_state: State<'_, AppState>, -) -> Result { - let mut usage = { - let mut monitor = app_state.resource_monitor.lock().await; - monitor.sample() - }; - - let (query_open, query_available, query_max, query_waiting) = { - let clients = app_state.clients.lock().await; - let mut open = 0usize; - let mut available = 0usize; - let mut max = 0usize; - let mut waiting = 0usize; - for pool in clients.values() { - let status = pool.status(); - open = open.saturating_add(status.size); - available = available.saturating_add(status.available); - max = max.saturating_add(status.max_size); - waiting = waiting.saturating_add(status.waiting); - } - (open, available, max, waiting) - }; - - let (meta_open, meta_available, meta_max, meta_waiting) = { - let clients = app_state.meta_clients.lock().await; - let mut open = 0usize; - let mut available = 0usize; - let mut max = 0usize; - let mut waiting = 0usize; - for pool in clients.values() { - let status = pool.status(); - open = open.saturating_add(status.size); - available = available.saturating_add(status.available); - max = max.saturating_add(status.max_size); - waiting = waiting.saturating_add(status.waiting); - } - (open, available, max, waiting) - }; - - let total_open = query_open.saturating_add(meta_open); - let total_available = query_available.saturating_add(meta_available); - - usage.db_connections_open = total_open; - usage.db_connections_max = query_max.saturating_add(meta_max); - usage.db_connections_waiting = query_waiting.saturating_add(meta_waiting); - usage.db_connections_in_use = total_open.saturating_sub(total_available); - - Ok(usage) -} - -const ROW_SEP: char = '\x1E'; - -fn parse_packed_rows(packed: &str) -> Vec<&str> { - if packed.is_empty() { - return Vec::new(); - } - let parts: Vec<&str> = packed.split(ROW_SEP).collect(); - if parts.len() > 1 { - parts[1..].to_vec() - } else { - Vec::new() - } -} - -fn pack_rows(header: &str, rows: &[&str]) -> String { - if rows.is_empty() { - return header.to_string(); - } - let mut result = - String::with_capacity(header.len() + rows.iter().map(|r| r.len() + 1).sum::()); - result.push_str(header); - for row in rows { - result.push(ROW_SEP); - result.push_str(row); - } - result -} - -/// Compute diff between two packed result sets. -/// Input: two packed strings (rows separated by \x1E, cells by \x1F). -/// First row of each is the header (columns). -/// Returns: (added_packed, removed_packed, unchanged_count) -#[tauri::command(rename_all = "snake_case")] -pub fn compute_diff(pinned_packed: String, current_packed: String) -> (String, String, usize) { - let pinned_rows = parse_packed_rows(&pinned_packed); - let current_rows = parse_packed_rows(¤t_packed); - - // Build hash sets for O(1) lookup - let pinned_set: HashSet<&str> = pinned_rows.iter().copied().collect(); - let current_set: HashSet<&str> = current_rows.iter().copied().collect(); - - // Compute diff using parallel iteration for large datasets - let (added, removed, unchanged_count) = if current_rows.len() > 5000 || pinned_rows.len() > 5000 - { - let added: Vec<&str> = current_rows - .par_iter() - .filter(|r| !pinned_set.contains(*r)) - .copied() - .collect(); - let removed: Vec<&str> = pinned_rows - .par_iter() - .filter(|r| !current_set.contains(*r)) - .copied() - .collect(); - let unchanged: usize = current_rows - .par_iter() - .filter(|r| pinned_set.contains(*r)) - .count(); - (added, removed, unchanged) - } else { - let added: Vec<&str> = current_rows - .iter() - .filter(|r| !pinned_set.contains(*r)) - .copied() - .collect(); - let removed: Vec<&str> = pinned_rows - .iter() - .filter(|r| !current_set.contains(*r)) - .copied() - .collect(); - let unchanged: usize = current_rows - .iter() - .filter(|r| pinned_set.contains(*r)) - .count(); - (added, removed, unchanged) - }; - - let header = pinned_packed.split(ROW_SEP).next().unwrap_or(""); - ( - pack_rows(header, &added), - pack_rows(header, &removed), - unchanged_count, - ) -} diff --git a/src/App.tsx b/src/App.tsx index e371e15..afd1972 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -22,7 +22,7 @@ import { TerminalPanel } from "@/components/terminal-panel"; import { TopBar } from "@/components/top-bar"; import { useAppStartup } from "@/hooks/use-app-startup"; import { useQueryLifecycle } from "@/hooks/use-query-lifecycle"; -import { checkForUpdates } from "@/lib/updater"; +import { updater } from "@/lib/platform"; import { useProjectStore } from "@/stores/project-store"; import { useActiveTab, useTabStore } from "@/stores/tab-store"; import { useUIStore } from "@/stores/ui-store"; @@ -123,7 +123,7 @@ export default function App() { onContextMenu={(e) => e.preventDefault()} > void checkForUpdates()} + onCheckUpdates={() => void updater.checkForUpdates()} onOpenCommandPalette={() => setCommandPaletteOpen(true)} /> @@ -298,7 +298,7 @@ export default function App() { onClose={() => setCommandPaletteOpen(false)} onExecute={() => void runQuery()} onExplain={() => void runExplain()} - onCheckUpdates={() => void checkForUpdates()} + onCheckUpdates={() => void updater.checkForUpdates()} /> diff --git a/src/components/command-palette/tools.tsx b/src/components/command-palette/tools.tsx index 4d2f0ad..6b6ebf0 100644 --- a/src/components/command-palette/tools.tsx +++ b/src/components/command-palette/tools.tsx @@ -152,17 +152,19 @@ export function ActionsGroup({ )} {theme === "light" ? "Dark Mode" : "Light Mode"} - { - onClose(); - onCheckUpdates(); - }} - > - - Check for Updates - App - + {__RSQL_BUILD_TARGET__ !== "web" && ( + { + onClose(); + onCheckUpdates(); + }} + > + + Check for Updates + App + + )} {pinnedResult ? ( s.projects); const pickFile = useCallback(async () => { - const selected = await open({ - multiple: false, + const selected = await dialog.openFile({ filters: [{ name: "CSV", extensions: ["csv", "tsv", "txt"] }], }); if (!selected) return; - const path = typeof selected === "string" ? selected : selected; + if (selected.kind === "file") { + setResult({ + success: false, + message: "CSV import in the web build is coming soon. Use the desktop app to import files.", + }); + return; + } + + const path = selected.path; setFilePath(path); setResult(null); diff --git a/src/components/notify-panel.tsx b/src/components/notify-panel.tsx index 5994214..744c2de 100644 --- a/src/components/notify-panel.tsx +++ b/src/components/notify-panel.tsx @@ -1,4 +1,4 @@ -import { listen } from "@tauri-apps/api/event"; +import { transport } from "@/lib/transport"; import { Bell, BellOff, Radio, Send, Trash2 } from "lucide-react"; import { useCallback, useEffect, useRef, useState } from "react"; import { DriverFactory } from "@/lib/database-driver"; @@ -44,18 +44,20 @@ export function NotifyPanel({ projectId }: NotifyPanelProps) { const eventName = `pg-notify-${projectId}`; let unlisten: (() => void) | null = null; - listen<{ channel: string; payload: string }>(eventName, (event) => { - setNotifications((prev) => [ - ...prev, - { - channel: event.payload.channel, - payload: event.payload.payload, - timestamp: new Date().toISOString(), - }, - ]); - }).then((fn) => { - unlisten = fn; - }); + transport + .listen<{ channel: string; payload: string }>(eventName, (payload) => { + setNotifications((prev) => [ + ...prev, + { + channel: payload.channel, + payload: payload.payload, + timestamp: new Date().toISOString(), + }, + ]); + }) + .then((fn) => { + unlisten = fn; + }); return () => { unlisten?.(); diff --git a/src/components/results-panel/diff-view.tsx b/src/components/results-panel/diff-view.tsx index ed8decc..799ad55 100644 --- a/src/components/results-panel/diff-view.tsx +++ b/src/components/results-panel/diff-view.tsx @@ -1,4 +1,4 @@ -import { invoke } from "@tauri-apps/api/core"; +import { transport } from "@/lib/transport"; import { Diff, Loader2 } from "lucide-react"; import { useRef, useState } from "react"; @@ -44,10 +44,11 @@ export function DiffView({ const pinnedPacked = packRows(pinnedColumns, pinnedRows); const currentPacked = packRows(currentColumns, currentRows); - invoke<[string, string, number]>("compute_diff", { - pinned_packed: pinnedPacked, - current_packed: currentPacked, - }) + transport + .invoke<[string, string, number]>("compute_diff", { + pinned_packed: pinnedPacked, + current_packed: currentPacked, + }) .then(([addedPacked, removedPacked, unchangedCount]) => { const unpackRows = (packed: string): string[][] => { if (!packed) return []; diff --git a/src/components/status-bar.tsx b/src/components/status-bar.tsx index b5fd198..637e3f2 100644 --- a/src/components/status-bar.tsx +++ b/src/components/status-bar.tsx @@ -3,7 +3,7 @@ import { cn } from "@/lib/utils"; import { useHistoryStore } from "@/stores/history-store"; import { useProjectStore } from "@/stores/project-store"; import { useActiveTab } from "@/stores/tab-store"; -import { getSystemResourceUsage, type SystemResourceUsage } from "@/tauri"; +import { getSystemResourceUsage, type SystemResourceUsage } from "@/lib/api"; import { ProjectConnectionStatus } from "@/types"; export function StatusBar() { diff --git a/src/components/terminal-panel.tsx b/src/components/terminal-panel.tsx index 630d77d..464f156 100644 --- a/src/components/terminal-panel.tsx +++ b/src/components/terminal-panel.tsx @@ -1,5 +1,4 @@ -import { invoke } from "@tauri-apps/api/core"; -import { listen } from "@tauri-apps/api/event"; +import { transport } from "@/lib/transport"; import { FitAddon } from "@xterm/addon-fit"; import { Terminal } from "@xterm/xterm"; import { useCallback, useEffect, useRef } from "react"; @@ -95,28 +94,28 @@ export function TerminalPanel({ terminalId }: TerminalPanelProps) { const cols = term.cols; const rows = term.rows; - invoke("terminal_spawn", { id: terminalId, cols, rows }).catch((err) => { + transport.invoke("terminal_spawn", { id: terminalId, cols, rows }).catch((err) => { term.writeln(`\r\nFailed to spawn terminal: ${err}\r\n`); }); } - const dataUnlisten = listen(`terminal-data-${terminalId}`, (event) => { - term.write(event.payload); + const dataUnlisten = transport.listen(`terminal-data-${terminalId}`, (payload) => { + term.write(payload); }); - const exitUnlisten = listen(`terminal-exit-${terminalId}`, () => { + const exitUnlisten = transport.listen(`terminal-exit-${terminalId}`, () => { term.writeln("\r\n[Process exited]"); }); const dataDisposable = term.onData((data) => { - invoke("terminal_write", { id: terminalId, data }).catch(() => {}); + transport.invoke("terminal_write", { id: terminalId, data }).catch(() => {}); }); const resizeObs = new ResizeObserver(() => { fitAddon.fit(); const cols = term.cols; const rows = term.rows; - invoke("terminal_resize", { id: terminalId, cols, rows }).catch(() => {}); + transport.invoke("terminal_resize", { id: terminalId, cols, rows }).catch(() => {}); }); resizeObs.observe(containerRef.current); diff --git a/src/components/top-bar.tsx b/src/components/top-bar.tsx index cee9e18..7bede25 100644 --- a/src/components/top-bar.tsx +++ b/src/components/top-bar.tsx @@ -84,10 +84,12 @@ export function TopBar({
- + {__RSQL_BUILD_TARGET__ !== "web" && ( + + )}