diff --git a/.envrc b/.envrc index 8392d15..adbca78 100644 --- a/.envrc +++ b/.envrc @@ -1 +1,3 @@ -use flake \ No newline at end of file +CARGO_TERM_COLOR=always +RUST_BACKTRACE=full +RUST_LOG="contained=debug,info" \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c6d5a32..58dab94 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,9 +1,7 @@ version: 2 updates: - package-ecosystem: docker - directories: - - . - - /.docker + directories: [/, /.docker] schedule: interval: monthly - package-ecosystem: github-actions @@ -11,10 +9,10 @@ updates: schedule: interval: monthly - package-ecosystem: cargo + schedule: + interval: monthly directories: - /contained - /core - /derive - /macros - schedule: - interval: monthly \ No newline at end of file diff --git a/.github/workflows/cargo-bench.yml b/.github/workflows/cargo-bench.yml index d562991..a7b7389 100644 --- a/.github/workflows/cargo-bench.yml +++ b/.github/workflows/cargo-bench.yml @@ -10,7 +10,7 @@ env: on: repository_dispatch: - types: [ cargo-bench, benchmark ] + types: [cargo-bench, benchmark] workflow_dispatch: permissions: @@ -27,24 +27,20 @@ jobs: strategy: fail-fast: false matrix: - target: [ x86_64-unknown-linux-gnu ] + target: [x86_64-unknown-linux-gnu] steps: - - - name: Checkout - uses: actions/checkout@v5 - - - name: Setup Rust + - name: Checkout + uses: actions/checkout@v6 + - name: Setup Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: cache-key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} target: ${{ matrix.target }} - - - name: Benchmark the workspace + - name: Benchmark the workspace run: cargo bench --locked --verbose --workspace --target ${{ matrix.target }} --features full -- - - - name: Upload the benchmarks + - name: Upload the benchmarks id: artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: Benchmark Report (${{ github.event.repository.name }}) if-no-files-found: error diff --git a/.github/workflows/cargo-clippy.yml b/.github/workflows/cargo-clippy.yml index 831d16c..facdb17 100644 --- a/.github/workflows/cargo-clippy.yml +++ b/.github/workflows/cargo-clippy.yml @@ -6,17 +6,15 @@ concurrency: on: pull_request: - branches: [ main, master, $default-branch ] - types: [ opened, synchronize, reopened ] + branches: [main, master] + types: [opened, reopened] push: - branches: [ main, master, $default-branch ] - tags: - - v*.*.* - - "*-nightly" + branches: [main, master] + tags: [latest, v*.*.*, "*-nightly"] release: - types: [ created, edited ] + types: [created, edited] repository_dispatch: - types: [ clippy, cargo-clippy ] + types: [clippy, cargo-clippy] workflow_dispatch: jobs: @@ -28,30 +26,24 @@ jobs: security-events: write statuses: write steps: - - - name: Checkout - uses: actions/checkout@v5 - - - name: Setup Rust + - name: Checkout + uses: actions/checkout@v6 + - name: Setup Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: cache-key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} components: clippy, rustfmt toolchain: nightly override: true - - - name: Setup the for sarif output + - name: Setup the for sarif output run: cargo install clippy-sarif sarif-fmt - - - name: Run Clippy - run: - cargo clippy + - name: Run Clippy + run: cargo clippy --all-features --workspace --message-format=json | clippy-sarif | tee rust-clippy-results.sarif | sarif-fmt - - - name: Upload analysis - uses: github/codeql-action/upload-sarif@v3 + - name: Upload analysis + uses: github/codeql-action/upload-sarif@v4 continue-on-error: true with: sarif_file: rust-clippy-results.sarif diff --git a/.github/workflows/cargo-publish.yml b/.github/workflows/cargo-publish.yml index bcff4de..743a061 100644 --- a/.github/workflows/cargo-publish.yml +++ b/.github/workflows/cargo-publish.yml @@ -6,12 +6,12 @@ concurrency: on: repository_dispatch: - types: [ deploy, publish, cargo-publish, crates-io ] + types: [deploy, publish, cargo-publish, crates-io] workflow_dispatch: inputs: publish: default: true - description: 'Publish the crate(s) to crates.io?' + description: "Publish the crate(s) to crates.io?" type: boolean jobs: @@ -24,7 +24,7 @@ jobs: environment: name: crates-io outputs: - url: ${{ steps.results.outputs.url }} + url: ${{ steps.results.outputs.url }} permissions: contents: read deployments: write @@ -39,20 +39,15 @@ jobs: - contained-macros - contained steps: - - - name: Checkout - uses: actions/checkout@v5 - - - name: Setup Rust + - name: Checkout + uses: actions/checkout@v6 + - name: Setup Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: cache-key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - - - name: Publish (${{ matrix.package }}) + - name: Publish (${{ matrix.package }}) id: publish run: cargo publish --locked --package ${{ matrix.package }} - - - name: Set output(s) + - name: Set output(s) id: results - run: - echo "url=https://crates.io/crates/${{ matrix.package }}" >> "$GITHUB_OUTPUT" + run: echo "url=https://crates.io/crates/${{ matrix.package }}" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/cleanup.yml b/.github/workflows/cleanup.yml index b57dc5e..6f26f81 100644 --- a/.github/workflows/cleanup.yml +++ b/.github/workflows/cleanup.yml @@ -1,31 +1,39 @@ -name: cleanup - -on: - pull_request: - types: - - closed - -jobs: - cache_cleanup: - runs-on: ubuntu-latest - permissions: - actions: write - steps: - - - name: Cleanup - run: | - echo "Fetching list of cache keys" - cacheKeysForPR=$(gh cache list --ref $BRANCH --limit 100 --json id --jq '.[].id') - - ## Setting this to not fail the workflow while deleting cache keys. - set +e - echo "Deleting caches..." - for cacheKey in $cacheKeysForPR - do - gh cache delete $cacheKey - done - echo "Done" - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GH_REPO: ${{ github.repository }} - BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge +name: cleanup + +on: + pull_request: + types: [closed] + +jobs: + cleanup: + name: Cleanup PR Cache(s) + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_REPO: ${{ github.repository }} + BRANCH: refs/pull/${{ github.event.pull_request.number }}/merge + permissions: + actions: write + outputs: + status: dirty + steps: + - uses: actions/checkout@v6 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + - name: Cleanup + run: | + echo "Fetching list of cache keys" + cacheKeysForPR=$(gh cache list --ref $BRANCH --limit 100 --json id --jq '.[].id') + + ## Setting this to not fail the workflow while deleting cache keys. + set +e + echo "Deleting caches..." + for cacheKey in $cacheKeysForPR + do + gh cache delete $cacheKey + done + echo "Done" + - name: Set output(s) + run: | + echo "status=cleaned" >> "$GITHUB_OUTPUT" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 27d890f..f4f7394 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,19 +2,19 @@ name: release on: release: - types: [ published ] + types: [published] repository_dispatch: - types: [ release ] + types: [release] workflow_dispatch: inputs: draft: default: false - description: 'Create a draft release' + description: "Create a draft release" required: true type: boolean prerelease: default: false - description: 'Create a prerelease' + description: "Create a prerelease" required: true type: boolean @@ -26,16 +26,14 @@ jobs: publish: runs-on: ubuntu-latest steps: - - - name: Checkout - uses: actions/checkout@v5 + - name: Checkout + uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ github.ref }} repository: ${{ github.repository }} - - - name: Publish to crates.io - uses: peter-evans/repository-dispatch@v3 + - name: Publish to crates.io + uses: peter-evans/repository-dispatch@v4 with: event-type: cargo-publish client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}' @@ -48,11 +46,9 @@ jobs: IS_DRAFT: ${{ github.event.inputs.draft || false }} runs-on: ubuntu-latest steps: - - - name: Checkout - uses: actions/checkout@v5 - - - name: Create release + - name: Checkout + uses: actions/checkout@v6 + - name: Create release uses: softprops/action-gh-release@v2 with: append_body: false diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index efb09c1..d300219 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -10,26 +10,25 @@ env: on: pull_request: - branches: [ main, master, $default-branch ] - types: [ opened, synchronize, reopened ] + branches: [main, master] + types: [opened, synchronize, reopened] paths: - - '**.rs' - - '**/Cargo.toml' - - '**/Cargo.lock' - - '.github/workflows/cargo-*.yml' - - '.github/workflows/rust.yml' + - "**.rs" + - "**/Cargo.toml" + - "**/Cargo.lock" + - ".github/workflows/rust.yml" push: - branches: [ main, master, $default-branch ] - tags: - - v*.*.* - - "*-nightly" + branches: [main, master] + tags: [latest, v*.*.*, "*-nightly"] + release: + types: [created, edited] repository_dispatch: - types: [ rust ] + types: [rust] workflow_dispatch: inputs: benchmark: default: false - description: 'Run benchmarks' + description: "Run benchmarks" required: true type: boolean @@ -39,18 +38,15 @@ jobs: strategy: fail-fast: false matrix: - target: [ x86_64-unknown-linux-gnu ] + target: [x86_64-unknown-linux-gnu] steps: - - - uses: actions/checkout@v5 - - - name: Setup Rust + - uses: actions/checkout@v6 + - name: Setup Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: cache-key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} target: ${{ matrix.target }} - - - name: Build the workspace + - name: Build the workspace run: cargo build --release --locked --workspace --features full --target ${{ matrix.target }} benchmark: if: ${{ inputs.benchmark || github.event_name == 'push' }} @@ -63,16 +59,14 @@ jobs: actions: read contents: write steps: - - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: fetch-depth: 0 ref: ${{ github.ref }} repository: ${{ github.repository }} - - - name: Benchmark the workspace + - name: Benchmark the workspace id: cargo-bench - uses: peter-evans/repository-dispatch@v3 + uses: peter-evans/repository-dispatch@v4 with: event-type: cargo-bench client-payload: '{"ref": "${{ github.ref }}", "sha": "${{ github.sha }}"}' @@ -83,21 +77,18 @@ jobs: strategy: fail-fast: false matrix: - features: [ full, default ] - target: [ x86_64-unknown-linux-gnu ] + features: [full, default] + target: [x86_64-unknown-linux-gnu] steps: - - uses: actions/checkout@v5 - - - name: Setup Rust + - uses: actions/checkout@v6 + - name: Setup Rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: cache-key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} target: ${{ matrix.target }} - - - name: Test (${{ matrix.features }}) + - name: Test (${{ matrix.features }}) if: matrix.features != 'default' && matrix.features != 'all' run: cargo test -r --locked --workspace --target ${{ matrix.target }} --features ${{ matrix.features }} - - - name: Test (default) + - name: Test (default) if: matrix.features == 'default' run: cargo test -r --locked --workspace --target ${{ matrix.target }} diff --git a/.gitignore b/.gitignore index 5d38b7b..669643f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,113 +1,118 @@ -# Artifacts +# General -**/.artifacts/data/ -**/.docker/data/ +**/.artifacts/data +**/.cache +**/.docker/data -## Caches +*.csv +*.csv.* -**/.cache/ +*.db +*.db.* -# Configuration Files - -**/config.* -**/*.config.* - -**/*.env -**/*.env.* +*.db-*.* -### Exceptions -!**/default.config.* -!**/*.config.cjs -!**/*.config.js -!**/*.config.mjs -!**/config.py -!**/config.rs +*.lock +*.lock.* -!**/example.env.* -!**/*.env.example -!**/*.env.default +*-lock.* -# Dev +*.log +*.log.* -### Idea +*.zip +*.zip.* -**/.idea/ +## Operating Systems -### vscode +### NixOS +!flake.lock -**/.vscode/* +### Windows (WSL2) +**/*:Zone.Identifier -!**/.vscode/settings.json +# Configuration Files -# File Extensions +**/.config/*.config.* +!**/default.config.* -**/*.lock -**/*.lock.* +*.env +*.env.* -**/*-lock.* +!**/default.env +!**/example.env -**/*.log -**/*.log.* +## Development Environments +**/.direnv/ -### Data Files +### JetBrains IDEs +**/.idea/ -**/*.csv -**/*.csv.* +*.iml +*.iml.* -**/*.db -**/*.db.* +### Visual Studio Code +**/.vscode/* -**/*.db-*.* +!**/.vscode/settings.json -**/*.zip -**/*.zip.* +# Language Specific ## Rust **/debug/ **/target/ -**/*.bk -**/*.bk.* +*.bk +*.bk.* !**/Cargo.lock -## Node -**/build/ -**/debug/ -**/dist/ -**/node_modules/ - -### SvelteKit -**/__sapper__/ -**/.DS_STORE/ -**/.svelte-kit/ - ## Python **/__pycache__/ **/.pytest_cache/ **/venv/ -**/*.egg -**/*.egg.* +*.egg +*.egg.* -**/*.egg-info +*.egg-info -**/*.pyc -**/*.pyc.* +*.pyc +*.pyc.* -**/*.pyo -**/*.pyo.* +*.pyo +*.pyo.* -**/*.pyz -**/*.pyz.* +*.pyz +*.pyz.* -**/*.pyzw -**/*.pyzw.* +*.pyzw +*.pyzw.* -**/*.whl -**/*.whl.* +*.whl +*.whl.* -## Operating Systems -### Windows (WSL2) -**/*:Zone.Identifier +## Node +**/build/ +**/debug/ +**/dist/ +**/node_modules/ + +### Frameworks + +#### Next.js +**/.next/ + +#### SvelteKit +**/__sapper__/ +**/.DS_STORE/ +**/.svelte-kit/ + +#### Supabase +**/.supabase/ +**/supabase/tmp/ + +#### Vercel +**/.vercel/ +**/.vercel_build_output/ diff --git a/CODEOWNERS b/CODEOWNERS index 92af143..2babb12 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,3 @@ # the default owners of all files and directories within the repository # except those that are explicitly assigned to other owners. -* @FL03 @Scattered-Systems \ No newline at end of file +* @FL03 \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index ce9ab44..12aa978 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,13 +4,37 @@ version = 4 [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] +[[package]] +name = "alloca" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" +dependencies = [ + "cc", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anes" version = "0.1.6" @@ -19,9 +43,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "autocfg" @@ -29,11 +53,17 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "cast" @@ -41,11 +71,33 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +[[package]] +name = "cc" +version = "1.2.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" +dependencies = [ + "find-msvc-tools", + "shlex", +] + [[package]] name = "cfg-if" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] [[package]] name = "ciborium" @@ -76,18 +128,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.47" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eac00902d9d136acd712710d71823fb8ac8004ca445a89e73a41d45aa712931" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.47" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ad9bbf750e73b5884fb8a211a9424a1906c1e156724260fdae972f31d70e1d6" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstyle", "clap_lex", @@ -95,13 +147,13 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" [[package]] name = "contained" -version = "0.2.2" +version = "0.2.3" dependencies = [ "contained-core", "contained-derive", @@ -111,8 +163,16 @@ dependencies = [ [[package]] name = "contained-core" -version = "0.2.2" +version = "0.2.3" dependencies = [ + "getrandom", + "hashbrown 0.16.1", + "num-complex", + "num-traits", + "rand 0.9.2", + "rand_core 0.9.3", + "rand_distr", + "rayon-core", "serde", "serde_derive", "serde_json", @@ -122,7 +182,7 @@ dependencies = [ [[package]] name = "contained-derive" -version = "0.2.2" +version = "0.2.3" dependencies = [ "proc-macro2", "quote", @@ -131,19 +191,26 @@ dependencies = [ [[package]] name = "contained-macros" -version = "0.2.2" +version = "0.2.3" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "criterion" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1c047a62b0cc3e145fa84415a3191f628e980b194c2755aa12300a4e6cbd928" +checksum = "4d883447757bb0ee46f233e9dc22eb84d93a9508c9b868687b274fc431d886bf" dependencies = [ + "alloca", "anes", "cast", "ciborium", @@ -152,6 +219,7 @@ dependencies = [ "itertools", "num-traits", "oorandom", + "page_size", "plotters", "rayon", "regex", @@ -163,9 +231,9 @@ dependencies = [ [[package]] name = "criterion-plot" -version = "0.6.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b1bcc0dc7dfae599d84ad0b1a55f80cde8af3725da8313b528da95ef783e338" +checksum = "ed943f81ea2faa8dcecbbfa50164acf95d555afec96a27871663b300e387b2e4" dependencies = [ "cast", "itertools", @@ -202,20 +270,184 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "deranged" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +dependencies = [ + "powerfmt", + "serde_core", +] + [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "find-msvc-tools" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasip2", + "wasm-bindgen", +] + [[package]] name = "half" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", + "zerocopy", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", + "rayon", + "rustc-std-workspace-alloc", + "serde", + "serde_core", +] + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "iana-time-zone" +version = "0.1.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", ] [[package]] @@ -229,31 +461,60 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" [[package]] name = "js-sys" -version = "0.3.78" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0b063578492ceec17683ef2f8c5e89121fbd0b172cbc280635ab7567db2738" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", ] +[[package]] +name = "libc" +version = "0.2.178" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-traits" @@ -262,6 +523,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -276,6 +538,16 @@ version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "plotters" version = "0.3.7" @@ -304,24 +576,103 @@ dependencies = [ "plotters-backend", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.40" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha", + "rand_core 0.9.3", + "serde", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "rand_distr" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463" +dependencies = [ + "num-traits", + "rand 0.9.2", + "serde", + "serde_with", +] + [[package]] name = "rayon" version = "1.11.0" @@ -340,13 +691,14 @@ checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", + "wasm_sync", ] [[package]] name = "regex" -version = "1.11.2" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -356,9 +708,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.10" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -367,21 +719,21 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] -name = "rustversion" -version = "1.0.22" +name = "rustc-std-workspace-alloc" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "f9d441c3b2ebf55cebf796bfdc265d67fa09db17b7bb6bd4be75c509e1e8fec3" [[package]] -name = "ryu" -version = "1.0.20" +name = "rustversion" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "same-file" @@ -394,18 +746,28 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -414,21 +776,64 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.143" +version = "1.0.147" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" +checksum = "6af14725505314343e673e9ecb7cd7e8a36aa9791eb936235a3567cc31447ae4" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_with" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e28bdad6db2b8340e449f7108f020b3b092e8583a9e3fb82713e1d4e71fe817" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.12.1", + "serde", + "serde_derive", + "serde_json", + "serde_with_macros", + "time", ] +[[package]] +name = "serde_with_macros" +version = "3.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d846214a9854ef724f3da161b426242d8de7c1fc7de2f89bb1efcb154dca79d" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "syn" -version = "2.0.106" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -437,24 +842,55 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.16" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "time" +version = "0.3.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" + +[[package]] +name = "time-macros" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -467,9 +903,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "walkdir" @@ -482,37 +918,32 @@ dependencies = [ ] [[package]] -name = "wasm-bindgen" -version = "0.2.101" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e14915cadd45b529bb8d1f343c4ed0ac1de926144b746e2710f9cd05df6603b" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", - "wasm-bindgen-shared", + "wit-bindgen", ] [[package]] -name = "wasm-bindgen-backend" -version = "0.2.101" +name = "wasm-bindgen" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28d1ba982ca7923fd01448d5c30c6864d0a14109560296a162f80f305fb93bb" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.101" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3d463ae3eff775b0c45df9da45d68837702ac35af998361e2c84e7c5ec1b0d" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -520,36 +951,63 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.101" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bb4ce89b08211f923caf51d527662b75bdc9c9c7aab40f86dcb9fb85ac552aa" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.101" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f143854a3b13752c6950862c906306adb27c7e839f7414cec8fea35beab624c1" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm_sync" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff360cade7fec41ff0e9d2cda57fe58258c5f16def0e21302394659e6bbb0ea" +dependencies = [ + "js-sys", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "web-sys" -version = "0.3.78" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e4b637749ff0d92b8fad63aa1f7cff3cbe125fd49c175cd6345e7272638b12" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", ] +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.11" @@ -559,17 +1017,108 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "windows-link" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] [[package]] name = "windows-sys" -version = "0.61.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" dependencies = [ "windows-link", ] + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "zerocopy" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "zmij" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4af59da1029247450b54ba43e0b62c8e376582464bbe5504dd525fe521e7e8fd" diff --git a/Cargo.toml b/Cargo.toml index e047036..767c671 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [workspace] default-members = ["contained"] members = [ - "contained", + "contained", "core", "derive", "macros", @@ -10,10 +10,10 @@ resolver = "3" [workspace.package] authors = [ - "FL03 (https://github.com/FL03)" + "FL03 (https://github.com/FL03)", ] categories = [] -description = "contained is a zero-cost Rust library for creating transparent wrapper types." +description = "contained works to provide several macros and interface for transparent wrapper types in Rust." edition = "2024" homepage = "https://github.com/FL03/contained/wiki" keywords = ["macros", "transparent", "wrapper"] @@ -21,23 +21,36 @@ license = "Apache-2.0" readme = "README.md" repository = "https://github.com/FL03/contained.git" rust-version = "1.85.0" -version = "0.2.2" +version = "0.2.3" [workspace.dependencies] -contained = { default-features = false, path = "contained", version = "0.2.2" } -contained-core = { default-features = false, path = "core", version = "0.2.2" } -contained-derive = { default-features = false, path = "derive", version = "0.2.2" } -contained-macros = { default-features = false, path = "macros", version = "0.2.2" } - +contained = { default-features = false, path = "contained", version = "0.2.3" } +contained-core = { default-features = false, path = "core", version = "0.2.3" } +contained-derive = { default-features = false, path = "derive", version = "0.2.3" } +contained-macros = { default-features = false, path = "macros", version = "0.2.3" } +# development +criterion = { version = "0.8" } +# concurrency & parallelism +rayon-core = { default-features = false, version = "1" } +# data structures +hashbrown = { default-features = false, version = "0.16" } # error handling +anyhow = { default-features = false, version = "1" } thiserror = { default-features = false, version = "2" } +# math +num-complex = { default-features = false, version = "0.4" } +num-traits = { default-features = false, version = "0.2" } +# random +getrandom = { default-features = false, version = "0.3" } +rand = { default-features = false, version = "0.9" } +rand_core = { default-features = false, version = "0.9" } +rand_distr = { default-features = false, version = "0.5" } # serialization serde = { default-features = false, features = ["derive"], version = "1" } -serde_derive = { version = "1" } +serde_derive = { default-features = false, version = "1" } serde_json = { default-features = false, version = "1" } # macros & utilities paste = { version = "1" } -smart-default = { version = "0.7" } strum = { default-features = false, features = ["derive"], version = "0.27" } # WebAssembly wasm-bindgen = { default-features = false, version = "0.2" } @@ -53,7 +66,7 @@ opt-level = 2 overflow-checks = true panic = "abort" rpath = false -strip = "symbols" +strip = false [profile.release] codegen-units = 16 diff --git a/contained/Cargo.toml b/contained/Cargo.toml index 77d3e68..26e408c 100644 --- a/contained/Cargo.toml +++ b/contained/Cargo.toml @@ -16,16 +16,18 @@ version.workspace = true [package.metadata.docs.rs] all-features = false +doc-scrape-examples = true features = ["full"] rustc-args = ["--cfg", "docsrs"] version = "v{{version}}" [package.metadata.release] no-dev-version = true -tag-name = "{{version}}" +tag-name = "v{{version}}" [lib] crate-type = ["cdylib", "rlib"] +path = "lib.rs" bench = true doctest = true test = true @@ -35,16 +37,15 @@ name = "default" harness = false [[example]] +doc-scrape-examples = true name = "derive" required-features = ["derive"] [[example]] +doc-scrape-examples = true name = "macros" required-features = ["macros"] -[[test]] -name = "default" - [[test]] name = "format" required-features = ["macros"] @@ -55,23 +56,25 @@ contained-derive = { optional = true, workspace = true } contained-macros = { optional = true, workspace = true } [dev-dependencies] -criterion = { features = ["plotters"], version = "0.7" } +criterion = { features = ["plotters"], workspace = true } [features] -default = [ - "std" -] +default = ["std"] full = [ "default", "derive", "macros", + "hashbrown", ] # ********* [FF] Features ********* derive = ["dep:contained-derive"] -macros = ["dep:contained-macros"] +macros = [ + "dep:contained-macros", + "contained-core/macros", +] nightly = [ "contained-core/nightly", @@ -81,6 +84,7 @@ nightly = [ json = [ "alloc", + "serde", "contained-core/json", ] @@ -105,6 +109,35 @@ alloc = [ "contained-core/alloc", ] +complex = [ + "contained-core/complex", +] + +hashbrown = [ + "contained-core/hashbrown", +] + +rand = [ + "contained-core/rand", + "rng", +] + +rayon = [ + "contained-core/rayon", +] + +rng = [ + "contained-core/rng", +] + serde = [ "contained-core/serde", ] + +serde_json = [ + "contained-core/serde_json", +] + +wasm_bindgen = [ + "contained-core/wasm_bindgen", +] diff --git a/contained/lib.rs b/contained/lib.rs new file mode 100644 index 0000000..adddb88 --- /dev/null +++ b/contained/lib.rs @@ -0,0 +1,33 @@ +//! `contained` is a collection of macros, traits, and other useful primitives for defining, +//! managing, and interacting with so-called wrapper types. More specifically, any type capable +//! of deriving the `#[repr(transparent)]` attribute in Rust. +#![allow( + clippy::missing_docs_in_private_items, + clippy::missing_errors_doc, + clippy::missing_safety_doc, + clippy::module_inception, + clippy::needless_doctest_main, + clippy::upper_case_acronyms +)] +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(feature = "nightly", feature(allocator_api))] +// compile-time checks +#[cfg(not(any(feature = "alloc", feature = "std")))] +compile_error! { "Either the 'alloc' or 'std' feature must be enabled for this crate to compile." } +// external crates +#[cfg(feature = "alloc")] +extern crate alloc; +// re-exports +pub use contained_core::*; +#[cfg(feature = "derive")] +pub use contained_derive::*; +#[cfg(feature = "macros")] +pub use contained_macros::*; +// prelude +#[doc(hidden)] +pub mod prelude { + #[cfg(feature = "derive")] + pub use contained_derive::*; + #[cfg(feature = "macros")] + pub use contained_macros::*; +} diff --git a/contained/src/lib.rs b/contained/src/lib.rs deleted file mode 100644 index b17d053..0000000 --- a/contained/src/lib.rs +++ /dev/null @@ -1,40 +0,0 @@ -/* - Appellation: contained - Contrib: FL03 -*/ -//! # contained -//! -//! Welcome to `contained`! A library focused on providing useful abstractions, macros, and -//! utilities for handling so-called wrapper types. In short, a wrapper type is any implemented -//! object capable of using `#[repr(transparent)]`. -#![allow( - clippy::missing_safety_doc, - clippy::module_inception, - clippy::needless_doctest_main, - clippy::upper_case_acronyms -)] -#![cfg_attr(not(feature = "std"), no_std)] - -#[cfg(any(feature = "alloc", feature = "std"))] -pub use contained_core::*; - -#[cfg(feature = "derive")] -pub use contained_derive::*; -#[cfg(feature = "macros")] -pub use contained_macros::*; - -#[macro_use] -pub(crate) mod macros { - #[macro_use] - mod format; -} - -#[allow(unused_imports)] -pub mod prelude { - #[cfg(any(feature = "alloc", feature = "std"))] - pub use contained_core::prelude::*; - #[cfg(feature = "derive")] - pub use contained_derive::*; - #[cfg(feature = "macros")] - pub use contained_macros::*; -} diff --git a/core/Cargo.toml b/core/Cargo.toml index 2cb8d12..f390fb6 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -30,12 +30,21 @@ bench = false doctest = true test = true -[[test]] -name = "default" - [dependencies] +# concurrency & parallelism +rayon-core = { optional = true, workspace = true } +# data structures +hashbrown = { optional = true, workspace = true } +# mathematics +num-complex = { optional = true, workspace = true } +num-traits = { workspace = true } # error handling thiserror = { workspace = true } +# random +getrandom = { optional = true, workspace = true } +rand = { optional = true, workspace = true } +rand_core = { optional = true, workspace = true } +rand_distr = { optional = true, workspace = true } # serialization serde = { optional = true, features = ["derive"], workspace = true } serde_derive = { optional = true, workspace = true } @@ -43,54 +52,100 @@ serde_json = { optional = true, workspace = true } # WebAssembly wasm-bindgen = { optional = true, workspace = true } -# ********* Feature Flags ********* [features] -default = [ - "std" -] +default = ["std"] full = [ "default", + "complex", + "hashbrown", "json", + "rand", "serde", ] # ********* [FF] Features ********* json = [ "alloc", + "serde", "serde_json", ] -nightly = [] +macros = [] + +nightly = [ + "hashbrown?/nightly", + "rand?/nightly", +] # ********* [FF] Environments ********* std = [ "alloc", + "hashbrown?/default", + "num-complex?/std", + "num-traits/std", + "rand?/std", + "rand?/std_rng", + "rand?/thread_rng", + "rand_core?/std", + "rand_distr?/std", "serde?/std", "serde_json?/std", "thiserror/std", ] -wasi = [ - "alloc", -] +wasi = [] wasm = [ - "alloc", "wasm_bindgen", + "getrandom?/wasm_js", + "rayon-core?/web_spin_lock", ] # ********* [FF] Dependencies ********* alloc = [ + "hashbrown?/alloc", + "rand?/alloc", + "rand_distr?/alloc", "serde?/alloc", "serde_json?/alloc", ] +complex = ["dep:num-complex"] + +hashbrown = ["dep:hashbrown"] + +rand = [ + "rng", + "dep:rand", + "dep:rand_core", + "dep:rand_distr", + "num-complex?/rand", +] + +rayon = [ + "dep:rayon-core", + "hashbrown?/rayon", +] + +rng = [ + "dep:getrandom", + "rand?/os_rng", + "rand?/small_rng", + "rand_core?/os_rng", +] + serde = [ "dep:serde", "dep:serde_derive", + "serde?/derive", + "hashbrown?/serde", + "num-complex?/serde", + "rand?/serde", + "rand_core?/serde", + "rand_distr?/serde", ] serde_json = ["dep:serde_json"] -wasm_bindgen = ["dep:wasm-bindgen"] +wasm_bindgen = ["dep:wasm-bindgen"] \ No newline at end of file diff --git a/core/src/lib.rs b/core/src/lib.rs index 02df903..23894c7 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -1,35 +1,51 @@ -/* - Appellation: core - Contrib: FL03 -*/ -//! this core components of the contained crate -#![allow( - clippy::missing_safety_doc, - clippy::module_inception, - clippy::needless_doctest_main, - clippy::upper_case_acronyms -)] -#![cfg_attr(not(feature = "std"), no_std)] - -#[cfg(not(any(feature = "std", feature = "alloc")))] -compile_error! { - "Either the 'std' or 'alloc' feature must be enabled." -} - -#[cfg(feature = "alloc")] -extern crate alloc; - -#[doc(inline)] -pub use self::error::{Error, Result}; - -#[macro_use] -pub(crate) mod macros { - #[macro_use] - pub mod seal; - #[macro_use] - pub mod wrapper; -} - -pub mod error; - -pub mod prelude {} +/* + Appellation: core + Contrib: FL03 +*/ +//! this core components of the contained crate +#![allow( + clippy::missing_docs_in_private_items, + clippy::missing_errors_doc, + clippy::missing_safety_doc, + clippy::module_inception, + clippy::needless_doctest_main, + clippy::upper_case_acronyms +)] +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(feature = "nightly", feature(allocator_api))] +// compile-time checks +#[cfg(not(any(feature = "std", feature = "alloc")))] +compile_error! { "Either the 'std' or 'alloc' feature must be enabled." } +// external crates +#[cfg(feature = "alloc")] +extern crate alloc; +// macros +#[macro_use] +pub(crate) mod macros { + #[macro_use] + pub mod seal; + + #[macro_use] + #[cfg(feature = "macros")] + pub mod ext { + #[macro_use] + pub mod format; + #[macro_use] + pub mod wrapper; + } +} +// modules +pub mod error; + +pub mod traits { + //! core traits and interfaces for wrappers and their operations, formatting, etc. +} +// re-exports +#[doc(inline)] +pub use self::error::{Error, Result}; +// prelude +#[doc(hidden)] +pub mod prelude { + #[cfg(feature = "macros")] + pub use crate::{fmt_wrapper, wrapper}; +} diff --git a/contained/src/macros/format.rs b/core/src/macros/ext/format.rs similarity index 100% rename from contained/src/macros/format.rs rename to core/src/macros/ext/format.rs diff --git a/core/src/macros/wrapper.rs b/core/src/macros/ext/wrapper.rs similarity index 96% rename from core/src/macros/wrapper.rs rename to core/src/macros/ext/wrapper.rs index ac22d11..aaee2b6 100644 --- a/core/src/macros/wrapper.rs +++ b/core/src/macros/ext/wrapper.rs @@ -1,132 +1,132 @@ -/* - Appellation: wrapper - Contrib: @FL03 -*/ - -#[macro_export] -macro_rules! wrapper { - ($($S:ident($vis:vis $T:ident) $(where $($rest:tt)*)?;),* $(,)?) => { - $( - $crate::wrapper!(@impl $S($vis $T) $(where $($rest)*)?;); - )* - }; - (@impl - #[derive($($derive:ident),*)] - $S:ident($vis:vis $T:ident) $(where $($rest:tt)*)?; - ) => { - #[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd, $($derive),*)] - #[cfg_attr( - feature = "serde", - derive(serde::Deserialize, serde::Serialize), - serde(default, transparent), - )] - #[repr(transparent)] - pub struct $S<$T>($vis $T) $(where $($rest)*)?; - - impl<$T> $S<$T> { - /// returns a new instance with the given value - pub const fn new(value: $T) -> Self { - Self(value) - } - /// returns an immutable reference to the inner value - pub const fn get(&self) -> &$T { - &self.0 - } - /// returns a mutable reference to the inner value - pub const fn get_mut(&mut self) -> &mut $T { - &mut self.0 - } - /// consumes the current instance to return the inner value - #[inline] - pub fn into_inner(self) -> $T { - self.0 - } - /// applies the given function to the inner value and returns a new instance with - /// the result - #[inline] - pub fn map(self, f: F) -> $S - where - F: FnOnce($T) -> R, - { - $S(f(self.0)) - } - /// [`replace`](core::mem::replace) the inner value with the given, returning the previous value - pub const fn replace(&mut self, value: $T) -> $T { - ::core::mem::replace(self.get_mut(), value) - } - /// set the inner value, in-place - #[inline] - pub fn set(&mut self, value: $T) { - *self.get_mut() = value; - } - /// [`swap`](core::mem::swap) the inner value with that of another instance of the same type - pub const fn swap(&mut self, other: &mut Self) { - ::core::mem::swap(self.get_mut(), other.get_mut()); - } - /// [`take`](core::mem::take) the inner value, leaving a default in its place - #[inline] - pub fn take(&mut self) -> $T - where - $T: Default, - { - ::core::mem::take(self.get_mut()) - } - /// consumes the current instance to create another with the given value - pub fn with<_U>(self, value: _U) -> $S<_U> { - $S::new(value) - } - /// captures a referenced value in a new instance - pub fn view(&self) -> $S<&$T> { - $S::new(self.get()) - } - /// captures a mutable reference to the inner value - pub fn view_mut(&mut self) -> $S<&mut $T> { - $S::new(self.get_mut()) - } - } - - impl<$T> AsRef<$T> for $S<$T> { - fn as_ref(&self) -> &$T { - self.get() - } - } - - impl<$T> AsMut<$T> for $S<$T> { - fn as_mut(&mut self) -> &mut $T { - self.get_mut() - } - } - - impl<$T> ::core::borrow::Borrow<$T> for $S<$T> { - fn borrow(&self) -> &$T { - self.get() - } - } - - impl<$T> ::core::borrow::BorrowMut<$T> for $S<$T> { - fn borrow_mut(&mut self) -> &mut $T { - self.get_mut() - } - } - - impl<$T> ::core::ops::Deref for $S<$T> { - type Target = $T; - - fn deref(&self) -> &Self::Target { - self.get() - } - } - - impl<$T> ::core::ops::DerefMut for $S<$T> { - fn deref_mut(&mut self) -> &mut Self::Target { - self.get_mut() - } - } - - impl<$T> From<$T> for $S<$T> { - fn from(value: $T) -> Self { - Self(value) - } - } - }; -} +/* + Appellation: wrapper + Contrib: @FL03 +*/ + +#[macro_export] +macro_rules! wrapper { + ($($S:ident($vis:vis $T:ident) $(where $($rest:tt)*)?;),* $(,)?) => { + $( + $crate::wrapper!(@impl $S($vis $T) $(where $($rest)*)?;); + )* + }; + (@impl + #[derive($($derive:ident),*)] + $S:ident($vis:vis $T:ident) $(where $($rest:tt)*)?; + ) => { + #[derive(Clone, Copy, Default, Eq, Hash, Ord, PartialEq, PartialOrd, $($derive),*)] + #[cfg_attr( + feature = "serde", + derive(serde::Deserialize, serde::Serialize), + serde(default, transparent), + )] + #[repr(transparent)] + pub struct $S<$T>($vis $T) $(where $($rest)*)?; + + impl<$T> $S<$T> { + /// returns a new instance with the given value + pub const fn new(value: $T) -> Self { + Self(value) + } + /// returns an immutable reference to the inner value + pub const fn get(&self) -> &$T { + &self.0 + } + /// returns a mutable reference to the inner value + pub const fn get_mut(&mut self) -> &mut $T { + &mut self.0 + } + /// consumes the current instance to return the inner value + #[inline] + pub fn into_inner(self) -> $T { + self.0 + } + /// applies the given function to the inner value and returns a new instance with + /// the result + #[inline] + pub fn map(self, f: F) -> $S + where + F: FnOnce($T) -> R, + { + $S(f(self.0)) + } + /// [`replace`](core::mem::replace) the inner value with the given, returning the previous value + pub const fn replace(&mut self, value: $T) -> $T { + ::core::mem::replace(self.get_mut(), value) + } + /// set the inner value, in-place + #[inline] + pub fn set(&mut self, value: $T) { + *self.get_mut() = value; + } + /// [`swap`](core::mem::swap) the inner value with that of another instance of the same type + pub const fn swap(&mut self, other: &mut Self) { + ::core::mem::swap(self.get_mut(), other.get_mut()); + } + /// [`take`](core::mem::take) the inner value, leaving a default in its place + #[inline] + pub fn take(&mut self) -> $T + where + $T: Default, + { + ::core::mem::take(self.get_mut()) + } + /// consumes the current instance to create another with the given value + pub fn with<_U>(self, value: _U) -> $S<_U> { + $S::new(value) + } + /// captures a referenced value in a new instance + pub fn view(&self) -> $S<&$T> { + $S::new(self.get()) + } + /// captures a mutable reference to the inner value + pub fn view_mut(&mut self) -> $S<&mut $T> { + $S::new(self.get_mut()) + } + } + + impl<$T> AsRef<$T> for $S<$T> { + fn as_ref(&self) -> &$T { + self.get() + } + } + + impl<$T> AsMut<$T> for $S<$T> { + fn as_mut(&mut self) -> &mut $T { + self.get_mut() + } + } + + impl<$T> ::core::borrow::Borrow<$T> for $S<$T> { + fn borrow(&self) -> &$T { + self.get() + } + } + + impl<$T> ::core::borrow::BorrowMut<$T> for $S<$T> { + fn borrow_mut(&mut self) -> &mut $T { + self.get_mut() + } + } + + impl<$T> ::core::ops::Deref for $S<$T> { + type Target = $T; + + fn deref(&self) -> &Self::Target { + self.get() + } + } + + impl<$T> ::core::ops::DerefMut for $S<$T> { + fn deref_mut(&mut self) -> &mut Self::Target { + self.get_mut() + } + } + + impl<$T> From<$T> for $S<$T> { + fn from(value: $T) -> Self { + Self(value) + } + } + }; +} diff --git a/default.nix b/default.nix index ca926f2..38cef25 100644 --- a/default.nix +++ b/default.nix @@ -5,7 +5,7 @@ let overlays = [ (import rust-overlay) ]; }; - rustVersion = "1.66.0"; + rustVersion = "1.85.0"; wasmUnknownUknown = "wasm32-unknown-unknown"; wasm32Wasi = "wasm32-wasi"; @@ -26,8 +26,8 @@ let }; common = { - version = "0.1.0"; - src = ./.; + version = "0.2.3"; + src = self; cargoLock = { lockFile = ./Cargo.lock; diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..0b1abb3 --- /dev/null +++ b/flake.lock @@ -0,0 +1,82 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1765779637, + "narHash": "sha256-KJ2wa/BLSrTqDjbfyNx70ov/HdgNBCBBSQP3BIzKnv4=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1306659b587dc277866c7b69eb97e5f07864d8c4", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1766025663, + "narHash": "sha256-VSrZmhM22nZckbbE8Cmmc5I2RUGtwo1aii77T/i8YPU=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "96617c96d4c455770e6664b5e3aad999b677fae6", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix index 5e3f96f..969884f 100644 --- a/flake.nix +++ b/flake.nix @@ -19,8 +19,8 @@ in rec { packages.default = pkgs.rustPlatform.buildRustPackage { pname = "contained"; - version = "0.2.2"; - src = ./.; + version = "0.2.3"; + src = self; # ./. cargoLock = { lockFile = ./Cargo.lock; }; diff --git a/macros/src/ast.rs b/macros/src/ast.rs new file mode 100644 index 0000000..52407e4 --- /dev/null +++ b/macros/src/ast.rs @@ -0,0 +1,29 @@ +/* + Appellation: ast + Created At: 2025.12.18:07:44:04 + Contrib: @FL03 +*/ +mod impl_ast_wrapper; + +use syn::punctuated::Punctuated; +use syn::token::Impl; +use syn::{AngleBracketedGenericArguments, Ident, Token, WhereClause}; + +#[allow(dead_code)] +/// The abstract syntax tree for the `binary_wrapper` macro input; +/// e.g. `impl A { Add.add, Sub.sub }` or `impl B.field { Add.add, Sub.sub }` +pub struct WrapperImpls { + pub impl_token: Impl, + pub generics: Option, + pub target: Ident, + pub field: Option, + pub where_clause: Option, + pub ops: Punctuated, +} + +#[allow(dead_code)] +pub struct MethodCallAst { + pub name: Ident, + pub dot: Token![.], + pub call: Ident, +} diff --git a/macros/src/ast/impl_ast_wrapper.rs b/macros/src/ast/impl_ast_wrapper.rs new file mode 100644 index 0000000..31d5fda --- /dev/null +++ b/macros/src/ast/impl_ast_wrapper.rs @@ -0,0 +1,79 @@ +/* + appellation: ops + authors: @FL03 +*/ +use crate::ast::{MethodCallAst, WrapperImpls}; + +use syn::parse::{Parse, ParseStream}; +use syn::punctuated::Punctuated; +use syn::token::Impl; +use syn::{Ident, Token, braced}; + +fn _parse_ops(input: ParseStream) -> syn::Result> { + // parse the operations defined within braces + let content; + let _ = braced! { content in input }; + Punctuated::parse_terminated(&content) +} + +impl Parse for MethodCallAst { + fn parse(input: ParseStream) -> syn::Result { + let name = input.parse::()?; + let period = input.parse::()?; + let call = input.parse::()?; + if input.peek(Token![,]) { + input.parse::()?; + } + Ok(Self { + name, + dot: period, + call, + }) + } +} + +impl Parse for WrapperImpls { + fn parse(input: ParseStream) -> syn::Result { + // parse the `impl` keyword + let impl_token = input.parse::()?; + // detect any generic parameters + let generics = if input.peek(Token![<]) { + input.parse().ok() + } else { + None + }; + let target = input.parse::()?; + // resolve the optional named field + let field = if input.peek(Token![.]) { + input.parse::()?; + Some(input.parse()?) + } else { + None + }; + // parse the optional where clause + let where_clause = if input.peek(Token![where]) { + Some(input.parse()?) + } else { + None + }; + // parse the operations block + let content; + let _ = braced! { content in input }; + let mut ops = Punctuated::new(); + while !content.is_empty() { + ops.push(content.parse::()?); + if content.peek(Token![,]) { + content.parse::()?; + } + } + + Ok(Self { + impl_token, + generics, + target, + field, + where_clause, + ops, + }) + } +} diff --git a/macros/src/ast/ops.rs b/macros/src/ast/ops.rs deleted file mode 100644 index 24ee58c..0000000 --- a/macros/src/ast/ops.rs +++ /dev/null @@ -1,48 +0,0 @@ -/* - appellation: ops - authors: @FL03 -*/ -use syn::parse::{Parse, ParseStream}; -use syn::token::Impl; -use syn::{Ident, Token, braced}; - -/// The abstract syntax tree for the `binary_wrapper` macro input; -/// e.g. `impl A { Add.add, Sub.sub }` or `impl B.field { Add.add, Sub.sub }` -pub struct WrapperOpsAst { - pub _impl: Impl, - pub target: Ident, - pub field: Option, - pub ops: Vec<(Ident, Ident)>, -} - -impl Parse for WrapperOpsAst { - fn parse(input: ParseStream) -> syn::Result { - let _impl = input.parse::()?; - let target = input.parse::()?; - // resolve the optional named field - let field = if input.peek(Token![.]) { - input.parse::()?; - Some(input.parse()?) - } else { - None - }; - let content; - braced!(content in input); - let mut ops = Vec::new(); - while !content.is_empty() { - let op: Ident = content.parse()?; - content.parse::()?; - let call: Ident = content.parse()?; - if content.peek(Token![,]) { - content.parse::()?; - } - ops.push((op, call)); - } - Ok(Self { - _impl, - target, - field, - ops, - }) - } -} diff --git a/macros/src/ast/wrapper.rs b/macros/src/ast/wrapper.rs deleted file mode 100644 index 773d3ba..0000000 --- a/macros/src/ast/wrapper.rs +++ /dev/null @@ -1,40 +0,0 @@ -/* - appellation: wrapper - authors: @FL03 -*/ -use syn::parse::{Parse, ParseStream}; -use syn::{Ident, Token}; - -pub struct WrapperAst { - pub target: Ident, - pub field: Option, -} - -pub struct NamedFieldAst { - pub period: Token![.], - pub field: Ident, -} - -/* - ************* Implementations ************* -*/ -impl Parse for NamedFieldAst { - fn parse(input: ParseStream) -> syn::Result { - let period = input.parse::()?; - let field = input.parse()?; - Ok(Self { period, field }) - } -} - -impl Parse for WrapperAst { - fn parse(input: ParseStream) -> syn::Result { - let target: Ident = input.parse()?; - // resolve the optional named field - let field = if input.peek(Token![.]) { - Some(input.parse()?) - } else { - None - }; - Ok(Self { target, field }) - } -} diff --git a/macros/src/impls.rs b/macros/src/impls.rs new file mode 100644 index 0000000..2d0dae6 --- /dev/null +++ b/macros/src/impls.rs @@ -0,0 +1,9 @@ +/* + Appellation: impls + Created At: 2025.12.26:20:55:44 + Contrib: @FL03 +*/ +pub use self::{binary::impl_wrapper_binary_ops, unary::impl_wrapper_unary_ops}; + +pub mod binary; +pub mod unary; diff --git a/macros/src/impl_binary.rs b/macros/src/impls/binary.rs similarity index 95% rename from macros/src/impl_binary.rs rename to macros/src/impls/binary.rs index 4362540..2fef1b2 100644 --- a/macros/src/impl_binary.rs +++ b/macros/src/impls/binary.rs @@ -2,13 +2,13 @@ appellation: impl_binary authors: @FL03 */ -use crate::ast::WrapperOpsAst; +use crate::ast::{MethodCallAst, WrapperImpls}; use proc_macro2::TokenStream; use quote::{format_ident, quote}; use syn::Ident; /// Procedural macro entry point -pub fn impl_wrapper_binary_ops(input: WrapperOpsAst) -> TokenStream { +pub fn impl_wrapper_binary_ops(input: WrapperImpls) -> TokenStream { let base = impl_core_binary_ops(&input); let assign = impl_assign_ops(&input); @@ -20,12 +20,12 @@ pub fn impl_wrapper_binary_ops(input: WrapperOpsAst) -> TokenStream { } fn impl_core_binary_ops( - WrapperOpsAst { + WrapperImpls { target, field, ops, .. - }: &WrapperOpsAst, + }: &WrapperImpls, ) -> Vec { let mut impls = Vec::new(); - for (op, call) in ops { + for MethodCallAst { name: op, call, .. } in ops { let _impl = if let Some(f) = field { impl_named(op, target, call, f) } else { @@ -36,13 +36,13 @@ fn impl_core_binary_ops( impls } -fn impl_assign_ops(options: &WrapperOpsAst) -> Vec { - let WrapperOpsAst { +fn impl_assign_ops(options: &WrapperImpls) -> Vec { + let WrapperImpls { target, field, ops, .. } = options; let mut impls = Vec::new(); - for (op, call) in ops { + for MethodCallAst { name: op, call, .. } in ops { let op_assign = format_ident!("{}Assign", op); let call_assign = format_ident!("{}_assign", call); diff --git a/macros/src/impl_unary.rs b/macros/src/impls/unary.rs similarity index 92% rename from macros/src/impl_unary.rs rename to macros/src/impls/unary.rs index 5fe6efd..892bbca 100644 --- a/macros/src/impl_unary.rs +++ b/macros/src/impls/unary.rs @@ -2,13 +2,13 @@ appellation: impl_unary authors: @FL03 */ -use crate::ast::WrapperOpsAst; +use crate::ast::{MethodCallAst, WrapperImpls}; use proc_macro2::TokenStream; use quote::quote; use syn::Ident; /// Procedural macro entry point -pub fn impl_wrapper_unary_ops(input: WrapperOpsAst) -> TokenStream { +pub fn impl_wrapper_unary_ops(input: WrapperImpls) -> TokenStream { let base = impl_core_unary_ops(&input); quote! { @@ -18,12 +18,12 @@ pub fn impl_wrapper_unary_ops(input: WrapperOpsAst) -> TokenStream { } fn impl_core_unary_ops( - WrapperOpsAst { + WrapperImpls { target, field, ops, .. - }: &WrapperOpsAst, + }: &WrapperImpls, ) -> Vec { let mut impls = Vec::new(); - for (op, call) in ops { + for MethodCallAst { name: op, call, .. } in ops { let _impl = if let Some(f) = field { impl_named(op, target, call, f) } else { diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 9132d8a..c4cbce2 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -5,20 +5,10 @@ //! procedural macros for interacting with various wrappers extern crate proc_macro; -pub(crate) mod impl_binary; -pub(crate) mod impl_unary; +mod ast; +mod impls; -pub(crate) mod ast { - #[doc(inline)] - #[allow(unused_imports)] - pub use self::{ops::*, wrapper::*}; - - mod ops; - #[allow(dead_code)] - mod wrapper; -} - -use crate::ast::WrapperOpsAst; +use crate::ast::WrapperImpls; use proc_macro::TokenStream; use syn::parse_macro_input; @@ -62,8 +52,8 @@ use syn::parse_macro_input; /// ``` #[proc_macro] pub fn binary_wrapper(input: TokenStream) -> TokenStream { - let ast = parse_macro_input!(input as WrapperOpsAst); - let output = impl_binary::impl_wrapper_binary_ops(ast); + let ast = parse_macro_input!(input as WrapperImpls); + let output = impls::impl_wrapper_binary_ops(ast); output.into() } @@ -72,7 +62,7 @@ pub fn binary_wrapper(input: TokenStream) -> TokenStream { /// /// ```rust /// extern crate contained_macros as macros; -/// +/// /// pub struct Wrapper(pub T); /// /// macros::unary_wrapper! { @@ -87,7 +77,7 @@ pub fn binary_wrapper(input: TokenStream) -> TokenStream { /// /// ```rust /// extern crate contained_macros as macros; -/// +/// /// pub struct Wrapper { /// pub field: T, /// } @@ -101,19 +91,7 @@ pub fn binary_wrapper(input: TokenStream) -> TokenStream { /// ``` #[proc_macro] pub fn unary_wrapper(input: TokenStream) -> TokenStream { - let ast = parse_macro_input!(input as WrapperOpsAst); - let output = impl_unary::impl_wrapper_unary_ops(ast); - output.into() -} - - -#[deprecated( - since = "0.2.2", - note = "use `unary_wrapper` instead" -)] -#[proc_macro] -pub fn impl_wrapper_unary(input: TokenStream) -> TokenStream { - let ast = parse_macro_input!(input as WrapperOpsAst); - let output = impl_unary::impl_wrapper_unary_ops(ast); + let ast = parse_macro_input!(input as WrapperImpls); + let output = impls::impl_wrapper_unary_ops(ast); output.into() } diff --git a/macros/tests/ops.rs b/macros/tests/ops.rs index fe863a4..80f5df8 100644 --- a/macros/tests/ops.rs +++ b/macros/tests/ops.rs @@ -15,7 +15,7 @@ pub struct B { } binary_wrapper! { - impl A { + impl A where T: core::fmt::Debug { Add.add, Sub.sub, Mul.mul, diff --git a/scripts/nix.sh b/scripts/nix.sh new file mode 100755 index 0000000..0933d25 --- /dev/null +++ b/scripts/nix.sh @@ -0,0 +1,3 @@ +#! /usr/bin/bash + +nix --extra-experimental-features nix-command --extra-experimental-features flakes "$@" \ No newline at end of file