对铁 rust 来说非常陌生.我希望使用指定的查询从Gmail下载邮箱附件,我有一个粗略的同步代码,功能和我希望使用多线程使用?Tokio::Sawn?(因为项目的其余部分已经使用Tokio)当前的多线程?代码如下:
struct EmailInterface {
pub gmail: Gmail<HttpsConnector<HttpConnector>>,
}
impl EmailInterface {
async fn new(path_to_key: String) -> Result<EmailInterface, Box<dyn error::Error>> {
let authenticator =
ServiceAccountAuthenticator::builder(read_service_account_key(path_to_key).await?)
.build()
.await?;
let gmail = Gmail::new(
hyper::Client::builder().build(
hyper_rustls::HttpsConnectorBuilder::new()
.with_native_roots()
.https_or_http()
.enable_http1()
.enable_http2()
.build(),
),
authenticator,
);
Ok(EmailInterface { gmail })
}
pub async fn get_attachments(
self,
query: &str,
) -> Result<(), Box<dyn std::error::Error>> {
if let Some(messages_list) = self
.gmail
.users()
.messages_list("me")
.q(query)
.include_spam_trash(false)
.doit()
.await?
.1
.messages
{
let messages_id_list: Vec<String> = messages_list
.into_iter()
.flat_map(|message| message.id)
.collect();
for id in messages_id_list {
tokio::spawn(async move {
let message = self.gmail
.users()
.messages_get("me", id.as_str())
.doit()
.await
.unwrap_or_default()
.1;
let message = self
.gmail
.users()
.messages_get("me", id.as_str())
.doit()
.await
.unwrap_or_default()
.1;
for part in message.payload {
if let Some(part_body) = part.body {
if let Some(attachment_id) = part_body.attachment_id {
let attachment = self
.gmail
.users()
.messages_attachments_get(
"me",
id.as_str(),
attachment_id.as_str(),
)
.doit()
.await
.unwrap_or_default();
let data = general_purpose::STANDARD
.decode(&attachment.1.data.unwrap_or_default())
.unwrap();
std::fs::write(part.filename.expect("Should have a name"), &data)
.unwrap();
}
}
}
});
}
}
Ok(())
}
}
我目前收到的错误
use of moved value: `self.gmail`
move occurs because `self.gmail` has type `Gmail<HttpsConnector<HttpConnector>>`, which does not implement the `Copy` trait
如果有更流畅的方式做这件事,我会洗耳恭听.
我也try 过使用ThreadPool Crate&;ChatGPT来寻求建议,但后者总是以错误告终.