как мне подключиться к mongoDB? (rust)

Я наклепал себе такую структуру, которую потом по моей задумке смогу развить

| src /
|       - api /
|       |       -patterns /
|       |       |       - mod.rs
|       |       |       - patterns.rs
|       |       |_________
|       |        - mod.rs
|       |______________
|    
|       - models /
|       |        - mod.rs
|       |        - pattern_model.rs
|       |        - pattern_asset_model.rs
|       |        - pattern_folder_model.rs
|       |        - device_model.rs
|       |        - device_asset_model.rs
|       |        - device_folder_model.rs
|       |        - universal_pattern_model.rs
|       |_________________
|
|       - repository /
|       |       | - mod.rs
|       |       | - mongodb_repo.rs
|       |_________________
|
|       - img /
|       |       
|       |       
|       |_________________
|
|       - .env      

|       - main.rs

|_________________________
- Cargo.lock
- Cargo.toml


api -  предназначен для модулизации обработчиков API. models -  предназначен для модулизации логики данных. repository -  предназначен для модулизации логики базы данных. но вопрос не к этому ( хотя у кого есть замечания, то не стесняйтесь).

я пытаюсь через Rocket поднять сервер с бд и просто выполнить простое добавление в коллекцию одной записи..

// main.rs 
mod api;
mod models;
mod repository;

#[macro_use]
extern crate rocket;

use api::patterns::patterns::{create_pattern};
use repository::mongodb_repo::MongoRepo;


#[launch]
fn rocket() -> _ {
    let db = MongoRepo::init();
    rocket::build().manage(db)
        .mount("/api/usepi/patterns", routes![create_pattern])
}

вот код инициализации бд..

//mongodb_repo.rs
use std::env;


extern crate dotenv;
use dotenv::dotenv;

use mongodb::{Client, Collection, options::ClientOptions};
use mongodb::error::Error;
use mongodb::results::InsertOneResult;

use crate::models::pattern_model::Pattern as ModelPattern;

pub struct MongoRepo {
    pattern_collection: Collection<ModelPattern>,
}

impl MongoRepo {

    pub async fn init() -> Self {
            dotenv().ok();
            let mongodb_uri = dotenv::var("MONGODB_URI");
            println!("AAAAAA {:?}",mongodb_uri);
            let client_options = ClientOptions::parse(mongodb_uri).await?;
            let client = Client::with_options(client_options)?;
            let db = client.database("RustBlueTractorDB");
            let pattern_collection: Collection<ModelPattern> = db.collection("Pattern");
            MongoRepo { pattern_collection }
        }

    .....

}

но вечно происходят ошибки по типу:

error[E0277]: the trait bound `Result<std::string::String, dotenv::Error>: AsRef<str>` is not satisfied
    --> src/repository/mongodb_repo.rs:26:55
     |
26   |             let client_options = ClientOptions::parse(mongodb_uri).await?;
     |                                  -------------------- ^^^^^^^^^^^ the trait `AsRef<str>` is not implemented for `Result<std::string::String, dotenv::Error>`
     |                                  |
     |                                  required by a bound introduced by this call
     |
note: required by a bound in `ClientOptions::parse`

исправляешь одно, появляется ошибка с "rocket::build().manage(db).." а от нее обратно на эту. я пробовал по мануалам делать (их не особо много, но все не работают по разным причинам). в .env у меня..

MONGODB_URI=mongodb://192.168.1.63:27018/

вот то что в pattern_model...

use mongodb::bson::oid::ObjectId;
use serde::{Serialize, Deserialize};

#[derive(Debug, Deserialize, Serialize)]
pub struct PatternRequest {
    pub data: Pattern,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Pattern {
    #[serde(rename = "_id", skip_serializing_if = "Option::is_none")]
    pub id: Option<ObjectId>,
    pub title: String,
    pub description: String,
    pub icon: String,
    pub pattern: String,
    pub create_date: String,
    pub update_date: String,
    pub version: String,
    pub favourite: bool,
}

и еще toml:

[package]
name = "rust"
version = "0.1.0"
edition = "2021"

[dependencies]
rocket = {version = "0.5.0-rc.2", features = ["json"]}
serde = "1.0.136"
dotenv = "0.15.0"
chrono = "0.4.31"

[dependencies.mongodb]
version = "2.8.0"
default-features = false
features = ["async-std-runtime"]

вопрос, как вообще мне это сделать? пересел с nestJS по острой нужде и если обычные функции вроде получаются, то с этим большая беда и не понимаю. Спасибо заранее!


Ответы (1 шт):

Автор решения: Exdet

вообщем, так:

#[launch]
async fn rocket() -> _ {
    let db = MongoRepo::init().await;
    rocket::build().manage(db)
        .mount("/api/patterns/patterns", routes![create_pattern])
}

и

   impl MongoRepo {

    pub async fn init() -> Self {
        dotenv().ok();
        // for (key, value) in env::vars() {
        //     println!("{}: {}", key, value);
        // }
        let uri = match env::var("MONGODB_URI") {
            Ok(v) => v.to_string(),
            Err(_) => format!("Error loading env variable"),
        };
        // println!("{}",uri);
        let client = Client::with_uri_str(uri).await.unwrap();
        let db = client.database("ModelPattern");
        let pattern_collection: Collection<ModelPattern> = db.collection("ModelPattern");
        MongoRepo { pattern_collection }
    }
}
→ Ссылка