auralis_signal/lib.rs
1//! auralis-signal: Reactive signal primitive with version tracking and
2//! proactive waker deregistration.
3//!
4//! # Overview
5//!
6//! This crate provides [`Signal<T>`] and [`Memo<T>`] — the foundational
7//! reactive primitives of the Auralis kernel. Every signal carries a
8//! monotonic version number. When a change-detection future is dropped
9//! before resolution, it eagerly removes its waker from the signal's
10//! internal list, preventing stale-waker accumulation (the "proactive
11//! deregistration" guarantee).
12//!
13//! The crate is **zero-dependency**, **`#![forbid(unsafe_code)]`**, and
14//! intentionally single-threaded (`!Send` / `!Sync`). See the
15//! [repository design docs](https://github.com/user/auralis) for the
16//! rationale behind those choices.
17//!
18//! # Quick example
19//!
20//! ```
21//! use auralis_signal::Signal;
22//!
23//! let sig = Signal::new(0);
24//! sig.set(1);
25//! assert_eq!(sig.read(), 1);
26//! ```
27
28#![forbid(unsafe_code)]
29#![warn(missing_docs, clippy::all, clippy::pedantic)]
30#![allow(clippy::module_name_repetitions)]
31
32mod batch;
33mod future;
34mod memo;
35mod observer;
36mod signal;
37
38/// Create a [`Memo`] with automatic clone of captured identifiers.
39///
40/// Instead of manually cloning every signal before the `move` closure:
41///
42/// ```
43/// use auralis_signal::{Signal, Memo};
44///
45/// let a = Signal::new(1);
46/// let b = Signal::new(2);
47///
48/// // Without the macro:
49/// let sum = Memo::new({
50/// let a = a.clone();
51/// let b = b.clone();
52/// move || a.read() + b.read()
53/// });
54///
55/// // With the macro:
56/// let sum = auralis_signal::memo!(a, b => a.read() + b.read());
57/// ```
58///
59/// The macro expands to the same pattern — a `move` closure with each
60/// captured identifier cloned into a local variable of the same name.
61#[macro_export]
62macro_rules! memo {
63 ($($capture:ident),+ $(,)? => $body:expr) => {
64 $crate::Memo::new({
65 $(let $capture = $capture.clone();)+
66 move || $body
67 })
68 };
69}
70
71pub use batch::{batch, in_batch};
72pub use future::{FilterChangedFuture, MapChangedFuture, SignalChangedFuture};
73pub use memo::Memo;
74#[doc(hidden)]
75pub use signal::{install_schedule_hook, remove_schedule_hook};
76#[doc(hidden)]
77pub use signal::{subscribe, unsubscribe};
78pub use signal::{Signal, SignalMap};