I have this code to connect with MongoDB from rust run when I try to cargo run
the code return an error in the if statement and I can’t figure out why. It has been days that I try to debug it.
This is the code:
use std::iter::FilterMap;
use rocket::serde::json::{json, Value};
use futures::{StreamExt};
use mongodb::{bson::doc, options::ClientOptions, Client};
use bson::{Document};
use warp::body::json;
/**
* MongoDB client
*/
#[tokio::main]
pub async fn database_connection(key: &str, value: &str) -> Result<Option<Value>, mongodb::error::Error> {
// uri to connect to the database
let uri = "mongodb://admin:adminpassword@localhost:27017";
// options to connect to the database
let mut client_options =
ClientOptions::parse(uri)
.await?;
// Create a new client and connect to the server with the given options
let client = Client::with_options(client_options)?;
//Connect to the BinGo! database
let material = client.database("BinGo!");
// Search thrue a collection
let collection = material.collection::<Document>("bingo_materials");
let filter = doc! {
key: value
};
print!("Making the query to the database...n");
println!("Filter: {:#?}", filter);
print!("-------------------------n");
let mut cursor = collection.
find(filter, None)
.await?;
if let Some(result) = cursor.next().await {
println!("{:#?}", result);
let result_json: &Result<Document, mongodb::error::Error> = &result;
return Ok(Some(result_json));
}else{
return Ok(None);
}
}
and the error is the following:
error[E0308]: mismatched types
--> src/databases.rs:57:5
|
25 | pub async fn database_connection(key: &str, value: &str) -> Result<Option<Value>, mongodb::error::Error> {
| -------------------------------------------- expected `Result<std::option::Option<rocket_dyn_templates::tera::Value>, mongodb::error::Error>` because of return type
...
57 | / if let Some(result) = cursor.next().await {
58 | | println!("{:#?}", result);
59 | | let result_json: &Result<Document, mongodb::error::Error> = &result;
60 | | return Ok(Some(result_json));
61 | | }else{
62 | | return Ok(None);
63 | | }
| |_____^ expected `Result<Option<Value>, Error>`, found `Result<Option<&...>, ...>`
|
= note: expected enum `Result<std::option::Option<rocket_dyn_templates::tera::Value>, mongodb::error::Error>`
found enum `Result<std::option::Option<&Result<bson::Document, mongodb::error::Error>>, _>`
Please be kind, I’m new to rust and I’m still learning.
I’m expecting to return the value of result_json
, because database_connection()
is called from a route in rocket.rs.
2
Answers
Here are a few tips…
I suggest that you
cargo add serde_json
(if you haven’t already done that) and then simply convert yourmongodb::bson::Document
intoserde_json::Value
. Here is an example how:You could also add the popular anyhow crate and make your return type
anyhow::Result<Option<serde_json::Value>>
. Then you could do something like this:I think error is here:
in case of error you are returning
return Ok(None);
but you should be returningmongodb::error::Error>
because this is what you added to the function definition: