maycoon_core/signal/
map.rs

1use crate::signal::{ArcSignal, Listener, Ref, Signal};
2
3/// A signal wrapping another signal and applying a mapping function, when the inner value is requested.
4/// The mapping function will be called every time the inner value is requested via [Signal::get].
5/// This signal cannot be directly mutated. Use [MapSignal::signal] to get the inner signal.
6///
7/// Calling [Signal::set], [Signal::set_value], [Signal::listen] or [Signal::notify] has no effect.
8pub struct MapSignal<T, U> {
9    signal: ArcSignal<T>,
10    map: Box<dyn Fn(Ref<T>) -> Ref<U>>,
11}
12
13impl<T: 'static, U> MapSignal<T, U> {
14    /// Create a new map signal using the given inner signal and mapping function.
15    pub fn new(signal: ArcSignal<T>, map: impl Fn(Ref<T>) -> Ref<U> + 'static) -> Self {
16        Self {
17            signal,
18            map: Box::new(map),
19        }
20    }
21
22    /// Get the inner signal.
23    ///
24    /// Can be used to mutate the inner value.
25    pub fn signal(&self) -> ArcSignal<T> {
26        self.signal.clone()
27    }
28
29    /// Get the inner signal's value, without applying the mapping function.
30    pub fn get_unmapped(&self) -> Ref<T> {
31        self.signal.get()
32    }
33}
34
35impl<T: 'static, U: 'static> Signal<U> for MapSignal<T, U> {
36    fn get(&self) -> Ref<U> {
37        (self.map)(self.get_unmapped())
38    }
39
40    fn set_value(&self, _: U) {}
41
42    fn listen(&mut self, _: Listener<U>) {}
43
44    fn notify(&self) {
45        self.signal.notify();
46    }
47}