extern crate reqwest;
use std::io;
use std::fs::File;
fn main() {
let mut resp = reqwest::get("https://sh.rustup.rs").expect("request failed");
let mut out = File::create("rustup-init.sh").expect("failed to create file");
io::copy(&mut resp, &mut out).expect("failed to copy content");
}
Cargo.toml
[package]
name = "example"
version = "0.1.0"
authors = ["fang <a@q.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
reqwest = "0.11.0"
But it cannot be compiled!
error[E0599]: no method named `expect` found for opaque type `impl Future` in the current scope
--> src/main.rs:7:57
|
7 | let mut resp = reqwest::get("https://sh.rustup.rs").expect("request failed");
| ^^^^^^ method not found in `impl Future`
|
help: consider awaiting before this method call
|
7 | let mut resp = reqwest::get("https://sh.rustup.rs").await.expect("request failed");
| ^^^^^^
Prompt to add await, I changed it to the following and still reported an error.
extern crate reqwest;
use std::io;
use std::fs::File;
async fn main() {
let mut resp = reqwest::get("https://sh.rustup.rs").await.expect("request failed");
let mut out = File::create("rustup-init.sh").expect("failed to create file");
io::copy(&mut resp, &mut out).expect("failed to copy content");
}
Error:
error[E0277]: the trait bound `Response: std::io::Read` is not satisfied
--> src/main.rs:9:5
|
9 | io::copy(&mut resp, &mut out).expect("failed to copy content");
| ^^^^^^^^ the trait `std::io::Read` is not implemented for `Response`
|
::: /Users/fangnan/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/std/src/io/util.rs:51:8
|
51 | R: Read,
| ---- required by this bound in `std::io::copy`
[dependencies]
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1", features = ["full"] }
extern crate reqwest;
use std::io;
use std::fs::File;
#[tokio::main]
async fn main() {
let mut resp = reqwest::get("https://sh.rustup.rs").await.expect("request failed");
let mut out = File::create("rustup-init.sh").expect("failed to create file");
io::copy(&mut resp, &mut out).expect("failed to copy content");
}
reqwest returns the Response as soon as the headers arrive, so you can't read the body directly from that object - the data might not have finished sending yet! You need to call one of the awaitable methods that decode the body when it's done being read. In this case, you probably want .text().
That gives you a String, but String doesn't implement Read, so you need to call .as_bytes() on it.
use std::io;
use std::fs::File;
#[tokio::main]
async fn main() {
let resp = reqwest::get("https://sh.rustup.rs").await.expect("request failed");
let body = resp.text().await.expect("body invalid");
let mut out = File::create("rustup-init.sh").expect("failed to create file");
io::copy(&mut body.as_bytes(), &mut out).expect("failed to copy content");
}
Note that since you are not writing a web server or something like that, I recommend just using reqwest::blocking.
[dependencies]
reqwest = { version = "0.11", features = ["blocking", "json"] }
use std::io;
use std::fs::File;
fn main() {
let resp = reqwest::blocking::get("https://sh.rustup.rs").expect("request failed");
let body = resp.text().expect("body invalid");
let mut out = File::create("rustup-init.sh").expect("failed to create file");
io::copy(&mut body.as_bytes(), &mut out).expect("failed to copy content");
}
@17cupsofcoffee You aren't supposed to use std file apis in async code because they are blocking. Instead you should prefer tokio::fs. These kind of details are why I recommend just using reqwest::blocking for non-web-server use-cases.