I am new to rust, and trying to learn it after python, and have faced to problem in one of the simplest tasks.
For simplicity I want to write function to get data(in this example - text) from http response.
src/main.rs
use reqwest;
fn main() {
let text = get_text();
println!("Got text {text}")
}
fn get_text() -> String {
let http_client = reqwest::blocking::Client::new();
let url = "https://google.com";
let response = http_client.get(url).send()?.text()?;
response
}
Cargo.toml
[package]
name = "test"
version = "0.1.0"
edition = "2021"
[dependencies]
reqwest = { version = "0.11", features = ["json", "blocking"] }
openssl = { version = "0.10", features = ["vendored"] }
I want to make get_text()
routine to return String type.
According to reqwest docs .text()
returns Result<String>
As I understand operator ?
means that call should return Ok<String>
or panic with Err(e)
With that code compilation fails:
let response = http_client.get(url).send()?.text()?;
cannot use the `?` operator in a function that returns `std::string::String`
Here I do not understand first thing:
Why compile compare function return type with return of both .send()
and .text()?
if return value is only after that?
And, well, I try to change return type to Result<String, Box<dyn std::error::Error>>
as in documentation and examples
and then compilator whines about wrong return type:
| response
| ^^^^^^^^ expected enum `Result`, found struct `std::string::String`
So the second question is:
How i can achieve my goal while compilators compare return type in the middle of function call and in the end of call
First and foremost have a good read here about ? operator
for answer of first question.
The ? placed after a Result value is defined to work in almost the same way as the match expressions we defined to handle the Result values
About your code you should do something like below
use reqwest;
// Have changed main method's return type
// as using ? operator on result returned by get_text() method
fn main() -> Result<(), Box<dyn std::error::Error>> {
// unwrapped result from get_text() with ?
let text = get_text()?;
// changed formatting
println!("Got text {}", text);
// as main method response type is changes return unit type in case of success
Ok(())
}
fn get_text() -> Result<String, Box<dyn std::error::Error>> {
let http_client = reqwest::blocking::Client::new();
let url = "https://google.com";
let response = http_client
// form a get request with get(url)
.get(url)
// send the request and get Response or else return the error
.send()?
// get text from response or else return the error
.text()?;
// wrapped response in Result
Ok(response)
}
Hope it helpls.