Context
I'm building a small Rust CLI to automate some tasks in Gitlab. I'm using reqwest to send my HTTP requests to the Gitlab API. I'm currently refactoring my code, and now I would like to remove this duplicated code snippet.
fn main() {
// ... some code
let create_branch_response = gitlab::create_branch(&client, &args)
.expect("An error ocurred while processing your request to create a new branch");
match create_branch_response.status() {
StatusCode::OK => (),
StatusCode::BAD_REQUEST => {
let json_response = create_branch_response
.json::<gitlab::GitlabError>()
.expect("An unkown error happened while creating your new branch!");
panic!(
"A validation error ocurred while creating your new branch: {}",
json_response.message
);
}
_ => panic!("An unexpected error ocurred while creating your new branch"),
}
let new_branch = create_branch_response
.json::<gitlab::Branch>()
.expect("An error ocurred while reading the response");
println!("New branch {} created!", new_branch.name);
println!("URL: {}", new_branch.web_url);
// Some other code
let create_pr_response = gitlab::create_pr(&client, &args)
.expect("An error ocurred while processing your request to create a merge request");
match create_pr_response.status() {
StatusCode::OK => (),
StatusCode::BAD_REQUEST => {
let json_response = create_pr_response
.json::<gitlab::GitlabError>()
.expect("An unkown error happened while creating your new merge request!");
panic!(
"A validation error ocurred while creating your new merge request: {}",
json_response.message
);
}
_ => panic!("An unexpected error ocurred while creating your merge request"),
}
let new_pr = create_pr_response
.json::<gitlab::MergeRequest>()
.expect("An error ocurred while reading the merge request response");
println!("New pull request \"{}\" created!", new_pr.title);
println!("URL: {}", new_pr.web_url);
}
My goal is to handle the response's status code on a separate function:
pub fn handle_response_status(status: StatusCode, resource: String, response: &Response) {
match status {
StatusCode::OK => (),
StatusCode::BAD_REQUEST => {
let json_response = response.json::<gitlab::GitlabError>().expect(
format!(
"An unkown error happened while creating your new {}!",
resource
)
.as_str(),
);
panic!(
"A validation error ocurred while creating your new {}: {}",
resource, json_response.message
);
}
_ => panic!(
"An unexpected error ocurred while creating your {}",
resource
),
}
}
This code does not work due to the json
method call which deserializes my response body into a desired struct.
error[E0507]: cannot move out of `*response` which is behind a shared reference
--> src/util.rs:22:33
|
22 | let json_response = response.json::<gitlab::GitlabError>().expect(
| ^^^^^^^^^-----------------------------
| | |
| | `*response` moved due to this method call
| move occurs because `*response` has type `reqwest::blocking::Response`, which does not implement the `Copy` trait
What I tried
I already tried the following (sorry, I'm still new to rust).
let json_response = response.clone().json::<gitlab::GitlabError>().expect(
format!(
"An unkown error happened while creating your new {}!",
resource
)
.as_str(),
);
But I get the same error.
error[E0507]: cannot move out of a shared reference
--> src/util.rs:12:33
|
12 | let json_response = response.clone().json::<gitlab::GitlabError>().expect(
| ^^^^^^^^^^^^^^^^^-----------------------------
| | |
| | value moved due to this method call
| move occurs because value has type `reqwest::blocking::Response`, which does not implement the `Copy` trait
|
I also tried receiving the response as text and then deserializing with serde_json
, but calling create_branch_response.json()
also causes a move.
If you are interested on reading the whole code for better context, here's a branch with these (broken) changes: https://github.com/Je12emy/shears-cli/tree/util_module. Any feedback is appreciated