Home > Mobile >  Succesfully return a connection instance MongoDb - Rust
Succesfully return a connection instance MongoDb - Rust

Time:10-17

I'm learning rust, and I have been following the rust book. Usually, I try to implement something to strengthen my knowledge.

Recently I was looking into how to use the MongoDb create to create an instace and return the name of the database.

Here's a sample of what I have:

  1. A folder containing a implementation to build a mongo connection string.
  2. A .env file
  3. A main function to get the info I need.

mongo_connection.rs

#[derive(Debug)]
pub struct ConnectionString {
    pub username: String,
    pub password: String,
    pub cluster: String,
}

impl ConnectionString {
    pub fn build_connection_string() -> String {
        return format!("mongodb srv://{}:{}@a{}.k1jklnx.mongodb.net/?retryWrites=true&w=majority",
        Self.username, Self.password, Self.cluster)
    }
}

main.rs

mod database;
use crate::database::mongo_connection;
use mongodb::{Client, options::ClientOptions};
use std::error::Error;
use dotenv::dotenv;
use std::env;
use tokio;

async fn create_database_connection() -> Client {
    dotenv().ok(); //Loading environment variables from .env file
    let connection_parameters = mongo_connection::ConnectionString{
        username: env::var("USERNAME").expect("No username found on .env"),
        password: env::var("PASSWORD").expect("No password found on .env"),
        cluster: env::var("CLUSTER").expect("No cluster found on .env")
    };
    let mut url: String = mongo_connection::ConnectionString::build_connection_string();
    println!("{}", url);
    let options = ClientOptions::parse(&url).await?;
    return Client::with_options(options).await;
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
    let client = create_database_connection().await?;
    let db = client.database(&"runt");
    println!("{:?}", db.name());
    Ok(())
}

The problem I am facing is that I need to return a connection client. But I keep getting the Error:

let options = ClientOptions::parse(&url).await?;
    ^ cannot use the `?` operator in an async function that returns `Client`

If I change the result of the function to something like: Result<Client, dyn Eq> then I get the error:

async fn create_database_connection() -> Result<Client, dyn Eq> {
`Eq` cannot be made into an object
^^^^^^^^^^^^^^^ the trait cannot be made into an object because it uses `Self` as a type parameter
    |

Any advice on how to solve the error or any workaround is much appreciated.

CodePudding user response:

You could change the return type to either Result<Client, mongodb::error::Error> or Result<Client, Box<dyn Error>>. Either should work, but here's the code with the first version:

async fn create_database_connection() -> Result<Client, mongodb::error::Error> {
    dotenv().ok(); //Loading environment variables from .env file
    let connection_parameters = mongo_connection::ConnectionString{
        username: env::var("USERNAME").expect("No username found on .env"),
        password: env::var("PASSWORD").expect("No password found on .env"),
        cluster: env::var("CLUSTER").expect("No cluster found on .env")
    };
    let mut url: String = mongo_connection::ConnectionString::build_connection_string();
    println!("{}", url);
    let options = ClientOptions::parse(&url).await?;
    return Client::with_options(options).await;
}

In case you want to use the Box<dyn Error> version, the return value also needs a .into() to convert the Result<Client, mongodb::error::Error> of Client::with_options() into a Result<Client, Box<dyn Error>>.

  • Related