[][src]Function moxie::load

pub fn load<Arg: ?Sized, Input, Fut, Output>(
    capture: &Arg,
    init: impl FnOnce(&Input) -> Fut
) -> Poll<Output> where
    Arg: PartialEq<Input> + ToOwned<Owned = Input>,
    Input: Borrow<Arg> + 'static,
    Fut: Future<Output = Output> + 'static,
    Output: Clone + 'static, 

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: