A lightweight Rust crate for building event-driven applications on top of Tokio's async I/O streams with low overhead. Facilitates decoupled architectures, suitable for inter-process communication or modular designs.
- Event-driven Architecture: Transforms async I/O operations into unified event streams
- Tokio Integration: Built upon and integrates seamlessly with Tokio's async runtime
- Extensibility: Supports custom event types and dynamic handler registration
- Bi-directional Communication: Enables event emission and response handling through Procedure Calls
See full working examples in the examples
directory.
#[derive(Deserialize, Serialize, Debug, Event)]
pub struct Ping {
pub timestamp: i64,
}
// Custom event tag
#[derive(Deserialize, Serialize, Debug, Event)]
#[event(tag = "com::demo::my::Event")]
pub struct CustomEvent(pub String, pub i64);
#[subscriber]
async fn handle_ping(state: State<AppState>, event: Ping) -> Result {
state.wright.emit(&Pong { timestamp: event.timestamp })?;
Ok(())
}
static SUBSCRIBERS: &[Subscriber<AppState>] = &[create_subscriber!(handle_ping)];
// Build the event bus
let subscribers = Subscribers::init(SUBSCRIBERS);
let mut builder = BusBuilder::new(subscribers);
builder.add_pair(IoPair::stdio());
let (bus, effect_wright) = builder.build();
// Run the bus
let state = State::new(AppState {}, effect_wright);
bus.run(state, &|error| { eprintln!("{:?}", error); }).await.join().await;
See the complete RPC example in examples/rpc
.
// Custom the path
#[derive(Deserialize, Serialize, Debug, ProcedureCall)]
#[procedure(path = "com::demo::my::CallPrint")]
pub struct CallPrint(pub String);
impl ProcedureCallRequest for CallPrint {
type RESPONSE = CallPrintResponse;
}
#[derive(Deserialize, Serialize, Debug, ProcedureCall)]
pub struct CallPrintResponse(pub u64);
impl ProcedureCallResponse for CallPrintResponse {}
#[procedure]
async fn print_handler(request: CallPrint) -> Result {
println!("Message: {}", request.0);
Ok(CallPrintResponse(42))
}
let response = state.call(&CallPrint("Hello".to_string())).await?;
// ^ CallPrintResponse
This project is licensed under the Unlicense - see the LICENSE file for details.
Special thanks to the Channels project for providing inspiration through its elegant communication model implementation. The simplicity and effectiveness of its design greatly influenced the development of IOEVENT's core architecture.
Built on top of Tokio, the robust asynchronous runtime for Rust. IOEVENT leverages Tokio's powerful async I/O capabilities and efficient task scheduler to deliver high-performance event processing.