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

            
3
use log::{error, info};
4
use mongodb::{
5
    event::{cmap::CmapEvent, EventHandler},
6
    options::ClientOptions,
7
    Client, Database,
8
};
9

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

            
20
/// Connect to MongoDB.
21
11
pub async fn connect(options: &Options) -> Result<Database, Box<dyn StdError>> {
22
11
    let mut opts = ClientOptions::parse(&options.url).await?;
23
11
    if let Some(pool_size) = options.pool_size {
24
1
        opts.max_pool_size = Some(pool_size);
25
10
    }
26
11
    opts.cmap_event_handler = Some(EventHandler::Callback(Arc::new(event_handler)));
27
11
    let client = Client::with_options(opts)?;
28
55
    client.list_database_names().await?;
29
11
    Ok(client.database(&options.db))
30
11
}
31

            
32
13253
fn event_handler(ev: CmapEvent) {
33
13253
    match ev {
34
11
        CmapEvent::PoolCreated(_ev) => {
35
11
            info!("[CmapEvent::PoolCreated]");
36
        }
37
11
        CmapEvent::PoolReady(_ev) => {
38
11
            info!("[CmapEvent::PoolReady]");
39
        }
40
        CmapEvent::PoolCleared(_ev) => {
41
            error!("[CmapEvent::PoolCleared]");
42
        }
43
6
        CmapEvent::PoolClosed(_ev) => {
44
6
            error!("[CmapEvent::PoolClosed]");
45
        }
46
11
        CmapEvent::ConnectionCreated(_ev) => {
47
11
            info!("[CmapEvent::ConnectionCreated]");
48
        }
49
11
        CmapEvent::ConnectionReady(_ev) => {
50
11
            info!("[CmapEvent::ConnectionReady]");
51
        }
52
6
        CmapEvent::ConnectionClosed(_ev) => {
53
6
            error!("[CmapEvent::ConnectionClosed]");
54
        }
55
4399
        CmapEvent::ConnectionCheckoutStarted(_ev) => {
56
4399
            info!("[CmapEvent::ConnectionCheckoutStarted]");
57
        }
58
        CmapEvent::ConnectionCheckoutFailed(_ev) => {
59
            error!("[CmapEvent::ConnectionCheckoutFailed]");
60
        }
61
4399
        CmapEvent::ConnectionCheckedOut(_ev) => {
62
4399
            info!("[CmapEvent::ConnectionCheckedOut]");
63
        }
64
4399
        CmapEvent::ConnectionCheckedIn(_ev) => {
65
4399
            info!("[CmapEvent::ConnectionCheckedIn]");
66
        }
67
        _ => {
68
            error!("[CmapEvent::Unknown]");
69
        }
70
    }
71
13253
}