Expand description
Event-Driven Architecture support for Armature
This crate provides in-process event publishing and handling.
§Features
- Event Bus - Publish/subscribe event system
- Event Handlers - Decorator-based event handling
- Type-safe - Strong typing with compile-time safety
- Async - Full async/await support
- Flexible - Sync and async handler execution
§Quick Start
ⓘ
use armature_events::*;
use async_trait::async_trait;
// Define an event
#[derive(Debug, Clone)]
struct UserCreatedEvent {
metadata: EventMetadata,
user_id: String,
email: String,
}
impl Event for UserCreatedEvent {
fn event_name(&self) -> &str { "user_created" }
fn event_id(&self) -> Uuid { self.metadata.id }
fn timestamp(&self) -> DateTime<Utc> { self.metadata.timestamp }
fn as_any(&self) -> &dyn Any { self }
fn clone_event(&self) -> Box<dyn Event> { Box::new(self.clone()) }
}
// Define a handler
#[derive(Clone)]
struct EmailHandler;
#[async_trait]
impl EventHandler<UserCreatedEvent> for EmailHandler {
async fn handle(&self, event: &UserCreatedEvent) -> Result<(), EventHandlerError> {
println!("Sending welcome email to {}", event.email);
Ok(())
}
}
// Use the event bus
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let bus = EventBus::new();
// Subscribe handler
bus.subscribe::<UserCreatedEvent, _>(TypedEventHandler::new(EmailHandler));
// Publish event
let event = UserCreatedEvent {
metadata: EventMetadata::new("user_created"),
user_id: "123".to_string(),
email: "alice@example.com".to_string(),
};
bus.publish(event).await?;
Ok(())
}§Multiple Handlers
ⓘ
// Subscribe multiple handlers
bus.subscribe::<UserCreatedEvent, _>(TypedEventHandler::new(EmailHandler));
bus.subscribe::<UserCreatedEvent, _>(TypedEventHandler::new(AnalyticsHandler));
bus.subscribe::<UserCreatedEvent, _>(TypedEventHandler::new(AuditHandler));
// All handlers will be invoked
bus.publish(event).await?;§Configuration
ⓘ
let bus = EventBusBuilder::new()
.async_handling(true) // Run handlers concurrently
.continue_on_error(true) // Don't stop on handler errors
.enable_logging(true) // Log events
.build();§Error Handling
ⓘ
let bus = EventBusBuilder::new()
.continue_on_error(false) // Stop on first error
.build();
match bus.publish(event).await {
Ok(()) => println!("All handlers succeeded"),
Err(EventBusError::HandlersFailed(errors)) => {
eprintln!("Some handlers failed: {:?}", errors);
}
Err(e) => eprintln!("Publish error: {}", e),
}Re-exports§
pub use bus::EventBus;pub use bus::EventBusBuilder;pub use bus::EventBusConfig;pub use bus::EventBusError;pub use event::DomainEvent;pub use event::DynEventHandler;pub use event::Event;pub use event::EventHandler;pub use event::EventHandlerError;pub use event::EventMetadata;pub use event::TypedEventHandler;