psbus

Generic Publish / Subscribe model for application messaging

NOTE: This module was heavily inspired by Lakelezz's (now dormant) heylisten: https://github.com/Lakelezz/heylisten

psbus allows for any application to implement their own Publish/Subscribe model for easy messaging. psbus currently supports the following use cases: * Single-threaded event dispatch * Single-threaded + prioritized event dispatch * Thread-safe / synchronized event dispatch * Thread-safe / synchronized + prioritized event dispatch

Installation

Add this to your Cargo.toml:

toml [dependencies] psbus = "0.1.0"

Example

Aside from type name differences, the usage is consistent across the board for dispatchers. This example uses a single-threaded, non-prioritized dispatch model.

```rust use psbus::{types::BusRequest, rc::{Event, Subscriber, Publisher, EventBus}}; use std::rc::Rc;

// Define the categories into which your events will fall

[derive(Debug, Eq, PartialEq, Hash, Clone)]

pub enum TestEventType { Variant1, Variant2, }

// Define the events themselves, note that you can use bare, tuple or struct enums all the same!

[derive(Debug, Eq, PartialEq, Hash, Clone)]

pub enum TestEvent { ButtonPressed(u32), SomeOtherEvent, }

// Implement the Event trait for your custom event impl Event for TestEvent { fn category(&self) -> TestEventType { match self { TestEvent::ButtonPressed(_) => TestEventType::Variant1, TestEvent::SomeOtherEvent => TestEventType::Variant2, // And more... } } }

// Now lets make a test Subscriber... pub struct TestSubscriber { id: Uuid, } impl Subscriber for TestSubscriber { fn id(&self) -> &Uuid { &self.id }

// ! Although we get a TestEvent enum, it is guaranteed to be only of the TestEventType that we are subscribed to
fn on_event(&self, event: &ThermiteEvent) -> BusRequest {
    println!("Subscriber {} received event: {:?}", self.id, event);
    // What do we want to tell the bus to do after this subscriber is processed? For now, nothing... see crate::types::BusRequest for more actions
    BusRequest::NoActionNeeded
}

}

// And a test Publisher... pub struct TestPublisher {} impl Publisher for TestPublisher { // You can override the publish_event method here if you really want to... }

// And finally, we define our EventBus type pub type TestEventBus = EventBus;

fn main() { // Again, what you wrap these datastructures with completely depends on your use case. let subscriber = Rc::new(TestSubscriber { id: Uuid::default() }); let publisher = Rc::new(TestPublisher {}); let bus = Rc::new(RefCell::new(TestEventBus::default()));

// Subscribe our subscriber to receive any event falling under the `Variant1` category
bus.try_borrow_mut().expect("Couldn't borrow event bus as mutable").subscribe(&subscriber, TestEventType::Variant1);

// Publish an event to be received by the subscriber (NOTE: Call site here may vary depending on how you wrap your datastructures)
publisher.publish_event(&TestEvent::ButtonPressed(1), &mut bus.try_borrow_mut().expect("Couldn't borrow event bus as mutable"));

} ```