flourish_unsend/
lib.rs

1#![warn(clippy::pedantic)]
2#![warn(missing_docs)]
3#![warn(unreachable_pub)]
4// #![warn(clippy::single_call_fn)]
5//! <details><summary>README / Quick Start (click to expand)</summary>
6//!
7#![cfg_attr(feature = "_doc", doc = include_str!("../README.md"))]
8//!
9//! </details>
10//!
11//! # Safety Notes
12//!
13//! [`impl FnMut`](`FnMut`) closures that appear in parameters with "`fn_pin`" in their name are guaranteed to be [pinned](`core::pin`) when called.
14
15pub mod conversions;
16mod opaque;
17
18mod signal;
19pub use signal::{Signal, SignalDyn, SignalDynCell};
20
21pub mod unmanaged;
22
23//TODO: Inter-runtime signals (i.e. takes two signals runtimes as parameters, acts as source for one and dynamic subscriber for the other).
24
25mod signal_arc;
26pub use signal_arc::{
27	SignalArc, SignalArcDyn, SignalArcDynCell, SignalWeak, SignalWeakDyn, SignalWeakDynCell,
28};
29
30mod subscription;
31pub use subscription::{Subscription, SubscriptionDyn, SubscriptionDynCell};
32
33mod effect;
34pub use effect::Effect;
35
36mod traits;
37pub use traits::Guard;
38
39pub use isoprenoid_unsend::runtime::{LocalSignalsRuntime, Propagation, SignalsRuntimeRef};
40
41pub mod prelude {
42	//! Unmanaged signal accessors and [`SignalsRuntimeRef`].  
43	//! Not necessary to use managed signals.
44
45	pub use crate::{
46		unmanaged::{UnmanagedSignal, UnmanagedSignalCell},
47		SignalsRuntimeRef,
48	};
49}
50
51#[doc(hidden)]
52pub mod __ {
53	pub use super::unmanaged::{
54		raw_effect::new_raw_unsubscribed_effect,
55		raw_subscription::{
56			new_raw_unsubscribed_subscription, pin_into_pin_impl_source, pull_new_subscription,
57		},
58	};
59}
60
61/// Shadows each identifier in place with its [`Clone::clone`].
62///
63/// This is useful to duplicate smart pointers:
64///
65/// ```
66/// # {
67/// # #![cfg(feature = "local_signals_runtime")] // flourish feature
68/// use flourish_unsend::{shadow_clone, LocalSignalsRuntime};
69///
70/// type Signal<T, S> = flourish_unsend::Signal<T, S, LocalSignalsRuntime>;
71///
72/// let a = Signal::cell(1);
73/// let b = Signal::cell(2);
74/// let c = Signal::computed({
75///     shadow_clone!(a, b);
76///     move || a.get() + b.get()
77/// });
78///
79/// drop((a, b, c));
80/// # }
81/// ```
82#[macro_export]
83macro_rules! shadow_clone {
84	($ident:ident$(,)?) => {
85		// This would warn because of extra parentheses… and it's fewer tokens.
86		let $ident = ::std::clone::Clone::clone(&$ident);
87	};
88    ($($ident:ident),*$(,)?) => {
89		let ($($ident),*) = ($(::std::clone::Clone::clone(&$ident)),*);
90	};
91}
92
93/// Shadows each reference in place with its [`ToOwned::Owned`].
94///
95/// This is useful to upgrade and persist borrows:
96///
97/// ```
98/// use std::ops::Add;
99/// use flourish_unsend::{prelude::*, shadow_ref_to_owned, Signal, SignalArc, SignalDyn};
100///
101/// fn live_sum<'a, SR: 'a + SignalsRuntimeRef>(
102/// 	a: &SignalDyn<'a, u64, SR>,
103/// 	b: &SignalDyn<'a, u64, SR>,
104/// ) -> SignalArc<u64, impl 'a + UnmanagedSignal<u64, SR>, SR> {
105/// 	Signal::computed_with_runtime({
106/// 		shadow_ref_to_owned!(a, b);
107/// 		move || a.get() + b.get()
108/// 	}, a.clone_runtime_ref())
109/// }
110/// ```
111#[macro_export]
112macro_rules! shadow_ref_to_owned {
113	($ident:ident$(,)?) => {
114		// This would warn because of extra parentheses… and it's fewer tokens.
115		let $ident = ::std::borrow::ToOwned::to_owned($ident);
116	};
117    ($($ident:ident),*$(,)?) => {
118		let ($($ident),*) = ($(::std::borrow::ToOwned::to_owned($ident)),*);
119	};
120}