From 909f09f09b7febb248c1deda47e2cd6331bead69 Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Mon, 4 Mar 2024 20:25:55 +0000 Subject: [PATCH] `SignalWith` now uses `GAT`s for it's `Value` type. --- dynatos-loadable/src/lazy_loadable.rs | 10 ++++++---- dynatos-reactive/src/derived.rs | 6 +++--- dynatos-reactive/src/lib.rs | 22 +++++++++++----------- dynatos-reactive/src/signal.rs | 6 +++--- dynatos-reactive/src/with_default.rs | 7 ++++--- dynatos-router/src/location.rs | 4 ++-- dynatos-router/src/query_array_signal.rs | 12 ++++++------ dynatos-router/src/query_signal.rs | 14 +++++++------- dynatos/src/element_dyn_attr.rs | 14 +++++++------- dynatos/src/node_dyn_text.rs | 8 ++++---- dynatos/src/object_dyn_prop.rs | 8 ++++---- 11 files changed, 57 insertions(+), 54 deletions(-) diff --git a/dynatos-loadable/src/lazy_loadable.rs b/dynatos-loadable/src/lazy_loadable.rs index 177b9c2..983801d 100644 --- a/dynatos-loadable/src/lazy_loadable.rs +++ b/dynatos-loadable/src/lazy_loadable.rs @@ -119,7 +119,8 @@ impl LazyLoadable { /// Reactively accesses the value, without loading it. pub fn with_unloaded(&self, f: impl FnOnce(Loadable<&T, E>) -> R) -> R where - E: Clone, + T: 'static, + E: Clone + 'static, { self.inner.with(|value| f(value.as_ref())) } @@ -151,13 +152,14 @@ impl Clone for LazyLoadable { // TODO: Use a `Loadable<&T, E>` when `SignalWith` allows? impl SignalWith for LazyLoadable where - E: Clone, + T: 'static, + E: Clone + 'static, { - type Value = Loadable; + type Value<'a> = &'a Loadable; fn with(&self, f: F) -> O where - F: FnOnce(&Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { self.load(); self.inner.with(f) diff --git a/dynatos-reactive/src/derived.rs b/dynatos-reactive/src/derived.rs index 87e99ce..43d00ed 100644 --- a/dynatos-reactive/src/derived.rs +++ b/dynatos-reactive/src/derived.rs @@ -58,12 +58,12 @@ impl Derived { } } -impl SignalWith for Derived { - type Value = T; +impl SignalWith for Derived { + type Value<'a> = &'a T; fn with(&self, f: F2) -> O where - F2: FnOnce(&Self::Value) -> O, + F2: for<'a> FnOnce(Self::Value<'a>) -> O, { let effect_fn = self.effect.inner_fn(); effect_fn.value.with(|value| { diff --git a/dynatos-reactive/src/lib.rs b/dynatos-reactive/src/lib.rs index 355b24d..ce8cd61 100644 --- a/dynatos-reactive/src/lib.rs +++ b/dynatos-reactive/src/lib.rs @@ -1,7 +1,7 @@ //! Reactivity for `dynatos` // Features -#![feature(unsize, coerce_unsized, unboxed_closures, fn_traits, test)] +#![feature(unsize, coerce_unsized, unboxed_closures, fn_traits, test, associated_type_bounds)] // Modules pub mod derived; @@ -28,12 +28,12 @@ pub trait SignalGet { fn get(&self) -> T; } -impl SignalGet for S +impl SignalGet for S where - S: SignalWith, - S::Value: Copy, + S: for<'a> SignalWith = &'a T>, + T: Copy, { - fn get(&self) -> S::Value { + fn get(&self) -> T { self.with(|value| *value) } } @@ -44,12 +44,12 @@ pub trait SignalGetCloned { fn get_cloned(&self) -> T; } -impl SignalGetCloned for S +impl SignalGetCloned for S where - S: SignalWith, - S::Value: Clone, + S: for<'a> SignalWith = &'a T>, + T: Clone, { - fn get_cloned(&self) -> S::Value { + fn get_cloned(&self) -> T { self.with(|value| value.clone()) } } @@ -57,12 +57,12 @@ where /// Signal with pub trait SignalWith { /// Value type - type Value: ?Sized; + type Value<'a>: ?Sized; /// Uses the signal value fn with(&self, f: F) -> O where - F: FnOnce(&Self::Value) -> O; + F: for<'a> FnOnce(Self::Value<'a>) -> O; } /// Signal set diff --git a/dynatos-reactive/src/signal.rs b/dynatos-reactive/src/signal.rs index 43c658a..ad6eeb1 100644 --- a/dynatos-reactive/src/signal.rs +++ b/dynatos-reactive/src/signal.rs @@ -43,12 +43,12 @@ impl Signal { impl CoerceUnsized> for Signal where T: Unsize {} -impl SignalWith for Signal { - type Value = T; +impl SignalWith for Signal { + type Value<'a> = &'a T; fn with(&self, f: F) -> O where - F: FnOnce(&Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { if let Some(effect) = effect::running() { self.inner.trigger.add_subscriber(effect); diff --git a/dynatos-reactive/src/with_default.rs b/dynatos-reactive/src/with_default.rs index ce844c9..77e39ce 100644 --- a/dynatos-reactive/src/with_default.rs +++ b/dynatos-reactive/src/with_default.rs @@ -22,13 +22,14 @@ impl WithDefault { impl SignalWith for WithDefault where - S: SignalWith>, + S: for<'a> SignalWith = &'a Option>, + T: 'static, { - type Value = T; + type Value<'a> = &'a T; fn with(&self, f: F) -> O where - F: FnOnce(&Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { self.inner.with(|value| match value { Some(value) => f(value), diff --git a/dynatos-router/src/location.rs b/dynatos-router/src/location.rs index 13f4235..df60adc 100644 --- a/dynatos-router/src/location.rs +++ b/dynatos-router/src/location.rs @@ -44,11 +44,11 @@ impl Location { } impl SignalWith for Location { - type Value = Url; + type Value<'a> = &'a Url; fn with(&self, f: F) -> O where - F: FnOnce(&Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { self.0.with(|inner| f(&inner.location)) } diff --git a/dynatos-router/src/query_array_signal.rs b/dynatos-router/src/query_array_signal.rs index 13847ce..1237062 100644 --- a/dynatos-router/src/query_array_signal.rs +++ b/dynatos-router/src/query_array_signal.rs @@ -63,12 +63,12 @@ impl QueryArraySignal { } } -impl SignalWith for QueryArraySignal { - type Value = Vec; +impl SignalWith for QueryArraySignal { + type Value<'a> = &'a Vec; fn with(&self, f: F) -> O where - F: FnOnce(&Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { self.inner.with(|value| f(value)) } @@ -76,7 +76,7 @@ impl SignalWith for QueryArraySignal { impl SignalSet> for QueryArraySignal where - T: ToString, + T: ToString + 'static, { fn set(&self, new_value: Vec) { self.update(|value| *value = new_value); @@ -85,7 +85,7 @@ where impl SignalReplace> for QueryArraySignal where - T: ToString, + T: ToString + 'static, { fn replace(&self, new_value: Vec) -> Vec { self.update(|value| mem::replace(value, new_value)) @@ -94,7 +94,7 @@ where impl SignalUpdate for QueryArraySignal where - T: ToString, + T: ToString + 'static, { type Value = Vec; diff --git a/dynatos-router/src/query_signal.rs b/dynatos-router/src/query_signal.rs index 10c01e7..612475c 100644 --- a/dynatos-router/src/query_signal.rs +++ b/dynatos-router/src/query_signal.rs @@ -62,12 +62,12 @@ impl QuerySignal { } } -impl SignalWith for QuerySignal { - type Value = Option; +impl SignalWith for QuerySignal { + type Value<'a> = &'a Option; fn with(&self, f: F) -> O where - F: FnOnce(&Self::Value) -> O, + F: for<'a> FnOnce(Self::Value<'a>) -> O, { self.inner.with(|value| f(value)) } @@ -75,7 +75,7 @@ impl SignalWith for QuerySignal { impl SignalSet> for QuerySignal where - T: ToString, + T: ToString + 'static, { fn set(&self, new_value: Option) { self.update(|value| *value = new_value); @@ -84,7 +84,7 @@ where impl SignalSet for QuerySignal where - T: ToString, + T: ToString + 'static, { fn set(&self, new_value: T) { self.update(|value| *value = Some(new_value)); @@ -93,7 +93,7 @@ where impl SignalReplace> for QuerySignal where - T: ToString, + T: ToString + 'static, { fn replace(&self, new_value: Option) -> Option { self.update(|value| mem::replace(value, new_value)) @@ -102,7 +102,7 @@ where impl SignalUpdate for QuerySignal where - T: ToString, + T: ToString + 'static, { type Value = Option; diff --git a/dynatos/src/element_dyn_attr.rs b/dynatos/src/element_dyn_attr.rs index 7957f1c..6df5675 100644 --- a/dynatos/src/element_dyn_attr.rs +++ b/dynatos/src/element_dyn_attr.rs @@ -145,10 +145,10 @@ where // TODO: Allow impl for `impl SignalGet` #[duplicate::duplicate_item( Generics Ty; - [T] [Signal where T: WithDynAttr]; - [T, F] [Derived where T: WithDynAttr, F: ?Sized]; - [T] [QuerySignal where T: WithDynAttr]; - [S, T] [WithDefault where S:SignalWith>, T: WithDynAttr]; + [T] [Signal where T: WithDynAttr + 'static]; + [T, F] [Derived where T: WithDynAttr + 'static, F: ?Sized]; + [T] [QuerySignal where T: WithDynAttr + 'static]; + [S, T] [WithDefault where S: for<'a> SignalWith = &'a Option>, T: WithDynAttr + 'static]; )] impl WithDynAttr for Ty { fn with_attr(&self, f: F2) -> O @@ -190,9 +190,9 @@ impl DynAttrPred for bool { // TODO: Allow impl for `impl SignalGet` #[duplicate::duplicate_item( Generics Ty; - [T] [Signal where T: DynAttrPred]; - [T, F] [Derived where T: DynAttrPred, F: ?Sized]; - [S, T] [WithDefault where S:SignalWith>, T: DynAttrPred]; + [T] [Signal where T: DynAttrPred + 'static]; + [T, F] [Derived where T: DynAttrPred + 'static, F: ?Sized]; + [S, T] [WithDefault where S: for<'a> SignalWith = &'a Option>, T: DynAttrPred + 'static]; )] impl DynAttrPred for Ty { fn eval(&self) -> bool { diff --git a/dynatos/src/node_dyn_text.rs b/dynatos/src/node_dyn_text.rs index b006296..b4bf4a7 100644 --- a/dynatos/src/node_dyn_text.rs +++ b/dynatos/src/node_dyn_text.rs @@ -115,10 +115,10 @@ where // TODO: Allow impl for `impl SignalGet` #[duplicate::duplicate_item( Generics Ty; - [T] [Signal where T: WithDynText]; - [T, F] [Derived where T: WithDynText, F: ?Sized]; - [T] [QuerySignal where T: WithDynText]; - [S, T] [WithDefault where S:SignalWith>, T: WithDynText]; + [T] [Signal where T: WithDynText + 'static]; + [T, F] [Derived where T: WithDynText + 'static, F: ?Sized]; + [T] [QuerySignal where T: WithDynText + 'static]; + [S, T] [WithDefault where S: for<'a> SignalWith = &'a Option>, T: WithDynText + 'static]; )] impl WithDynText for Ty { fn with_text(&self, f: F2) -> O diff --git a/dynatos/src/object_dyn_prop.rs b/dynatos/src/object_dyn_prop.rs index 7e4dc2c..c06344f 100644 --- a/dynatos/src/object_dyn_prop.rs +++ b/dynatos/src/object_dyn_prop.rs @@ -142,10 +142,10 @@ impl ToDynProp for Ty { // TODO: Allow impl for `impl SignalGet` #[duplicate::duplicate_item( Generics Ty; - [T] [Signal where T: ToDynProp]; - [T, F] [Derived where T: ToDynProp, F: ?Sized]; - [T] [QuerySignal where T: ToDynProp]; - [S, T] [WithDefault where S:SignalWith>, T: ToDynProp]; + [T] [Signal where T: ToDynProp + 'static]; + [T, F] [Derived where T: ToDynProp + 'static, F: ?Sized]; + [T] [QuerySignal where T: ToDynProp + 'static]; + [S, T] [WithDefault where S: for<'a> SignalWith = &'a Option>, T: ToDynProp + 'static]; )] impl ToDynProp for Ty { fn to_prop(&self) -> Option {