diff --git a/packages/signals/src/map.rs b/packages/signals/src/map.rs index e83dabe7b..9e1ec7ce5 100644 --- a/packages/signals/src/map.rs +++ b/packages/signals/src/map.rs @@ -4,18 +4,16 @@ use std::cell::Ref; use std::fmt::Debug; use std::fmt::Display; -/// A signal that can only be read from. -pub struct SignalMap { - inner: Signal, - mapping: fn(&T) -> &U, +/// A read only signal that has been mapped to a new type. +pub struct SignalMap { + mapping: Box Ref<'static, U>>, } impl SignalMap { - /// Create a new read-only signal. + /// Create a new mapped signal. pub fn new(signal: Signal, mapping: fn(&T) -> &U) -> Self { Self { - inner: signal, - mapping, + mapping: Box::new(move || Ref::map(signal.read(), |v| (mapping)(v))), } } @@ -26,56 +24,56 @@ impl SignalMap { /// Get the current value of the signal. This will subscribe the current scope to the signal. pub fn read(&self) -> Ref { - Ref::map(self.inner.read(), |v| (self.mapping)(v)) + (self.mapping)() } /// Run a closure with a reference to the signal's value. pub fn with(&self, f: impl FnOnce(&U) -> O) -> O { - self.inner.with(|v| f((self.mapping)(v))) + f(&*self.read()) } } -impl SignalMap { +impl SignalMap { /// Get the current value of the signal. This will subscribe the current scope to the signal. pub fn value(&self) -> U { self.read().clone() } } -impl PartialEq for SignalMap { +impl PartialEq for SignalMap { fn eq(&self, other: &Self) -> bool { self.inner == other.inner } } -impl std::clone::Clone for SignalMap { +impl std::clone::Clone for SignalMap { fn clone(&self) -> Self { *self } } -impl Copy for SignalMap {} +impl Copy for SignalMap {} -impl Display for SignalMap { +impl Display for SignalMap { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.with(|v| Display::fmt(v, f)) } } -impl Debug for SignalMap { +impl Debug for SignalMap { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.with(|v| Debug::fmt(v, f)) } } -impl SignalMap> { +impl SignalMap> { /// Read a value from the inner vector. - pub fn get(&self, index: usize) -> Option> { + pub fn get(&self, index: usize) -> Option> { Ref::filter_map(self.read(), |v| v.get(index)).ok() } } -impl SignalMap> { +impl SignalMap> { /// Unwraps the inner value and clones it. pub fn unwrap(&self) -> U where @@ -85,7 +83,7 @@ impl SignalMap> { } /// Attemps to read the inner value of the Option. - pub fn as_ref(&self) -> Option> { + pub fn as_ref(&self) -> Option> { Ref::filter_map(self.read(), |v| v.as_ref()).ok() } }