use evno::{Bus, Chain, Close, Emit, Event, Guard, Step, from_fn};
use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Clone, PartialEq)]
struct AppEvent(String);
#[derive(Debug, Clone, PartialEq)]
struct RequestContext {
request_id: u64,
}
#[derive(Debug, Clone, PartialEq)]
struct ContextualEvent<E>(E, RequestContext);
#[derive(Clone)]
struct RequestTracer(Arc<AtomicU64>);
impl Step for RequestTracer {
type Event<E: Event> = ContextualEvent<E>;
async fn process<E: Event>(self, event: E) -> Self::Event<E> {
let id = self.0.fetch_add(1, Ordering::Relaxed);
ContextualEvent(event, RequestContext { request_id: id })
}
}
#[tokio::main]
async fn main() {
let bus = Bus::new(4);
let counter = Arc::new(AtomicU64::new(1));
let chain = Chain::from(bus.clone()).prepend(RequestTracer(counter));
bus.on(from_fn(
|event: Guard<ContextualEvent<AppEvent>>| async move {
let (original_event, context) = (&event.0, &event.1);
println!(
"[Listener] Received '{}' | Injected ID: {}",
original_event.0, context.request_id
);
},
));
chain.emit(AppEvent("Start Request".to_string())).await;
chain.emit(AppEvent("End Request".to_string())).await;
chain.close().await;
bus.close().await;
println!("\nChain and Bus closed successfully.");
}