I have this code which is throwing the following error: use of moved value: response value used here after move.
use std::collections::HashMap;
use reqwest::Response;
use serde_json::json;
async fn error_example() -> (Response, String) {
let execute_url = "https://jsonplaceholder.typicode.com/todos/1";
let client = reqwest::Client::new();
let response = client.post(execute_url).send().await.unwrap();
let response_body = response.text().await.unwrap();
let response_body: HashMap<String, String> = serde_json::from_str(&response_body).unwrap();
let execution_id = response_body.get("userId").unwrap();
return (response, execution_id.clone()); // use of moved value: `response` value used here after move
}
The error come from the response_body variable using the response variable and taking ownership of it. I wanted to clone the response, or wrap the extraction of the key (execution_id) in a function and passing a ref of the response but none worked.
I should have the Clone or Copy trait implemented but I can't implement it for struct not defined within the crate. So I don't know how to handle this case.
How can I get rid of the error ? Thanks
Reqwest's Response type does not really contain the response body. It's basically an open network socket plus the state needed to accept the data. When you call text, it builds a String straight from the socket. If you wanted to call text again, you'd need to resend the request, since neither Response nor the socket store this data.
So if you want to return the whole request body, you can return the string that was just created.
let response_body = response.text().await.unwrap();
let response_map: HashMap<String, String> = serde_json::from_str(&response_body).unwrap();
let execution_id = response_map.get("userId").unwrap().clone();
(response_body, execution_id)
Or you could return the headers, or status code, or whatever else you need. Reqwest doesn't have a type to represent a spent response, but you could make your own.
Another thing is that deserializing the entire response is not necessary. You can make a struct for just the field you need, which means you only need to allocate one String, and you don't need to clone it.
#[derive(serde::Deserialize)]
#[serde(rename_all = "camelCase")]
struct OnlyUserId {
user_id: String
}
let only_user_id: OnlyUserId = serde_json::from_str(&response_body).unwrap();
let execution_id = only_user_id.user_id;
(response_body, execution_id)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With