Rust操作MongoDB更新模型时遭遇E0532编译错误求助
问题场景
想要在Rust中更新MongoDB的整个User模型,避免逐个字段编写$set语句,编写对应代码后出现编译错误。
原代码
use mongodb::{bson, bson::doc, Client, Collection}; let collection: Collection<User> = client.database(DB_NAME).collection(users::REPOSITORY_NAME); let filter = doc! {"email": new_user_copy.email}; let new_user_bson = match bson::to_bson(&new_user_copy) { bson::Document(doc) => doc, _ => unreachable!(), }; let update = doc! {"$set": new_user_bson}; let result = collection.update_one(filter, update, None).await;
编译错误
error[E0532]: expected tuple struct or tuple variant, found struct
Document
--> src/controllers/users.rs:82:17
|
82 | Document(doc) => doc,
| ^^^^^^^^^^^^^
|
::: /Users/adrien/.cargo/registry/src/github.com-1ecc6299db9ec823/bson-2.6.1/src/document.rs:63:1
|
63 | pub struct Document {
| -------------------Documentdefined here
|
help: use struct pattern syntax instead
|
82 | Document { inner } => doc,
| ~~~~~~~~~~~~~~~~~~
help: consider importing one of these items instead
|
1 | use crate::controllers::users::bson::Bson::Document;
|
1 | use crate::controllers::users::bson::RawBson::Document;
|
1 | use crate::controllers::users::bson::RawBsonRef::Document;
|
1 | use mongodb::options::UpdateModifications::Document;
错误原因
bson::to_bson返回的是Bson枚举类型,其中的Document是该枚举的一个变体,而非直接的bson::Document结构体。原代码中直接写bson::Document(doc)是在匹配结构体,而非枚举变体,导致编译错误。
解决方法
方法1:明确匹配Bson枚举的Document变体
修改match语句,指定枚举变体bson::Bson::Document:
use mongodb::{bson, bson::doc, Client, Collection}; let collection: Collection<User> = client.database(DB_NAME).collection(users::REPOSITORY_NAME); let filter = doc! {"email": new_user_copy.email}; let new_user_bson = match bson::to_bson(&new_user_copy) { bson::Bson::Document(doc) => doc, // 明确指定枚举变体 _ => unreachable!(), }; let update = doc! {"$set": new_user_bson}; let result = collection.update_one(filter, update, None).await;
方法2:导入Bson枚举的Document变体简化代码
在开头导入bson::Bson::Document,匹配时可直接写Document(doc):
use mongodb::{bson, bson::Bson::Document, bson::doc, Client, Collection}; let collection: Collection<User> = client.database(DB_NAME).collection(users::REPOSITORY_NAME); let filter = doc! {"email": new_user_copy.email}; let new_user_bson = match bson::to_bson(&new_user_copy) { Document(doc) => doc, _ => unreachable!(), }; let update = doc! {"$set": new_user_bson}; let result = collection.update_one(filter, update, None).await;
方法3:使用bson::to_document直接转换(更简洁)
无需通过to_bson再匹配,直接用to_document将User实例转为Document:
use mongodb::{bson, bson::doc, Client, Collection}; let collection: Collection<User> = client.database(DB_NAME).collection(users::REPOSITORY_NAME); let filter = doc! {"email": new_user_copy.email}; let new_user_doc = bson::to_document(&new_user_copy)?; // 直接转为Document,用?处理错误 let update = doc! {"$set": new_user_doc}; let result = collection.update_one(filter, update, None).await;
注:实际代码中建议用?替代unwrap()处理转换错误,提升程序健壮性。
内容的提问来源于stack exchange,提问作者Adrien Chapelet

