├── .github └── workflows │ ├── release.yml │ ├── test.yml │ └── web.yml ├── .gitignore ├── .vscode └── settings.json ├── BUILDLING.md ├── Cargo.lock ├── Cargo.toml ├── README.md ├── build.rs ├── dist-workspace.toml ├── oranda.json └── src ├── cli.rs ├── files.rs ├── hash.rs ├── log.rs ├── main.rs ├── paths.rs └── progress.rs /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # This file was autogenerated by dist: https://opensource.axo.dev/cargo-dist/ 2 | # 3 | # Copyright 2022-2024, axodotdev 4 | # SPDX-License-Identifier: MIT or Apache-2.0 5 | # 6 | # CI that: 7 | # 8 | # * checks for a Git Tag that looks like a release 9 | # * builds artifacts with dist (archives, installers, hashes) 10 | # * uploads those artifacts to temporary workflow zip 11 | # * on success, uploads the artifacts to a GitHub Release 12 | # 13 | # Note that the GitHub Release will be created with a generated 14 | # title/body based on your changelogs. 15 | 16 | name: Release 17 | permissions: 18 | "contents": "write" 19 | 20 | # This task will run whenever you push a git tag that looks like a version 21 | # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. 22 | # Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where 23 | # PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION 24 | # must be a Cargo-style SemVer Version (must have at least major.minor.patch). 25 | # 26 | # If PACKAGE_NAME is specified, then the announcement will be for that 27 | # package (erroring out if it doesn't have the given version or isn't dist-able). 28 | # 29 | # If PACKAGE_NAME isn't specified, then the announcement will be for all 30 | # (dist-able) packages in the workspace with that version (this mode is 31 | # intended for workspaces with only one dist-able package, or with all dist-able 32 | # packages versioned/released in lockstep). 33 | # 34 | # If you push multiple tags at once, separate instances of this workflow will 35 | # spin up, creating an independent announcement for each one. However, GitHub 36 | # will hard limit this to 3 tags per commit, as it will assume more tags is a 37 | # mistake. 38 | # 39 | # If there's a prerelease-style suffix to the version, then the release(s) 40 | # will be marked as a prerelease. 41 | on: 42 | pull_request: 43 | push: 44 | tags: 45 | - '**[0-9]+.[0-9]+.[0-9]+*' 46 | 47 | jobs: 48 | # Run 'dist plan' (or host) to determine what tasks we need to do 49 | plan: 50 | runs-on: "ubuntu-20.04" 51 | outputs: 52 | val: ${{ steps.plan.outputs.manifest }} 53 | tag: ${{ !github.event.pull_request && github.ref_name || '' }} 54 | tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} 55 | publishing: ${{ !github.event.pull_request }} 56 | env: 57 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 58 | steps: 59 | - uses: actions/checkout@v4 60 | with: 61 | submodules: recursive 62 | - name: Install dist 63 | # we specify bash to get pipefail; it guards against the `curl` command 64 | # failing. otherwise `sh` won't catch that `curl` returned non-0 65 | shell: bash 66 | run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.26.1/cargo-dist-installer.sh | sh" 67 | - name: Cache dist 68 | uses: actions/upload-artifact@v4 69 | with: 70 | name: cargo-dist-cache 71 | path: ~/.cargo/bin/dist 72 | # sure would be cool if github gave us proper conditionals... 73 | # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible 74 | # functionality based on whether this is a pull_request, and whether it's from a fork. 75 | # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* 76 | # but also really annoying to build CI around when it needs secrets to work right.) 77 | - id: plan 78 | run: | 79 | dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json 80 | echo "dist ran successfully" 81 | cat plan-dist-manifest.json 82 | echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" 83 | - name: "Upload dist-manifest.json" 84 | uses: actions/upload-artifact@v4 85 | with: 86 | name: artifacts-plan-dist-manifest 87 | path: plan-dist-manifest.json 88 | 89 | # Build and packages all the platform-specific things 90 | build-local-artifacts: 91 | name: build-local-artifacts (${{ join(matrix.targets, ', ') }}) 92 | # Let the initial task tell us to not run (currently very blunt) 93 | needs: 94 | - plan 95 | if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }} 96 | strategy: 97 | fail-fast: false 98 | # Target platforms/runners are computed by dist in create-release. 99 | # Each member of the matrix has the following arguments: 100 | # 101 | # - runner: the github runner 102 | # - dist-args: cli flags to pass to dist 103 | # - install-dist: expression to run to install dist on the runner 104 | # 105 | # Typically there will be: 106 | # - 1 "global" task that builds universal installers 107 | # - N "local" tasks that build each platform's binaries and platform-specific installers 108 | matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }} 109 | runs-on: ${{ matrix.runner }} 110 | container: ${{ matrix.container && matrix.container.image || null }} 111 | env: 112 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 113 | BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json 114 | steps: 115 | - name: enable windows longpaths 116 | run: | 117 | git config --global core.longpaths true 118 | - uses: actions/checkout@v4 119 | with: 120 | submodules: recursive 121 | - name: Install Rust non-interactively if not already installed 122 | if: ${{ matrix.container }} 123 | run: | 124 | if ! command -v cargo > /dev/null 2>&1; then 125 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 126 | echo "$HOME/.cargo/bin" >> $GITHUB_PATH 127 | fi 128 | - name: Install dist 129 | run: ${{ matrix.install_dist.run }} 130 | # Get the dist-manifest 131 | - name: Fetch local artifacts 132 | uses: actions/download-artifact@v4 133 | with: 134 | pattern: artifacts-* 135 | path: target/distrib/ 136 | merge-multiple: true 137 | - name: Install dependencies 138 | run: | 139 | ${{ matrix.packages_install }} 140 | - name: Build artifacts 141 | run: | 142 | # Actually do builds and make zips and whatnot 143 | dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json 144 | echo "dist ran successfully" 145 | - id: cargo-dist 146 | name: Post-build 147 | # We force bash here just because github makes it really hard to get values up 148 | # to "real" actions without writing to env-vars, and writing to env-vars has 149 | # inconsistent syntax between shell and powershell. 150 | shell: bash 151 | run: | 152 | # Parse out what we just built and upload it to scratch storage 153 | echo "paths<> "$GITHUB_OUTPUT" 154 | dist print-upload-files-from-manifest --manifest dist-manifest.json >> "$GITHUB_OUTPUT" 155 | echo "EOF" >> "$GITHUB_OUTPUT" 156 | 157 | cp dist-manifest.json "$BUILD_MANIFEST_NAME" 158 | - name: "Upload artifacts" 159 | uses: actions/upload-artifact@v4 160 | with: 161 | name: artifacts-build-local-${{ join(matrix.targets, '_') }} 162 | path: | 163 | ${{ steps.cargo-dist.outputs.paths }} 164 | ${{ env.BUILD_MANIFEST_NAME }} 165 | 166 | # Build and package all the platform-agnostic(ish) things 167 | build-global-artifacts: 168 | needs: 169 | - plan 170 | - build-local-artifacts 171 | runs-on: "ubuntu-20.04" 172 | env: 173 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 174 | BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json 175 | steps: 176 | - uses: actions/checkout@v4 177 | with: 178 | submodules: recursive 179 | - name: Install cached dist 180 | uses: actions/download-artifact@v4 181 | with: 182 | name: cargo-dist-cache 183 | path: ~/.cargo/bin/ 184 | - run: chmod +x ~/.cargo/bin/dist 185 | # Get all the local artifacts for the global tasks to use (for e.g. checksums) 186 | - name: Fetch local artifacts 187 | uses: actions/download-artifact@v4 188 | with: 189 | pattern: artifacts-* 190 | path: target/distrib/ 191 | merge-multiple: true 192 | - id: cargo-dist 193 | shell: bash 194 | run: | 195 | dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json 196 | echo "dist ran successfully" 197 | 198 | # Parse out what we just built and upload it to scratch storage 199 | echo "paths<> "$GITHUB_OUTPUT" 200 | jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT" 201 | echo "EOF" >> "$GITHUB_OUTPUT" 202 | 203 | cp dist-manifest.json "$BUILD_MANIFEST_NAME" 204 | - name: "Upload artifacts" 205 | uses: actions/upload-artifact@v4 206 | with: 207 | name: artifacts-build-global 208 | path: | 209 | ${{ steps.cargo-dist.outputs.paths }} 210 | ${{ env.BUILD_MANIFEST_NAME }} 211 | # Determines if we should publish/announce 212 | host: 213 | needs: 214 | - plan 215 | - build-local-artifacts 216 | - build-global-artifacts 217 | # Only run if we're "publishing", and only if local and global didn't fail (skipped is fine) 218 | if: ${{ always() && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} 219 | env: 220 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 221 | runs-on: "ubuntu-20.04" 222 | outputs: 223 | val: ${{ steps.host.outputs.manifest }} 224 | steps: 225 | - uses: actions/checkout@v4 226 | with: 227 | submodules: recursive 228 | - name: Install cached dist 229 | uses: actions/download-artifact@v4 230 | with: 231 | name: cargo-dist-cache 232 | path: ~/.cargo/bin/ 233 | - run: chmod +x ~/.cargo/bin/dist 234 | # Fetch artifacts from scratch-storage 235 | - name: Fetch artifacts 236 | uses: actions/download-artifact@v4 237 | with: 238 | pattern: artifacts-* 239 | path: target/distrib/ 240 | merge-multiple: true 241 | - id: host 242 | shell: bash 243 | run: | 244 | dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json 245 | echo "artifacts uploaded and released successfully" 246 | cat dist-manifest.json 247 | echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" 248 | - name: "Upload dist-manifest.json" 249 | uses: actions/upload-artifact@v4 250 | with: 251 | # Overwrite the previous copy 252 | name: artifacts-dist-manifest 253 | path: dist-manifest.json 254 | # Create a GitHub Release while uploading all files to it 255 | - name: "Download GitHub Artifacts" 256 | uses: actions/download-artifact@v4 257 | with: 258 | pattern: artifacts-* 259 | path: artifacts 260 | merge-multiple: true 261 | - name: Cleanup 262 | run: | 263 | # Remove the granular manifests 264 | rm -f artifacts/*-dist-manifest.json 265 | - name: Create GitHub Release 266 | env: 267 | PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}" 268 | ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" 269 | ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" 270 | RELEASE_COMMIT: "${{ github.sha }}" 271 | run: | 272 | # Write and read notes from a file to avoid quoting breaking things 273 | echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt 274 | 275 | gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* 276 | 277 | announce: 278 | needs: 279 | - plan 280 | - host 281 | # use "always() && ..." to allow us to wait for all publish jobs while 282 | # still allowing individual publish jobs to skip themselves (for prereleases). 283 | # "host" however must run to completion, no skipping allowed! 284 | if: ${{ always() && needs.host.result == 'success' }} 285 | runs-on: "ubuntu-20.04" 286 | env: 287 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 288 | steps: 289 | - uses: actions/checkout@v4 290 | with: 291 | submodules: recursive 292 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | paths: 9 | - ".github/workflows/lint.yml" 10 | - "src/**" 11 | - "Cargo.*" 12 | workflow_dispatch: 13 | 14 | env: 15 | RUST_BACKTRACE: 1 16 | CARGO_PROFILE_DEV_DEBUG: 0 # This would add unnecessary bloat to the target folder, decreasing cache efficiency. 17 | 18 | concurrency: 19 | group: ${{ github.workflow }}-${{ github.ref }} 20 | cancel-in-progress: true 21 | 22 | jobs: 23 | fmt: 24 | runs-on: macos-latest 25 | 26 | steps: 27 | - uses: actions/checkout@v4 28 | 29 | - name: install Rust stable and rustfmt 30 | uses: dtolnay/rust-toolchain@stable 31 | with: 32 | components: rustfmt 33 | 34 | - name: Run cargo fmt 35 | run: cargo fmt --manifest-path Cargo.toml --all -- --check 36 | 37 | test: 38 | runs-on: macos-latest 39 | 40 | steps: 41 | - uses: actions/checkout@v4 42 | 43 | - name: install Rust stable and clippy 44 | uses: dtolnay/rust-toolchain@stable 45 | with: 46 | components: clippy 47 | 48 | - uses: Swatinem/rust-cache@v2 49 | 50 | - name: run test 51 | run: cargo test 52 | 53 | clippy: 54 | runs-on: macos-latest 55 | 56 | steps: 57 | - uses: actions/checkout@v4 58 | 59 | - name: install Rust stable and clippy 60 | uses: dtolnay/rust-toolchain@stable 61 | with: 62 | components: clippy 63 | 64 | - uses: Swatinem/rust-cache@v2 65 | 66 | - name: run Clippy 67 | run: cargo clippy --manifest-path Cargo.toml --all-targets -- -D warnings 68 | -------------------------------------------------------------------------------- /.github/workflows/web.yml: -------------------------------------------------------------------------------- 1 | # Workflow to build your docs with oranda (and mdbook) 2 | # and deploy them to Github Pages 3 | name: Web 4 | 5 | # We're going to push to the gh-pages branch, so we need that permission 6 | permissions: 7 | contents: write 8 | 9 | # What situations do we want to build docs in? 10 | # All of these work independently and can be removed / commented out 11 | # if you don't want oranda/mdbook running in that situation 12 | on: 13 | # Check that a PR didn't break docs! 14 | # 15 | # Note that the "Deploy to Github Pages" step won't run in this mode, 16 | # so this won't have any side-effects. But it will tell you if a PR 17 | # completely broke oranda/mdbook. Sadly we don't provide previews (yet)! 18 | pull_request: 19 | 20 | # Whenever something gets pushed to main, update the docs! 21 | # This is great for getting docs changes live without cutting a full release. 22 | # 23 | # Note that if you're using cargo-dist, this will "race" the Release workflow 24 | # that actually builds the Github Release that oranda tries to read (and 25 | # this will almost certainly complete first). As a result you will publish 26 | # docs for the latest commit but the oranda landing page won't know about 27 | # the latest release. The workflow_run trigger below will properly wait for 28 | # cargo-dist, and so this half-published state will only last for ~10 minutes. 29 | # 30 | # If you only want docs to update with releases, disable this, or change it to 31 | # a "release" branch. You can, of course, also manually trigger a workflow run 32 | # when you want the docs to update. 33 | push: 34 | branches: 35 | - main 36 | 37 | # Whenever a workflow called "Release" completes, update the docs! 38 | # 39 | # If you're using cargo-dist, this is recommended, as it will ensure that 40 | # oranda always sees the latest release right when it's available. Note 41 | # however that Github's UI is wonky when you use workflow_run, and won't 42 | # show this workflow as part of any commit. You have to go to the "actions" 43 | # tab for your repo to see this one running (the gh-pages deploy will also 44 | # only show up there). 45 | workflow_run: 46 | workflows: [ "Release" ] 47 | types: 48 | - completed 49 | 50 | # Alright, let's do it! 51 | jobs: 52 | web: 53 | name: Build and deploy site and docs 54 | runs-on: ubuntu-latest 55 | steps: 56 | # Setup 57 | - uses: actions/checkout@v3 58 | with: 59 | fetch-depth: 0 60 | - uses: dtolnay/rust-toolchain@stable 61 | - uses: swatinem/rust-cache@v2 62 | 63 | # If you use any mdbook plugins, here's the place to install them! 64 | 65 | # Install and run oranda (and mdbook)! 66 | # 67 | # This will write all output to ./public/ (including copying mdbook's output to there). 68 | - name: Install and run oranda 69 | run: | 70 | curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/oranda/releases/latest/download/oranda-installer.sh | sh 71 | oranda build 72 | 73 | # Deploy to our gh-pages branch (creating it if it doesn't exist). 74 | # The "public" dir that oranda made above will become the root dir 75 | # of this branch. 76 | # 77 | # Note that once the gh-pages branch exists, you must 78 | # go into repo's settings > pages and set "deploy from branch: gh-pages". 79 | # The other defaults work fine. 80 | - name: Deploy to Github Pages 81 | uses: JamesIves/github-pages-deploy-action@v4.4.1 82 | # ONLY if we're on main (so no PRs or feature branches allowed!) 83 | if: ${{ github.ref == 'refs/heads/main' }} 84 | with: 85 | branch: gh-pages 86 | # Gotta tell the action where to find oranda's output 87 | folder: public 88 | token: ${{ secrets.GITHUB_TOKEN }} 89 | single-commit: true -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | 3 | # Generated by `oranda generate ci` 4 | public/ -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } -------------------------------------------------------------------------------- /BUILDLING.md: -------------------------------------------------------------------------------- 1 | # Building 2 | 3 | ## Release new version 4 | 5 | ```console 6 | git tag v0.1.0 7 | git push --tags 8 | cargo publish 9 | ``` 10 | 11 | ## Test with dummay file 12 | 13 | ```console 14 | dd if=/dev/zero of=dummy bs=1G count=5 15 | mc dummy copied_dummy --verify 16 | ``` 17 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "anstream" 31 | version = "0.6.18" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 34 | dependencies = [ 35 | "anstyle", 36 | "anstyle-parse", 37 | "anstyle-query", 38 | "anstyle-wincon", 39 | "colorchoice", 40 | "is_terminal_polyfill", 41 | "utf8parse", 42 | ] 43 | 44 | [[package]] 45 | name = "anstyle" 46 | version = "1.0.10" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 49 | 50 | [[package]] 51 | name = "anstyle-parse" 52 | version = "0.2.6" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 55 | dependencies = [ 56 | "utf8parse", 57 | ] 58 | 59 | [[package]] 60 | name = "anstyle-query" 61 | version = "1.1.2" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 64 | dependencies = [ 65 | "windows-sys 0.59.0", 66 | ] 67 | 68 | [[package]] 69 | name = "anstyle-wincon" 70 | version = "3.0.6" 71 | source = "registry+https://github.com/rust-lang/crates.io-index" 72 | checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" 73 | dependencies = [ 74 | "anstyle", 75 | "windows-sys 0.59.0", 76 | ] 77 | 78 | [[package]] 79 | name = "apple-bindgen" 80 | version = "0.2.0" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "38f109ee76f68b4767848cb5dc93bfcc7c425deca849c4c81fa11cdce525e3d2" 83 | dependencies = [ 84 | "apple-sdk", 85 | "bindgen", 86 | "derive_more", 87 | "regex", 88 | "serde", 89 | "thiserror", 90 | "toml", 91 | ] 92 | 93 | [[package]] 94 | name = "apple-sdk" 95 | version = "0.4.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "a04f192a700686ee70008ff4e4eb76fe7d11814ab93b7ee9d48c36b9a9f0bd2a" 98 | dependencies = [ 99 | "plist", 100 | "serde", 101 | "serde_json", 102 | ] 103 | 104 | [[package]] 105 | name = "apple-sys" 106 | version = "0.2.0" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "12b3a1c3342678cd72676d0c1644fde496c1f65ea41f51465f54a89cad3bdf34" 109 | dependencies = [ 110 | "apple-bindgen", 111 | "apple-sdk", 112 | "objc", 113 | ] 114 | 115 | [[package]] 116 | name = "arrayvec" 117 | version = "0.7.6" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" 120 | 121 | [[package]] 122 | name = "assert_fs" 123 | version = "1.1.2" 124 | source = "registry+https://github.com/rust-lang/crates.io-index" 125 | checksum = "7efdb1fdb47602827a342857666feb372712cbc64b414172bd6b167a02927674" 126 | dependencies = [ 127 | "anstyle", 128 | "doc-comment", 129 | "globwalk", 130 | "predicates", 131 | "predicates-core", 132 | "predicates-tree", 133 | "tempfile", 134 | ] 135 | 136 | [[package]] 137 | name = "async-broadcast" 138 | version = "0.5.1" 139 | source = "registry+https://github.com/rust-lang/crates.io-index" 140 | checksum = "7c48ccdbf6ca6b121e0f586cbc0e73ae440e56c67c30fa0873b4e110d9c26d2b" 141 | dependencies = [ 142 | "event-listener 2.5.3", 143 | "futures-core", 144 | ] 145 | 146 | [[package]] 147 | name = "async-channel" 148 | version = "2.3.1" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" 151 | dependencies = [ 152 | "concurrent-queue", 153 | "event-listener-strategy", 154 | "futures-core", 155 | "pin-project-lite", 156 | ] 157 | 158 | [[package]] 159 | name = "async-executor" 160 | version = "1.13.1" 161 | source = "registry+https://github.com/rust-lang/crates.io-index" 162 | checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" 163 | dependencies = [ 164 | "async-task", 165 | "concurrent-queue", 166 | "fastrand 2.3.0", 167 | "futures-lite 2.5.0", 168 | "slab", 169 | ] 170 | 171 | [[package]] 172 | name = "async-fs" 173 | version = "1.6.0" 174 | source = "registry+https://github.com/rust-lang/crates.io-index" 175 | checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" 176 | dependencies = [ 177 | "async-lock 2.8.0", 178 | "autocfg", 179 | "blocking", 180 | "futures-lite 1.13.0", 181 | ] 182 | 183 | [[package]] 184 | name = "async-io" 185 | version = "1.13.0" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" 188 | dependencies = [ 189 | "async-lock 2.8.0", 190 | "autocfg", 191 | "cfg-if", 192 | "concurrent-queue", 193 | "futures-lite 1.13.0", 194 | "log", 195 | "parking", 196 | "polling 2.8.0", 197 | "rustix 0.37.27", 198 | "slab", 199 | "socket2", 200 | "waker-fn", 201 | ] 202 | 203 | [[package]] 204 | name = "async-io" 205 | version = "2.4.0" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" 208 | dependencies = [ 209 | "async-lock 3.4.0", 210 | "cfg-if", 211 | "concurrent-queue", 212 | "futures-io", 213 | "futures-lite 2.5.0", 214 | "parking", 215 | "polling 3.7.4", 216 | "rustix 0.38.42", 217 | "slab", 218 | "tracing", 219 | "windows-sys 0.59.0", 220 | ] 221 | 222 | [[package]] 223 | name = "async-lock" 224 | version = "2.8.0" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" 227 | dependencies = [ 228 | "event-listener 2.5.3", 229 | ] 230 | 231 | [[package]] 232 | name = "async-lock" 233 | version = "3.4.0" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" 236 | dependencies = [ 237 | "event-listener 5.3.1", 238 | "event-listener-strategy", 239 | "pin-project-lite", 240 | ] 241 | 242 | [[package]] 243 | name = "async-process" 244 | version = "1.8.1" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" 247 | dependencies = [ 248 | "async-io 1.13.0", 249 | "async-lock 2.8.0", 250 | "async-signal", 251 | "blocking", 252 | "cfg-if", 253 | "event-listener 3.1.0", 254 | "futures-lite 1.13.0", 255 | "rustix 0.38.42", 256 | "windows-sys 0.48.0", 257 | ] 258 | 259 | [[package]] 260 | name = "async-recursion" 261 | version = "1.1.1" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" 264 | dependencies = [ 265 | "proc-macro2", 266 | "quote", 267 | "syn 2.0.90", 268 | ] 269 | 270 | [[package]] 271 | name = "async-signal" 272 | version = "0.2.10" 273 | source = "registry+https://github.com/rust-lang/crates.io-index" 274 | checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" 275 | dependencies = [ 276 | "async-io 2.4.0", 277 | "async-lock 3.4.0", 278 | "atomic-waker", 279 | "cfg-if", 280 | "futures-core", 281 | "futures-io", 282 | "rustix 0.38.42", 283 | "signal-hook-registry", 284 | "slab", 285 | "windows-sys 0.59.0", 286 | ] 287 | 288 | [[package]] 289 | name = "async-task" 290 | version = "4.7.1" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" 293 | 294 | [[package]] 295 | name = "async-trait" 296 | version = "0.1.83" 297 | source = "registry+https://github.com/rust-lang/crates.io-index" 298 | checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" 299 | dependencies = [ 300 | "proc-macro2", 301 | "quote", 302 | "syn 2.0.90", 303 | ] 304 | 305 | [[package]] 306 | name = "atomic-waker" 307 | version = "1.1.2" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 310 | 311 | [[package]] 312 | name = "autocfg" 313 | version = "1.4.0" 314 | source = "registry+https://github.com/rust-lang/crates.io-index" 315 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 316 | 317 | [[package]] 318 | name = "backtrace" 319 | version = "0.3.74" 320 | source = "registry+https://github.com/rust-lang/crates.io-index" 321 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 322 | dependencies = [ 323 | "addr2line", 324 | "cfg-if", 325 | "libc", 326 | "miniz_oxide", 327 | "object", 328 | "rustc-demangle", 329 | "windows-targets 0.52.6", 330 | ] 331 | 332 | [[package]] 333 | name = "base64" 334 | version = "0.22.1" 335 | source = "registry+https://github.com/rust-lang/crates.io-index" 336 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 337 | 338 | [[package]] 339 | name = "bindgen" 340 | version = "0.63.0" 341 | source = "registry+https://github.com/rust-lang/crates.io-index" 342 | checksum = "36d860121800b2a9a94f9b5604b332d5cffb234ce17609ea479d723dbc9d3885" 343 | dependencies = [ 344 | "bitflags 1.3.2", 345 | "cexpr", 346 | "clang-sys", 347 | "lazy_static", 348 | "lazycell", 349 | "log", 350 | "peeking_take_while", 351 | "proc-macro2", 352 | "quote", 353 | "regex", 354 | "rustc-hash", 355 | "shlex", 356 | "syn 1.0.109", 357 | "which", 358 | ] 359 | 360 | [[package]] 361 | name = "bitflags" 362 | version = "1.3.2" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 365 | 366 | [[package]] 367 | name = "bitflags" 368 | version = "2.6.0" 369 | source = "registry+https://github.com/rust-lang/crates.io-index" 370 | checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 371 | 372 | [[package]] 373 | name = "blake2" 374 | version = "0.10.6" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" 377 | dependencies = [ 378 | "digest", 379 | ] 380 | 381 | [[package]] 382 | name = "block-buffer" 383 | version = "0.10.4" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 386 | dependencies = [ 387 | "generic-array", 388 | ] 389 | 390 | [[package]] 391 | name = "blocking" 392 | version = "1.6.1" 393 | source = "registry+https://github.com/rust-lang/crates.io-index" 394 | checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" 395 | dependencies = [ 396 | "async-channel", 397 | "async-task", 398 | "futures-io", 399 | "futures-lite 2.5.0", 400 | "piper", 401 | ] 402 | 403 | [[package]] 404 | name = "bstr" 405 | version = "1.11.1" 406 | source = "registry+https://github.com/rust-lang/crates.io-index" 407 | checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8" 408 | dependencies = [ 409 | "memchr", 410 | "serde", 411 | ] 412 | 413 | [[package]] 414 | name = "bumpalo" 415 | version = "3.16.0" 416 | source = "registry+https://github.com/rust-lang/crates.io-index" 417 | checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 418 | 419 | [[package]] 420 | name = "byteorder" 421 | version = "1.5.0" 422 | source = "registry+https://github.com/rust-lang/crates.io-index" 423 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 424 | 425 | [[package]] 426 | name = "bytes" 427 | version = "1.9.0" 428 | source = "registry+https://github.com/rust-lang/crates.io-index" 429 | checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" 430 | 431 | [[package]] 432 | name = "cexpr" 433 | version = "0.6.0" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" 436 | dependencies = [ 437 | "nom", 438 | ] 439 | 440 | [[package]] 441 | name = "cfg-if" 442 | version = "1.0.0" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 445 | 446 | [[package]] 447 | name = "clang-sys" 448 | version = "1.8.1" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" 451 | dependencies = [ 452 | "glob", 453 | "libc", 454 | "libloading", 455 | ] 456 | 457 | [[package]] 458 | name = "clap" 459 | version = "4.5.23" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" 462 | dependencies = [ 463 | "clap_builder", 464 | "clap_derive", 465 | ] 466 | 467 | [[package]] 468 | name = "clap_builder" 469 | version = "4.5.23" 470 | source = "registry+https://github.com/rust-lang/crates.io-index" 471 | checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" 472 | dependencies = [ 473 | "anstream", 474 | "anstyle", 475 | "clap_lex", 476 | "strsim 0.11.1", 477 | ] 478 | 479 | [[package]] 480 | name = "clap_derive" 481 | version = "4.5.18" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" 484 | dependencies = [ 485 | "heck", 486 | "proc-macro2", 487 | "quote", 488 | "syn 2.0.90", 489 | ] 490 | 491 | [[package]] 492 | name = "clap_lex" 493 | version = "0.7.4" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" 496 | 497 | [[package]] 498 | name = "colorchoice" 499 | version = "1.0.3" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 502 | 503 | [[package]] 504 | name = "concurrent-queue" 505 | version = "2.5.0" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 508 | dependencies = [ 509 | "crossbeam-utils", 510 | ] 511 | 512 | [[package]] 513 | name = "console" 514 | version = "0.15.8" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" 517 | dependencies = [ 518 | "encode_unicode", 519 | "lazy_static", 520 | "libc", 521 | "unicode-width 0.1.14", 522 | "windows-sys 0.52.0", 523 | ] 524 | 525 | [[package]] 526 | name = "convert_case" 527 | version = "0.4.0" 528 | source = "registry+https://github.com/rust-lang/crates.io-index" 529 | checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 530 | 531 | [[package]] 532 | name = "core-foundation" 533 | version = "0.9.4" 534 | source = "registry+https://github.com/rust-lang/crates.io-index" 535 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 536 | dependencies = [ 537 | "core-foundation-sys", 538 | "libc", 539 | ] 540 | 541 | [[package]] 542 | name = "core-foundation-sys" 543 | version = "0.8.7" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 546 | 547 | [[package]] 548 | name = "cpufeatures" 549 | version = "0.2.16" 550 | source = "registry+https://github.com/rust-lang/crates.io-index" 551 | checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" 552 | dependencies = [ 553 | "libc", 554 | ] 555 | 556 | [[package]] 557 | name = "crossbeam-deque" 558 | version = "0.8.5" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" 561 | dependencies = [ 562 | "crossbeam-epoch", 563 | "crossbeam-utils", 564 | ] 565 | 566 | [[package]] 567 | name = "crossbeam-epoch" 568 | version = "0.9.18" 569 | source = "registry+https://github.com/rust-lang/crates.io-index" 570 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 571 | dependencies = [ 572 | "crossbeam-utils", 573 | ] 574 | 575 | [[package]] 576 | name = "crossbeam-utils" 577 | version = "0.8.20" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 580 | 581 | [[package]] 582 | name = "crypto-common" 583 | version = "0.1.6" 584 | source = "registry+https://github.com/rust-lang/crates.io-index" 585 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 586 | dependencies = [ 587 | "generic-array", 588 | "typenum", 589 | ] 590 | 591 | [[package]] 592 | name = "darling" 593 | version = "0.14.4" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" 596 | dependencies = [ 597 | "darling_core", 598 | "darling_macro", 599 | ] 600 | 601 | [[package]] 602 | name = "darling_core" 603 | version = "0.14.4" 604 | source = "registry+https://github.com/rust-lang/crates.io-index" 605 | checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" 606 | dependencies = [ 607 | "fnv", 608 | "ident_case", 609 | "proc-macro2", 610 | "quote", 611 | "strsim 0.10.0", 612 | "syn 1.0.109", 613 | ] 614 | 615 | [[package]] 616 | name = "darling_macro" 617 | version = "0.14.4" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" 620 | dependencies = [ 621 | "darling_core", 622 | "quote", 623 | "syn 1.0.109", 624 | ] 625 | 626 | [[package]] 627 | name = "data-encoding" 628 | version = "2.6.0" 629 | source = "registry+https://github.com/rust-lang/crates.io-index" 630 | checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" 631 | 632 | [[package]] 633 | name = "deranged" 634 | version = "0.3.11" 635 | source = "registry+https://github.com/rust-lang/crates.io-index" 636 | checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" 637 | dependencies = [ 638 | "powerfmt", 639 | ] 640 | 641 | [[package]] 642 | name = "derivative" 643 | version = "2.2.0" 644 | source = "registry+https://github.com/rust-lang/crates.io-index" 645 | checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" 646 | dependencies = [ 647 | "proc-macro2", 648 | "quote", 649 | "syn 1.0.109", 650 | ] 651 | 652 | [[package]] 653 | name = "derive_builder" 654 | version = "0.13.1" 655 | source = "registry+https://github.com/rust-lang/crates.io-index" 656 | checksum = "8f59169f400d8087f238c5c0c7db6a28af18681717f3b623227d92f397e938c7" 657 | dependencies = [ 658 | "derive_builder_macro", 659 | ] 660 | 661 | [[package]] 662 | name = "derive_builder_core" 663 | version = "0.13.1" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "a4ec317cc3e7ef0928b0ca6e4a634a4d6c001672ae210438cf114a83e56b018d" 666 | dependencies = [ 667 | "darling", 668 | "proc-macro2", 669 | "quote", 670 | "syn 1.0.109", 671 | ] 672 | 673 | [[package]] 674 | name = "derive_builder_macro" 675 | version = "0.13.1" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "870368c3fb35b8031abb378861d4460f573b92238ec2152c927a21f77e3e0127" 678 | dependencies = [ 679 | "derive_builder_core", 680 | "syn 1.0.109", 681 | ] 682 | 683 | [[package]] 684 | name = "derive_more" 685 | version = "0.99.18" 686 | source = "registry+https://github.com/rust-lang/crates.io-index" 687 | checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" 688 | dependencies = [ 689 | "convert_case", 690 | "proc-macro2", 691 | "quote", 692 | "rustc_version", 693 | "syn 2.0.90", 694 | ] 695 | 696 | [[package]] 697 | name = "difflib" 698 | version = "0.4.0" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" 701 | 702 | [[package]] 703 | name = "digest" 704 | version = "0.10.7" 705 | source = "registry+https://github.com/rust-lang/crates.io-index" 706 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 707 | dependencies = [ 708 | "block-buffer", 709 | "crypto-common", 710 | "subtle", 711 | ] 712 | 713 | [[package]] 714 | name = "doc-comment" 715 | version = "0.3.3" 716 | source = "registry+https://github.com/rust-lang/crates.io-index" 717 | checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" 718 | 719 | [[package]] 720 | name = "either" 721 | version = "1.13.0" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 724 | 725 | [[package]] 726 | name = "encode_unicode" 727 | version = "0.3.6" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 730 | 731 | [[package]] 732 | name = "enumflags2" 733 | version = "0.7.10" 734 | source = "registry+https://github.com/rust-lang/crates.io-index" 735 | checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" 736 | dependencies = [ 737 | "enumflags2_derive", 738 | "serde", 739 | ] 740 | 741 | [[package]] 742 | name = "enumflags2_derive" 743 | version = "0.7.10" 744 | source = "registry+https://github.com/rust-lang/crates.io-index" 745 | checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" 746 | dependencies = [ 747 | "proc-macro2", 748 | "quote", 749 | "syn 2.0.90", 750 | ] 751 | 752 | [[package]] 753 | name = "equivalent" 754 | version = "1.0.1" 755 | source = "registry+https://github.com/rust-lang/crates.io-index" 756 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 757 | 758 | [[package]] 759 | name = "errno" 760 | version = "0.3.10" 761 | source = "registry+https://github.com/rust-lang/crates.io-index" 762 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 763 | dependencies = [ 764 | "libc", 765 | "windows-sys 0.59.0", 766 | ] 767 | 768 | [[package]] 769 | name = "event-listener" 770 | version = "2.5.3" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 773 | 774 | [[package]] 775 | name = "event-listener" 776 | version = "3.1.0" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" 779 | dependencies = [ 780 | "concurrent-queue", 781 | "parking", 782 | "pin-project-lite", 783 | ] 784 | 785 | [[package]] 786 | name = "event-listener" 787 | version = "5.3.1" 788 | source = "registry+https://github.com/rust-lang/crates.io-index" 789 | checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" 790 | dependencies = [ 791 | "concurrent-queue", 792 | "parking", 793 | "pin-project-lite", 794 | ] 795 | 796 | [[package]] 797 | name = "event-listener-strategy" 798 | version = "0.5.3" 799 | source = "registry+https://github.com/rust-lang/crates.io-index" 800 | checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" 801 | dependencies = [ 802 | "event-listener 5.3.1", 803 | "pin-project-lite", 804 | ] 805 | 806 | [[package]] 807 | name = "eyre" 808 | version = "0.6.12" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" 811 | dependencies = [ 812 | "indenter", 813 | "once_cell", 814 | ] 815 | 816 | [[package]] 817 | name = "fastrand" 818 | version = "1.9.0" 819 | source = "registry+https://github.com/rust-lang/crates.io-index" 820 | checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" 821 | dependencies = [ 822 | "instant", 823 | ] 824 | 825 | [[package]] 826 | name = "fastrand" 827 | version = "2.3.0" 828 | source = "registry+https://github.com/rust-lang/crates.io-index" 829 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 830 | 831 | [[package]] 832 | name = "file-hashing" 833 | version = "0.1.2" 834 | source = "registry+https://github.com/rust-lang/crates.io-index" 835 | checksum = "77ad8e0086197e90a6582b00067f5dff327e96117a1bbcba58dd3974c982ccea" 836 | dependencies = [ 837 | "assert_fs", 838 | "data-encoding", 839 | "digest", 840 | "rand", 841 | "rayon", 842 | "walkdir", 843 | ] 844 | 845 | [[package]] 846 | name = "fnv" 847 | version = "1.0.7" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 850 | 851 | [[package]] 852 | name = "fs_extra" 853 | version = "1.3.0" 854 | source = "registry+https://github.com/rust-lang/crates.io-index" 855 | checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" 856 | 857 | [[package]] 858 | name = "futures-core" 859 | version = "0.3.31" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 862 | 863 | [[package]] 864 | name = "futures-io" 865 | version = "0.3.31" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 868 | 869 | [[package]] 870 | name = "futures-lite" 871 | version = "1.13.0" 872 | source = "registry+https://github.com/rust-lang/crates.io-index" 873 | checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" 874 | dependencies = [ 875 | "fastrand 1.9.0", 876 | "futures-core", 877 | "futures-io", 878 | "memchr", 879 | "parking", 880 | "pin-project-lite", 881 | "waker-fn", 882 | ] 883 | 884 | [[package]] 885 | name = "futures-lite" 886 | version = "2.5.0" 887 | source = "registry+https://github.com/rust-lang/crates.io-index" 888 | checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1" 889 | dependencies = [ 890 | "fastrand 2.3.0", 891 | "futures-core", 892 | "futures-io", 893 | "parking", 894 | "pin-project-lite", 895 | ] 896 | 897 | [[package]] 898 | name = "futures-sink" 899 | version = "0.3.31" 900 | source = "registry+https://github.com/rust-lang/crates.io-index" 901 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 902 | 903 | [[package]] 904 | name = "futures-task" 905 | version = "0.3.31" 906 | source = "registry+https://github.com/rust-lang/crates.io-index" 907 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 908 | 909 | [[package]] 910 | name = "futures-util" 911 | version = "0.3.31" 912 | source = "registry+https://github.com/rust-lang/crates.io-index" 913 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 914 | dependencies = [ 915 | "futures-core", 916 | "futures-io", 917 | "futures-sink", 918 | "futures-task", 919 | "memchr", 920 | "pin-project-lite", 921 | "pin-utils", 922 | "slab", 923 | ] 924 | 925 | [[package]] 926 | name = "generic-array" 927 | version = "0.14.7" 928 | source = "registry+https://github.com/rust-lang/crates.io-index" 929 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 930 | dependencies = [ 931 | "typenum", 932 | "version_check", 933 | ] 934 | 935 | [[package]] 936 | name = "getrandom" 937 | version = "0.2.15" 938 | source = "registry+https://github.com/rust-lang/crates.io-index" 939 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 940 | dependencies = [ 941 | "cfg-if", 942 | "libc", 943 | "wasi", 944 | ] 945 | 946 | [[package]] 947 | name = "gimli" 948 | version = "0.31.1" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 951 | 952 | [[package]] 953 | name = "glob" 954 | version = "0.3.1" 955 | source = "registry+https://github.com/rust-lang/crates.io-index" 956 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 957 | 958 | [[package]] 959 | name = "globset" 960 | version = "0.4.15" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" 963 | dependencies = [ 964 | "aho-corasick", 965 | "bstr", 966 | "log", 967 | "regex-automata 0.4.9", 968 | "regex-syntax 0.8.5", 969 | ] 970 | 971 | [[package]] 972 | name = "globwalk" 973 | version = "0.9.1" 974 | source = "registry+https://github.com/rust-lang/crates.io-index" 975 | checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" 976 | dependencies = [ 977 | "bitflags 2.6.0", 978 | "ignore", 979 | "walkdir", 980 | ] 981 | 982 | [[package]] 983 | name = "hashbrown" 984 | version = "0.12.3" 985 | source = "registry+https://github.com/rust-lang/crates.io-index" 986 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 987 | 988 | [[package]] 989 | name = "hashbrown" 990 | version = "0.15.2" 991 | source = "registry+https://github.com/rust-lang/crates.io-index" 992 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 993 | 994 | [[package]] 995 | name = "heck" 996 | version = "0.5.0" 997 | source = "registry+https://github.com/rust-lang/crates.io-index" 998 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 999 | 1000 | [[package]] 1001 | name = "hermit-abi" 1002 | version = "0.3.9" 1003 | source = "registry+https://github.com/rust-lang/crates.io-index" 1004 | checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 1005 | 1006 | [[package]] 1007 | name = "hermit-abi" 1008 | version = "0.4.0" 1009 | source = "registry+https://github.com/rust-lang/crates.io-index" 1010 | checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" 1011 | 1012 | [[package]] 1013 | name = "hex" 1014 | version = "0.4.3" 1015 | source = "registry+https://github.com/rust-lang/crates.io-index" 1016 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 1017 | 1018 | [[package]] 1019 | name = "home" 1020 | version = "0.5.9" 1021 | source = "registry+https://github.com/rust-lang/crates.io-index" 1022 | checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" 1023 | dependencies = [ 1024 | "windows-sys 0.52.0", 1025 | ] 1026 | 1027 | [[package]] 1028 | name = "humansize" 1029 | version = "2.1.3" 1030 | source = "registry+https://github.com/rust-lang/crates.io-index" 1031 | checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" 1032 | dependencies = [ 1033 | "libm", 1034 | ] 1035 | 1036 | [[package]] 1037 | name = "ident_case" 1038 | version = "1.0.1" 1039 | source = "registry+https://github.com/rust-lang/crates.io-index" 1040 | checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1041 | 1042 | [[package]] 1043 | name = "ignore" 1044 | version = "0.4.23" 1045 | source = "registry+https://github.com/rust-lang/crates.io-index" 1046 | checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" 1047 | dependencies = [ 1048 | "crossbeam-deque", 1049 | "globset", 1050 | "log", 1051 | "memchr", 1052 | "regex-automata 0.4.9", 1053 | "same-file", 1054 | "walkdir", 1055 | "winapi-util", 1056 | ] 1057 | 1058 | [[package]] 1059 | name = "indenter" 1060 | version = "0.3.3" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" 1063 | 1064 | [[package]] 1065 | name = "indexmap" 1066 | version = "1.9.3" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 1069 | dependencies = [ 1070 | "autocfg", 1071 | "hashbrown 0.12.3", 1072 | ] 1073 | 1074 | [[package]] 1075 | name = "indexmap" 1076 | version = "2.7.0" 1077 | source = "registry+https://github.com/rust-lang/crates.io-index" 1078 | checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" 1079 | dependencies = [ 1080 | "equivalent", 1081 | "hashbrown 0.15.2", 1082 | ] 1083 | 1084 | [[package]] 1085 | name = "indicatif" 1086 | version = "0.17.9" 1087 | source = "registry+https://github.com/rust-lang/crates.io-index" 1088 | checksum = "cbf675b85ed934d3c67b5c5469701eec7db22689d0a2139d856e0925fa28b281" 1089 | dependencies = [ 1090 | "console", 1091 | "number_prefix", 1092 | "portable-atomic", 1093 | "unicode-width 0.2.0", 1094 | "vt100", 1095 | "web-time", 1096 | ] 1097 | 1098 | [[package]] 1099 | name = "instant" 1100 | version = "0.1.13" 1101 | source = "registry+https://github.com/rust-lang/crates.io-index" 1102 | checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" 1103 | dependencies = [ 1104 | "cfg-if", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "io-lifetimes" 1109 | version = "1.0.11" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" 1112 | dependencies = [ 1113 | "hermit-abi 0.3.9", 1114 | "libc", 1115 | "windows-sys 0.48.0", 1116 | ] 1117 | 1118 | [[package]] 1119 | name = "is_terminal_polyfill" 1120 | version = "1.70.1" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 1123 | 1124 | [[package]] 1125 | name = "itoa" 1126 | version = "1.0.14" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" 1129 | 1130 | [[package]] 1131 | name = "js-sys" 1132 | version = "0.3.76" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" 1135 | dependencies = [ 1136 | "once_cell", 1137 | "wasm-bindgen", 1138 | ] 1139 | 1140 | [[package]] 1141 | name = "keepawake" 1142 | version = "0.5.1" 1143 | source = "registry+https://github.com/rust-lang/crates.io-index" 1144 | checksum = "2a1e324a09aa048770b565b4ab2970bb9d1a7dac1038c68c2d243d8f7b6b1c90" 1145 | dependencies = [ 1146 | "apple-sys", 1147 | "cfg-if", 1148 | "core-foundation", 1149 | "derive_builder", 1150 | "thiserror", 1151 | "windows 0.52.0", 1152 | "zbus", 1153 | ] 1154 | 1155 | [[package]] 1156 | name = "lazy_static" 1157 | version = "1.5.0" 1158 | source = "registry+https://github.com/rust-lang/crates.io-index" 1159 | checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 1160 | 1161 | [[package]] 1162 | name = "lazycell" 1163 | version = "1.3.0" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" 1166 | 1167 | [[package]] 1168 | name = "libc" 1169 | version = "0.2.168" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "5aaeb2981e0606ca11d79718f8bb01164f1d6ed75080182d3abf017e6d244b6d" 1172 | 1173 | [[package]] 1174 | name = "libloading" 1175 | version = "0.8.6" 1176 | source = "registry+https://github.com/rust-lang/crates.io-index" 1177 | checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" 1178 | dependencies = [ 1179 | "cfg-if", 1180 | "windows-targets 0.52.6", 1181 | ] 1182 | 1183 | [[package]] 1184 | name = "libm" 1185 | version = "0.2.11" 1186 | source = "registry+https://github.com/rust-lang/crates.io-index" 1187 | checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" 1188 | 1189 | [[package]] 1190 | name = "linux-raw-sys" 1191 | version = "0.3.8" 1192 | source = "registry+https://github.com/rust-lang/crates.io-index" 1193 | checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" 1194 | 1195 | [[package]] 1196 | name = "linux-raw-sys" 1197 | version = "0.4.14" 1198 | source = "registry+https://github.com/rust-lang/crates.io-index" 1199 | checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 1200 | 1201 | [[package]] 1202 | name = "log" 1203 | version = "0.4.22" 1204 | source = "registry+https://github.com/rust-lang/crates.io-index" 1205 | checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 1206 | 1207 | [[package]] 1208 | name = "malloc_buf" 1209 | version = "0.0.6" 1210 | source = "registry+https://github.com/rust-lang/crates.io-index" 1211 | checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" 1212 | dependencies = [ 1213 | "libc", 1214 | ] 1215 | 1216 | [[package]] 1217 | name = "matchers" 1218 | version = "0.1.0" 1219 | source = "registry+https://github.com/rust-lang/crates.io-index" 1220 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 1221 | dependencies = [ 1222 | "regex-automata 0.1.10", 1223 | ] 1224 | 1225 | [[package]] 1226 | name = "mc-cli" 1227 | version = "0.4.3" 1228 | dependencies = [ 1229 | "blake2", 1230 | "clap", 1231 | "console", 1232 | "digest", 1233 | "eyre", 1234 | "file-hashing", 1235 | "fs_extra", 1236 | "hex", 1237 | "humansize", 1238 | "indicatif", 1239 | "keepawake", 1240 | "num_cpus", 1241 | "rand", 1242 | "reflink-copy", 1243 | "sha256", 1244 | "tempfile", 1245 | "tracing", 1246 | "tracing-indicatif", 1247 | "tracing-subscriber", 1248 | ] 1249 | 1250 | [[package]] 1251 | name = "memchr" 1252 | version = "2.7.4" 1253 | source = "registry+https://github.com/rust-lang/crates.io-index" 1254 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1255 | 1256 | [[package]] 1257 | name = "memoffset" 1258 | version = "0.7.1" 1259 | source = "registry+https://github.com/rust-lang/crates.io-index" 1260 | checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" 1261 | dependencies = [ 1262 | "autocfg", 1263 | ] 1264 | 1265 | [[package]] 1266 | name = "memoffset" 1267 | version = "0.9.1" 1268 | source = "registry+https://github.com/rust-lang/crates.io-index" 1269 | checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" 1270 | dependencies = [ 1271 | "autocfg", 1272 | ] 1273 | 1274 | [[package]] 1275 | name = "minimal-lexical" 1276 | version = "0.2.1" 1277 | source = "registry+https://github.com/rust-lang/crates.io-index" 1278 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 1279 | 1280 | [[package]] 1281 | name = "miniz_oxide" 1282 | version = "0.8.0" 1283 | source = "registry+https://github.com/rust-lang/crates.io-index" 1284 | checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" 1285 | dependencies = [ 1286 | "adler2", 1287 | ] 1288 | 1289 | [[package]] 1290 | name = "nix" 1291 | version = "0.26.4" 1292 | source = "registry+https://github.com/rust-lang/crates.io-index" 1293 | checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" 1294 | dependencies = [ 1295 | "bitflags 1.3.2", 1296 | "cfg-if", 1297 | "libc", 1298 | "memoffset 0.7.1", 1299 | ] 1300 | 1301 | [[package]] 1302 | name = "nom" 1303 | version = "7.1.3" 1304 | source = "registry+https://github.com/rust-lang/crates.io-index" 1305 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 1306 | dependencies = [ 1307 | "memchr", 1308 | "minimal-lexical", 1309 | ] 1310 | 1311 | [[package]] 1312 | name = "nom8" 1313 | version = "0.2.0" 1314 | source = "registry+https://github.com/rust-lang/crates.io-index" 1315 | checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" 1316 | dependencies = [ 1317 | "memchr", 1318 | ] 1319 | 1320 | [[package]] 1321 | name = "nu-ansi-term" 1322 | version = "0.46.0" 1323 | source = "registry+https://github.com/rust-lang/crates.io-index" 1324 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 1325 | dependencies = [ 1326 | "overload", 1327 | "winapi", 1328 | ] 1329 | 1330 | [[package]] 1331 | name = "num-conv" 1332 | version = "0.1.0" 1333 | source = "registry+https://github.com/rust-lang/crates.io-index" 1334 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 1335 | 1336 | [[package]] 1337 | name = "num_cpus" 1338 | version = "1.16.0" 1339 | source = "registry+https://github.com/rust-lang/crates.io-index" 1340 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 1341 | dependencies = [ 1342 | "hermit-abi 0.3.9", 1343 | "libc", 1344 | ] 1345 | 1346 | [[package]] 1347 | name = "number_prefix" 1348 | version = "0.4.0" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 1351 | 1352 | [[package]] 1353 | name = "objc" 1354 | version = "0.2.7" 1355 | source = "registry+https://github.com/rust-lang/crates.io-index" 1356 | checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" 1357 | dependencies = [ 1358 | "malloc_buf", 1359 | ] 1360 | 1361 | [[package]] 1362 | name = "object" 1363 | version = "0.36.5" 1364 | source = "registry+https://github.com/rust-lang/crates.io-index" 1365 | checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" 1366 | dependencies = [ 1367 | "memchr", 1368 | ] 1369 | 1370 | [[package]] 1371 | name = "once_cell" 1372 | version = "1.20.2" 1373 | source = "registry+https://github.com/rust-lang/crates.io-index" 1374 | checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" 1375 | 1376 | [[package]] 1377 | name = "ordered-stream" 1378 | version = "0.2.0" 1379 | source = "registry+https://github.com/rust-lang/crates.io-index" 1380 | checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50" 1381 | dependencies = [ 1382 | "futures-core", 1383 | "pin-project-lite", 1384 | ] 1385 | 1386 | [[package]] 1387 | name = "overload" 1388 | version = "0.1.1" 1389 | source = "registry+https://github.com/rust-lang/crates.io-index" 1390 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 1391 | 1392 | [[package]] 1393 | name = "parking" 1394 | version = "2.2.1" 1395 | source = "registry+https://github.com/rust-lang/crates.io-index" 1396 | checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 1397 | 1398 | [[package]] 1399 | name = "peeking_take_while" 1400 | version = "0.1.2" 1401 | source = "registry+https://github.com/rust-lang/crates.io-index" 1402 | checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" 1403 | 1404 | [[package]] 1405 | name = "pin-project-lite" 1406 | version = "0.2.15" 1407 | source = "registry+https://github.com/rust-lang/crates.io-index" 1408 | checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" 1409 | 1410 | [[package]] 1411 | name = "pin-utils" 1412 | version = "0.1.0" 1413 | source = "registry+https://github.com/rust-lang/crates.io-index" 1414 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1415 | 1416 | [[package]] 1417 | name = "piper" 1418 | version = "0.2.4" 1419 | source = "registry+https://github.com/rust-lang/crates.io-index" 1420 | checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" 1421 | dependencies = [ 1422 | "atomic-waker", 1423 | "fastrand 2.3.0", 1424 | "futures-io", 1425 | ] 1426 | 1427 | [[package]] 1428 | name = "plist" 1429 | version = "1.7.0" 1430 | source = "registry+https://github.com/rust-lang/crates.io-index" 1431 | checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016" 1432 | dependencies = [ 1433 | "base64", 1434 | "indexmap 2.7.0", 1435 | "quick-xml", 1436 | "serde", 1437 | "time", 1438 | ] 1439 | 1440 | [[package]] 1441 | name = "polling" 1442 | version = "2.8.0" 1443 | source = "registry+https://github.com/rust-lang/crates.io-index" 1444 | checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" 1445 | dependencies = [ 1446 | "autocfg", 1447 | "bitflags 1.3.2", 1448 | "cfg-if", 1449 | "concurrent-queue", 1450 | "libc", 1451 | "log", 1452 | "pin-project-lite", 1453 | "windows-sys 0.48.0", 1454 | ] 1455 | 1456 | [[package]] 1457 | name = "polling" 1458 | version = "3.7.4" 1459 | source = "registry+https://github.com/rust-lang/crates.io-index" 1460 | checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" 1461 | dependencies = [ 1462 | "cfg-if", 1463 | "concurrent-queue", 1464 | "hermit-abi 0.4.0", 1465 | "pin-project-lite", 1466 | "rustix 0.38.42", 1467 | "tracing", 1468 | "windows-sys 0.59.0", 1469 | ] 1470 | 1471 | [[package]] 1472 | name = "portable-atomic" 1473 | version = "1.10.0" 1474 | source = "registry+https://github.com/rust-lang/crates.io-index" 1475 | checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" 1476 | 1477 | [[package]] 1478 | name = "powerfmt" 1479 | version = "0.2.0" 1480 | source = "registry+https://github.com/rust-lang/crates.io-index" 1481 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 1482 | 1483 | [[package]] 1484 | name = "ppv-lite86" 1485 | version = "0.2.20" 1486 | source = "registry+https://github.com/rust-lang/crates.io-index" 1487 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1488 | dependencies = [ 1489 | "zerocopy", 1490 | ] 1491 | 1492 | [[package]] 1493 | name = "predicates" 1494 | version = "3.1.2" 1495 | source = "registry+https://github.com/rust-lang/crates.io-index" 1496 | checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97" 1497 | dependencies = [ 1498 | "anstyle", 1499 | "difflib", 1500 | "predicates-core", 1501 | ] 1502 | 1503 | [[package]] 1504 | name = "predicates-core" 1505 | version = "1.0.8" 1506 | source = "registry+https://github.com/rust-lang/crates.io-index" 1507 | checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931" 1508 | 1509 | [[package]] 1510 | name = "predicates-tree" 1511 | version = "1.0.11" 1512 | source = "registry+https://github.com/rust-lang/crates.io-index" 1513 | checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13" 1514 | dependencies = [ 1515 | "predicates-core", 1516 | "termtree", 1517 | ] 1518 | 1519 | [[package]] 1520 | name = "proc-macro-crate" 1521 | version = "1.3.1" 1522 | source = "registry+https://github.com/rust-lang/crates.io-index" 1523 | checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" 1524 | dependencies = [ 1525 | "once_cell", 1526 | "toml_edit 0.19.15", 1527 | ] 1528 | 1529 | [[package]] 1530 | name = "proc-macro2" 1531 | version = "1.0.92" 1532 | source = "registry+https://github.com/rust-lang/crates.io-index" 1533 | checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" 1534 | dependencies = [ 1535 | "unicode-ident", 1536 | ] 1537 | 1538 | [[package]] 1539 | name = "quick-xml" 1540 | version = "0.32.0" 1541 | source = "registry+https://github.com/rust-lang/crates.io-index" 1542 | checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" 1543 | dependencies = [ 1544 | "memchr", 1545 | ] 1546 | 1547 | [[package]] 1548 | name = "quote" 1549 | version = "1.0.37" 1550 | source = "registry+https://github.com/rust-lang/crates.io-index" 1551 | checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 1552 | dependencies = [ 1553 | "proc-macro2", 1554 | ] 1555 | 1556 | [[package]] 1557 | name = "rand" 1558 | version = "0.8.5" 1559 | source = "registry+https://github.com/rust-lang/crates.io-index" 1560 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1561 | dependencies = [ 1562 | "libc", 1563 | "rand_chacha", 1564 | "rand_core", 1565 | ] 1566 | 1567 | [[package]] 1568 | name = "rand_chacha" 1569 | version = "0.3.1" 1570 | source = "registry+https://github.com/rust-lang/crates.io-index" 1571 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1572 | dependencies = [ 1573 | "ppv-lite86", 1574 | "rand_core", 1575 | ] 1576 | 1577 | [[package]] 1578 | name = "rand_core" 1579 | version = "0.6.4" 1580 | source = "registry+https://github.com/rust-lang/crates.io-index" 1581 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1582 | dependencies = [ 1583 | "getrandom", 1584 | ] 1585 | 1586 | [[package]] 1587 | name = "rayon" 1588 | version = "1.10.0" 1589 | source = "registry+https://github.com/rust-lang/crates.io-index" 1590 | checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" 1591 | dependencies = [ 1592 | "either", 1593 | "rayon-core", 1594 | ] 1595 | 1596 | [[package]] 1597 | name = "rayon-core" 1598 | version = "1.12.1" 1599 | source = "registry+https://github.com/rust-lang/crates.io-index" 1600 | checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" 1601 | dependencies = [ 1602 | "crossbeam-deque", 1603 | "crossbeam-utils", 1604 | ] 1605 | 1606 | [[package]] 1607 | name = "reflink-copy" 1608 | version = "0.1.20" 1609 | source = "registry+https://github.com/rust-lang/crates.io-index" 1610 | checksum = "17400ed684c3a0615932f00c271ae3eea13e47056a1455821995122348ab6438" 1611 | dependencies = [ 1612 | "cfg-if", 1613 | "rustix 0.38.42", 1614 | "windows 0.58.0", 1615 | ] 1616 | 1617 | [[package]] 1618 | name = "regex" 1619 | version = "1.11.1" 1620 | source = "registry+https://github.com/rust-lang/crates.io-index" 1621 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 1622 | dependencies = [ 1623 | "aho-corasick", 1624 | "memchr", 1625 | "regex-automata 0.4.9", 1626 | "regex-syntax 0.8.5", 1627 | ] 1628 | 1629 | [[package]] 1630 | name = "regex-automata" 1631 | version = "0.1.10" 1632 | source = "registry+https://github.com/rust-lang/crates.io-index" 1633 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 1634 | dependencies = [ 1635 | "regex-syntax 0.6.29", 1636 | ] 1637 | 1638 | [[package]] 1639 | name = "regex-automata" 1640 | version = "0.4.9" 1641 | source = "registry+https://github.com/rust-lang/crates.io-index" 1642 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1643 | dependencies = [ 1644 | "aho-corasick", 1645 | "memchr", 1646 | "regex-syntax 0.8.5", 1647 | ] 1648 | 1649 | [[package]] 1650 | name = "regex-syntax" 1651 | version = "0.6.29" 1652 | source = "registry+https://github.com/rust-lang/crates.io-index" 1653 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 1654 | 1655 | [[package]] 1656 | name = "regex-syntax" 1657 | version = "0.8.5" 1658 | source = "registry+https://github.com/rust-lang/crates.io-index" 1659 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1660 | 1661 | [[package]] 1662 | name = "rustc-demangle" 1663 | version = "0.1.24" 1664 | source = "registry+https://github.com/rust-lang/crates.io-index" 1665 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1666 | 1667 | [[package]] 1668 | name = "rustc-hash" 1669 | version = "1.1.0" 1670 | source = "registry+https://github.com/rust-lang/crates.io-index" 1671 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 1672 | 1673 | [[package]] 1674 | name = "rustc_version" 1675 | version = "0.4.1" 1676 | source = "registry+https://github.com/rust-lang/crates.io-index" 1677 | checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 1678 | dependencies = [ 1679 | "semver", 1680 | ] 1681 | 1682 | [[package]] 1683 | name = "rustix" 1684 | version = "0.37.27" 1685 | source = "registry+https://github.com/rust-lang/crates.io-index" 1686 | checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" 1687 | dependencies = [ 1688 | "bitflags 1.3.2", 1689 | "errno", 1690 | "io-lifetimes", 1691 | "libc", 1692 | "linux-raw-sys 0.3.8", 1693 | "windows-sys 0.48.0", 1694 | ] 1695 | 1696 | [[package]] 1697 | name = "rustix" 1698 | version = "0.38.42" 1699 | source = "registry+https://github.com/rust-lang/crates.io-index" 1700 | checksum = "f93dc38ecbab2eb790ff964bb77fa94faf256fd3e73285fd7ba0903b76bedb85" 1701 | dependencies = [ 1702 | "bitflags 2.6.0", 1703 | "errno", 1704 | "libc", 1705 | "linux-raw-sys 0.4.14", 1706 | "windows-sys 0.59.0", 1707 | ] 1708 | 1709 | [[package]] 1710 | name = "ryu" 1711 | version = "1.0.18" 1712 | source = "registry+https://github.com/rust-lang/crates.io-index" 1713 | checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1714 | 1715 | [[package]] 1716 | name = "same-file" 1717 | version = "1.0.6" 1718 | source = "registry+https://github.com/rust-lang/crates.io-index" 1719 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1720 | dependencies = [ 1721 | "winapi-util", 1722 | ] 1723 | 1724 | [[package]] 1725 | name = "semver" 1726 | version = "1.0.24" 1727 | source = "registry+https://github.com/rust-lang/crates.io-index" 1728 | checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" 1729 | 1730 | [[package]] 1731 | name = "serde" 1732 | version = "1.0.216" 1733 | source = "registry+https://github.com/rust-lang/crates.io-index" 1734 | checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" 1735 | dependencies = [ 1736 | "serde_derive", 1737 | ] 1738 | 1739 | [[package]] 1740 | name = "serde_derive" 1741 | version = "1.0.216" 1742 | source = "registry+https://github.com/rust-lang/crates.io-index" 1743 | checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" 1744 | dependencies = [ 1745 | "proc-macro2", 1746 | "quote", 1747 | "syn 2.0.90", 1748 | ] 1749 | 1750 | [[package]] 1751 | name = "serde_json" 1752 | version = "1.0.133" 1753 | source = "registry+https://github.com/rust-lang/crates.io-index" 1754 | checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" 1755 | dependencies = [ 1756 | "itoa", 1757 | "memchr", 1758 | "ryu", 1759 | "serde", 1760 | ] 1761 | 1762 | [[package]] 1763 | name = "serde_repr" 1764 | version = "0.1.19" 1765 | source = "registry+https://github.com/rust-lang/crates.io-index" 1766 | checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" 1767 | dependencies = [ 1768 | "proc-macro2", 1769 | "quote", 1770 | "syn 2.0.90", 1771 | ] 1772 | 1773 | [[package]] 1774 | name = "serde_spanned" 1775 | version = "0.6.8" 1776 | source = "registry+https://github.com/rust-lang/crates.io-index" 1777 | checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" 1778 | dependencies = [ 1779 | "serde", 1780 | ] 1781 | 1782 | [[package]] 1783 | name = "sha1" 1784 | version = "0.10.6" 1785 | source = "registry+https://github.com/rust-lang/crates.io-index" 1786 | checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 1787 | dependencies = [ 1788 | "cfg-if", 1789 | "cpufeatures", 1790 | "digest", 1791 | ] 1792 | 1793 | [[package]] 1794 | name = "sha2" 1795 | version = "0.10.8" 1796 | source = "registry+https://github.com/rust-lang/crates.io-index" 1797 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1798 | dependencies = [ 1799 | "cfg-if", 1800 | "cpufeatures", 1801 | "digest", 1802 | ] 1803 | 1804 | [[package]] 1805 | name = "sha256" 1806 | version = "1.5.0" 1807 | source = "registry+https://github.com/rust-lang/crates.io-index" 1808 | checksum = "18278f6a914fa3070aa316493f7d2ddfb9ac86ebc06fa3b83bffda487e9065b0" 1809 | dependencies = [ 1810 | "async-trait", 1811 | "bytes", 1812 | "hex", 1813 | "sha2", 1814 | "tokio", 1815 | ] 1816 | 1817 | [[package]] 1818 | name = "sharded-slab" 1819 | version = "0.1.7" 1820 | source = "registry+https://github.com/rust-lang/crates.io-index" 1821 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 1822 | dependencies = [ 1823 | "lazy_static", 1824 | ] 1825 | 1826 | [[package]] 1827 | name = "shlex" 1828 | version = "1.3.0" 1829 | source = "registry+https://github.com/rust-lang/crates.io-index" 1830 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 1831 | 1832 | [[package]] 1833 | name = "signal-hook-registry" 1834 | version = "1.4.2" 1835 | source = "registry+https://github.com/rust-lang/crates.io-index" 1836 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 1837 | dependencies = [ 1838 | "libc", 1839 | ] 1840 | 1841 | [[package]] 1842 | name = "slab" 1843 | version = "0.4.9" 1844 | source = "registry+https://github.com/rust-lang/crates.io-index" 1845 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1846 | dependencies = [ 1847 | "autocfg", 1848 | ] 1849 | 1850 | [[package]] 1851 | name = "smallvec" 1852 | version = "1.13.2" 1853 | source = "registry+https://github.com/rust-lang/crates.io-index" 1854 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1855 | 1856 | [[package]] 1857 | name = "socket2" 1858 | version = "0.4.10" 1859 | source = "registry+https://github.com/rust-lang/crates.io-index" 1860 | checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" 1861 | dependencies = [ 1862 | "libc", 1863 | "winapi", 1864 | ] 1865 | 1866 | [[package]] 1867 | name = "static_assertions" 1868 | version = "1.1.0" 1869 | source = "registry+https://github.com/rust-lang/crates.io-index" 1870 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1871 | 1872 | [[package]] 1873 | name = "strsim" 1874 | version = "0.10.0" 1875 | source = "registry+https://github.com/rust-lang/crates.io-index" 1876 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1877 | 1878 | [[package]] 1879 | name = "strsim" 1880 | version = "0.11.1" 1881 | source = "registry+https://github.com/rust-lang/crates.io-index" 1882 | checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 1883 | 1884 | [[package]] 1885 | name = "subtle" 1886 | version = "2.6.1" 1887 | source = "registry+https://github.com/rust-lang/crates.io-index" 1888 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 1889 | 1890 | [[package]] 1891 | name = "syn" 1892 | version = "1.0.109" 1893 | source = "registry+https://github.com/rust-lang/crates.io-index" 1894 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1895 | dependencies = [ 1896 | "proc-macro2", 1897 | "quote", 1898 | "unicode-ident", 1899 | ] 1900 | 1901 | [[package]] 1902 | name = "syn" 1903 | version = "2.0.90" 1904 | source = "registry+https://github.com/rust-lang/crates.io-index" 1905 | checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31" 1906 | dependencies = [ 1907 | "proc-macro2", 1908 | "quote", 1909 | "unicode-ident", 1910 | ] 1911 | 1912 | [[package]] 1913 | name = "tempfile" 1914 | version = "3.14.0" 1915 | source = "registry+https://github.com/rust-lang/crates.io-index" 1916 | checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" 1917 | dependencies = [ 1918 | "cfg-if", 1919 | "fastrand 2.3.0", 1920 | "once_cell", 1921 | "rustix 0.38.42", 1922 | "windows-sys 0.59.0", 1923 | ] 1924 | 1925 | [[package]] 1926 | name = "termtree" 1927 | version = "0.4.1" 1928 | source = "registry+https://github.com/rust-lang/crates.io-index" 1929 | checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" 1930 | 1931 | [[package]] 1932 | name = "thiserror" 1933 | version = "1.0.69" 1934 | source = "registry+https://github.com/rust-lang/crates.io-index" 1935 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 1936 | dependencies = [ 1937 | "thiserror-impl", 1938 | ] 1939 | 1940 | [[package]] 1941 | name = "thiserror-impl" 1942 | version = "1.0.69" 1943 | source = "registry+https://github.com/rust-lang/crates.io-index" 1944 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 1945 | dependencies = [ 1946 | "proc-macro2", 1947 | "quote", 1948 | "syn 2.0.90", 1949 | ] 1950 | 1951 | [[package]] 1952 | name = "thread_local" 1953 | version = "1.1.8" 1954 | source = "registry+https://github.com/rust-lang/crates.io-index" 1955 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 1956 | dependencies = [ 1957 | "cfg-if", 1958 | "once_cell", 1959 | ] 1960 | 1961 | [[package]] 1962 | name = "time" 1963 | version = "0.3.37" 1964 | source = "registry+https://github.com/rust-lang/crates.io-index" 1965 | checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" 1966 | dependencies = [ 1967 | "deranged", 1968 | "itoa", 1969 | "num-conv", 1970 | "powerfmt", 1971 | "serde", 1972 | "time-core", 1973 | "time-macros", 1974 | ] 1975 | 1976 | [[package]] 1977 | name = "time-core" 1978 | version = "0.1.2" 1979 | source = "registry+https://github.com/rust-lang/crates.io-index" 1980 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 1981 | 1982 | [[package]] 1983 | name = "time-macros" 1984 | version = "0.2.19" 1985 | source = "registry+https://github.com/rust-lang/crates.io-index" 1986 | checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" 1987 | dependencies = [ 1988 | "num-conv", 1989 | "time-core", 1990 | ] 1991 | 1992 | [[package]] 1993 | name = "tokio" 1994 | version = "1.42.0" 1995 | source = "registry+https://github.com/rust-lang/crates.io-index" 1996 | checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" 1997 | dependencies = [ 1998 | "backtrace", 1999 | "bytes", 2000 | "pin-project-lite", 2001 | ] 2002 | 2003 | [[package]] 2004 | name = "toml" 2005 | version = "0.6.0" 2006 | source = "registry+https://github.com/rust-lang/crates.io-index" 2007 | checksum = "4fb9d890e4dc9298b70f740f615f2e05b9db37dce531f6b24fb77ac993f9f217" 2008 | dependencies = [ 2009 | "serde", 2010 | "serde_spanned", 2011 | "toml_datetime 0.5.1", 2012 | "toml_edit 0.18.1", 2013 | ] 2014 | 2015 | [[package]] 2016 | name = "toml_datetime" 2017 | version = "0.5.1" 2018 | source = "registry+https://github.com/rust-lang/crates.io-index" 2019 | checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" 2020 | dependencies = [ 2021 | "serde", 2022 | ] 2023 | 2024 | [[package]] 2025 | name = "toml_datetime" 2026 | version = "0.6.8" 2027 | source = "registry+https://github.com/rust-lang/crates.io-index" 2028 | checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 2029 | 2030 | [[package]] 2031 | name = "toml_edit" 2032 | version = "0.18.1" 2033 | source = "registry+https://github.com/rust-lang/crates.io-index" 2034 | checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b" 2035 | dependencies = [ 2036 | "indexmap 1.9.3", 2037 | "nom8", 2038 | "serde", 2039 | "serde_spanned", 2040 | "toml_datetime 0.5.1", 2041 | ] 2042 | 2043 | [[package]] 2044 | name = "toml_edit" 2045 | version = "0.19.15" 2046 | source = "registry+https://github.com/rust-lang/crates.io-index" 2047 | checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" 2048 | dependencies = [ 2049 | "indexmap 2.7.0", 2050 | "toml_datetime 0.6.8", 2051 | "winnow", 2052 | ] 2053 | 2054 | [[package]] 2055 | name = "tracing" 2056 | version = "0.1.41" 2057 | source = "registry+https://github.com/rust-lang/crates.io-index" 2058 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 2059 | dependencies = [ 2060 | "pin-project-lite", 2061 | "tracing-attributes", 2062 | "tracing-core", 2063 | ] 2064 | 2065 | [[package]] 2066 | name = "tracing-attributes" 2067 | version = "0.1.28" 2068 | source = "registry+https://github.com/rust-lang/crates.io-index" 2069 | checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 2070 | dependencies = [ 2071 | "proc-macro2", 2072 | "quote", 2073 | "syn 2.0.90", 2074 | ] 2075 | 2076 | [[package]] 2077 | name = "tracing-core" 2078 | version = "0.1.33" 2079 | source = "registry+https://github.com/rust-lang/crates.io-index" 2080 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 2081 | dependencies = [ 2082 | "once_cell", 2083 | "valuable", 2084 | ] 2085 | 2086 | [[package]] 2087 | name = "tracing-indicatif" 2088 | version = "0.3.8" 2089 | source = "registry+https://github.com/rust-lang/crates.io-index" 2090 | checksum = "74ba258e9de86447f75edf6455fded8e5242704c6fccffe7bf8d7fb6daef1180" 2091 | dependencies = [ 2092 | "indicatif", 2093 | "tracing", 2094 | "tracing-core", 2095 | "tracing-subscriber", 2096 | ] 2097 | 2098 | [[package]] 2099 | name = "tracing-log" 2100 | version = "0.2.0" 2101 | source = "registry+https://github.com/rust-lang/crates.io-index" 2102 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 2103 | dependencies = [ 2104 | "log", 2105 | "once_cell", 2106 | "tracing-core", 2107 | ] 2108 | 2109 | [[package]] 2110 | name = "tracing-subscriber" 2111 | version = "0.3.19" 2112 | source = "registry+https://github.com/rust-lang/crates.io-index" 2113 | checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" 2114 | dependencies = [ 2115 | "matchers", 2116 | "nu-ansi-term", 2117 | "once_cell", 2118 | "regex", 2119 | "sharded-slab", 2120 | "smallvec", 2121 | "thread_local", 2122 | "tracing", 2123 | "tracing-core", 2124 | "tracing-log", 2125 | ] 2126 | 2127 | [[package]] 2128 | name = "typenum" 2129 | version = "1.17.0" 2130 | source = "registry+https://github.com/rust-lang/crates.io-index" 2131 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 2132 | 2133 | [[package]] 2134 | name = "uds_windows" 2135 | version = "1.1.0" 2136 | source = "registry+https://github.com/rust-lang/crates.io-index" 2137 | checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9" 2138 | dependencies = [ 2139 | "memoffset 0.9.1", 2140 | "tempfile", 2141 | "winapi", 2142 | ] 2143 | 2144 | [[package]] 2145 | name = "unicode-ident" 2146 | version = "1.0.14" 2147 | source = "registry+https://github.com/rust-lang/crates.io-index" 2148 | checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" 2149 | 2150 | [[package]] 2151 | name = "unicode-width" 2152 | version = "0.1.14" 2153 | source = "registry+https://github.com/rust-lang/crates.io-index" 2154 | checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 2155 | 2156 | [[package]] 2157 | name = "unicode-width" 2158 | version = "0.2.0" 2159 | source = "registry+https://github.com/rust-lang/crates.io-index" 2160 | checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" 2161 | 2162 | [[package]] 2163 | name = "utf8parse" 2164 | version = "0.2.2" 2165 | source = "registry+https://github.com/rust-lang/crates.io-index" 2166 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 2167 | 2168 | [[package]] 2169 | name = "valuable" 2170 | version = "0.1.0" 2171 | source = "registry+https://github.com/rust-lang/crates.io-index" 2172 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 2173 | 2174 | [[package]] 2175 | name = "version_check" 2176 | version = "0.9.5" 2177 | source = "registry+https://github.com/rust-lang/crates.io-index" 2178 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2179 | 2180 | [[package]] 2181 | name = "vt100" 2182 | version = "0.15.2" 2183 | source = "registry+https://github.com/rust-lang/crates.io-index" 2184 | checksum = "84cd863bf0db7e392ba3bd04994be3473491b31e66340672af5d11943c6274de" 2185 | dependencies = [ 2186 | "itoa", 2187 | "log", 2188 | "unicode-width 0.1.14", 2189 | "vte", 2190 | ] 2191 | 2192 | [[package]] 2193 | name = "vte" 2194 | version = "0.11.1" 2195 | source = "registry+https://github.com/rust-lang/crates.io-index" 2196 | checksum = "f5022b5fbf9407086c180e9557be968742d839e68346af7792b8592489732197" 2197 | dependencies = [ 2198 | "arrayvec", 2199 | "utf8parse", 2200 | "vte_generate_state_changes", 2201 | ] 2202 | 2203 | [[package]] 2204 | name = "vte_generate_state_changes" 2205 | version = "0.1.2" 2206 | source = "registry+https://github.com/rust-lang/crates.io-index" 2207 | checksum = "2e369bee1b05d510a7b4ed645f5faa90619e05437111783ea5848f28d97d3c2e" 2208 | dependencies = [ 2209 | "proc-macro2", 2210 | "quote", 2211 | ] 2212 | 2213 | [[package]] 2214 | name = "waker-fn" 2215 | version = "1.2.0" 2216 | source = "registry+https://github.com/rust-lang/crates.io-index" 2217 | checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" 2218 | 2219 | [[package]] 2220 | name = "walkdir" 2221 | version = "2.5.0" 2222 | source = "registry+https://github.com/rust-lang/crates.io-index" 2223 | checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" 2224 | dependencies = [ 2225 | "same-file", 2226 | "winapi-util", 2227 | ] 2228 | 2229 | [[package]] 2230 | name = "wasi" 2231 | version = "0.11.0+wasi-snapshot-preview1" 2232 | source = "registry+https://github.com/rust-lang/crates.io-index" 2233 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2234 | 2235 | [[package]] 2236 | name = "wasm-bindgen" 2237 | version = "0.2.99" 2238 | source = "registry+https://github.com/rust-lang/crates.io-index" 2239 | checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" 2240 | dependencies = [ 2241 | "cfg-if", 2242 | "once_cell", 2243 | "wasm-bindgen-macro", 2244 | ] 2245 | 2246 | [[package]] 2247 | name = "wasm-bindgen-backend" 2248 | version = "0.2.99" 2249 | source = "registry+https://github.com/rust-lang/crates.io-index" 2250 | checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" 2251 | dependencies = [ 2252 | "bumpalo", 2253 | "log", 2254 | "proc-macro2", 2255 | "quote", 2256 | "syn 2.0.90", 2257 | "wasm-bindgen-shared", 2258 | ] 2259 | 2260 | [[package]] 2261 | name = "wasm-bindgen-macro" 2262 | version = "0.2.99" 2263 | source = "registry+https://github.com/rust-lang/crates.io-index" 2264 | checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" 2265 | dependencies = [ 2266 | "quote", 2267 | "wasm-bindgen-macro-support", 2268 | ] 2269 | 2270 | [[package]] 2271 | name = "wasm-bindgen-macro-support" 2272 | version = "0.2.99" 2273 | source = "registry+https://github.com/rust-lang/crates.io-index" 2274 | checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" 2275 | dependencies = [ 2276 | "proc-macro2", 2277 | "quote", 2278 | "syn 2.0.90", 2279 | "wasm-bindgen-backend", 2280 | "wasm-bindgen-shared", 2281 | ] 2282 | 2283 | [[package]] 2284 | name = "wasm-bindgen-shared" 2285 | version = "0.2.99" 2286 | source = "registry+https://github.com/rust-lang/crates.io-index" 2287 | checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" 2288 | 2289 | [[package]] 2290 | name = "web-time" 2291 | version = "1.1.0" 2292 | source = "registry+https://github.com/rust-lang/crates.io-index" 2293 | checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" 2294 | dependencies = [ 2295 | "js-sys", 2296 | "wasm-bindgen", 2297 | ] 2298 | 2299 | [[package]] 2300 | name = "which" 2301 | version = "4.4.2" 2302 | source = "registry+https://github.com/rust-lang/crates.io-index" 2303 | checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" 2304 | dependencies = [ 2305 | "either", 2306 | "home", 2307 | "once_cell", 2308 | "rustix 0.38.42", 2309 | ] 2310 | 2311 | [[package]] 2312 | name = "winapi" 2313 | version = "0.3.9" 2314 | source = "registry+https://github.com/rust-lang/crates.io-index" 2315 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2316 | dependencies = [ 2317 | "winapi-i686-pc-windows-gnu", 2318 | "winapi-x86_64-pc-windows-gnu", 2319 | ] 2320 | 2321 | [[package]] 2322 | name = "winapi-i686-pc-windows-gnu" 2323 | version = "0.4.0" 2324 | source = "registry+https://github.com/rust-lang/crates.io-index" 2325 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2326 | 2327 | [[package]] 2328 | name = "winapi-util" 2329 | version = "0.1.9" 2330 | source = "registry+https://github.com/rust-lang/crates.io-index" 2331 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 2332 | dependencies = [ 2333 | "windows-sys 0.59.0", 2334 | ] 2335 | 2336 | [[package]] 2337 | name = "winapi-x86_64-pc-windows-gnu" 2338 | version = "0.4.0" 2339 | source = "registry+https://github.com/rust-lang/crates.io-index" 2340 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2341 | 2342 | [[package]] 2343 | name = "windows" 2344 | version = "0.52.0" 2345 | source = "registry+https://github.com/rust-lang/crates.io-index" 2346 | checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" 2347 | dependencies = [ 2348 | "windows-core 0.52.0", 2349 | "windows-targets 0.52.6", 2350 | ] 2351 | 2352 | [[package]] 2353 | name = "windows" 2354 | version = "0.58.0" 2355 | source = "registry+https://github.com/rust-lang/crates.io-index" 2356 | checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" 2357 | dependencies = [ 2358 | "windows-core 0.58.0", 2359 | "windows-targets 0.52.6", 2360 | ] 2361 | 2362 | [[package]] 2363 | name = "windows-core" 2364 | version = "0.52.0" 2365 | source = "registry+https://github.com/rust-lang/crates.io-index" 2366 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 2367 | dependencies = [ 2368 | "windows-targets 0.52.6", 2369 | ] 2370 | 2371 | [[package]] 2372 | name = "windows-core" 2373 | version = "0.58.0" 2374 | source = "registry+https://github.com/rust-lang/crates.io-index" 2375 | checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" 2376 | dependencies = [ 2377 | "windows-implement", 2378 | "windows-interface", 2379 | "windows-result", 2380 | "windows-strings", 2381 | "windows-targets 0.52.6", 2382 | ] 2383 | 2384 | [[package]] 2385 | name = "windows-implement" 2386 | version = "0.58.0" 2387 | source = "registry+https://github.com/rust-lang/crates.io-index" 2388 | checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" 2389 | dependencies = [ 2390 | "proc-macro2", 2391 | "quote", 2392 | "syn 2.0.90", 2393 | ] 2394 | 2395 | [[package]] 2396 | name = "windows-interface" 2397 | version = "0.58.0" 2398 | source = "registry+https://github.com/rust-lang/crates.io-index" 2399 | checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" 2400 | dependencies = [ 2401 | "proc-macro2", 2402 | "quote", 2403 | "syn 2.0.90", 2404 | ] 2405 | 2406 | [[package]] 2407 | name = "windows-result" 2408 | version = "0.2.0" 2409 | source = "registry+https://github.com/rust-lang/crates.io-index" 2410 | checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" 2411 | dependencies = [ 2412 | "windows-targets 0.52.6", 2413 | ] 2414 | 2415 | [[package]] 2416 | name = "windows-strings" 2417 | version = "0.1.0" 2418 | source = "registry+https://github.com/rust-lang/crates.io-index" 2419 | checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" 2420 | dependencies = [ 2421 | "windows-result", 2422 | "windows-targets 0.52.6", 2423 | ] 2424 | 2425 | [[package]] 2426 | name = "windows-sys" 2427 | version = "0.48.0" 2428 | source = "registry+https://github.com/rust-lang/crates.io-index" 2429 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2430 | dependencies = [ 2431 | "windows-targets 0.48.5", 2432 | ] 2433 | 2434 | [[package]] 2435 | name = "windows-sys" 2436 | version = "0.52.0" 2437 | source = "registry+https://github.com/rust-lang/crates.io-index" 2438 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2439 | dependencies = [ 2440 | "windows-targets 0.52.6", 2441 | ] 2442 | 2443 | [[package]] 2444 | name = "windows-sys" 2445 | version = "0.59.0" 2446 | source = "registry+https://github.com/rust-lang/crates.io-index" 2447 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2448 | dependencies = [ 2449 | "windows-targets 0.52.6", 2450 | ] 2451 | 2452 | [[package]] 2453 | name = "windows-targets" 2454 | version = "0.48.5" 2455 | source = "registry+https://github.com/rust-lang/crates.io-index" 2456 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2457 | dependencies = [ 2458 | "windows_aarch64_gnullvm 0.48.5", 2459 | "windows_aarch64_msvc 0.48.5", 2460 | "windows_i686_gnu 0.48.5", 2461 | "windows_i686_msvc 0.48.5", 2462 | "windows_x86_64_gnu 0.48.5", 2463 | "windows_x86_64_gnullvm 0.48.5", 2464 | "windows_x86_64_msvc 0.48.5", 2465 | ] 2466 | 2467 | [[package]] 2468 | name = "windows-targets" 2469 | version = "0.52.6" 2470 | source = "registry+https://github.com/rust-lang/crates.io-index" 2471 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2472 | dependencies = [ 2473 | "windows_aarch64_gnullvm 0.52.6", 2474 | "windows_aarch64_msvc 0.52.6", 2475 | "windows_i686_gnu 0.52.6", 2476 | "windows_i686_gnullvm", 2477 | "windows_i686_msvc 0.52.6", 2478 | "windows_x86_64_gnu 0.52.6", 2479 | "windows_x86_64_gnullvm 0.52.6", 2480 | "windows_x86_64_msvc 0.52.6", 2481 | ] 2482 | 2483 | [[package]] 2484 | name = "windows_aarch64_gnullvm" 2485 | version = "0.48.5" 2486 | source = "registry+https://github.com/rust-lang/crates.io-index" 2487 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2488 | 2489 | [[package]] 2490 | name = "windows_aarch64_gnullvm" 2491 | version = "0.52.6" 2492 | source = "registry+https://github.com/rust-lang/crates.io-index" 2493 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2494 | 2495 | [[package]] 2496 | name = "windows_aarch64_msvc" 2497 | version = "0.48.5" 2498 | source = "registry+https://github.com/rust-lang/crates.io-index" 2499 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2500 | 2501 | [[package]] 2502 | name = "windows_aarch64_msvc" 2503 | version = "0.52.6" 2504 | source = "registry+https://github.com/rust-lang/crates.io-index" 2505 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2506 | 2507 | [[package]] 2508 | name = "windows_i686_gnu" 2509 | version = "0.48.5" 2510 | source = "registry+https://github.com/rust-lang/crates.io-index" 2511 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2512 | 2513 | [[package]] 2514 | name = "windows_i686_gnu" 2515 | version = "0.52.6" 2516 | source = "registry+https://github.com/rust-lang/crates.io-index" 2517 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2518 | 2519 | [[package]] 2520 | name = "windows_i686_gnullvm" 2521 | version = "0.52.6" 2522 | source = "registry+https://github.com/rust-lang/crates.io-index" 2523 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2524 | 2525 | [[package]] 2526 | name = "windows_i686_msvc" 2527 | version = "0.48.5" 2528 | source = "registry+https://github.com/rust-lang/crates.io-index" 2529 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2530 | 2531 | [[package]] 2532 | name = "windows_i686_msvc" 2533 | version = "0.52.6" 2534 | source = "registry+https://github.com/rust-lang/crates.io-index" 2535 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2536 | 2537 | [[package]] 2538 | name = "windows_x86_64_gnu" 2539 | version = "0.48.5" 2540 | source = "registry+https://github.com/rust-lang/crates.io-index" 2541 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2542 | 2543 | [[package]] 2544 | name = "windows_x86_64_gnu" 2545 | version = "0.52.6" 2546 | source = "registry+https://github.com/rust-lang/crates.io-index" 2547 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2548 | 2549 | [[package]] 2550 | name = "windows_x86_64_gnullvm" 2551 | version = "0.48.5" 2552 | source = "registry+https://github.com/rust-lang/crates.io-index" 2553 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2554 | 2555 | [[package]] 2556 | name = "windows_x86_64_gnullvm" 2557 | version = "0.52.6" 2558 | source = "registry+https://github.com/rust-lang/crates.io-index" 2559 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2560 | 2561 | [[package]] 2562 | name = "windows_x86_64_msvc" 2563 | version = "0.48.5" 2564 | source = "registry+https://github.com/rust-lang/crates.io-index" 2565 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2566 | 2567 | [[package]] 2568 | name = "windows_x86_64_msvc" 2569 | version = "0.52.6" 2570 | source = "registry+https://github.com/rust-lang/crates.io-index" 2571 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2572 | 2573 | [[package]] 2574 | name = "winnow" 2575 | version = "0.5.40" 2576 | source = "registry+https://github.com/rust-lang/crates.io-index" 2577 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 2578 | dependencies = [ 2579 | "memchr", 2580 | ] 2581 | 2582 | [[package]] 2583 | name = "xdg-home" 2584 | version = "1.3.0" 2585 | source = "registry+https://github.com/rust-lang/crates.io-index" 2586 | checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" 2587 | dependencies = [ 2588 | "libc", 2589 | "windows-sys 0.59.0", 2590 | ] 2591 | 2592 | [[package]] 2593 | name = "zbus" 2594 | version = "3.15.2" 2595 | source = "registry+https://github.com/rust-lang/crates.io-index" 2596 | checksum = "675d170b632a6ad49804c8cf2105d7c31eddd3312555cffd4b740e08e97c25e6" 2597 | dependencies = [ 2598 | "async-broadcast", 2599 | "async-executor", 2600 | "async-fs", 2601 | "async-io 1.13.0", 2602 | "async-lock 2.8.0", 2603 | "async-process", 2604 | "async-recursion", 2605 | "async-task", 2606 | "async-trait", 2607 | "blocking", 2608 | "byteorder", 2609 | "derivative", 2610 | "enumflags2", 2611 | "event-listener 2.5.3", 2612 | "futures-core", 2613 | "futures-sink", 2614 | "futures-util", 2615 | "hex", 2616 | "nix", 2617 | "once_cell", 2618 | "ordered-stream", 2619 | "rand", 2620 | "serde", 2621 | "serde_repr", 2622 | "sha1", 2623 | "static_assertions", 2624 | "tracing", 2625 | "uds_windows", 2626 | "winapi", 2627 | "xdg-home", 2628 | "zbus_macros", 2629 | "zbus_names", 2630 | "zvariant", 2631 | ] 2632 | 2633 | [[package]] 2634 | name = "zbus_macros" 2635 | version = "3.15.2" 2636 | source = "registry+https://github.com/rust-lang/crates.io-index" 2637 | checksum = "7131497b0f887e8061b430c530240063d33bf9455fa34438f388a245da69e0a5" 2638 | dependencies = [ 2639 | "proc-macro-crate", 2640 | "proc-macro2", 2641 | "quote", 2642 | "regex", 2643 | "syn 1.0.109", 2644 | "zvariant_utils", 2645 | ] 2646 | 2647 | [[package]] 2648 | name = "zbus_names" 2649 | version = "2.6.1" 2650 | source = "registry+https://github.com/rust-lang/crates.io-index" 2651 | checksum = "437d738d3750bed6ca9b8d423ccc7a8eb284f6b1d6d4e225a0e4e6258d864c8d" 2652 | dependencies = [ 2653 | "serde", 2654 | "static_assertions", 2655 | "zvariant", 2656 | ] 2657 | 2658 | [[package]] 2659 | name = "zerocopy" 2660 | version = "0.7.35" 2661 | source = "registry+https://github.com/rust-lang/crates.io-index" 2662 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2663 | dependencies = [ 2664 | "byteorder", 2665 | "zerocopy-derive", 2666 | ] 2667 | 2668 | [[package]] 2669 | name = "zerocopy-derive" 2670 | version = "0.7.35" 2671 | source = "registry+https://github.com/rust-lang/crates.io-index" 2672 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2673 | dependencies = [ 2674 | "proc-macro2", 2675 | "quote", 2676 | "syn 2.0.90", 2677 | ] 2678 | 2679 | [[package]] 2680 | name = "zvariant" 2681 | version = "3.15.2" 2682 | source = "registry+https://github.com/rust-lang/crates.io-index" 2683 | checksum = "4eef2be88ba09b358d3b58aca6e41cd853631d44787f319a1383ca83424fb2db" 2684 | dependencies = [ 2685 | "byteorder", 2686 | "enumflags2", 2687 | "libc", 2688 | "serde", 2689 | "static_assertions", 2690 | "zvariant_derive", 2691 | ] 2692 | 2693 | [[package]] 2694 | name = "zvariant_derive" 2695 | version = "3.15.2" 2696 | source = "registry+https://github.com/rust-lang/crates.io-index" 2697 | checksum = "37c24dc0bed72f5f90d1f8bb5b07228cbf63b3c6e9f82d82559d4bae666e7ed9" 2698 | dependencies = [ 2699 | "proc-macro-crate", 2700 | "proc-macro2", 2701 | "quote", 2702 | "syn 1.0.109", 2703 | "zvariant_utils", 2704 | ] 2705 | 2706 | [[package]] 2707 | name = "zvariant_utils" 2708 | version = "1.0.1" 2709 | source = "registry+https://github.com/rust-lang/crates.io-index" 2710 | checksum = "7234f0d811589db492d16893e3f21e8e2fd282e6d01b0cddee310322062cc200" 2711 | dependencies = [ 2712 | "proc-macro2", 2713 | "quote", 2714 | "syn 1.0.109", 2715 | ] 2716 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mc-cli" 3 | version = "0.4.3" 4 | edition = "2021" 5 | repository = "https://github.com/thewh1teagle/mc" 6 | description = "Cross platform copy files with progress" 7 | license = "MIT" 8 | 9 | [[bin]] 10 | name = "mc" 11 | path = "src/main.rs" 12 | 13 | [dependencies] 14 | blake2 = "0.10.6" 15 | clap = { version = "4.5.23", features = ["derive"] } 16 | console = "0.15.8" 17 | digest = "0.10.7" 18 | eyre = "0.6.12" 19 | file-hashing = "0.1.2" 20 | fs_extra = "1.3.0" 21 | hex = "0.4.3" 22 | humansize = "2.1.3" 23 | indicatif = "0.17.9" 24 | keepawake = "0.5.1" 25 | num_cpus = "1.16.0" 26 | reflink-copy = "0.1.20" 27 | sha256 = "1.5.0" 28 | tracing = "0.1.41" 29 | tracing-indicatif = "0.3.8" 30 | tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } 31 | 32 | [dev-dependencies] 33 | rand = "0.8.5" 34 | tempfile = "3.14.0" 35 | 36 | # The profile that 'dist' will build with 37 | [profile.dist] 38 | inherits = "release" 39 | lto = "thin" 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mc 2 | 3 | Modern file copying 4 | 5 | ## Features 6 | 7 | - 📂 Copy file or folder 8 | - 🔄 Progress bar 9 | - 🔐 Verify with hash 10 | - 🔗 Hard link files 11 | - 🔗 Symbolic link files 12 | - 🔗 Reflink link files 13 | - ⚡ Faster than Finder or Explorer 14 | - 🛏️ Keep system awake while copying 15 | - 🔄 Auto update with command (`mc-cli-update`) 16 | - 💻 Cross platform: Windows / macOS / Linux 17 | 18 | ## Install 19 | 20 | See installation options in [Mc Website](https://thewh1teagle.github.io/mc/) or in Github [Releases](https://github.com/thewh1teagle/mc/releases/latest) 21 | 22 | ## Usage 23 | 24 | See `--help` 25 | 26 |
27 | 28 | Details 29 | 30 | ```console 31 | Copies files or directories with options for recursion and overwriting. 32 | 33 | Usage: mc [OPTIONS] ... 34 | 35 | Arguments: 36 | ... Source file or directory to copy 37 | Destination file or directory 38 | 39 | Options: 40 | -f, --force Overwrite destination if it exists 41 | --hard-link Hard link file 42 | --symlink Symbol link file 43 | --reflink Ref link file Similar to hardlink except modify one doesn't affect the other 44 | --verify Verify hash of folder / file once copied 45 | --no-progress Disable progress bar 46 | --no-keep-awake Disable keep system awake while copy 47 | --keep-display-awake Keep display awake while copy 48 | -h, --help Print help 49 | ``` 50 | 51 |
52 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | fn commit_hash() -> String { 2 | let output = std::process::Command::new("git") 3 | .args(["rev-parse", "--short", "HEAD"]) 4 | .output() 5 | .unwrap(); 6 | String::from_utf8(output.stdout).unwrap() 7 | } 8 | 9 | fn main() { 10 | let hash = commit_hash(); 11 | println!("cargo:rerun-if-env-changed=COMMIT_HASH"); 12 | println!("cargo:rustc-env=COMMIT_HASH={}", hash); 13 | } 14 | -------------------------------------------------------------------------------- /dist-workspace.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | members = ["cargo:."] 3 | 4 | # Config for 'dist' 5 | [dist] 6 | # The preferred dist version to use in CI (Cargo.toml SemVer syntax) 7 | cargo-dist-version = "0.26.1" 8 | # CI backends to support 9 | ci = "github" 10 | # The installers to generate for each app 11 | installers = ["shell", "powershell"] 12 | # Target platforms to build apps for (Rust target-triple syntax) 13 | targets = [ 14 | "aarch64-apple-darwin", 15 | "aarch64-unknown-linux-gnu", 16 | "x86_64-apple-darwin", 17 | "x86_64-unknown-linux-gnu", 18 | "x86_64-pc-windows-msvc", 19 | ] 20 | # Path that installers should place binaries in 21 | install-path = "CARGO_HOME" 22 | # Whether to install an updater program 23 | install-updater = true 24 | -------------------------------------------------------------------------------- /oranda.json: -------------------------------------------------------------------------------- 1 | { 2 | "build": { 3 | "path_prefix": "mc/" 4 | }, 5 | "styles": { 6 | "theme": "axodark", 7 | "favicon": "https://www.axo.dev/favicon.ico" 8 | }, 9 | "components": { 10 | "changelog": true, 11 | "artifacts": { 12 | "package_managers": { 13 | "additional": { 14 | "binstall": "cargo binstall mc-cli", 15 | "cargo": "cargo install mc-cli", 16 | "git": "cargo install --git https://github.com/thewh1teagle/mc" 17 | } 18 | } 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /src/cli.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | 3 | /// Command-line utility for copying files or directories with optional recursion and overwriting. 4 | #[derive(Parser, Debug)] 5 | #[command(about = "Copies files or directories with options for recursion and overwriting.")] 6 | pub struct Args { 7 | /// Source file or directory to copy 8 | #[arg(required = true)] 9 | pub source: Vec, 10 | 11 | /// Destination file or directory 12 | #[arg(required = true)] 13 | pub destination: String, 14 | 15 | /// Overwrite destination if it exists 16 | #[arg(short, long)] 17 | pub force: bool, 18 | 19 | /// Hard link file 20 | #[arg(long)] 21 | pub hard_link: bool, 22 | 23 | /// Symbol link file 24 | #[arg(long)] 25 | pub symlink: bool, 26 | 27 | /// Ref link file 28 | /// Similar to hardlink except modify one doesn't affect the other 29 | #[arg(long)] 30 | pub reflink: bool, 31 | 32 | /// Verify hash of folder / file once copied 33 | #[arg(long)] 34 | pub verify: bool, 35 | 36 | /// Disable progress bar 37 | #[arg(long)] 38 | pub no_progress: bool, 39 | 40 | /// Disable keep system awake while copy 41 | #[arg(long)] 42 | pub no_keep_awake: bool, 43 | 44 | /// Keep display awake while copy 45 | #[arg(long)] 46 | pub keep_display_awake: bool, 47 | } 48 | -------------------------------------------------------------------------------- /src/files.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | 3 | use eyre::{bail, Result}; 4 | use fs_extra::dir::CopyOptions; 5 | use fs_extra::dir::{self, TransitState}; 6 | use indicatif::ProgressBar; 7 | 8 | use crate::cli::Args; 9 | 10 | pub fn perform_copy_operation( 11 | args: &Args, 12 | source_path: &Path, 13 | destination_path: &Path, 14 | pb: &Option, 15 | ) -> Result<()> { 16 | // Perform the copy operation 17 | if source_path.is_dir() { 18 | copy_dir(args, source_path, destination_path, pb)?; 19 | } else { 20 | copy_file(args, source_path, destination_path, pb)?; 21 | } 22 | if let Some(pb) = pb { 23 | pb.finish(); 24 | } 25 | Ok(()) 26 | } 27 | 28 | pub fn copy_dir>( 29 | args: &Args, 30 | source_path: P, 31 | destination_path: P, 32 | pb: &Option, 33 | ) -> Result<()> { 34 | #[allow(unused)] 35 | let dir_progress_handler = |info: fs_extra::dir::TransitProcess| { 36 | let progress = info.copied_bytes * 100 / info.total_bytes; 37 | if let Some(pb) = &pb { 38 | pb.set_length(info.total_bytes); 39 | pb.set_position(info.copied_bytes); 40 | }; 41 | 42 | // Exists 43 | if info.state == TransitState::Exists && args.force { 44 | return fs_extra::dir::TransitProcessResult::Overwrite; 45 | } 46 | // Access denied 47 | else if info.state == TransitState::NoAccess && args.force { 48 | tracing::warn!("Access denied to file {}. Skipping...", info.file_name); 49 | return fs_extra::dir::TransitProcessResult::Skip; 50 | } 51 | // Normal 52 | if args.force { 53 | fs_extra::dir::TransitProcessResult::Overwrite 54 | } else { 55 | fs_extra::dir::TransitProcessResult::ContinueOrAbort 56 | } 57 | }; 58 | 59 | // Set up copy options 60 | let mut options = CopyOptions::new(); 61 | options.overwrite = args.force; 62 | options.copy_inside = true; 63 | if !args.no_progress { 64 | dir::copy(source_path, destination_path, &options)?; 65 | } else { 66 | dir::copy_with_progress( 67 | source_path, 68 | destination_path, 69 | &options, 70 | dir_progress_handler, 71 | )?; 72 | }; 73 | Ok(()) 74 | } 75 | 76 | pub fn copy_file>( 77 | args: &Args, 78 | source_path: P, 79 | destination_path: P, 80 | pb: &Option, 81 | ) -> Result<()> { 82 | #[allow(unused)] 83 | let file_progress_handler = |info: fs_extra::file::TransitProcess| { 84 | let progress = info.copied_bytes * 100 / info.total_bytes; 85 | if let Some(pb) = &pb { 86 | pb.set_length(info.total_bytes); 87 | pb.set_position(info.copied_bytes); 88 | }; 89 | }; 90 | 91 | if destination_path.as_ref().exists() && !args.force { 92 | bail!( 93 | "Fail already exists at {}", 94 | destination_path.as_ref().display() 95 | ) 96 | } 97 | if args.hard_link { 98 | std::fs::hard_link(source_path, destination_path)?; 99 | } else if args.symlink { 100 | #[cfg(unix)] 101 | std::os::unix::fs::symlink(source_path, destination_path)?; 102 | #[cfg(windows)] 103 | std::os::windows::fs::symlink(source_path, destination_path)?; 104 | } else { 105 | let mut file_options = fs_extra::file::CopyOptions::new(); 106 | file_options.overwrite = args.force; 107 | if args.reflink { 108 | reflink_copy::reflink_or_copy(source_path, destination_path)?; 109 | } else if !args.no_progress { 110 | fs_extra::file::copy_with_progress( 111 | source_path, 112 | destination_path, 113 | &file_options, 114 | file_progress_handler, 115 | )?; 116 | } else { 117 | fs_extra::file::copy(source_path, destination_path, &file_options)?; 118 | } 119 | }; 120 | Ok(()) 121 | } 122 | 123 | #[cfg(test)] 124 | mod tests { 125 | use super::*; 126 | use std::fs::{self, File}; 127 | use std::io::Write; 128 | use tempfile::tempdir; 129 | 130 | // Helper function to create a file with some content 131 | fn create_test_file>(path: P) -> Result<()> { 132 | let mut file = File::create(path)?; 133 | writeln!(file, "Hello, world!")?; 134 | Ok(()) 135 | } 136 | 137 | #[test] 138 | fn test_copy_file_success() { 139 | let temp_dir = tempdir().unwrap(); 140 | let source_file = temp_dir.path().join("source.txt"); 141 | let dest_file = temp_dir.path().join("destination.txt"); 142 | 143 | // Create a source file 144 | create_test_file(&source_file).unwrap(); 145 | 146 | // Prepare arguments 147 | let args = Args { 148 | force: true, 149 | no_progress: true, 150 | symlink: false, 151 | hard_link: false, 152 | destination: dest_file.to_str().unwrap().to_string(), 153 | keep_display_awake: false, 154 | no_keep_awake: true, 155 | source: vec![source_file.to_str().unwrap().to_string()], 156 | verify: false, 157 | reflink: false, 158 | }; 159 | 160 | // Perform the copy operation 161 | perform_copy_operation( 162 | &args, 163 | &source_file, 164 | &dest_file, 165 | &None, // No progress bar 166 | ) 167 | .unwrap(); 168 | 169 | // Verify the destination file exists and has the same content 170 | assert!(dest_file.exists()); 171 | let content = fs::read_to_string(dest_file).unwrap(); 172 | assert_eq!(content, "Hello, world!\n"); 173 | } 174 | 175 | #[test] 176 | fn test_copy_directory_success() { 177 | let temp_dir = tempdir().unwrap(); 178 | let source_dir = temp_dir.path().join("source"); 179 | let dest_dir = temp_dir.path().join("destination"); 180 | 181 | // Create a source directory with a file 182 | fs::create_dir_all(&source_dir).unwrap(); 183 | let source_file = source_dir.join("file.txt"); 184 | create_test_file(&source_file).unwrap(); 185 | 186 | // Prepare arguments 187 | let args = Args { 188 | force: true, 189 | no_progress: true, 190 | symlink: false, 191 | hard_link: false, 192 | destination: dest_dir.to_str().unwrap().to_string(), 193 | keep_display_awake: false, 194 | no_keep_awake: true, 195 | source: vec![source_dir.to_str().unwrap().to_string()], 196 | verify: false, 197 | reflink: false, 198 | }; 199 | 200 | // Perform the copy operation 201 | perform_copy_operation( 202 | &args, 203 | &source_dir, 204 | &dest_dir, 205 | &None, // No progress bar 206 | ) 207 | .unwrap(); 208 | 209 | // Verify the destination directory and file exist 210 | assert!(dest_dir.exists()); 211 | assert!(dest_dir.join("file.txt").exists()); 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /src/hash.rs: -------------------------------------------------------------------------------- 1 | use blake2::{Blake2s256, Digest}; 2 | use eyre::{bail, Result}; 3 | use std::path::Path; 4 | 5 | pub fn verify_hash(source_path: &Path, destination_path: &Path) -> Result<()> { 6 | let mut source_hash = Blake2s256::new(); 7 | let mut dst_hash = Blake2s256::new(); 8 | 9 | if source_path.is_dir() { 10 | file_hashing::get_hash_folder(source_path, &mut source_hash, num_cpus::get(), |_| {})?; 11 | file_hashing::get_hash_folder(destination_path, &mut dst_hash, num_cpus::get(), |_| {})?; 12 | } else { 13 | file_hashing::get_hash_file(source_path, &mut source_hash)?; 14 | file_hashing::get_hash_file(destination_path, &mut dst_hash)?; 15 | } 16 | 17 | let source_hash = source_hash.finalize(); 18 | let dst_hash = dst_hash.finalize(); 19 | let source_hash = hex::encode(source_hash); 20 | let dst_hash = hex::encode(dst_hash); 21 | 22 | tracing::info!("Source hash: {}", source_hash); 23 | tracing::info!("Destination hash: {}", dst_hash); 24 | 25 | if source_hash == dst_hash { 26 | Ok(()) 27 | } else { 28 | bail!("Hashes do not match") 29 | } 30 | } 31 | 32 | #[cfg(test)] 33 | mod tests { 34 | use super::*; 35 | use std::io::Write; 36 | use tempfile::{NamedTempFile, TempDir}; 37 | 38 | #[test] 39 | fn test_verify_hash_file_identical() { 40 | // Create temporary files for source and destination 41 | let temp_dir = TempDir::new().unwrap(); 42 | let mut source_file = NamedTempFile::new_in(temp_dir.path()).unwrap(); 43 | let mut destination_file = NamedTempFile::new_in(temp_dir.path()).unwrap(); 44 | 45 | // Write identical content to both files 46 | let content = b"Hello, world!"; 47 | source_file.write_all(content).unwrap(); 48 | destination_file.write_all(content).unwrap(); 49 | 50 | // Ensure the files are correctly created 51 | let source_path = source_file.path(); 52 | let destination_path = destination_file.path(); 53 | 54 | // Call verify_hash to check that the hashes are identical 55 | let result = verify_hash(source_path, destination_path); 56 | assert!( 57 | result.is_ok(), 58 | "Hashes should be identical for the same content." 59 | ); 60 | } 61 | 62 | #[test] 63 | fn test_verify_hash_file_different() { 64 | // Create temporary files for source and destination 65 | let temp_dir = TempDir::new().unwrap(); 66 | let mut source_file = NamedTempFile::new_in(temp_dir.path()).unwrap(); 67 | let mut destination_file = NamedTempFile::new_in(temp_dir.path()).unwrap(); 68 | 69 | // Write different content to both files 70 | let content_1 = b"Hello, world!"; 71 | let content_2 = b"Goodbye, world!"; 72 | source_file.write_all(content_1).unwrap(); 73 | destination_file.write_all(content_2).unwrap(); 74 | 75 | // Ensure the files are correctly created 76 | let source_path = source_file.path(); 77 | let destination_path = destination_file.path(); 78 | 79 | // Call verify_hash to check that the hashes are different 80 | let result = verify_hash(source_path, destination_path); 81 | assert!( 82 | result.is_err(), 83 | "Hashes should be different for different content." 84 | ); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/log.rs: -------------------------------------------------------------------------------- 1 | use tracing_indicatif::IndicatifLayer; 2 | use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; 3 | 4 | pub fn init_logger() { 5 | let default_log_directive = format!("{}=INFO", env!("CARGO_PKG_NAME")); 6 | let rust_log = std::env::var("RUST_LOG").unwrap_or(default_log_directive); 7 | let indicatif_layer: IndicatifLayer = 8 | IndicatifLayer::new(); 9 | 10 | tracing_subscriber::registry() 11 | .with(tracing_subscriber::fmt::layer().with_writer(indicatif_layer.get_stderr_writer())) 12 | .with(EnvFilter::new(rust_log)) 13 | .init(); 14 | } 15 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | use console::style; 3 | use eyre::{ContextCompat, Result}; 4 | use std::{path::Path, time::Instant}; 5 | mod cli; 6 | use cli::Args; 7 | mod files; 8 | mod hash; 9 | mod log; 10 | mod paths; 11 | mod progress; 12 | 13 | fn main() -> Result<()> { 14 | let start_time = Instant::now(); 15 | log::init_logger(); 16 | 17 | // Version 18 | let args: Vec = std::env::args().collect(); 19 | if args.contains(&"-v".to_string()) || args.contains(&"--version".to_string()) { 20 | let commit_hash = env!("COMMIT_HASH"); 21 | 22 | println!( 23 | "{} {}{}", 24 | env!("CARGO_PKG_NAME"), 25 | env!("CARGO_PKG_VERSION"), 26 | if commit_hash.is_empty() { 27 | "".to_string() 28 | } else { 29 | format!(" ({})", commit_hash).to_string() 30 | } 31 | ); 32 | return Ok(()); 33 | } 34 | 35 | let args = Args::parse(); 36 | 37 | if !args.no_keep_awake { 38 | // Stopped when program ends 39 | keepawake::Builder::default() 40 | .app_name(env!("CARGO_PKG_NAME")) 41 | .display(args.keep_display_awake) 42 | .idle(true); 43 | } 44 | 45 | let destination_path = paths::ensure_valid_paths(&args)?; 46 | 47 | for source in &args.source { 48 | let source_path = Path::new(&source); 49 | 50 | let mut current_destination = destination_path.clone(); 51 | 52 | if source_path.is_file() && destination_path.is_dir() { 53 | current_destination = 54 | current_destination.join(source_path.file_name().context("filename")?); 55 | } 56 | let destination_path = current_destination.as_path(); 57 | tracing::debug!("destination: {}", destination_path.display()); 58 | 59 | let pb = progress::create_progress_bar()?; 60 | 61 | // Perform the copy operation 62 | println!( 63 | "{}", 64 | style(format!( 65 | "Copy {} to {}", 66 | source_path.display(), 67 | destination_path.display() 68 | )) 69 | .bold() 70 | .dim(), 71 | ); 72 | files::perform_copy_operation(&args, source_path, destination_path, &pb)?; 73 | 74 | println!( 75 | "{}", 76 | style(format!( 77 | "Copy completed successfully in {:.2?}.", 78 | start_time.elapsed() 79 | )) 80 | .bold() 81 | .green() 82 | ); 83 | 84 | if args.verify { 85 | tracing::info!("Computing hash..."); 86 | hash::verify_hash(source_path, destination_path)?; 87 | } 88 | } 89 | Ok(()) 90 | } 91 | -------------------------------------------------------------------------------- /src/paths.rs: -------------------------------------------------------------------------------- 1 | use eyre::{bail, Result}; 2 | use std::{ 3 | fs, 4 | path::{Path, PathBuf}, 5 | }; 6 | 7 | use crate::cli::Args; 8 | 9 | pub fn ensure_valid_paths(args: &Args) -> Result { 10 | for source in &args.source { 11 | if !Path::new(&source).exists() { 12 | bail!("No such source file {}.", source); 13 | } 14 | } 15 | 16 | if args.source.len() > 1 && !Path::new(&args.destination).exists() { 17 | if args.force { 18 | fs::create_dir_all(&args.destination)?; 19 | } else { 20 | bail!("No such directory {}.", args.destination); 21 | } 22 | } 23 | 24 | let destination_path = if Path::new(&args.destination).exists() { 25 | PathBuf::from(&args.destination).canonicalize()? 26 | } else { 27 | if args.destination.ends_with('/') && args.force { 28 | fs::create_dir_all(&args.destination)?; 29 | } 30 | PathBuf::from(&args.destination) 31 | }; 32 | 33 | if let Some(parent) = Path::new(&args.destination).parent() { 34 | if args.force && !parent.exists() { 35 | fs::create_dir_all(parent)?; 36 | } 37 | } 38 | 39 | Ok(destination_path) 40 | } 41 | 42 | #[cfg(test)] 43 | mod tests { 44 | use super::*; 45 | use rand::Rng; 46 | use tempfile::TempDir; 47 | 48 | #[test] 49 | fn test_ensure_valid_paths_valid() { 50 | // Setup a valid directory structure using TempDir 51 | let temp_dir = TempDir::new().unwrap(); 52 | let temp_file = temp_dir.path().join("test.txt"); 53 | std::fs::write(&temp_file, b"").unwrap(); 54 | 55 | // Create a dummy Args struct 56 | let args = Args { 57 | source: vec![temp_file.to_str().unwrap().to_string()], 58 | destination: temp_dir.path().to_str().unwrap().to_string(), 59 | force: false, 60 | no_progress: false, 61 | verify: false, 62 | symlink: false, 63 | hard_link: false, 64 | keep_display_awake: false, 65 | no_keep_awake: true, 66 | reflink: false, 67 | }; 68 | 69 | let result = ensure_valid_paths(&args); 70 | println!("Result: {:?}", result); 71 | assert!(result.is_ok()); 72 | } 73 | 74 | #[test] 75 | fn test_ensure_valid_paths_nonexistent_source() { 76 | let args = Args { 77 | source: vec!["/non/existent/file.txt".to_string()], 78 | destination: "/tmp".to_string(), 79 | force: true, 80 | no_progress: false, 81 | verify: false, 82 | symlink: false, 83 | hard_link: false, 84 | keep_display_awake: false, 85 | no_keep_awake: true, 86 | reflink: false, 87 | }; 88 | 89 | let result = ensure_valid_paths(&args); 90 | println!("Result: {:?}", result); 91 | assert!(result.is_err()); 92 | } 93 | 94 | #[test] 95 | fn test_ensure_valid_paths_create_destination() { 96 | // Create a temporary directory for the source file 97 | let temp_dir = TempDir::new().unwrap(); 98 | 99 | // Create a temporary source file 100 | let temp_file = temp_dir.path().join("source_file.txt"); 101 | std::fs::write(&temp_file, "dummy content").unwrap(); // Create a dummy file 102 | 103 | // Create a temporary directory for the destination 104 | let random_dir_name: String = rand::thread_rng() 105 | .sample_iter(&rand::distributions::Alphanumeric) 106 | .take(10) 107 | .map(char::from) // 10-character random string 108 | .collect(); 109 | let destination_dir = temp_dir.path().join(random_dir_name); 110 | let destination_dir = destination_dir.to_str().unwrap().to_string() + "/"; 111 | 112 | // Create the Args struct with the updated paths 113 | let args = Args { 114 | source: vec![temp_file.to_str().unwrap().to_string()], 115 | destination: destination_dir.clone(), 116 | force: true, 117 | no_progress: false, 118 | verify: false, 119 | symlink: false, 120 | hard_link: false, 121 | keep_display_awake: false, 122 | no_keep_awake: true, 123 | reflink: false, 124 | }; 125 | 126 | // Ensure that the destination directory doesn't exist before the test 127 | let destination_dir = Path::new(&destination_dir); 128 | assert!( 129 | !&destination_dir.exists(), 130 | "Destination directory should not exist before test." 131 | ); 132 | 133 | // Run the function and check the result 134 | let result = ensure_valid_paths(&args); 135 | println!("Result: {:?}", result); 136 | 137 | // Ensure the result is Ok and the destination directory was created 138 | assert!(result.is_ok()); 139 | assert!( 140 | destination_dir.exists(), 141 | "Destination directory should be created at {}.", 142 | destination_dir.display() 143 | ); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/progress.rs: -------------------------------------------------------------------------------- 1 | use eyre::Result; 2 | use indicatif::{ProgressBar, ProgressState, ProgressStyle}; 3 | use std::fmt::Write; 4 | 5 | pub fn create_progress_bar() -> Result> { 6 | Ok(Some( 7 | ProgressBar::new(0) 8 | .with_style( 9 | ProgressStyle::with_template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} ({eta_precise})") 10 | ? 11 | .with_key("eta", |state: &ProgressState, w: &mut dyn Write| { 12 | write!(w, "{:.1}s", state.eta().as_secs_f64()).unwrap() 13 | }) 14 | .progress_chars("#>-") 15 | ) 16 | )) 17 | } 18 | --------------------------------------------------------------------------------