Compare commits

...

36 commits
v0.1.2 ... main

Author SHA1 Message Date
JasterV
21529c65db chore: update cargo.lock 2026-04-23 02:32:49 +02:00
JasterV
04814d4011 chore: release 0.1.10 2026-04-23 02:28:12 +02:00
JasterV
dd6f0ddcbb chore: release-plz update (#3)
This is an automated PR generated by [release-plz](https://github.com/MarcoIeni/release-plz) via Woodpecker CI.

Co-authored-by: release-plz-bot <bot@codeberg.org>
Co-authored-by: JasterV <49537445+JasterV@users.noreply.github.com>
Reviewed-on: https://codeberg.org/JasterV/event_bus.rs/pulls/3
2026-04-23 02:19:55 +02:00
JasterV
ee91c5f8f5 chore: update CI 2026-04-23 02:10:24 +02:00
JasterV
87604d9ceb chore: update dependencies 2026-04-23 02:02:32 +02:00
JasterV
fccb54ba49 fix: CD steps order 2026-03-07 01:06:13 +01:00
JasterV
cecd3f1797 chore: use codeberg registry images 2026-03-07 00:28:06 +01:00
JasterV
155832b542 feat: update CD to automatically release unpublished crates 2026-03-06 23:07:10 +01:00
JasterV
3c6e925ac9 chore: update README 2026-03-06 22:08:41 +01:00
release-plz-bot
5ea7230977 feat: implement CD with release-plz 2026-03-06 22:01:39 +01:00
JasterV
ee8295935c chore: migrate from Github to Codeberg 2026-03-04 01:25:06 +01:00
JasterV
524db0da43 Force CI run 2026-03-04 01:04:13 +01:00
JasterV
a0c54df4a3 feat: use our own rust docker image 2026-03-04 00:43:44 +01:00
6543
2e233180c6 Fix CI config (#1)
by moving the PATH re-declaration into the runtime

Reviewed-on: https://codeberg.org/JasterV/event_bus.rs/pulls/1
Reviewed-by: Victor Martinez Montané <jasterv@noreply.codeberg.org>
Co-authored-by: 6543 <6543@obermui.de>
Co-committed-by: 6543 <6543@obermui.de>
2026-03-04 00:16:50 +01:00
JasterV
c47579a536 feat: move CI to woodpecker 2026-03-04 00:07:26 +01:00
github-actions[bot]
5c883b62bf
chore: release v0.1.7 (#14)
* chore: release v0.1.7

* Update CHANGELOG.md

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Víctor Martínez <49537445+JasterV@users.noreply.github.com>
2026-03-02 02:25:30 +01:00
dependabot[bot]
d45ec93095
chore(deps): bump proptest from 1.9.0 to 1.10.0 (#18)
Bumps [proptest](https://github.com/proptest-rs/proptest) from 1.9.0 to 1.10.0.
- [Release notes](https://github.com/proptest-rs/proptest/releases)
- [Changelog](https://github.com/proptest-rs/proptest/blob/main/CHANGELOG.md)
- [Commits](https://github.com/proptest-rs/proptest/compare/v1.9.0...v1.10.0)

---
updated-dependencies:
- dependency-name: proptest
  dependency-version: 1.10.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-01 19:37:47 +01:00
dependabot[bot]
0c5a39a993
chore(deps): bump thiserror from 2.0.17 to 2.0.18 (#16)
Bumps [thiserror](https://github.com/dtolnay/thiserror) from 2.0.17 to 2.0.18.
- [Release notes](https://github.com/dtolnay/thiserror/releases)
- [Commits](https://github.com/dtolnay/thiserror/compare/2.0.17...2.0.18)

---
updated-dependencies:
- dependency-name: thiserror
  dependency-version: 2.0.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-01 19:36:22 +01:00
dependabot[bot]
5414b798dc
chore(deps): bump tokio from 1.48.0 to 1.49.0 (#15)
Bumps [tokio](https://github.com/tokio-rs/tokio) from 1.48.0 to 1.49.0.
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.48.0...tokio-1.49.0)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.49.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-01 19:36:11 +01:00
dependabot[bot]
6036db0d4a
chore(deps): bump test-strategy from 0.4.3 to 0.4.5 (#19)
Bumps [test-strategy](https://github.com/frozenlib/test-strategy) from 0.4.3 to 0.4.5.
- [Commits](https://github.com/frozenlib/test-strategy/compare/v0.4.3...v0.4.5)

---
updated-dependencies:
- dependency-name: test-strategy
  dependency-version: 0.4.5
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-01 19:35:41 +01:00
dependabot[bot]
7388abe45b
chore(deps): bump futures from 0.3.31 to 0.3.32 (#20)
Bumps [futures](https://github.com/rust-lang/futures-rs) from 0.3.31 to 0.3.32.
- [Release notes](https://github.com/rust-lang/futures-rs/releases)
- [Changelog](https://github.com/rust-lang/futures-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/futures-rs/compare/0.3.31...0.3.32)

---
updated-dependencies:
- dependency-name: futures
  dependency-version: 0.3.32
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-01 19:29:43 +01:00
JasterV
636de18dfa update rust version & nextest installation 2026-03-01 19:27:24 +01:00
JasterV
9b2c431d46 chore: update cargo-deny version 2026-03-01 19:15:10 +01:00
JasterV
728f93f9a3 chore: fix a clippy issue 2026-03-01 19:02:38 +01:00
JasterV
85ce22e721 refactor: update code style to remove indentation levels 2025-12-09 19:12:17 +01:00
github-actions[bot]
61ab093a93
chore: release v0.1.6 (#13)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-05 03:11:41 +01:00
JasterV
11111c9dbb refactor: we do not need to use an AtomicIsize 2025-12-05 01:53:58 +01:00
dependabot[bot]
a1f4056ca6
chore(deps): bump Swatinem/rust-cache from 2.8.1 to 2.8.2 (#3)
Bumps [Swatinem/rust-cache](https://github.com/swatinem/rust-cache) from 2.8.1 to 2.8.2.
- [Release notes](https://github.com/swatinem/rust-cache/releases)
- [Changelog](https://github.com/Swatinem/rust-cache/blob/master/CHANGELOG.md)
- [Commits](f13886b937...779680da71)

---
updated-dependencies:
- dependency-name: Swatinem/rust-cache
  dependency-version: 2.8.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 12:30:26 +01:00
github-actions[bot]
2e1536515a
chore: release v0.1.5 (#11)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-01 12:17:00 +01:00
JasterV
db6424b8ad refactor: do not enforce the internal key of RcMap to be Clone 2025-12-01 12:15:41 +01:00
JasterV
fd0d761e17 refactor: make more clear internally the management of the channel 2025-12-01 12:12:10 +01:00
github-actions[bot]
21d7c2257a
chore: release v0.1.4 (#9)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-12-01 01:47:51 +01:00
JasterV
9a466e976a chore: introduce property testing in the test suite 2025-12-01 01:40:52 +01:00
github-actions[bot]
1207ed90af
chore: release v0.1.3 (#8)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2025-11-28 21:42:36 +01:00
JasterV
05928599db chore: test event bus more extensively 2025-11-28 21:07:21 +01:00
Víctor Martínez
371ce0ea08
Update README.md 2025-11-28 15:34:01 +01:00
14 changed files with 1008 additions and 262 deletions

View file

@ -1,12 +0,0 @@
version: 2
updates:
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 10
- package-ecosystem: "github-actions"
directory: "/"
# Check for updates every Monday
schedule:
interval: "weekly"

View file

@ -1,49 +0,0 @@
name: Release-plz
on:
push:
branches:
- main
jobs:
# Release unpublished packages.
release-plz-release:
name: Release-plz release
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- &checkout
name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
persist-credentials: false
- &install-rust
name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Run release-plz
uses: release-plz/action@v0.5
with:
command: release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
# Create a PR with the new versions and changelog, preparing the next release.
release-plz-pr:
name: Release-plz PR
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
concurrency:
group: release-plz-${{ github.ref }}
cancel-in-progress: false
steps:
- *checkout
- *install-rust
- name: Run release-plz
uses: release-plz/action@v0.5
with:
command: release-pr
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}

View file

@ -1,46 +0,0 @@
name: CI
on:
push:
branches:
- main
pull_request:
concurrency:
group: ci-${{ github.head_ref || github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- run: rustup default 1.91.1
- run: rustup component add clippy rustfmt
- uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # ratchet:Swatinem/rust-cache@v2
- uses: taiki-e/install-action@ae532dedd825648efd18d9c49c9a443d0398ca0a # ratchet:taiki-e/install-action@cargo-make
- uses: taiki-e/install-action@b98f5bfc2edc235d74c94cb39bd9d8cdd69dbbdf # ratchet:taiki-e/install-action@cargo-deny
- run: cargo make -p ci fmt-check
- run: cargo make -p ci clippy
- run: cargo make -p ci deny-check
- run: cargo make -p ci docs
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- run: rustup default 1.91.1
- uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # ratchet:Swatinem/rust-cache@v2
- uses: taiki-e/install-action@ae532dedd825648efd18d9c49c9a443d0398ca0a # ratchet:taiki-e/install-action@cargo-make
- run: cargo make -p ci test
alls-green:
if: always()
runs-on: ubuntu-latest
needs:
- lint
- test
steps:
- run: ${{ !contains(needs.*.result, 'failure') }}

23
.woodpecker/cd.yml Normal file
View file

@ -0,0 +1,23 @@
when:
event: push
branch: main
depends_on:
- ci
steps:
- name: Release unpublished
image: codeberg.org/jasterv/rust-magic-release:latest
pull: true
settings:
token:
from_secret: CODEBERG_TOKEN
crates_io_token:
from_secret: CRATES_IO_TOKEN
- name: Update PR
image: codeberg.org/jasterv/release-plz-update-pr:latest
pull: true
settings:
token:
from_secret: CODEBERG_TOKEN

19
.woodpecker/ci.yml Normal file
View file

@ -0,0 +1,19 @@
when:
- event: [push, pull_request]
branch: main
steps:
lint:
image: codeberg.org/jasterv/rust-ci:1.95
pull: true
commands:
- cargo make -p ci fmt-check
- cargo make -p ci clippy
- cargo make -p ci deny-check
- cargo make -p ci docs
test:
image: codeberg.org/jasterv/rust-ci:1.95
pull: true
commands:
- cargo make -p ci test

View file

@ -7,19 +7,74 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.1.2](https://github.com/JasterV/event_bus.rs/compare/v0.1.1...v0.1.2) - 2025-11-28
## [0.1.10](https://codeberg.org/JasterV/event_bus.rs/compare/v0.1.9...v0.1.10) - 2026-04-23
### Other
- [chore]: update docs
## [0.1.9](https://codeberg.org/JasterV/event_bus.rs/compare/v0.1.8...v0.1.9) - 2026-04-23
### Other
- [chore]: update deps
## [0.1.8](https://codeberg.org/JasterV/event_bus.rs/compare/v0.1.7...v0.1.8) - 2026-03-02
- [chore]: Migrate from Github to Codeberg
## [0.1.7](https://codeberg.org/JasterV/event_bus.rs/compare/v0.1.6...v0.1.7) - 2026-03-01
### Other
- *(deps)* bump proptest from 1.9.0 to 1.10.0 ([#18](https://codeberg.org/JasterV/event_bus.rs/pull/18))
- *(deps)* bump thiserror from 2.0.17 to 2.0.18 ([#16](https://codeberg.org/JasterV/event_bus.rs/pull/16))
- *(deps)* bump tokio from 1.48.0 to 1.49.0 ([#15](https://codeberg.org/JasterV/event_bus.rs/pull/15))
- *(deps)* bump test-strategy from 0.4.3 to 0.4.5 ([#19](https://codeberg.org/JasterV/event_bus.rs/pull/19))
- *(deps)* bump futures from 0.3.31 to 0.3.32 ([#20](https://codeberg.org/JasterV/event_bus.rs/pull/20))
- [chore]: update rust version & CI
- [refactor]: update code style to remove indentation levels
## [0.1.6](https://codeberg.org/JasterV/event_bus.rs/compare/v0.1.5...v0.1.6) - 2025-12-05
### Other
- we do not need to use an AtomicIsize
- *(deps)* bump Swatinem/rust-cache from 2.8.1 to 2.8.2 ([#3](https://codeberg.org/JasterV/event_bus.rs/pull/3))
## [0.1.5](https://codeberg.org/JasterV/event_bus.rs/compare/v0.1.4...v0.1.5) - 2025-12-01
### Other
- do not enforce the internal key of RcMap to be Clone
- make more clear internally the management of the channel
## [0.1.4](https://codeberg.org/JasterV/event_bus.rs/compare/v0.1.3...v0.1.4) - 2025-12-01
### Other
- introduce property testing in the test suite
## [0.1.3](https://codeberg.org/JasterV/event_bus.rs/compare/v0.1.2...v0.1.3) - 2025-11-28
### Other
- test event bus more extensively
- Update README.md
## [0.1.2](https://codeberg.org/JasterV/event_bus.rs/compare/v0.1.1...v0.1.2) - 2025-11-28
### Other
- update docs
## [0.1.1](https://github.com/JasterV/event_bus.rs/compare/v0.1.0...v0.1.1) - 2025-11-28
## [0.1.1](https://codeberg.org/JasterV/event_bus.rs/compare/v0.1.0...v0.1.1) - 2025-11-28
### Other
- update README & docs
## [0.1.0](https://github.com/JasterV/event_bus.rs/releases/tag/v0.1.0) - 2025-11-28
## [0.1.0](https://codeberg.org/JasterV/event_bus.rs/releases/tag/v0.1.0) - 2025-11-28
### Added

763
Cargo.lock generated
View file

@ -2,6 +2,12 @@
# It is not intended for manual editing.
version = 4
[[package]]
name = "anyhow"
version = "1.0.102"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
[[package]]
name = "async-broadcast"
version = "0.7.2"
@ -37,10 +43,31 @@ dependencies = [
]
[[package]]
name = "bitflags"
version = "2.10.0"
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bit-set"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
[[package]]
name = "bitflags"
version = "2.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3"
[[package]]
name = "cfg-if"
@ -57,6 +84,15 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "convert_case"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "affbf0190ed2caf063e3def54ff444b449371d55c58e513a95ab98eca50adb49"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
@ -71,12 +107,52 @@ checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf"
dependencies = [
"cfg-if",
"crossbeam-utils",
"hashbrown",
"hashbrown 0.14.5",
"lock_api",
"once_cell",
"parking_lot_core",
]
[[package]]
name = "derive-ex"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bba95f299f6b9cd47f68a847eca2ae9060a2713af532dc35c342065544845407"
dependencies = [
"proc-macro2",
"quote",
"structmeta",
"syn",
]
[[package]]
name = "deunicode"
version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abd57806937c9cc163efc8ea3910e00a62e2aeb0b8119f1793a978088f8f6b04"
[[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 = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "event-listener"
version = "5.4.1"
@ -100,21 +176,53 @@ dependencies = [
[[package]]
name = "event_bus_rs"
version = "0.1.2"
version = "0.1.10"
dependencies = [
"async-broadcast",
"async-stream",
"dashmap",
"fake",
"futures",
"proptest",
"test-strategy",
"thiserror",
"tokio",
]
[[package]]
name = "futures"
version = "0.3.31"
name = "fake"
version = "4.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
checksum = "f2b0902eb36fbab51c14eda1c186bda119fcff91e5e4e7fc2dd2077298197ce8"
dependencies = [
"deunicode",
"either",
"rand",
]
[[package]]
name = "fastrand"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foldhash"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "futures"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d"
dependencies = [
"futures-channel",
"futures-core",
@ -127,9 +235,9 @@ dependencies = [
[[package]]
name = "futures-channel"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
dependencies = [
"futures-core",
"futures-sink",
@ -137,15 +245,15 @@ dependencies = [
[[package]]
name = "futures-core"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d"
[[package]]
name = "futures-executor"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d"
dependencies = [
"futures-core",
"futures-task",
@ -154,15 +262,15 @@ dependencies = [
[[package]]
name = "futures-io"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718"
[[package]]
name = "futures-macro"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
dependencies = [
"proc-macro2",
"quote",
@ -171,21 +279,21 @@ dependencies = [
[[package]]
name = "futures-sink"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893"
[[package]]
name = "futures-task"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393"
[[package]]
name = "futures-util"
version = "0.3.31"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6"
dependencies = [
"futures-channel",
"futures-core",
@ -195,10 +303,34 @@ dependencies = [
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]]
name = "getrandom"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
"cfg-if",
"libc",
"r-efi 5.3.0",
"wasip2",
]
[[package]]
name = "getrandom"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
dependencies = [
"cfg-if",
"libc",
"r-efi 6.0.0",
"wasip2",
"wasip3",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
@ -206,10 +338,67 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "libc"
version = "0.2.177"
name = "hashbrown"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"foldhash",
]
[[package]]
name = "hashbrown"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "id-arena"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
[[package]]
name = "indexmap"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9"
dependencies = [
"equivalent",
"hashbrown 0.17.0",
"serde",
"serde_core",
]
[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
[[package]]
name = "leb128fmt"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "libc"
version = "0.2.185"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
[[package]]
name = "linux-raw-sys"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
[[package]]
name = "lock_api"
@ -221,16 +410,31 @@ dependencies = [
]
[[package]]
name = "memchr"
version = "2.7.6"
name = "log"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "memchr"
version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.3"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[[package]]
name = "parking"
@ -253,34 +457,135 @@ dependencies = [
[[package]]
name = "pin-project-lite"
version = "0.2.16"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
[[package]]
name = "pin-utils"
version = "0.1.0"
name = "ppv-lite86"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]]
name = "prettyplease"
version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.103"
version = "1.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.42"
name = "proptest"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744"
dependencies = [
"bit-set",
"bit-vec",
"bitflags",
"num-traits",
"proptest-macro",
"rand",
"rand_chacha",
"rand_xorshift",
"regex-syntax",
"rusty-fork",
"tempfile",
"unarray",
]
[[package]]
name = "proptest-macro"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efaa288b896cb2b345da7b7f2110ab19e51565b83495b56fcec98a62f8b1f33e"
dependencies = [
"convert_case",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quote"
version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
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 = "r-efi"
version = "6.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
[[package]]
name = "rand"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea"
dependencies = [
"rand_chacha",
"rand_core",
]
[[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",
]
[[package]]
name = "rand_core"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c"
dependencies = [
"getrandom 0.3.4",
]
[[package]]
name = "rand_xorshift"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a"
dependencies = [
"rand_core",
]
[[package]]
name = "redox_syscall"
version = "0.5.18"
@ -290,6 +595,37 @@ dependencies = [
"bitflags",
]
[[package]]
name = "regex-syntax"
version = "0.8.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
[[package]]
name = "rustix"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "rusty-fork"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2"
dependencies = [
"fnv",
"quick-error",
"tempfile",
"wait-timeout",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -297,10 +633,58 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "slab"
version = "0.4.11"
name = "semver"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589"
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
[[package]]
name = "serde"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
dependencies = [
"itoa",
"memchr",
"serde",
"serde_core",
"zmij",
]
[[package]]
name = "slab"
version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
name = "smallvec"
@ -309,10 +693,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "syn"
version = "2.0.111"
name = "structmeta"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
checksum = "2e1575d8d40908d70f6fd05537266b90ae71b15dbbe7a8b7dffa2b759306d329"
dependencies = [
"proc-macro2",
"quote",
"structmeta-derive",
"syn",
]
[[package]]
name = "structmeta-derive"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "152a0b65a590ff6c3da95cabe2353ee04e6167c896b28e3b14478c2636c922fc"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "2.0.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
dependencies = [
"proc-macro2",
"quote",
@ -320,19 +727,45 @@ dependencies = [
]
[[package]]
name = "thiserror"
version = "2.0.17"
name = "tempfile"
version = "3.27.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
dependencies = [
"fastrand",
"getrandom 0.4.2",
"once_cell",
"rustix",
"windows-sys",
]
[[package]]
name = "test-strategy"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f7fd1eb9efb36942b85a290c4201d317980fe09bc88d34dd48aaaae03075c6a"
dependencies = [
"derive-ex",
"proc-macro2",
"quote",
"structmeta",
"syn",
]
[[package]]
name = "thiserror"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.17"
version = "2.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
dependencies = [
"proc-macro2",
"quote",
@ -341,9 +774,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.48.0"
version = "1.52.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408"
checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6"
dependencies = [
"pin-project-lite",
"tokio-macros",
@ -351,9 +784,9 @@ dependencies = [
[[package]]
name = "tokio-macros"
version = "2.6.0"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
dependencies = [
"proc-macro2",
"quote",
@ -361,13 +794,221 @@ dependencies = [
]
[[package]]
name = "unicode-ident"
version = "1.0.22"
name = "unarray"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
[[package]]
name = "unicode-segmentation"
version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"
[[package]]
name = "unicode-xid"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "wait-timeout"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11"
dependencies = [
"libc",
]
[[package]]
name = "wasip2"
version = "1.0.1+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
dependencies = [
"wit-bindgen 0.46.0",
]
[[package]]
name = "wasip3"
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
dependencies = [
"wit-bindgen 0.51.0",
]
[[package]]
name = "wasm-encoder"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
dependencies = [
"leb128fmt",
"wasmparser",
]
[[package]]
name = "wasm-metadata"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
dependencies = [
"anyhow",
"indexmap",
"wasm-encoder",
"wasmparser",
]
[[package]]
name = "wasmparser"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
dependencies = [
"bitflags",
"hashbrown 0.15.5",
"indexmap",
"semver",
]
[[package]]
name = "windows-link"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
[[package]]
name = "windows-sys"
version = "0.61.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
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 = "wit-bindgen"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
dependencies = [
"wit-bindgen-rust-macro",
]
[[package]]
name = "wit-bindgen-core"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
dependencies = [
"anyhow",
"heck",
"wit-parser",
]
[[package]]
name = "wit-bindgen-rust"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
dependencies = [
"anyhow",
"heck",
"indexmap",
"prettyplease",
"syn",
"wasm-metadata",
"wit-bindgen-core",
"wit-component",
]
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
dependencies = [
"anyhow",
"prettyplease",
"proc-macro2",
"quote",
"syn",
"wit-bindgen-core",
"wit-bindgen-rust",
]
[[package]]
name = "wit-component"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
dependencies = [
"anyhow",
"bitflags",
"indexmap",
"log",
"serde",
"serde_derive",
"serde_json",
"wasm-encoder",
"wasm-metadata",
"wasmparser",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
dependencies = [
"anyhow",
"id-arena",
"indexmap",
"log",
"semver",
"serde",
"serde_derive",
"serde_json",
"unicode-xid",
"wasmparser",
]
[[package]]
name = "zerocopy"
version = "0.8.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.48"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"

View file

@ -1,22 +1,25 @@
[package]
name = "event_bus_rs"
version = "0.1.2"
version = "0.1.10"
edition = "2024"
description = "A runtime-agnostic, async, and thread-safe event bus for Rust."
keywords = ["event_bus", "pubsub", "event", "messaging", "event_based"]
categories = ["asynchronous", "data-structures", "rust-patterns"]
authors = ["Victor Martínez Montané <jaster.victor@gmail.com>"]
rust-version = "1.85.0"
homepage = "https://github.com/JasterV/event_bus.rs"
repository = "https://github.com/JasterV/event_bus.rs"
homepage = "https://codeberg.org/JasterV/event_bus.rs"
repository = "https://codeberg.org/JasterV/event_bus.rs"
license = "MIT"
[dependencies]
dashmap = "6.1.0"
thiserror = "2.0.17"
async-broadcast = "0.7"
futures = "0.3"
async-stream = "0.3"
dashmap = "6.1.0"
futures = "0.3"
thiserror = "2.0.18"
[dev-dependencies]
fake = "4.4.0"
proptest = { version = "1.11.0", features = ["attr-macro"] }
test-strategy = "0.4.5"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }

View file

@ -1,5 +1,7 @@
# event_bus.rs
[![Crate Version: event_bus_rs](https://img.shields.io/crates/v/event_bus_rs.svg)](https://crates.io/crates/event_bus_rs)
A **runtime-agnostic**, **async**, and **thread-safe** event bus for Rust.
Designed to be **efficient**, **simple**, and **easy to use**, allowing you to publish and subscribe to messages across threads and async tasks.
@ -29,7 +31,7 @@ Add to your `Cargo.toml`:
```toml
[dependencies]
event_bus_rs = "0.1.0"
event_bus_rs = "0.1"
futures = "0.3"
````

View file

@ -7,8 +7,16 @@ no-default-features = false
feature-depth = 1
[advisories]
version = 2
# The path where the advisory database is cloned/fetched into
db-path = "~/.cargo/advisory-db"
# The url(s) of the advisory databases to use
db-urls = ["https://github.com/rustsec/advisory-db"]
# The lint level for crates that have been yanked from their source registry
yanked = "warn"
ignore = []
[licenses]
allow = ["Unicode-3.0", "Apache-2.0", "MIT"]
confidence-threshold = 0.8

View file

@ -1,3 +1,3 @@
[toolchain]
channel = "1.91"
channel = "1.93"
components = ["rustfmt", "clippy", "rust-src", "rust-analyzer"]

View file

@ -1,10 +1,13 @@
#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))]
mod rc_map;
mod subscription;
use crate::{
rc_map::{InsertError, RcMap},
subscription::Subscription,
};
use async_broadcast::{Sender, broadcast};
use async_broadcast::{InactiveReceiver, Sender, broadcast};
use std::sync::Arc;
/// The default topic capacity, it has been set to this value
@ -12,8 +15,17 @@ use std::sync::Arc;
/// set their preferred value.
pub const DEFAULT_TOPIC_CAPACITY: usize = 1000;
mod rc_map;
mod subscription;
/// Utility typed used to keep at least an instance of both a sender and a receiver
/// in memory so the channel doesn't get closed.
///
/// `async_broadcast` will drop a channel if either all the receivers or all the senders get dropped.
#[derive(Clone)]
struct Channel(
pub Sender<Arc<[u8]>>,
// The inactive receiver is never used but it needs to be here
// otherwise we risk the channel being closed if all other receivers are dropped.
#[allow(dead_code)] InactiveReceiver<Arc<[u8]>>,
);
/// Error type returned by the `publish` method.
#[derive(thiserror::Error, Debug)]
@ -32,7 +44,7 @@ pub enum PublishError {
/// When all the subscriptions to a topic get dropped, the topic itself is dropped from memory.
#[derive(Clone)]
pub struct EventBus {
inner: RcMap<Arc<str>, Sender<Arc<[u8]>>>,
inner: RcMap<Arc<str>, Channel>,
topic_capacity: usize,
}
@ -64,17 +76,10 @@ impl EventBus {
/// the topic will automatically be dropped from memory.
pub fn subscribe(&self, topic: &str) -> Subscription {
let (tx, rx) = broadcast(self.topic_capacity);
let channel = Channel(tx, rx.deactivate());
match self.inner.insert(topic.into(), tx) {
Ok(object_ref) => {
// If in the moment of the channel creation, either the sender or the receiver get dropped, the channel will immediately be closed.
//
// This is why we are not using `Subscription::from(object_ref)` in this scenario
// but rather we must make use of the receiver created or the channel will be closed.
Subscription::new_with_rx(object_ref, rx)
}
// In this case we are fine with the new channel we created being dropped.
// Since a channel already exists for this key we don't need to store the receiver and we can let the channel be closed.
match self.inner.insert(topic.into(), channel) {
Ok(object_ref) => Subscription::from(object_ref),
Err(InsertError::AlreadyExists(_key, object_ref)) => Subscription::from(object_ref),
}
}
@ -88,7 +93,7 @@ impl EventBus {
return Ok(());
};
let tx = object_ref.value();
let Channel(tx, _) = object_ref.value();
let result = tx.try_broadcast(Arc::from(data));
match result {
@ -110,32 +115,159 @@ impl EventBus {
#[cfg(test)]
mod tests {
use super::*;
use fake::{Fake, Faker};
use futures::StreamExt;
// Helper function to extract a message from the subscription
async fn get_next_message(sub: &mut Subscription) -> String {
let payload = sub.next().await.expect("Stream unexpectedly closed");
String::from_utf8_lossy(&payload).to_string()
}
use futures::stream;
use proptest::prop_assert_eq;
use test_strategy::proptest;
#[tokio::test(flavor = "multi_thread")]
async fn test_simple_pub_sub() {
async fn test_multithreaded_pub_sub() {
let event_bus = EventBus::new();
let topic = "test_simple";
let expected_message = "Hello EventBus";
let expected_message = b"Hello EventBus";
let mut subscription = event_bus.subscribe(topic);
let task_handle = tokio::spawn(async move { get_next_message(&mut subscription).await });
let task_handle = tokio::spawn(async move { subscription.next().await.unwrap() });
event_bus
.publish(topic, expected_message.as_bytes())
.unwrap();
event_bus.publish(topic, expected_message).unwrap();
let received = task_handle
.await
.expect("Failed to receive result from task");
assert_eq!(received, expected_message);
assert_eq!(&*received, expected_message);
}
#[tokio::test(flavor = "multi_thread")]
async fn test_publish_to_nonexistent_topic() {
let bus = EventBus::new();
let result = bus.publish("missing_topic", b"ignored");
// Should not error, just ignored silently
assert!(result.is_ok());
}
#[tokio::test(flavor = "multi_thread")]
async fn test_multiple_subscribers_receive() {
let topic = "multi_subs";
let bus = EventBus::new();
let mut s1 = bus.subscribe(topic);
let mut s2 = bus.subscribe(topic);
bus.publish(topic, b"msg").unwrap();
let r1 = s1.next().await.unwrap();
let r2 = s2.next().await.unwrap();
assert_eq!(&*r1, b"msg");
assert_eq!(&*r2, b"msg");
}
#[tokio::test(flavor = "multi_thread")]
async fn test_topic_removed_when_no_subscribers() {
let bus = EventBus::new();
let topic = "temp_topic";
{
let mut sub = bus.subscribe(topic);
// Topic exists so publish succeeds
bus.publish(topic, b"hello").unwrap();
// Assert the message was received
let r1 = sub.next().await.unwrap();
assert_eq!(&*r1, b"hello");
// The topic will be cleaned up here
}
// The topic doesn't exist anymore → publish should silently no-op
let result = bus.publish(topic, b"nobody_listens");
// No err: behaves like non-existent topic
assert!(result.is_ok());
}
#[tokio::test(flavor = "multi_thread")]
async fn test_capacity_overflow() {
let topic = "overflow_test";
let bus = EventBus::new_with_topic_capacity(1);
let mut sub = bus.subscribe(topic);
// Fill buffer with one message
bus.publish(topic, b"A").unwrap();
// Second publish should overflow → Err(CapacityOverflow)
let err = bus.publish(topic, b"B").unwrap_err();
matches!(err, PublishError::CapacityOverflow(_));
// Drain the first message to help debugging if needed
let _ = sub.next().await;
}
#[tokio::test(flavor = "multi_thread")]
async fn test_multiple_topics_isolation() {
let bus = EventBus::new();
let mut sub_a = bus.subscribe("A");
let mut sub_b = bus.subscribe("B");
bus.publish("A", b"msgA").unwrap();
bus.publish("A", b"msgC").unwrap();
bus.publish("B", b"msgB").unwrap();
bus.publish("B", b"msgD").unwrap();
let recv_a = sub_a.next().await.unwrap();
let recv_c = sub_a.next().await.unwrap();
let recv_b = sub_b.next().await.unwrap();
let recv_d = sub_b.next().await.unwrap();
assert_eq!(&*recv_a, b"msgA");
assert_eq!(&*recv_c, b"msgC");
assert_eq!(&*recv_b, b"msgB");
assert_eq!(&*recv_d, b"msgD");
}
#[proptest(async = "tokio")]
async fn stress_test_multiple_subscribers_prop(
#[strategy(1usize..100)] subscribers: usize,
#[strategy(20usize..1_000)] total_msgs: usize,
) {
const TOPIC: &str = "stress_multi_subs";
let bus = EventBus::new_with_topic_capacity(total_msgs);
// Generate messages to publish
let mut messages: Vec<Arc<[u8]>> = (0..total_msgs)
.map(|_| Faker.fake::<u64>().to_le_bytes().into())
.collect();
// Register all subscribers
let subs: Vec<_> = (0..subscribers).map(|_| bus.subscribe(TOPIC)).collect();
// Run all subscribers concurrently
let subs_handles = tokio::spawn(async move {
stream::iter(subs)
.map(|sub| sub.take(total_msgs).collect::<Vec<_>>())
.buffer_unordered(subscribers)
.collect::<Vec<_>>()
.await
});
// Publish all messages
for msg in &messages {
bus.publish(TOPIC, msg.as_ref()).unwrap();
}
// Wait for all subscribers to complete
let sub_results = subs_handles.await.unwrap();
// Sort input messages to be able to assert against the results
messages.sort();
for mut result in sub_results {
result.sort();
prop_assert_eq!(&result, &messages, "subscriber missed or altered messages");
}
}
}

View file

@ -5,21 +5,18 @@ use dashmap::DashMap;
use std::{
fmt::Debug,
hash::Hash,
sync::{
Arc, Weak,
atomic::{AtomicIsize, Ordering},
},
sync::{Arc, Weak},
};
/// A smart reference around a key value pair.
///
/// Once it is dropped, it will decrease the reference counter of the pair and potentially remove the pair if the counter hits 0.
#[derive(Clone, Debug)]
#[derive(Debug)]
pub struct ObjectRef<K, V>
where
K: Hash + Eq + Clone,
K: Hash + Eq,
{
parent_ref: Weak<DashMap<K, (AtomicIsize, V)>>,
parent_ref: Weak<DashMap<K, (isize, V)>>,
key: K,
value: V,
}
@ -35,28 +32,22 @@ where
impl<K, V> Drop for ObjectRef<K, V>
where
K: Hash + Eq + Clone,
K: Hash + Eq,
{
fn drop(&mut self) {
let Some(map) = self.parent_ref.upgrade() else {
return;
};
map.alter(&self.key, |_, (count, value)| {
count.fetch_sub(1, Ordering::Relaxed);
(count, value)
});
map.remove_if(&self.key, |_, (count, _)| {
count.load(Ordering::Relaxed) <= 0
});
map.alter(&self.key, |_, (count, value)| (count - 1, value));
map.remove_if(&self.key, |_, (count, _)| *count <= 0);
}
}
#[derive(thiserror::Error, Debug)]
pub enum InsertError<K, V>
where
K: Hash + Eq + Clone + Debug,
K: Hash + Eq + Debug,
{
#[error(
"An entry already exists with the given key: '{0:?}'. You must wait until all existing object references are dropped for the pair to be removed."
@ -74,7 +65,7 @@ where
/// When the references counter of a value hits 0, the whole pair is removed from the map.
#[derive(Clone)]
pub struct RcMap<K, V> {
inner: Arc<DashMap<K, (AtomicIsize, V)>>,
inner: Arc<DashMap<K, (isize, V)>>,
}
impl<K, V> RcMap<K, V>
@ -89,25 +80,18 @@ where
}
pub fn get(&self, key: K) -> Option<ObjectRef<K, V>> {
self.inner.alter(&key, |_, (count, value)| {
count.fetch_add(1, Ordering::Relaxed);
(count, value)
});
self.inner
.alter(&key, |_, (count, value)| (count + 1, value));
let option = self.inner.get(&key);
let value_ref = self.inner.get(&key)?;
match option {
Some(value_ref) => {
let (_count, value) = value_ref.value();
let (_count, value) = value_ref.value();
Some(ObjectRef {
key,
parent_ref: Arc::downgrade(&self.inner),
value: value.clone(),
})
}
None => None,
}
Some(ObjectRef {
key,
parent_ref: Arc::downgrade(&self.inner),
value: value.clone(),
})
}
/// Insert a new pair into the map.
@ -124,9 +108,7 @@ where
return Err(InsertError::AlreadyExists(key, object_ref));
}
let _prev = self
.inner
.insert(key.clone(), (AtomicIsize::new(1), value.clone()));
let _prev = self.inner.insert(key.clone(), (1, value.clone()));
Ok(ObjectRef {
key,

View file

@ -1,5 +1,5 @@
use crate::rc_map::ObjectRef;
use async_broadcast::{Receiver, Sender};
use crate::{Channel, rc_map::ObjectRef};
use async_broadcast::Receiver;
use futures::Stream;
use std::{
pin::Pin,
@ -24,25 +24,13 @@ pub struct Subscription {
// We need to keep the ownership of the object ref
// Otherwise if the object ref gets dropped, it might cleanup the topic
// And the channel would get closed
_object_ref: ObjectRef<Arc<str>, Sender<Arc<[u8]>>>,
_object_ref: ObjectRef<Arc<str>, Channel>,
rx: Receiver<Arc<[u8]>>,
}
impl Subscription {
pub(crate) fn new_with_rx(
object_ref: ObjectRef<Arc<str>, Sender<Arc<[u8]>>>,
rx: Receiver<Arc<[u8]>>,
) -> Self {
Self {
_object_ref: object_ref,
rx,
}
}
}
impl From<ObjectRef<Arc<str>, Sender<Arc<[u8]>>>> for Subscription {
fn from(object_ref: ObjectRef<Arc<str>, Sender<Arc<[u8]>>>) -> Self {
let tx = object_ref.value();
impl From<ObjectRef<Arc<str>, Channel>> for Subscription {
fn from(object_ref: ObjectRef<Arc<str>, Channel>) -> Self {
let Channel(tx, _) = object_ref.value();
let rx = tx.new_receiver();
Self {