James Larkin
James Larkin

Reputation: 621

How to use take_while with futures::Stream?

I'm trying to understand what syntax should I use for take_while() with futures::Stream; crate (0.1.25). Here's a piece of code (on playground):

use futures::{stream, Stream}; // 0.1.25

fn into_many(i: i32) -> impl Stream<Item = i32, Error = ()> {
    stream::iter_ok(0..i)
}

fn main() {
    println!("start:");
    let _ = into_many(10)
        // .take_while(|x| { x < 10 })
        .map(|x| {
            println!("number={}", x);
            x
        })
        .wait();
    for _ in foo {} // ← this (by @mcarton)

    println!("finish:");
}

The main goal is to determine the right combinations of operators/commands to run the presented playground successfully with take_while: when I uncomment my take_while() it says

expected &i32, found integral variable | help: consider borrowing here: &10

and if I put a reference, it says:

error[E0277]: the trait bound bool: futures::future::Future is not satisfied

which is weird to me.

Upvotes: 0

Views: 913

Answers (2)

Francis Gagn&#233;
Francis Gagn&#233;

Reputation: 65692

take_while expects the closure to return a future, or something that can be converted to a future. bool doesn't implement IntoFuture, so you have to wrap it in a future instead. future::ok returns a future that is immediately ready with the specified value.

use futures::{future, stream, Stream}; // 0.1.25

fn into_many(i: i32) -> impl Stream<Item = i32, Error = ()> {
    stream::iter_ok(0..i)
}

fn main() {
    println!("start:");
    let foo = into_many(10)
        .take_while(|&x| { future::ok(x < 10) })
        .map(|x| {
            println!("number={}", x);
            x
        })
        .wait();

    for _ in foo {}

    println!("finish:");
}

Upvotes: 4

mcarton
mcarton

Reputation: 29981

wait returns an iterator version of the stream, but that iterator remains lazy, which means you need to iterate it to actually execute your closure:

use futures::{stream, Stream}; // 0.1.25

fn into_many(i: i32) -> impl Stream<Item = i32, Error = ()> {
    stream::iter_ok(0..i)
}

fn main() {
    println!("start:");
    let foo = into_many(10)
        // .take_while(|x| { x < 10 })
        .map(|x| {
            println!("number={}", x);
            x
        })
        .wait();

    for _ in foo {} // ← this

    println!("finish:");
}

(link to playground)

Upvotes: 1

Related Questions