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
11
pub async fn connect(options: &Options) -> Result<Database, Box<dyn StdError>> {
27
11
    let mut opts = ClientOptions::parse(&options.url).await?;
28
11
    if let Some(pool_size) = options.pool_size {
29
1
        opts.max_pool_size = Some(pool_size);
30
10
    }
31
11
    opts.cmap_event_handler = Some(Arc::new(ConnectionHandler));
32
11
    let client = Client::with_options(opts)?;
33
55
    client.list_database_names(None, None).await?;
34
11
    Ok(client.database(&options.db))
35
11
}
36

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