I have following Error:
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
My handler code containing the post_news function that throws this 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,
}
}
The error occurs in this line in the post_news
function:
let inserted = coll.insert_one(serialized_news, None).await.unwrap();
Tried to add Clone
and Debug
to my struct and that didn't help
When encountering an error, you need to dig in and figure out why the error occurs, rather than just fiddling left and right.
In this case, the first step is looking at the function you are attempting to call Collection::insert_one
:
pub async fn insert_one( &self, doc: impl Borrow<T>, options: impl Into<Option<InsertOneOptions>> ) -> Result<InsertOneResult>
And double checking what Borrow
is by following the link -- just to make sure it's indeed std::borrow::Borrow
(spoiler: it is).
So, since your coll
is of type Collection<News>
, you need a type implementing Borrow<News>
-- as mentioned by the error message -- which means amongst others News
and &News
.
Hence, as shown in the documentation of Collection
, you should just insert your News
object, without first serializing it:
let inserted = coll.insert_one(news, None).await.unwrap();
Collection
will take care of serializing and deserializing as appropriate, no need to do the bson
step yourself.