I'm trying to create a method to which I can pass a mongodb connection pool, an objectId and the collection name to retrieve data.
I came up with the code below but which doesn't compile because of the following error:
error: the method
find_one
exists for structmongodb::Collection<T>
, but its trait bounds were not satisfied label: method cannot be called onmongodb::Collection<T>
due to unsatisfied trait bounds note: the following trait bounds were not satisfied:T: DeserializeOwned
T: Unpin
T: std::marker::Send
T: Sync
label: method cannot be called onmongodb::Collection<T>
due to unsatisfied trait bounds
What I'm I doing wrong?
pub async fn generic_find_by_id<T>(db: &AppContext, object_id: String, collection_name: &str) -> Option<T> {
let collection = db.mongodb_pool.collection::<T>(collection_name);
let id_obj = ObjectId::parse_str(object_id);
let found = match id_obj {
Ok(id) => {
let filter = doc! {"_id": id};
let result = collection.find_one(filter, None).await;
match result {
Ok(result) => {
match result {
Some(result) => {
return Some(result);
}
None => {
return None;
}
}
}
Err(_) => {
return None;
}
}
}
Err(_) => {
return None;
}
};
}
CodePudding user response:
It seems Collection<T>::find_one()
is only implemented if T: DeserializeOwned Unpin Send Sync
. (See it in the source here: https://docs.rs/mongodb/latest/src/mongodb/coll/mod.rs.html#795). I gather some of those traits have to do with the collection being potentially sent across threads during async function calls. To solve this, you can make your T
type implement those traits. T automatically implements Send
and Sync
if all T
's members are Send
and Sync
.