Rust CRUD新增接口出现`Bson: Borrow<News>` trait未满足错误
Axum + MongoDB 新增新闻接口编译错误E0277解决
问题
使用Axum与MongoDB实现新闻新增接口post_news时,出现编译错误E0277:提示Bson未实现Borrow<News> trait,错误触发于coll.insert_one(serialized_news, None)代码行。已尝试为News结构体添加Clone和Debug trait,但问题未解决。
错误信息
error[E0277]: the trait bound `Bson: Borrow<News>` is not satisfied --> src\handlers.rs:46:36 | 46 | let inserted = coll.insert_one(serialized_news, None).await.unwrap(); | ---------- ^^^^^^^^^^^^^^^ the trait `Borrow<News>` is not implemented for `Bson` | | | required by a bound introduced by this call | note: required by a bound in `mongodb::Collection::<T>::insert_one` --> C:\Users\User\.cargo\registry\src\github.com-1ecc6299db9ec823\mongodb-2.3.1\src\coll\mod.rs:1279:19 | 1279 | doc: impl Borrow<T>, | ^^^^^^^^^ required by this bound in `mongodb::Collection::<T>::insert_one` For more information about this error, try `rustc --explain E0277`. error: could not compile `backend` due to previous error
相关代码
use crate::structs::News; use axum::{extract::Path, extract::State, http::StatusCode, response::IntoResponse, Json}; use bson::oid::ObjectId; use futures::stream::StreamExt; use mongodb::{bson::doc, options::FindOptions, Client, Collection}; pub async fn get_all(State(client): State<Client>) -> impl IntoResponse { let coll: Collection<News> = client.database("axum").collection::<News>("news"); let mut options = FindOptions::default(); options.limit = Some(1); options.sort = Some(doc! { "title": 1 }); let mut cursor = coll .find(None, options) .await .expect("could not load news data."); let mut rows: Vec<News> = Vec::new(); while let Some(doc) = cursor.next().await { rows.push(doc.expect("could not load news info.")); } (StatusCode::OK, Json(rows)) } pub async fn get_one(Path(id): Path<u64>) {} pub async fn post_news( State(client): State<Client>, Json(payload): Json<News>, ) -> impl IntoResponse { let coll: Collection<News> = client.database("axum").collection::<News>("news"); let news = News { id: ObjectId::new(), title: payload.title.to_string(), short_description: payload.short_description.to_string(), }; let serialized_news = bson::to_bson(&news).unwrap(); let inserted = coll.insert_one(serialized_news, None).await.unwrap(); (StatusCode::CREATED, Json(news)) } pub async fn handler_404() -> impl IntoResponse { (StatusCode::NOT_FOUND, "nothing to see here") } mod structs { use bson::{self, oid::ObjectId}; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] pub struct News { #[serde(rename = "_id")] pub id: ObjectId, pub title: String, pub short_description: String, } }
错误触发代码行
let inserted = coll.insert_one(serialized_news, None).await.unwrap();
解决方案
错误核心原因:Collection<News>的insert_one方法要求参数实现Borrow<News>约束,但手动将News序列化为Bson后,Bson类型并不满足该约束。MongoDB Rust驱动会自动处理结构体的序列化/反序列化,无需手动转换为Bson。
修改post_news函数,删除手动序列化步骤,直接传入&news即可:
pub async fn post_news( State(client): State<Client>, Json(payload): Json<News>, ) -> impl IntoResponse { let coll: Collection<News> = client.database("axum").collection::<News>("news"); let news = News { id: ObjectId::new(), title: payload.title.to_string(), short_description: payload.short_description.to_string(), }; // 直接传入&news,驱动自动完成序列化 let inserted = coll.insert_one(&news, None).await.unwrap(); (StatusCode::CREATED, Json(news)) }
注:确保News结构体已正确实现Serialize和Deserialize trait(你的代码中已满足该条件),这是驱动自动序列化的前提。
内容的提问来源于stack exchange,提问作者Azashiro Merume
相关产品推荐
相关产品推荐

