Context
我正在构建一个小型的Rust CLI来自动化Gitlab中的一些任务。我使用reqwest将我的HTTP请求发送到Gitlab API。我目前正在重构我的代码,现在我想删除这个重复的代码段。
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);
}
我的目标是在一个单独的函数上处理响应的状态码:
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
),
}
}
由于json
方法调用将我的响应体反序列化为所需的结构体,因此此代码无法工作。
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
我所尝试的
我已经尝试了以下方法(对不起,我对生 rust 还是新手)。
let json_response = response.clone().json::<gitlab::GitlabError>().expect(
format!(
"An unkown error happened while creating your new {}!",
resource
)
.as_str(),
);
但我得到了同样的错误。
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
|
我还尝试以文本形式接收响应,然后用serde_json
进行反序列化,但调用create_branch_response.json()
也会导致移动。
如果你有兴趣阅读整个代码以获得更好的上下文,这里有一个包含这些(破碎的)更改的分支:https://github.com/Je12emy/shears-cli/tree/util_module。欢迎任何反馈
1条答案
按热度按时间ws51t4hk1#
得到
error[E0507]: cannot move out of a shared reference
的原因是因为实际上克隆的是引用而不是实际的结构体(Response
)。Rust在某些情况下会隐式地对函数调用的ref进行deref(参见函数和方法的隐式deref强制),但不适用于您的情况,因为reqwest::blocking::Response
没有实现Clone。See this example
为了解决借用问题,我建议您从request中获取bytes值,创建一个
BufReader
,然后使用serde_json::from_reader
(reqwest内部使用这个)。然后你可以多次解析json。