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

            
32
10374
fn event_handler(ev: CmapEvent) {
33
10374
    match ev {
34
9
        CmapEvent::PoolCreated(_ev) => {
35
9
            info!("[CmapEvent::PoolCreated]");
36
        }
37
9
        CmapEvent::PoolReady(_ev) => {
38
9
            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
9
        CmapEvent::ConnectionCreated(_ev) => {
47
9
            info!("[CmapEvent::ConnectionCreated]");
48
        }
49
9
        CmapEvent::ConnectionReady(_ev) => {
50
9
            info!("[CmapEvent::ConnectionReady]");
51
        }
52
3
        CmapEvent::ConnectionClosed(_ev) => {
53
3
            error!("[CmapEvent::ConnectionClosed]");
54
        }
55
3444
        CmapEvent::ConnectionCheckoutStarted(_ev) => {
56
3444
            info!("[CmapEvent::ConnectionCheckoutStarted]");
57
        }
58
        CmapEvent::ConnectionCheckoutFailed(_ev) => {
59
            error!("[CmapEvent::ConnectionCheckoutFailed]");
60
        }
61
3444
        CmapEvent::ConnectionCheckedOut(_ev) => {
62
3444
            info!("[CmapEvent::ConnectionCheckedOut]");
63
        }
64
3444
        CmapEvent::ConnectionCheckedIn(_ev) => {
65
3444
            info!("[CmapEvent::ConnectionCheckedIn]");
66
        }
67
        _ => {
68
            error!("[CmapEvent::Unknown]");
69
        }
70
    }
71
10374
}