[][src]Function moxie::load_with

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

Load a value from the future returned by init whenever capture changes, returning the result of calling with with the loaded value. Cancels the running future after any revision during which this call was not made.

Example

use futures::{channel::oneshot, executor::LocalPool};
use moxie::{load_with, 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_with(
        &epoch.load(Ordering::Relaxed),
        |_| {
            let (sender, receiver) = oneshot::channel();
            send_futs.send(sender).unwrap();
            receiver
        },
        // makes this equivalent to load(...)
        |res| res.clone(),
    )
});

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 sender = recv_futs.recv().unwrap();
assert!(recv_futs.try_recv().is_err(), "only one channel is created per epoch");

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 sender = recv_futs.recv().unwrap();
assert!(recv_futs.try_recv().is_err(), "only one channel is created per epoch");

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: