Search code examples
rustfuturelifetimerust-tokio

Take ownership of closure argument for rust future in and_then


I am trying to read all content from a file into a vector using the async rust api:

    let mut content : Vec<u8> = vec![];
    let f = tokio::fs::File::open("myfilecontent")
        .and_then(|mut myfile| {
            myfile.read_buf(&mut content)
        });
    f.await;

But I keep getting this error: error[E0515]: cannot return value referencing function parameter `myfile`

Which sounds reasonable, because the future returned by the closure must keep a reference to the file, but as this closure is the only user of the file it could take ownership. How can I convince rust to do the right thing?


Solution

  • You can use an async move block like so:

    use futures::TryFutureExt;
    use tokio::io::AsyncReadExt;
    
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let mut content: Vec<u8> = vec![];
    
        let f = tokio::fs::File::open("myfilecontent").and_then(
            |mut myfile| async move { myfile.read_buf(&mut content).await },
        );
    
        f.await?;
    
        Ok(())
    }
    

    or skip and_then and go straight for .await:

    use tokio::io::AsyncReadExt;
    
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let mut content: Vec<u8> = vec![];
    
        let mut myfile = tokio::fs::File::open("myfilecontent").await?;
        myfile.read_buf(&mut content).await?;
    
        Ok(())
    }