1//! A few handy utilities.
23use crate::*;
45/// A trait that is implemented for reactive data that can be tracked, such as [`Signal`].
6///
7/// Also implemented for tuples containing `Trackable`s.
8pub trait Trackable {
9/// Track the data reactively.
10fn _track(&self);
11}
1213impl<T> Trackable for Signal<T> {
14fn _track(&self) {
15self.track();
16 }
17}
1819impl<T> Trackable for ReadSignal<T> {
20fn _track(&self) {
21self.track();
22 }
23}
2425macro_rules! impl_trackable_deps_for_tuple {
26 ($($T:tt),*) => {
27paste::paste! {
28impl<$($T,)*> Trackable for ($($T,)*)
29where
30$($T: Trackable,)*
31 {
32fn _track(&self) {
33let ($([<$T:lower>],)*) = self;
34 $(
35 [<$T:lower>]._track();
36 )*
37 }
38 }
39 }
40 }
41}
4243impl_trackable_deps_for_tuple!(A);
44impl_trackable_deps_for_tuple!(A, B);
45impl_trackable_deps_for_tuple!(A, B, C);
46impl_trackable_deps_for_tuple!(A, B, C, D);
47impl_trackable_deps_for_tuple!(A, B, C, D, E);
48impl_trackable_deps_for_tuple!(A, B, C, D, E, F);
49impl_trackable_deps_for_tuple!(A, B, C, D, E, F, G);
50impl_trackable_deps_for_tuple!(A, B, C, D, E, F, G, H);
51impl_trackable_deps_for_tuple!(A, B, C, D, E, F, G, H, I);
52impl_trackable_deps_for_tuple!(A, B, C, D, E, F, G, H, I, J);
53impl_trackable_deps_for_tuple!(A, B, C, D, E, F, G, H, I, J, K);
54impl_trackable_deps_for_tuple!(A, B, C, D, E, F, G, H, I, J, K, L);
5556/// A helper function for making dependencies explicit.
57///
58/// # Params
59/// * `deps` - A list of signals/memos that are tracked. This can be a single signal or it can be a
60/// tuple of signals.
61/// * `f` - The callback function.
62///
63/// # Example
64/// ```
65/// # use sycamore_reactive::*;
66/// # create_root(|| {
67/// let state = create_signal(0);
68///
69/// create_effect(on(state, move || {
70/// println!("State changed. New state value = {}", state.get());
71/// }));
72/// // Prints "State changed. New state value = 0"
73///
74/// state.set(1);
75/// // Prints "State changed. New state value = 1"
76/// # });
77/// ```
78pub fn on<T>(
79 deps: impl Trackable + 'static,
80mut f: impl FnMut() -> T + 'static,
81) -> impl FnMut() -> T + 'static {
82move || {
83 deps._track();
84 f()
85 }
86}