pub struct Resource<T> { /* private fields */ }Expand description
A reactive handle to an async-loaded value.
Clone is cheap (internally Rc-backed via Signal); all clones share the
same underlying state, so providing a Resource to a subtree and updating
it from a task updates every consumer.
Implementations§
Source§impl<T: Clone + 'static> Resource<T>
impl<T: Clone + 'static> Resource<T>
Sourcepub fn new(loader: impl FnOnce() -> Result<T, String>) -> Self
pub fn new(loader: impl FnOnce() -> Result<T, String>) -> Self
Creates a resource in the Loading state, then runs loader
synchronously and stores the result. Useful for “load on creation”
cases where the loader is already resolved (e.g. a cached value or a
blocking fetch driven by the caller’s executor).
Sourcepub fn error(message: impl Into<String>) -> Self
pub fn error(message: impl Into<String>) -> Self
Creates a resource already in the Error state.
Sourcepub fn load_blocking(&self, loader: impl FnOnce() -> Result<T, String>)
pub fn load_blocking(&self, loader: impl FnOnce() -> Result<T, String>)
Runs loader and updates the shared state to Ready/Error. Safe to
call from any thread/task that can reach this Resource (e.g. the
continuation of an awaited future).
Sourcepub fn set_result(&self, result: Result<T, String>)
pub fn set_result(&self, result: Result<T, String>)
Updates the state directly (e.g. from an already-resolved future).
Async callers should prefer Resource::load_async, whose spawn
closure uses Resource::is_current to commit a result only if it
hasn’t been superseded by a newer load — that is the cancellation guard.
Sourcepub fn generation(&self) -> u64
pub fn generation(&self) -> u64
The current generation counter. Incremented on every reload/async (re)load, so async tasks can detect that they’ve been superseded.
Sourcepub fn is_current(&self, gen: u64) -> bool
pub fn is_current(&self, gen: u64) -> bool
True only if the resource is still on generation gen — i.e. no newer
reload/load_async has superseded the load that started at gen. A
task that captured gen = resource.generation() before awaiting its
future checks resource.is_current(gen) after the await: if false, a
newer load has started and the result must be dropped (cancellation).
Sourcepub fn load_async<F, Fut>(&self, spawn: F, loader: Fut)
pub fn load_async<F, Fut>(&self, spawn: F, loader: Fut)
Spawns an async loader and bridges its result back into this resource.
The core is runtime-free, so the caller supplies a spawn function that
drives a Future<Output = Result<T, String>> to completion on whatever
executor the backend provides (the DOM uses wasm_bindgen_futures, a
native app uses tokio/smol, tests use a oneshot channel). spawn
is given the future plus a clone of this Resource and the generation it
started with; once the future resolves the result is committed only if
the resource is still on that generation (cancellation on reload).
The resource is immediately put into the Loading state and its
generation is bumped so any in-flight load from a previous generation is
invalidated. Calling load_async again on the same resource (or any
clone) cancels the prior in-flight future.
Sourcepub fn reload(&self)
pub fn reload(&self)
Resets the resource back to Loading (e.g. to re-trigger a fetch).
Bumps the generation so any in-flight async load is cancelled (its
eventual result will be discarded by Resource::is_current).
Sourcepub fn state(&self) -> ResourceState<T>
pub fn state(&self) -> ResourceState<T>
The current state.
Sourcepub fn ready_value(&self) -> Option<T>
pub fn ready_value(&self) -> Option<T>
Convenience accessor: the ready value, or None while loading/errored.
Sourcepub fn is_loading(&self) -> bool
pub fn is_loading(&self) -> bool
true while the loader has not completed.
Sourcepub fn signal(&self) -> Signal<ResourceState<T>>
pub fn signal(&self) -> Signal<ResourceState<T>>
The underlying state signal, so views can subscribe to changes.