From e87bf87157ba1658c85a620e2318100d4ffc762b Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Tue, 5 Mar 2024 14:53:22 +0000 Subject: [PATCH] `SignalUpdate` now uses `GAT`s for it's `Value` type. --- dynatos-loadable/src/lazy_loadable.rs | 12 +++++++----- dynatos-reactive/src/derived.rs | 3 +++ dynatos-reactive/src/lib.rs | 16 ++++++++-------- dynatos-reactive/src/signal.rs | 8 ++++---- dynatos-reactive/src/with_default.rs | 8 ++++---- dynatos-router/src/location.rs | 4 ++-- dynatos-router/src/query_array_signal.rs | 4 ++-- dynatos-router/src/query_signal.rs | 4 ++-- 8 files changed, 32 insertions(+), 27 deletions(-) diff --git a/dynatos-loadable/src/lazy_loadable.rs b/dynatos-loadable/src/lazy_loadable.rs index 2888f27..2134b21 100644 --- a/dynatos-loadable/src/lazy_loadable.rs +++ b/dynatos-loadable/src/lazy_loadable.rs @@ -130,7 +130,8 @@ impl LazyLoadable { /// Will notify any subscribers of the value. pub fn update_unloaded(&self, f: impl FnOnce(Loadable<&mut T, E>) -> R) -> R where - E: Clone, + T: 'static, + E: Clone + 'static, { let mut output = None; self.inner.update(|inner| output = Some(f(inner.as_mut()))); @@ -168,15 +169,16 @@ where impl SignalUpdate for LazyLoadable where - E: Clone, + T: 'static, + E: Clone + 'static, { - type Value = Loadable; + type Value<'a> = Loadable<&'a mut T, E>; fn update(&self, f: F) -> O where - F: FnOnce(&mut Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { self.load(); - self.inner.update(f) + self.inner.update(|loadable| f(loadable.as_mut())) } } diff --git a/dynatos-reactive/src/derived.rs b/dynatos-reactive/src/derived.rs index 43d00ed..f02c6ef 100644 --- a/dynatos-reactive/src/derived.rs +++ b/dynatos-reactive/src/derived.rs @@ -102,6 +102,7 @@ struct EffectFn { impl FnOnce<()> for EffectFn where + T: 'static, F: Fn() -> T, { type Output = (); @@ -112,6 +113,7 @@ where } impl FnMut<()> for EffectFn where + T: 'static, F: Fn() -> T, { extern "rust-call" fn call_mut(&mut self, args: ()) -> Self::Output { @@ -120,6 +122,7 @@ where } impl Fn<()> for EffectFn where + T: 'static, F: Fn() -> T, { extern "rust-call" fn call(&self, _args: ()) -> Self::Output { diff --git a/dynatos-reactive/src/lib.rs b/dynatos-reactive/src/lib.rs index b9ae098..ba976bd 100644 --- a/dynatos-reactive/src/lib.rs +++ b/dynatos-reactive/src/lib.rs @@ -99,16 +99,16 @@ pub trait SignalWith { /// Types which may be set by [`SignalSet`] pub trait SignalSetWith: Sized { - fn set(&mut self, new_value: T); + fn set(self, new_value: T); } -impl SignalSetWith for T { - fn set(&mut self, new_value: T) { +impl SignalSetWith for &'_ mut T { + fn set(self, new_value: T) { *self = new_value; } } -impl SignalSetWith for Option { - fn set(&mut self, new_value: T) { +impl SignalSetWith for &'_ mut Option { + fn set(self, new_value: T) { *self = Some(new_value); } } @@ -122,7 +122,7 @@ pub trait SignalSet { impl SignalSet for S where S: SignalUpdate, - S::Value: SignalSetWith, + for<'a> S::Value<'a>: SignalSetWith, { fn set(&self, new_value: T) { self.update(|value| SignalSetWith::set(value, new_value)); @@ -138,12 +138,12 @@ pub trait SignalReplace { /// Signal update pub trait SignalUpdate { /// Value type - type Value: ?Sized; + type Value<'a>: ?Sized; /// Updates the signal value fn update(&self, f: F) -> O where - F: FnOnce(&mut Self::Value) -> O; + F: for<'a> FnOnce(Self::Value<'a>) -> O; } /// Types that may be converted into a subscriber diff --git a/dynatos-reactive/src/signal.rs b/dynatos-reactive/src/signal.rs index 9047ad5..e105be3 100644 --- a/dynatos-reactive/src/signal.rs +++ b/dynatos-reactive/src/signal.rs @@ -63,18 +63,18 @@ impl SignalWith for Signal { } } -impl SignalReplace for Signal { +impl SignalReplace for Signal { fn replace(&self, new_value: T) -> T { self.update(|value| mem::replace(value, new_value)) } } -impl SignalUpdate for Signal { - type Value = T; +impl SignalUpdate for Signal { + type Value<'a> = &'a mut T; fn update(&self, f: F) -> O where - F: FnOnce(&mut Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { // Update the value and get the output let output = { diff --git a/dynatos-reactive/src/with_default.rs b/dynatos-reactive/src/with_default.rs index 6afd311..258eebb 100644 --- a/dynatos-reactive/src/with_default.rs +++ b/dynatos-reactive/src/with_default.rs @@ -59,14 +59,14 @@ where impl SignalUpdate for WithDefault where - S: SignalUpdate>, - T: Copy, + S: for<'a> SignalUpdate = &'a mut Option>, + T: Copy + 'static, { - type Value = T; + type Value<'a> = &'a mut T; fn update(&self, f: F) -> O where - F: FnOnce(&mut Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { self.inner.update(|value| f(value.get_or_insert(self.default))) } diff --git a/dynatos-router/src/location.rs b/dynatos-router/src/location.rs index 3f517ae..9241cb5 100644 --- a/dynatos-router/src/location.rs +++ b/dynatos-router/src/location.rs @@ -55,11 +55,11 @@ impl SignalWith for Location { } impl SignalUpdate for Location { - type Value = Url; + type Value<'a> = &'a mut Url; fn update(&self, f: F) -> O where - F: FnOnce(&mut Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { self.0.update(|inner| { let output = f(&mut inner.location); diff --git a/dynatos-router/src/query_array_signal.rs b/dynatos-router/src/query_array_signal.rs index 43a4930..9526046 100644 --- a/dynatos-router/src/query_array_signal.rs +++ b/dynatos-router/src/query_array_signal.rs @@ -87,11 +87,11 @@ impl SignalUpdate for QueryArraySignal where T: ToString + 'static, { - type Value = Vec; + type Value<'a> = &'a mut Vec; fn update(&self, f: F) -> O where - F: FnOnce(&mut Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { // Update the value let output = self.inner.update(f); diff --git a/dynatos-router/src/query_signal.rs b/dynatos-router/src/query_signal.rs index 1ccbad7..52f0b20 100644 --- a/dynatos-router/src/query_signal.rs +++ b/dynatos-router/src/query_signal.rs @@ -86,11 +86,11 @@ impl SignalUpdate for QuerySignal where T: ToString + 'static, { - type Value = Option; + type Value<'a> = &'a mut Option; fn update(&self, f: F) -> O where - F: FnOnce(&mut Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { // Update the value let output = self.inner.update(f);