skip to Main Content

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


  1. Here are a few tips…

    I suggest that you cargo add serde_json (if you haven’t already done that) and then simply convert your mongodb::bson::Document into serde_json::Value. Here is an example how:

    if let Some(doc) = cursor.try_next().await? {
        let v = serde_json::to_value(&doc).unwrap();
    }
    

    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:

    if let Some(doc) = cursor.try_next().await? {
        let v = serde_json::to_value(&doc).unwrap();
        return Ok(Some(v));
    }
    
    Login or Signup to reply.
  2. I think error is here:

    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);
    }
    

    in case of error you are returning return Ok(None); but you should be returning mongodb::error::Error> because this is what you added to the function definition:

    pub async fn database_connection(key: &str, value: &str) -> Result<Option<Value>, mongodb::error::Error> {
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search