pub trait EventId: AsRef<str> { }Expand description
A generic event id trait for type-safe event identification.
This trait enables using custom types (especially enums) as event identifiers, providing compile-time guarantees about which events exist in your system.
§Benefits of Type-Safe Event IDs
Using enums instead of raw strings provides several advantages:
- Bounded event set: Compiler enforces a fixed set of events, preventing typos
- Memory safety: Enum variants guarantee a bounded number of event counters
- Refactoring safety: Renaming events shows all usage sites at compile time
- Documentation: Enum definition serves as single source of truth for all events
§Memory Implications
Each unique event ID creates a new counter in memory (~2KB per event with default config).
Using patterns like format!("user:{}:event", user_id) creates unbounded event IDs
that grow with your user base, defeating the fixed-memory guarantee.
Safe pattern (bounded events):
use tiny_counter::{EventStore, EventId};
#[derive(Debug)]
enum AppEvent {
UserLogin,
UserLogout,
ApiCall,
}
impl AsRef<str> for AppEvent {
fn as_ref(&self) -> &str {
match self {
AppEvent::UserLogin => "user_login",
AppEvent::UserLogout => "user_logout",
AppEvent::ApiCall => "api_call",
}
}
}
impl EventId for AppEvent {}
let store = EventStore::new();
store.record(AppEvent::UserLogin); // Type-safe, bounded memoryUnsafe pattern (unbounded events, avoid this):
let store = EventStore::new();
for user_id in 0..1_000_000 {
// WARNING: Creates 1M separate counters, ~2GB memory!
store.record(format!("user:{}:login", user_id));
}For per-user tracking, use a single event ID and separate EventStore instances per user, or aggregate at the application level rather than in the event store.
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".