Reputation: 893
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;
}
};
}
Upvotes: 0
Views: 970
Reputation: 6723
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 think Send
and Sync
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 Unpin
and DeserializeOwned
. (T
automatically implements Send
and Sync
if all T
's members are Send
and Sync
.)
Upvotes: 1