[][src]Function tokio::prelude::future::loop_fn

pub fn loop_fn<S, T, A, F>(initial_state: S, func: F) -> LoopFn<A, F> where
    A: IntoFuture<Item = Loop<T, S>>,
    F: FnMut(S) -> A, 

Creates a new future implementing a tail-recursive loop.

The loop function is immediately called with initial_state and should return a value that can be converted to a future. On successful completion, this future should output a Loop<T, S> to indicate the status of the loop.

Loop::Break(T) halts the loop and completes the future with output T.

Loop::Continue(S) reinvokes the loop function with state S. The returned future will be subsequently polled for a new Loop<T, S> value.

Examples

use futures::future::{ok, loop_fn, Future, FutureResult, Loop};
use std::io::Error;

struct Client {
    ping_count: u8,
}

impl Client {
    fn new() -> Self {
        Client { ping_count: 0 }
    }

    fn send_ping(self) -> FutureResult<Self, Error> {
        ok(Client { ping_count: self.ping_count + 1 })
    }

    fn receive_pong(self) -> FutureResult<(Self, bool), Error> {
        let done = self.ping_count >= 5;
        ok((self, done))
    }
}

let ping_til_done = loop_fn(Client::new(), |client| {
    client.send_ping()
        .and_then(|client| client.receive_pong())
        .and_then(|(client, done)| {
            if done {
                Ok(Loop::Break(client))
            } else {
                Ok(Loop::Continue(client))
            }
        })
});