George
George

Reputation: 4011

How to chain tokio read functions?

Is there a way to chain the read_* functions in tokio::io in a "recursive" way ?

I'm essentially looking to do something like:

read_until x then read_exact y then write response then go back to the top.

In case you are confused what functions i'm talking about: https://docs.rs/tokio/0.1.11/tokio/io/index.html

Upvotes: 0

Views: 1022

Answers (1)

hellow
hellow

Reputation: 13460

Yes, there is a way.

read_until is returns a struct ReadUntil, which implements the Future-trait, which iteself provides a lot of useful functions, e.g. and_then which can be used to chain futures.

A simple (and silly) example looks like this:

extern crate futures;
extern crate tokio_io; // 0.1.8 // 0.1.24

use futures::future::Future;
use std::io::Cursor;
use tokio_io::io::{read_exact, read_until};

fn main() {
    let cursor = Cursor::new(b"abcdef\ngh");
    let mut buf = vec![0u8; 2];
    println!(
        "{:?}",
        String::from_utf8_lossy(
            read_until(cursor, b'\n', vec![])
                .and_then(|r| read_exact(r.0, &mut buf))
                .wait()
                .unwrap()
                .1
        )
    );
}

Here I use a Cursor, which happens to implement the AsyncRead-trait and use the read_until function to read until a newline occurs (between 'f' and 'g').
Afterwards to chain those I use and_then to use read_exact in case of an success, use wait to get the Result unwrap it (don't do this in production kids!) and take the second argument from the tuple (the first one is the cursor).
Last I convert the Vec into a String to display "gh" with println!.

Upvotes: 1

Related Questions