0

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.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129

1 Answers1

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

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)?;
    return Ok(Some(v));
}
at54321
  • 8,726
  • 26
  • 46
  • While these are helpful tips, they don't actually *answer the question asked*, as you don't explain why the error is triggered. – jthulhu Jul 22 '23 at 20:57
  • @jthulhu the compiler message seems quite clear to me: the declared (and expected) result type of the function is different from what the function _tries_ to return. – at54321 Jul 22 '23 at 21:36
  • Thanks for the reply, right now I'm using anyhow to return value and it seems to work but I still have this error on the &doc reference ``` error[E0277]: the trait bound `mongodb::error::Error: Serialize` is not satisfied --> src/databases.rs:65:39 | | let v = serde_json::to_value(&doc).unwrap(); | -------------------- ^^^ the trait `Serialize` is not implemented for ``` This is the type`core::result::Result` – Elia Todescato Jul 23 '23 at 11:09
  • @EliaTodescato in my example code the type of `doc` is `mongodb::bson::Document`. Be careful not to skip some of the `?`s from my code, as they play a crucial role - they essentially "unwrap" the `Result` value. I don't know what exactly is causing your problems, but it looks to me you're trying to encode a `Result` value as a JSON. – at54321 Jul 23 '23 at 11:19