pub trait SignalOrFn {
type Output;
fn run(&self) -> Self::Output;
}
impl<F, T> SignalOrFn for F
where
F: Fn() -> T,
{
type Output = T;
fn run(&self) -> T {
self()
}
}
#[cfg(test)]
mod tests {
use super::SignalOrFn;
#[allow(deprecated)]
use crate::wrappers::read::MaybeSignal;
use crate::{
computed::Memo,
owner::Owner,
signal::{ArcRwSignal, RwSignal},
traits::Get,
wrappers::read::{MaybeProp, Signal},
};
fn collect<S>(each: S) -> Vec<i32>
where
S: SignalOrFn<Output = Vec<i32>>,
{
each.run()
}
#[test]
fn accepts_signal_or_closure() {
let owner = Owner::new();
owner.set();
assert_eq!(collect(|| vec![1, 2, 3]), vec![1, 2, 3]);
let sig = RwSignal::new(vec![4, 5, 6]);
assert_eq!(collect(sig), vec![4, 5, 6]);
let wrapped: Signal<Vec<i32>> = Signal::derive(move || vec![7, 8]);
assert_eq!(collect(wrapped), vec![7, 8]);
let src = RwSignal::new(vec![9]);
assert_eq!(collect(move || src.get()), vec![9]);
}
#[test]
#[allow(deprecated)]
fn coverage_across_signal_types() {
let owner = Owner::new();
owner.set();
fn accepts_signal_or_fn<S: SignalOrFn<Output = i32>>(s: S) -> i32 {
s.run()
}
fn accepts_signal_or_fn_opt<S: SignalOrFn<Output = Option<i32>>>(
s: S,
) -> Option<i32> {
s.run()
}
assert_eq!(accepts_signal_or_fn(RwSignal::new(1)), 1);
assert_eq!(accepts_signal_or_fn(Memo::new(|_| 2)), 2);
assert_eq!(accepts_signal_or_fn(Signal::derive(|| 3)), 3);
assert_eq!(accepts_signal_or_fn(MaybeSignal::from(4)), 4);
assert_eq!(accepts_signal_or_fn(ArcRwSignal::new(5)), 5);
assert_eq!(accepts_signal_or_fn_opt(MaybeProp::from(6)), Some(6));
assert_eq!(accepts_signal_or_fn(|| 7), 7);
}
}