Key Features
- Zero-cost abstractions: No runtime overhead for event dispatch.
- Type-safe: Compile-time guarantees, plus a typed
ListenerErrorinstead ofBox<dyn Error>. - Thread-safe: Built for concurrent applications, with
parking_lotlocks that never poison. - Lock-free metrics: Per-event-type
AtomicU64counters; the dispatch path never takes a write lock. - Async support: Full async/await compatibility.
- Flexible: Support for sync, async, and priority-based listeners (FIFO within equal priority).
- Easy to use: Simple API and intuitive methods.
- Performance: Optimized for high-throughput scenarios; subscribe is O(n), dispatch is read-lock-only.
- Monitoring: Built-in metrics, middleware, and
loom-verified concurrency invariants.
Quick Start
Add this to your Cargo.toml:
[]
= "0.9.0"
# For async support (default)
= { = "0.9.0", = ["async"] }
# Sync-only build
= { = "0.9.0", = false }
MSRV: Rust 1.81.
Basic Usage
use *;
// Define your event
// Create dispatcher and subscribe
let dispatcher = new;
dispatcher.on;
// Dispatch events
dispatcher.emit;
Features
Priority System
use ;
let dispatcher = new;
// High priority listener executes first
dispatcher.subscribe_with_priority;
// Normal priority listener executes second
dispatcher.on;
Async Support
// Enable with the "async" feature
dispatcher.subscribe_async;
let result = dispatcher.dispatch_async.await;
Middleware
// Add middleware for logging, filtering, etc.
dispatcher.add_middleware;
Error Handling
Listeners return Result<(), ListenerError>. ListenerError wraps any
Error + Send + Sync + 'static and converts from &str, String, or
an existing Box<dyn Error + Send + Sync> via Into, so common
patterns like Err("bad input".into()) keep working.
use ListenerError;
dispatcher.subscribe;
let result = dispatcher.dispatch;
if result.all_succeeded else
Examples
Run the examples:
Benchmarks