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
14
pub async fn connect(options: &Options) -> Result<Database, Box<dyn StdError>> {
22
14
    let mut opts = ClientOptions::parse(&options.url).await?;
23
14
    if let Some(pool_size) = options.pool_size {
24
1
        opts.max_pool_size = Some(pool_size);
25
13
    }
26
14
    opts.cmap_event_handler = Some(EventHandler::Callback(Arc::new(event_handler)));
27
14
    let client = Client::with_options(opts)?;
28
70
    client.list_database_names().await?;
29
14
    Ok(client.database(&options.db))
30
14
}
31

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