Skip to main content

ferrox_database_mongo/
lib.rs

1//! # Ferrox Database Mongo (`ferrox-database-mongo`)
2//!
3//! `ferrox-database-mongo` provides document storage capabilities for Ferrox applications, wrapping the official MongoDB Rust driver
4//! with strongly-typed `MongoRepository` traits and BSON conversion utilities.
5//!
6//! ## Key Features
7//! - 🍃 **MongoDB Async Client**: Managed database connection pooling.
8//! - 📦 **Document Repository**: Generic CRUD methods for BSON-serializable domain models.
9//! - 🔍 **Aggregation Builders**: Helpers for building MongoDB pipeline queries.
10
11use mongodb::{Client, options::ClientOptions};
12use ferrox_errors::AppError;
13use std::time::Duration;
14
15#[derive(Clone)]
16pub struct MongoClient {
17    pub client: Client,
18    pub db_name: String,
19}
20
21impl MongoClient {
22    pub async fn connect(connection_string: &str, db_name: &str) -> Result<Self, AppError> {
23        let mut client_options = ClientOptions::parse(connection_string)
24            .await
25            .map_err(|e| AppError::DatabaseError(format!("Mongo URL Parse Error: {}", e)))?;
26
27        // Optional: configure pooling explicitly if needed, but defaults are usually fine
28        client_options.connect_timeout = Some(Duration::from_secs(10));
29        client_options.max_pool_size = Some(100);
30        client_options.min_pool_size = Some(5);
31
32        let client = Client::with_options(client_options)
33            .map_err(|e| AppError::DatabaseError(format!("Mongo Client Init Error: {}", e)))?;
34
35        // Test connection
36        client
37            .database(db_name)
38            .run_command(mongodb::bson::doc! {"ping": 1})
39            .await
40            .map_err(|e| AppError::DatabaseError(format!("Mongo Ping Failed: {}", e)))?;
41
42        tracing::info!("Connected to MongoDB: {}", db_name);
43
44        Ok(Self {
45            client,
46            db_name: db_name.to_string(),
47        })
48    }
49}