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:
- A folder containing a implementation to build a mongo connection string.
- A .env file
- 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>>
.