From f8339133a34af893433fdfb8e2d448cb42290057 Mon Sep 17 00:00:00 2001 From: Filipe Rodrigues Date: Tue, 5 Mar 2024 18:59:48 +0000 Subject: [PATCH] Removed `LazyLoadable`. --- dynatos-loadable/src/lazy_loadable.rs | 184 -------------------------- dynatos-loadable/src/lib.rs | 6 +- 2 files changed, 1 insertion(+), 189 deletions(-) delete mode 100644 dynatos-loadable/src/lazy_loadable.rs diff --git a/dynatos-loadable/src/lazy_loadable.rs b/dynatos-loadable/src/lazy_loadable.rs deleted file mode 100644 index 2134b21..0000000 --- a/dynatos-loadable/src/lazy_loadable.rs +++ /dev/null @@ -1,184 +0,0 @@ -//! Lazy loadable. - -// Imports -use { - crate::Loadable, - dynatos_reactive::{Effect, Signal, SignalGet, SignalSet, SignalUpdate, SignalWith}, - std::{future::Future, rc::Rc}, -}; - -/// Load status -#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)] -enum LoadStatus { - /// Not loading - Unloaded, - - /// Load if empty - LoadIfEmpty, - - /// Always load - LoadAlways, - - /// Loading - Loading, -} - -impl LoadStatus { - /// Sets this load status, to at least `load_status`. - /// - /// If the current value is higher than `load_status`, this value won't - /// be lowered. - pub fn set_at_least(&mut self, other: Self) { - *self = Ord::max(*self, other); - } -} - -/// A lazy loadable. -#[derive(Debug)] -pub struct LazyLoadable { - /// Inner - inner: Signal>, - - /// Load status - load_status: Signal, - - /// Effect - effect: Effect, -} - -impl LazyLoadable { - /// Creates a new, empty, loadable. - pub fn new(load: F) -> Self - where - T: 'static, - E: 'static, - F: Fn() -> Fut + 'static, - Fut: Future> + 'static, - { - let inner = Signal::new(Loadable::Empty); - let load_status = Signal::new(LoadStatus::Unloaded); - let load = Rc::new(load); - - let effect = Effect::new({ - let inner = inner.clone(); - let load_status = load_status.clone(); - move || { - // If we're loading, or shouldn't load, quit. - let should_load = match load_status.get() { - LoadStatus::Unloaded => false, - LoadStatus::LoadIfEmpty => inner.with(|inner| inner.is_empty()), - LoadStatus::LoadAlways => true, - LoadStatus::Loading => false, - }; - if !should_load { - return; - } - - // Else spawn a future to load the value - // Note: We need to ensure that we only update `inner` inside while `load_status` - // is `Loading`. Otherwise, we could get a race and lose the loaded value to - // another load. - // Note: Although we could get the future outside of `spawn_local`, if we do, it's - // dependencies would leak into this effect, which we don't want. This way, the - // user also receives a warning if they try to use any dependencies within `load`. - load_status.set(LoadStatus::Loading); - let inner = inner.clone(); - let load_status = load_status.clone(); - let load = Rc::clone(&load); - wasm_bindgen_futures::spawn_local(async move { - let res = load().await; - inner.set(Loadable::from_res(res)); - load_status.set(LoadStatus::Unloaded); - }); - } - }); - - Self { - inner, - load_status, - effect, - } - } - - /// Starts loading. - /// - /// If loading or loaded, does nothing - pub fn load(&self) { - self.load_status - .update(|load_status| load_status.set_at_least(LoadStatus::LoadIfEmpty)); - } - - /// Reloads the inner value. - /// - /// If loading, does nothing. - pub fn reload(&self) { - self.load_status - .update(|load_status| load_status.set_at_least(LoadStatus::LoadAlways)); - } - - /// Reactively accesses the value, without loading it. - pub fn with_unloaded(&self, f: impl FnOnce(Loadable<&T, E>) -> R) -> R - where - T: 'static, - E: Clone + 'static, - { - self.inner.with(|value| f(value.as_ref())) - } - - /// Updates the value mutably, without loading it. - /// - /// Will notify any subscribers of the value. - pub fn update_unloaded(&self, f: impl FnOnce(Loadable<&mut T, E>) -> R) -> R - where - T: 'static, - E: Clone + 'static, - { - let mut output = None; - self.inner.update(|inner| output = Some(f(inner.as_mut()))); - - output.expect("Value was not updated") - } -} - -impl Clone for LazyLoadable { - fn clone(&self) -> Self { - Self { - inner: self.inner.clone(), - load_status: self.load_status.clone(), - effect: self.effect.clone(), - } - } -} - -// TODO: Use a `Loadable<&T, E>` when `SignalWith` allows? -impl SignalWith for LazyLoadable -where - T: 'static, - E: Clone + 'static, -{ - type Value<'a> = Loadable<&'a T, E>; - - fn with(&self, f: F) -> O - where - F: for<'a> FnOnce(Self::Value<'a>) -> O, - { - self.load(); - self.inner.with(|loadable| f(loadable.as_ref())) - } -} - -impl SignalUpdate for LazyLoadable -where - T: 'static, - E: Clone + 'static, -{ - type Value<'a> = Loadable<&'a mut T, E>; - - fn update(&self, f: F) -> O - where - F: for<'a> FnOnce(Self::Value<'a>) -> O, - { - self.load(); - self.inner.update(|loadable| f(loadable.as_mut())) - } -} diff --git a/dynatos-loadable/src/lib.rs b/dynatos-loadable/src/lib.rs index b1206d8..eb49dd2 100644 --- a/dynatos-loadable/src/lib.rs +++ b/dynatos-loadable/src/lib.rs @@ -4,11 +4,7 @@ #![feature(try_trait_v2, lint_reasons, never_type, extend_one)] // Modules -mod lazy_loadable; pub mod loadable; // Exports -pub use self::{ - lazy_loadable::LazyLoadable, - loadable::{IntoLoaded, IteratorLoadableExt, Loadable}, -}; +pub use self::loadable::{IntoLoaded, IteratorLoadableExt, Loadable};