0
votes

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

1
They are the read functions here: docs.rs/tokio/0.1.11/tokio/io/index.htmlGeorge
Though I have read the doc for the functions, but it's quite unclear from the documentation how to actually chain them together properlyGeorge
Edit your post and add the description there ;) You are not posting this for me, but for everyone else who might stumple upon your questionhellow
I assume most people that could answer the question wouldn't need the docs link :p... but, w/eGeorge
Don't assume things you don't know ;) Stackoverflow is a place for people who google for a thing and start digging around. The more you clarify your question, the more you can help people. You provided the documentation, so a person who reads this knows exactly the version you are using and the exact crate you were using.hellow

1 Answers

1
votes

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!.