SignalWith now uses GATs for it's Value type.

This commit is contained in:
2024-03-04 20:25:55 +00:00
parent f9e6a24489
commit 909f09f09b
11 changed files with 57 additions and 54 deletions

View File

@@ -119,7 +119,8 @@ impl<T, E> LazyLoadable<T, E> {
/// Reactively accesses the value, without loading it.
pub fn with_unloaded<R>(&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<T, E> Clone for LazyLoadable<T, E> {
// TODO: Use a `Loadable<&T, E>` when `SignalWith` allows?
impl<T, E> SignalWith for LazyLoadable<T, E>
where
E: Clone,
T: 'static,
E: Clone + 'static,
{
type Value = Loadable<T, E>;
type Value<'a> = &'a Loadable<T, E>;
fn with<F, O>(&self, f: F) -> O
where
F: FnOnce(&Self::Value) -> O,
F: for<'a> FnOnce(Self::Value<'a>) -> O,
{
self.load();
self.inner.with(f)

View File

@@ -58,12 +58,12 @@ impl<T, F> Derived<T, F> {
}
}
impl<T, F: ?Sized> SignalWith for Derived<T, F> {
type Value = T;
impl<T: 'static, F: ?Sized> SignalWith for Derived<T, F> {
type Value<'a> = &'a T;
fn with<F2, O>(&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| {

View File

@@ -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<T> {
fn get(&self) -> T;
}
impl<S> SignalGet<S::Value> for S
impl<S, T> SignalGet<T> for S
where
S: SignalWith,
S::Value: Copy,
S: for<'a> SignalWith<Value<'a> = &'a T>,
T: Copy,
{
fn get(&self) -> S::Value {
fn get(&self) -> T {
self.with(|value| *value)
}
}
@@ -44,12 +44,12 @@ pub trait SignalGetCloned<T> {
fn get_cloned(&self) -> T;
}
impl<S> SignalGetCloned<S::Value> for S
impl<S, T> SignalGetCloned<T> for S
where
S: SignalWith,
S::Value: Clone,
S: for<'a> SignalWith<Value<'a> = &'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<F, O>(&self, f: F) -> O
where
F: FnOnce(&Self::Value) -> O;
F: for<'a> FnOnce(Self::Value<'a>) -> O;
}
/// Signal set

View File

@@ -43,12 +43,12 @@ impl<T> Signal<T> {
impl<T: ?Sized, U: ?Sized> CoerceUnsized<Signal<U>> for Signal<T> where T: Unsize<U> {}
impl<T: ?Sized> SignalWith for Signal<T> {
type Value = T;
impl<T: ?Sized + 'static> SignalWith for Signal<T> {
type Value<'a> = &'a T;
fn with<F, O>(&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);

View File

@@ -22,13 +22,14 @@ impl<S, T> WithDefault<S, T> {
impl<S, T> SignalWith for WithDefault<S, T>
where
S: SignalWith<Value = Option<T>>,
S: for<'a> SignalWith<Value<'a> = &'a Option<T>>,
T: 'static,
{
type Value = T;
type Value<'a> = &'a T;
fn with<F, O>(&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),

View File

@@ -44,11 +44,11 @@ impl Location {
}
impl SignalWith for Location {
type Value = Url;
type Value<'a> = &'a Url;
fn with<F, O>(&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))
}

View File

@@ -63,12 +63,12 @@ impl<T> QueryArraySignal<T> {
}
}
impl<T> SignalWith for QueryArraySignal<T> {
type Value = Vec<T>;
impl<T: 'static> SignalWith for QueryArraySignal<T> {
type Value<'a> = &'a Vec<T>;
fn with<F, O>(&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<T> SignalWith for QueryArraySignal<T> {
impl<T> SignalSet<Vec<T>> for QueryArraySignal<T>
where
T: ToString,
T: ToString + 'static,
{
fn set(&self, new_value: Vec<T>) {
self.update(|value| *value = new_value);
@@ -85,7 +85,7 @@ where
impl<T> SignalReplace<Vec<T>> for QueryArraySignal<T>
where
T: ToString,
T: ToString + 'static,
{
fn replace(&self, new_value: Vec<T>) -> Vec<T> {
self.update(|value| mem::replace(value, new_value))
@@ -94,7 +94,7 @@ where
impl<T> SignalUpdate for QueryArraySignal<T>
where
T: ToString,
T: ToString + 'static,
{
type Value = Vec<T>;

View File

@@ -62,12 +62,12 @@ impl<T> QuerySignal<T> {
}
}
impl<T> SignalWith for QuerySignal<T> {
type Value = Option<T>;
impl<T: 'static> SignalWith for QuerySignal<T> {
type Value<'a> = &'a Option<T>;
fn with<F, O>(&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<T> SignalWith for QuerySignal<T> {
impl<T> SignalSet<Option<T>> for QuerySignal<T>
where
T: ToString,
T: ToString + 'static,
{
fn set(&self, new_value: Option<T>) {
self.update(|value| *value = new_value);
@@ -84,7 +84,7 @@ where
impl<T> SignalSet<T> for QuerySignal<T>
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<T> SignalReplace<Option<T>> for QuerySignal<T>
where
T: ToString,
T: ToString + 'static,
{
fn replace(&self, new_value: Option<T>) -> Option<T> {
self.update(|value| mem::replace(value, new_value))
@@ -102,7 +102,7 @@ where
impl<T> SignalUpdate for QuerySignal<T>
where
T: ToString,
T: ToString + 'static,
{
type Value = Option<T>;

View File

@@ -145,10 +145,10 @@ where
// TODO: Allow impl for `impl SignalGet<Value: WithDynText>`
#[duplicate::duplicate_item(
Generics Ty;
[T] [Signal<T> where T: WithDynAttr];
[T, F] [Derived<T, F> where T: WithDynAttr, F: ?Sized];
[T] [QuerySignal<T> where T: WithDynAttr];
[S, T] [WithDefault<S, T> where S:SignalWith<Value = Option<T>>, T: WithDynAttr];
[T] [Signal<T> where T: WithDynAttr + 'static];
[T, F] [Derived<T, F> where T: WithDynAttr + 'static, F: ?Sized];
[T] [QuerySignal<T> where T: WithDynAttr + 'static];
[S, T] [WithDefault<S, T> where S: for<'a> SignalWith<Value<'a> = &'a Option<T>>, T: WithDynAttr + 'static];
)]
impl<Generics> WithDynAttr for Ty {
fn with_attr<F2, O>(&self, f: F2) -> O
@@ -190,9 +190,9 @@ impl DynAttrPred for bool {
// TODO: Allow impl for `impl SignalGet<Value: WithDynText>`
#[duplicate::duplicate_item(
Generics Ty;
[T] [Signal<T> where T: DynAttrPred];
[T, F] [Derived<T, F> where T: DynAttrPred, F: ?Sized];
[S, T] [WithDefault<S, T> where S:SignalWith<Value = Option<T>>, T: DynAttrPred];
[T] [Signal<T> where T: DynAttrPred + 'static];
[T, F] [Derived<T, F> where T: DynAttrPred + 'static, F: ?Sized];
[S, T] [WithDefault<S, T> where S: for<'a> SignalWith<Value<'a> = &'a Option<T>>, T: DynAttrPred + 'static];
)]
impl<Generics> DynAttrPred for Ty {
fn eval(&self) -> bool {

View File

@@ -115,10 +115,10 @@ where
// TODO: Allow impl for `impl SignalGet<Value: WithDynText>`
#[duplicate::duplicate_item(
Generics Ty;
[T] [Signal<T> where T: WithDynText];
[T, F] [Derived<T, F> where T: WithDynText, F: ?Sized];
[T] [QuerySignal<T> where T: WithDynText];
[S, T] [WithDefault<S, T> where S:SignalWith<Value = Option<T>>, T: WithDynText];
[T] [Signal<T> where T: WithDynText + 'static];
[T, F] [Derived<T, F> where T: WithDynText + 'static, F: ?Sized];
[T] [QuerySignal<T> where T: WithDynText + 'static];
[S, T] [WithDefault<S, T> where S: for<'a> SignalWith<Value<'a> = &'a Option<T>>, T: WithDynText + 'static];
)]
impl<Generics> WithDynText for Ty {
fn with_text<F2, O>(&self, f: F2) -> O

View File

@@ -142,10 +142,10 @@ impl ToDynProp for Ty {
// TODO: Allow impl for `impl SignalGet<Value: WithDynText>`
#[duplicate::duplicate_item(
Generics Ty;
[T] [Signal<T> where T: ToDynProp];
[T, F] [Derived<T, F> where T: ToDynProp, F: ?Sized];
[T] [QuerySignal<T> where T: ToDynProp];
[S, T] [WithDefault<S, T> where S:SignalWith<Value = Option<T>>, T: ToDynProp];
[T] [Signal<T> where T: ToDynProp + 'static];
[T, F] [Derived<T, F> where T: ToDynProp + 'static, F: ?Sized];
[T] [QuerySignal<T> where T: ToDynProp + 'static];
[S, T] [WithDefault<S, T> where S: for<'a> SignalWith<Value<'a> = &'a Option<T>>, T: ToDynProp + 'static];
)]
impl<Generics> ToDynProp for Ty {
fn to_prop(&self) -> Option<JsValue> {