toys/lib.rs
1//! # toys
2//!
3//! Lightweight application primitives for async Rust, built on [Tokio].
4//!
5//! Each primitive lives behind a feature flag so you only compile what you need.
6//!
7//! ## Feature flags
8//!
9//! | Flag | Default | Enables |
10//! |------|:-------:|---------|
11//! | `event` | | Typed global broadcast event bus and the [`asynchronous`] attribute macro |
12//!
13//! ## Event system
14//!
15//! The event system decouples producers and consumers of typed events through a
16//! process-wide broadcast channel. Any number of handlers can subscribe to the same
17//! event type independently.
18//!
19//! ```text
20//! event::<E>().dispatch(e)
21//! │
22//! ▼
23//! ┌──────────────────────┐
24//! │ EventChannel<E> │ ← one per type, process-global
25//! └──────────┬───────────┘
26//! │ broadcast
27//! ┌──────────────┼──────────────┐
28//! ▼ ▼ ▼
29//! Handler A Handler B Handler C
30//! ```
31//!
32//! ### Minimal example
33//!
34//! ```no_run
35//! use toys::event::{event, EventHandler, EventLoop};
36//! use toys::asynchronous;
37//! use std::sync::Arc;
38//!
39//! pub enum Signal { Ping }
40//!
41//! struct Logger;
42//!
43//! #[asynchronous]
44//! impl EventHandler<Signal> for Logger {
45//! async fn handle(self: Arc<Self>, _event: Signal) {
46//! println!("ping received");
47//! }
48//! }
49//!
50//! # tokio_test::block_on(async {
51//! let logger = Arc::new(Logger) as Arc<dyn EventHandler<Signal>>;
52//! EventLoop::<Signal>::new().dispatch(&[logger]).await;
53//! event::<Signal>().dispatch(Signal::Ping).await.unwrap();
54//! # });
55//! ```
56//!
57//! [`EventHandler`]: event::EventHandler
58//! [`EventLoop`]: event::EventLoop
59//! [`EventLoop::dispatch`]: event::EventLoop::dispatch
60//! [Tokio]: https://tokio.rs
61
62#![allow(
63 dead_code,
64 unused,
65 non_camel_case_types,
66 non_snake_case,
67 non_upper_case_globals
68)]
69
70/// Typed global broadcast event bus.
71///
72/// See [`event::event`] to obtain a channel, [`event::EventHandler`] to react to
73/// events, and [`event::EventLoop`] to register handlers.
74#[cfg(feature = "event")]
75pub mod event;
76
77/// Transforms `async fn` methods in `trait` and `impl` blocks into boxed,
78/// dyn-compatible futures.
79///
80/// Re-exported from `toys_macros`. See that crate's documentation for supported
81/// arguments (`no_sync`, `local`, `static_lifetime`).
82#[cfg(feature = "event")]
83pub use toys_macros::asynchronous;