Function moxie::load [−][src]
pub fn load<Arg, Input, Fut, Output>(
capture: &Arg,
init: impl FnOnce(&Input) -> Fut
) -> Poll<Output> where
Arg: PartialEq<Input> + ToOwned<Owned = Input> + ?Sized,
Input: Borrow<Arg> + 'static,
Fut: Future<Output = Output> + 'static,
Output: Clone + 'static,
Expand description
Load a value from a future, cloning it on subsequent revisions after it is first returned. Re-initializes the loading future if the capture argument changes from previous revisions.
Example
use futures::{channel::oneshot, executor::LocalPool};
use moxie::{load, runtime::RunLoop};
use std::{
sync::{
atomic::{AtomicU64, Ordering},
mpsc::channel,
},
task::Poll,
};
let epoch = AtomicU64::new(0);
let (send_futs, recv_futs) = channel();
let mut rt = RunLoop::new(|| {
// loads a new future when epoch changes
load(&epoch.load(Ordering::Relaxed), |e| {
let (sender, receiver) = oneshot::channel();
send_futs.send((*e, sender)).unwrap();
receiver
})
});
let mut exec = LocalPool::new();
rt.set_task_executor(exec.spawner());
assert_eq!(rt.run_once(), Poll::Pending);
exec.run_until_stalled();
assert_eq!(rt.run_once(), Poll::Pending);
// resolve the future
let (created_in_epoch, sender) = recv_futs.recv().unwrap();
assert!(recv_futs.try_recv().is_err(), "only one channel is created per epoch");
assert_eq!(created_in_epoch, 0);
sender.send(()).unwrap();
exec.run();
assert_eq!(rt.run_once(), Poll::Ready(Ok(())));
// force the future to be reinitialized
epoch.store(1, Ordering::Relaxed);
assert_eq!(rt.run_once(), Poll::Pending);
// resolve the future
let (created_in_epoch, sender) = recv_futs.recv().unwrap();
assert!(recv_futs.try_recv().is_err(), "only one channel is created per epoch");
assert_eq!(created_in_epoch, 1);
sender.send(()).unwrap();
exec.run();
assert_eq!(rt.run_once(), Poll::Ready(Ok(())));
Environment Expectations
This function requires the following types to be visible to illicit::get
and will
panic otherwise:
Context