You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中如何不移动Response对象反序列化JSON响应?

问题背景

我正在构建一个小型Rust CLI工具,用于自动化GitLab中的部分任务。使用reqwest向GitLab API发送HTTP请求,目前正在重构代码以移除重复片段。

原始代码片段:

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
已尝试的方法

尝试克隆响应后调用json方法:

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()仍会导致移动操作。


内容的提问来源于stack exchange,提问作者Jeremy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 05:02:04