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.