[][src]Crate revent

Synchronous publisher/subscriber broker event system for Rust.

Introduction

The synchronous publisher/subscriebr broker event system (event hub for short) is a mechanism by which objects can communicate without knowing about each other. Event hubs are implemented by defining a set of signals to which an arbitrary struct can subscribe. Said struct will then have to impl that signal and will be invoked once that signal is called.

Example

use revent::{hub, Hubbed, Selfscribe, Subscriber};

// Main macro of this crate. Sets up types and boilerplate to make the event hub work.
hub! {
    // Module for holding helper structs and other things, a user does not need to
    // care about its contents.
    mod x;
    // Hub and Sub. The Hub is the top-level signal emitter; from the `Hub` you emit
    // signals. The `Sub` is similar to the `Hub` but allows one to subscribe to
    // signals, and is used only in the `Selfscribe` trait.
    Hub(Sub) {
        // A signal is just a function with the ability to
        // propagate further signals to `Subsignals`. You can decide which names
        // to use here.
        signal: fn(i32) -> (), Subsignals {
            // This is a "subsignal" - a signal which can be signalled from `signal`.
            subsignal: fn(str) -> (), EmptySignals,
        },
        subsignal: fn(str) -> (), EmptySignals {},
        unrelated: fn(()) -> (), UnrelatedSignals {},
    }
}

// Create a hub
let hub = Hub::default();

struct X;

// Handler for the signal `signal`. Types in this impl must match the one given in the hub
// macro.
impl Subscriber<i32, (), Subsignals> for X {
    fn event(&mut self, input: &i32, subsignals: &Subsignals) {
        println!("Hello world!");

        // We can now call signals defined in `Subsignals`.
        subsignals.subsignal("A string from signal");
    }
}

impl Selfscribe<Sub> for X {
    fn subscribe(&mut self, this: &Hubbed<Self>, hub: &mut Sub) {
        // Make `X` subscribe to the signal `signal`.
        hub.signal(this);
    }
}

// Add an object of X to this hub.
hub.subscribe(X);

// Invoke `signal` on this hub.
hub.signal(&123);

// Return values can be iterated from signals. Any unconsumed iterator values are consumed in
// the `Drop` implementation for this iterator.
for _ in hub.signal(&123) {
    // ...
}

Validation

To avoid chained signalling (where one object signals itself causing mutable aliasing), or recursive signalling (where one object signals another which signals back again) we perform two checks at initialization time.

Check 1 is performed during hub construction via Hub::default() and ensures that there exists no possibility for subsignals to call into their originating signal.

Check 2 is performed after a Selfscribe has performed a Selfscribe::subscribe and ensures that the object does not have the ability to signal itself.

Both checks ensure that no object gets mutably borrowed more than once.

Limitations

It is currently not possible to create a signal that has an argument containing lifetimes.

Macros

hub

Generate an event hub.

Structs

EmitIter

Iterator over all subscriber return values. Will finish itself on drop.

Hubbed

Wrapper around a shared pointer to a subscriber.

Recursion

Computes signal recursions.

Traits

Selfscribe

Selfscribe allows a subscriber to decide which notification channels it will subscribe to.

Subscriber

Subscriber trait for a specific input type and re-sending scheme.