johnthagen
johnthagen

Reputation: 9149

How to convert from std::io::Bytes to &[u8]

I am trying to write the contents of an HTTP Response to a file.

extern crate reqwest;

use std::io::Write;
use std::fs::File;

fn main() {
    let mut resp = reqwest::get("https://www.rust-lang.org").unwrap();
    assert!(resp.status().is_success());

    // Write contents to disk.
    let mut f = File::create("download_file").expect("Unable to create file");
    f.write_all(resp.bytes());
}

But I get the following compile error:

error[E0308]: mismatched types
  --> src/main.rs:12:17
   |
12 |     f.write_all(resp.bytes());
   |                 ^^^^^^^^^^^^ expected &[u8], found struct `std::io::Bytes`
   |
   = note: expected type `&[u8]`
              found type `std::io::Bytes<reqwest::Response>`

Upvotes: 13

Views: 14932

Answers (1)

Shepmaster
Shepmaster

Reputation: 430554

You cannot. Checking the docs for io::Bytes, there are no appropriate methods. That's because io::Bytes is an iterator that returns things byte-by-byte so there may not even be a single underlying slice of data.

It you only had io::Bytes, you would need to collect the iterator into a Vec:

let data: Result<Vec<_>, _> = resp.bytes().collect();
let data = data.expect("Unable to read data");
f.write_all(&data).expect("Unable to write data");

However, in most cases you have access to the type that implements Read, so you could instead use Read::read_to_end:

let mut data = Vec::new();
resp.read_to_end(&mut data).expect("Unable to read data");
f.write_all(&data).expect("Unable to write data");

In this specific case, you can use io::copy to directly copy from the Request to the file because Request implements io::Read and File implements io::Write:

extern crate reqwest;

use std::io;
use std::fs::File;

fn main() {
    let mut resp = reqwest::get("https://www.rust-lang.org").unwrap();
    assert!(resp.status().is_success());

    // Write contents to disk.
    let mut f = File::create("download_file").expect("Unable to create file");
    io::copy(&mut resp, &mut f).expect("Unable to copy data");
}

Upvotes: 16

Related Questions