1
use std::{error::Error as StdError, sync::Arc};
2

            
3
use log::{error, info};
4
use mongodb::{
5
    event::cmap::{
6
        CmapEventHandler, ConnectionClosedEvent, ConnectionCreatedEvent, ConnectionReadyEvent,
7
        PoolClearedEvent, PoolClosedEvent, PoolCreatedEvent, PoolReadyEvent,
8
    },
9
    options::ClientOptions,
10
    Client, Database,
11
};
12

            
13
/// MongoDB connection options.
14
pub struct Options {
15
    /// MongoDB URL. Use `mongodb://username:password@host:port` format.
16
    pub url: String,
17
    /// The database.
18
    pub db: String,
19
    /// Connection pool size.
20
    pub pool_size: Option<u32>,
21
}
22

            
23
struct ConnectionHandler;
24

            
25
/// Connect to MongoDB.
26
9
pub async fn connect(options: &Options) -> Result<Database, Box<dyn StdError>> {
27
9
    let mut opts = ClientOptions::parse(&options.url).await?;
28
9
    if let Some(pool_size) = options.pool_size {
29
1
        opts.max_pool_size = Some(pool_size);
30
8
    }
31
9
    opts.cmap_event_handler = Some(Arc::new(ConnectionHandler));
32
9
    let client = Client::with_options(opts)?;
33
46
    client.list_database_names(None, None).await?;
34
9
    Ok(client.database(&options.db))
35
9
}
36

            
37
impl CmapEventHandler for ConnectionHandler {
38
9
    fn handle_pool_created_event(&self, _event: PoolCreatedEvent) {
39
9
        info!("[handle_pool_created_event]");
40
9
    }
41
9
    fn handle_pool_ready_event(&self, _event: PoolReadyEvent) {
42
9
        info!("[handle_pool_ready_event]");
43
9
    }
44
    fn handle_pool_cleared_event(&self, _event: PoolClearedEvent) {
45
        error!("[handle_pool_cleared_event]");
46
    }
47
3
    fn handle_pool_closed_event(&self, _event: PoolClosedEvent) {
48
3
        error!("[handle_pool_closed_event]");
49
3
    }
50
9
    fn handle_connection_created_event(&self, _event: ConnectionCreatedEvent) {
51
9
        info!("[handle_connection_created_event]");
52
9
    }
53
9
    fn handle_connection_ready_event(&self, _event: ConnectionReadyEvent) {
54
9
        info!("[handle_connection_ready_event]");
55
9
    }
56
3
    fn handle_connection_closed_event(&self, _event: ConnectionClosedEvent) {
57
3
        error!("[handle_connection_closed_event]");
58
3
    }
59
}