解析json响应时,无法移出与Rust共享引用后面的`*response`

x33g5p2x  于 2023-05-30  发布在  其他
关注(0)|答案(1)|浏览(148)

我是一个新手,正在尝试做一个简单的电子邮件解析器,但我面临着新手在Rust中借用东西的常见问题。
我尝试编译下面的代码,它希望将带有reqwest的json响应解析到我的结构MessagesListResponse中,然后我只想返回一个只包含Mapid的字符串的Vec:

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct MessagesListResponse{
    messages: Vec<MessageId>
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct MessageId{
    id: String,
    thread_id: String
}

#[async_trait]
impl MessageGetter for GmailMessageGetter{

    async fn get_message_ids(&self) -> Vec<String> {
        

        let url = "https://gmail.googleapis.com/gmail/v1/users/me/messages?q=from%3Awebank%40webank.it%20subject%3Aautorizzato%20pagamento".to_owned();
        
        dbg!(&url);
        let response = &self.client.get(url).send().await.unwrap();

        _ = &response.error_for_status_ref().unwrap();
        let msg_list_response = response.json::<MessagesListResponse>().await.unwrap();
        msg_list_response.messages.into_iter().map(|message_id| message_id.id).collect()
    }
    
}

不幸的是,我一直得到错误

cannot move out of `*response` which is behind a shared reference

在线

let msg_list_response = response.json::<MessagesListResponse>().await.unwrap();

但是我不明白如何使它工作,因为响应类型reqwest::async_impl::response是不可克隆的,而response.json方法消耗了响应。有人能帮帮我吗多谢了。

gzjq41n4

gzjq41n41#

这里有一个不必要的参考。

let response = &client.get(url).send().await.unwrap();

删除它,你的代码就可以工作了。

let response = client.get(url).send().await.unwrap();

这里的赋值和引用是不必要的,没有任何作用。

_ = &response.error_for_status_ref().unwrap();

你可以删除它们。

response.error_for_status_ref().unwrap();

URL末尾的.to_owned()也是不必要的。你应该把它拿掉。
这些是唯一的问题,但另一种编写方法是作为一个大的方法链。

client
    .get(url)
    .send()
    .await
    .unwrap()
    .error_for_status()
    .unwrap()
    .json::<MessagesListResponse>()
    .await
    .unwrap()
    .messages
    .into_iter()
    .map(|message_id| message_id.id)
    .collect()

相关问题